Skip to content
This repository was archived by the owner on Oct 8, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Android.common.mk
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,9 @@ LOCAL_C_INCLUDES += \
LOCAL_SHARED_LIBRARIES += \
libva \
libva-android
LOCAL_CPPFLAGS += -DVA_WITH_PAVP
LOCAL_CPPFLAGS += \
-DVA_WITH_PAVP \
-DVA_WITH_VPP
else
LOCAL_CPPFLAGS += -DDISABLE_VA
endif
Expand Down
4 changes: 3 additions & 1 deletion common/Android.mk
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,9 @@ LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/libva
LOCAL_SRC_FILES += compositor/va/varenderer.cpp \
compositor/va/vautils.cpp

LOCAL_CPPFLAGS += -DVA_WITH_PAVP
LOCAL_CPPFLAGS += \
-DVA_WITH_PAVP \
-DVA_WITH_VPP
else
LOCAL_CPPFLAGS += -DDISABLE_VA
endif
Expand Down
17 changes: 10 additions & 7 deletions common/compositor/compositor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,16 @@ bool Compositor::Draw(DisplayPlaneStateList &comp_planes,
media_state.scaling_mode_ = scaling_mode_;
media_state.deinterlace_ = deinterlace_;
lock_.unlock();
const OverlayLayer &layer = layers[plane.GetSourceLayers().at(0)];
media_state.layer_ = &layer;
// exclude the media buffer
OverlayBuffer *layerbuffer = layer.GetBuffer();
for (size_t index = 0; index < draw_buffers.size(); index++) {
if (draw_buffers[index] == layerbuffer) {
draw_buffers[index] = NULL;

for (auto layer_id : plane.GetSourceLayers()) {
OverlayLayer *layer = &(layers.at(layer_id));
media_state.layers_.emplace_back(layer);
// exclude the media buffer
OverlayBuffer *layerbuffer = layer->GetBuffer();
for (size_t index = 0; index < draw_buffers.size(); index++) {
if (draw_buffers[index] == layerbuffer) {
draw_buffers[index] = NULL;
}
}
}
} else if (plane.NeedsOffScreenComposition()) {
Expand Down
2 changes: 1 addition & 1 deletion common/compositor/renderstate.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ struct RenderState {
};

struct MediaState {
const OverlayLayer *layer_;
std::vector<OverlayLayer *> layers_;
HWCColorMap colors_;
HWCDeinterlaceProp deinterlace_;
uint32_t scaling_mode_;
Expand Down
202 changes: 104 additions & 98 deletions common/compositor/va/varenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@
#include "varenderer.h"
#include "platformdefines.h"

#include <xf86drm.h>
#include <drm_fourcc.h>
#include <math.h>
#include <xf86drm.h>

#include "hwctrace.h"
#include "hwcutils.h"
#include "nativesurface.h"
#include "overlaybuffer.h"
#include "renderstate.h"
Expand Down Expand Up @@ -233,14 +234,7 @@ bool VARenderer::Draw(const MediaState& state, NativeSurface* surface) {
CTRACE();
// TODO: Clear surface ?
surface->SetClearSurface(NativeSurface::kNone);
surface->GetLayer()->SetVideoLayer(true);

OverlayBuffer* buffer_out = surface->GetLayer()->GetBuffer();
if (!buffer_out) {
ETRACE("Get DRM buffer failed for buffer_out.\n");
return false;
}

int rt_format = DrmFormatToRTFormat(buffer_out->GetFormat());
if (va_context_ == VA_INVALID_ID || render_target_format_ != rt_format) {
render_target_format_ = rt_format;
Expand All @@ -250,127 +244,139 @@ bool VARenderer::Draw(const MediaState& state, NativeSurface* surface) {
}
}

// Get Input Surface.
OverlayBuffer* buffer_in = state.layer_->GetBuffer();
if (!buffer_in) {
ETRACE("Get DRM buffer failed for buffer_in.\n");
return false;
}
uint32_t dataspace = buffer_in->GetDataSpace();
const MediaResourceHandle& resource = buffer_in->GetMediaResource(
va_display_, state.layer_->GetSourceCropWidth(),
state.layer_->GetSourceCropHeight());
VASurfaceID surface_in = resource.surface_;
if (surface_in == VA_INVALID_ID) {
ETRACE("Failed to create Va Input Surface. \n");
return false;
}

// Get Output Surface.
OverlayLayer* layer_out = surface->GetLayer();
HwcRect<int> layer_out_disp_frame = layer_out->GetDisplayFrame();
int xtranslation = layer_out_disp_frame.left;
int ytranslation = layer_out_disp_frame.top;

const MediaResourceHandle& out_resource =
layer_out->GetBuffer()->GetMediaResource(
va_display_, layer_out->GetSourceCropWidth(),
layer_out->GetSourceCropHeight());
va_display_, layer_out->GetDisplayFrameWidth(),
layer_out->GetDisplayFrameWidth());
VASurfaceID surface_out = out_resource.surface_;
if (surface_out == VA_INVALID_ID) {
ETRACE("Failed to create Va Output Surface. \n");
return false;
}

// Set the protected status to output layer if input layer is protected
if (state.layer_->IsProtected()) {
layer_out->SetProtected(true);
} else {
layer_out->SetProtected(false);
}
layer_out->SetProtected(false);

VAStatus ret = VA_STATUS_SUCCESS;
ret = vaBeginPicture(va_display_, va_context_, surface_out);

VARectangle surface_region;
const OverlayLayer* layer_in = state.layer_;
const HwcRect<float>& source_crop = layer_in->GetSourceCrop();
surface_region.x = static_cast<int>(source_crop.left);
surface_region.y = static_cast<int>(source_crop.top);
surface_region.width = layer_in->GetSourceCropWidth();
surface_region.height = layer_in->GetSourceCropHeight();

VARectangle output_region;
const HwcRect<float>& source_crop_out = layer_out->GetSourceCrop();
output_region.x = static_cast<int>(source_crop_out.left);
output_region.y = static_cast<int>(source_crop_out.top);
output_region.width = layer_out->GetSourceCropWidth();
output_region.height = layer_out->GetSourceCropHeight();

VAProcPipelineParameterBuffer pipe_param = {};
pipe_param.surface = surface_in;
pipe_param.surface_region = &surface_region;
pipe_param.surface_color_standard = VAProcColorStandardBT601;
pipe_param.output_region = &output_region;
pipe_param.output_color_standard = VAProcColorStandardBT601;
OverlayLayer* layer_in = NULL;
uint32_t total_layers = state.layers_.size();
std::vector<ScopedVABufferID> pipeline_buffers(total_layers, va_display_);

for (uint32_t i = 0; i < total_layers; i++) {
layer_in = state.layers_.at(i);
if (layer_in->IsSolidColor())
continue;
ScopedVABufferID& pipeline_buffer = pipeline_buffers.at(i);
// Get Input Surface.
OverlayBuffer* buffer_in = layer_in->GetBuffer();
if (!buffer_in) {
ETRACE("Get DRM buffer failed for buffer_in.\n");
return false;
}
uint32_t dataspace = buffer_in->GetDataSpace();
const MediaResourceHandle& resource =
buffer_in->GetMediaResource(va_display_, layer_in->GetSourceCropWidth(),
layer_in->GetSourceCropHeight());
VASurfaceID surface_in = resource.surface_;
if (surface_in == VA_INVALID_ID) {
ETRACE("Failed to create Va Input Surface. \n");
return false;
}

// Set the protected status to output layer if input layer is protected
if (layer_in->IsProtected()) {
layer_out->SetProtected(true);
}

VARectangle surface_region;
const HwcRect<float>& source_crop = layer_in->GetSourceCrop();
surface_region.x = static_cast<int>(source_crop.left);
surface_region.y = static_cast<int>(source_crop.top);
surface_region.width = layer_in->GetSourceCropWidth();
surface_region.height = layer_in->GetSourceCropHeight();

VARectangle output_region;
HwcRect<int> display_frame = layer_in->GetDisplayFrame();
display_frame = TranslateRect(display_frame, -xtranslation, -ytranslation);
output_region.x = display_frame.left;
output_region.y = display_frame.top;
output_region.width = layer_in->GetDisplayFrameWidth();
output_region.height = layer_in->GetDisplayFrameHeight();

VAProcPipelineParameterBuffer pipe_param = {};
pipe_param.surface = surface_in;
pipe_param.surface_region = &surface_region;
pipe_param.surface_color_standard = VAProcColorStandardBT601;
pipe_param.output_region = &output_region;
pipe_param.output_color_standard = VAProcColorStandardBT601;
#ifdef VA_SUPPORT_COLOR_RANGE
if ((dataspace & HAL_DATASPACE_RANGE_FULL) != 0) {
pipe_param.input_color_properties.color_range = VA_SOURCE_RANGE_FULL;
}
if ((dataspace & HAL_DATASPACE_RANGE_FULL) != 0) {
pipe_param.input_color_properties.color_range = VA_SOURCE_RANGE_FULL;
}
#endif

#ifdef VA_WITH_PAVP
if (state.layer_->IsProtected()) {
/*Turn on protected flag*/
pipe_param.input_surface_flag = 1;
}
if (layer_in->IsProtected()) {
/*Turn on protected flag*/
pipe_param.input_surface_flag = 1;
}
#endif

DUMPTRACE("surface_region: (%d, %d, %d, %d)\n", surface_region.x,
surface_region.y, surface_region.width, surface_region.height);
DUMPTRACE("Layer DisplayFrame:(%d,%d,%d,%d)\n", output_region.x,
output_region.y, output_region.width, output_region.height);
#ifdef VA_WITH_VPP
VABlendState bs = {};
bs.flags = VA_BLEND_PREMULTIPLIED_ALPHA;
pipe_param.blend_state = &bs;
#endif

for (auto itr = state.colors_.begin(); itr != state.colors_.end(); itr++) {
SetVAProcFilterColorValue(itr->first, itr->second);
}
DUMPTRACE("surface_region: (%d, %d, %d, %d)\n", surface_region.x,
surface_region.y, surface_region.width, surface_region.height);
DUMPTRACE("Layer DisplayFrame:(%d,%d,%d,%d)\n", output_region.x,
output_region.y, output_region.width, output_region.height);

SetVAProcFilterDeinterlaceMode(state.deinterlace_, buffer_in);
for (auto itr = state.colors_.begin(); itr != state.colors_.end(); itr++) {
SetVAProcFilterColorValue(itr->first, itr->second);
}
SetVAProcFilterDeinterlaceMode(state.deinterlace_, buffer_in);

if (!UpdateCaps()) {
ETRACE("Failed to update capabailities. \n");
return false;
}
if (!UpdateCaps()) {
ETRACE("Failed to update capabailities. \n");
return false;
}

pipe_param.filter_flags = GetVAProcFilterScalingMode(state.scaling_mode_);
if (filters_.size()) {
pipe_param.filters = filters_.data();
}
pipe_param.num_filters = static_cast<unsigned int>(filters_.size());
pipe_param.filter_flags = GetVAProcFilterScalingMode(state.scaling_mode_);
if (filters_.size()) {
pipe_param.filters = filters_.data();
}
pipe_param.num_filters = static_cast<unsigned int>(filters_.size());

#if VA_MAJOR_VERSION >= 1
// currently rotation is only supported by VA on Android.
uint32_t rotation = 0, mirror = 0;
HWCTransformToVA(state.layer_->GetTransform(), rotation, mirror);
pipe_param.rotation_state = rotation;
pipe_param.mirror_state = mirror;
// currently rotation is only supported by VA on Android.
uint32_t rotation = 0, mirror = 0;
HWCTransformToVA(layer_in->GetTransform(), rotation, mirror);
pipe_param.rotation_state = rotation;
pipe_param.mirror_state = mirror;
#endif

ScopedVABufferID pipeline_buffer(va_display_);
if (!pipeline_buffer.CreateBuffer(
va_context_, VAProcPipelineParameterBufferType,
sizeof(VAProcPipelineParameterBuffer), 1, &pipe_param)) {
return false;
if (!pipeline_buffer.CreateBuffer(
va_context_, VAProcPipelineParameterBufferType,
sizeof(VAProcPipelineParameterBuffer), 1, &pipe_param)) {
return false;
}

ret |=
vaRenderPicture(va_display_, va_context_, &pipeline_buffer.buffer(), 1);
}

VAStatus ret = VA_STATUS_SUCCESS;
ret = vaBeginPicture(va_display_, va_context_, surface_out);
ret |=
vaRenderPicture(va_display_, va_context_, &pipeline_buffer.buffer(), 1);
ret |= vaEndPicture(va_display_, va_context_);

if (surface_region.width == 1920 && surface_region.height == 1080) {
// FIXME: WA for OAM-63127. Not sure why this is needed but seems
// to ensure we have consistent 60 fps.
vaSyncSurface(va_display_, surface_out);
}

surface->ResetDamage();

return ret == VA_STATUS_SUCCESS ? true : false;
}

Expand Down
12 changes: 12 additions & 0 deletions common/compositor/va/vautils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ int DrmFormatToVAFormat(int format) {
return VA_FOURCC_YUY2;
case DRM_FORMAT_P010:
return VA_FOURCC_P010;
case DRM_FORMAT_ABGR8888:
return VA_FOURCC_RGBA;
case DRM_FORMAT_XBGR8888:
return VA_FOURCC_RGBX;
case DRM_FORMAT_ARGB8888:
return VA_FOURCC_ABGR;
case DRM_FORMAT_YVYU:
case DRM_FORMAT_VYUY:
case DRM_FORMAT_YUV444:
Expand Down Expand Up @@ -69,6 +75,12 @@ int DrmFormatToRTFormat(int format) {
return VA_RT_FORMAT_YUV444;
case DRM_FORMAT_P010:
return VA_RT_FORMAT_YUV420_10BPP;
case DRM_FORMAT_ABGR8888:
return VA_RT_FORMAT_RGB32;
case DRM_FORMAT_XBGR8888:
return VA_RT_FORMAT_RGB32;
case DRM_FORMAT_ARGB8888:
return VA_RT_FORMAT_RGB32;
default:
ETRACE("Unable to convert to RTFormat from format %x", format);
break;
Expand Down
Loading