Skip to content
This repository was archived by the owner on Oct 8, 2024. It is now read-only.
Closed
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
130 changes: 80 additions & 50 deletions common/compositor/compositor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,6 @@ bool Compositor::Draw(DisplayPlaneStateList &comp_planes,
plane.GetSourceLayers().end());
}
} else if (plane.IsVideoPlane()) {
dedicated_layers.insert(dedicated_layers.end(),
plane.GetSourceLayers().begin(),
plane.GetSourceLayers().end());
media_state.emplace_back();
plane.SwapSurfaceIfNeeded();
DrawState &state = media_state.back();
Expand All @@ -87,56 +84,89 @@ 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;
OverlayLayer* layer = &(layers[plane.GetSourceLayers().at(0)]);
media_state.layers_.emplace_back(layer);
} else if (plane.NeedsOffScreenComposition()) {
comp = &plane;
plane.SwapSurfaceIfNeeded();
std::vector<CompositionRegion> &comp_regions =
plane.GetCompositionRegion();
bool regions_empty = comp_regions.empty();
NativeSurface *surface = plane.GetOffScreenTarget();
if (surface == NULL) {
ETRACE("GetOffScreenTarget() returned NULL pointer 'surface'.");
return false;
}
if (!regions_empty &&
(surface->ClearSurface() || surface->IsPartialClear() ||
surface->IsSurfaceDamageChanged())) {
plane.ResetCompositionRegion();
regions_empty = true;
}

if (surface->ClearSurface()) {
plane.UpdateDamage(plane.GetDisplayFrame());
}

if (regions_empty) {
SeparateLayers(dedicated_layers, comp->GetSourceLayers(), display_frame,
surface->GetSurfaceDamage(), comp_regions);
bool content_protected = false;

// If we have a video layer along with other layers then check
// if any of the layers contain protected content.
if (plane.HasVideoLayer()) {
for (size_t l : plane.GetSourceLayers()) {
OverlayLayer& layer = layers.at(l);
if (layer.IsProtected()) {
content_protected = true;
break;
}
}
}

std::vector<size_t>().swap(dedicated_layers);
if (comp_regions.empty())
continue;

draw_state.emplace_back();
DrawState &state = draw_state.back();
state.surface_ = surface;
size_t num_regions = comp_regions.size();
state.states_.reserve(num_regions);
bool use_plane_transform = false;
if (plane.GetRotationType() ==
DisplayPlaneState::RotationType::kGPURotation) {
use_plane_transform = true;
}

CalculateRenderState(layers, comp_regions, state,
plane.GetDownScalingFactor(),
plane.IsUsingPlaneScalar(), use_plane_transform);

if (state.states_.empty()) {
draw_state.pop_back();
if (content_protected) {
// if we have protected content along with other layers, then we
// need to use libva for the blending of the layers.
media_state.emplace_back();
plane.SwapSurfaceIfNeeded();
DrawState &state = media_state.back();
state.surface_ = plane.GetOffScreenTarget();
MediaState &media_state = state.media_state_;
lock_.lock();
media_state.colors_ = colors_;
media_state.scaling_mode_ = scaling_mode_;
media_state.deinterlace_ = deinterlace_;
lock_.unlock();
for (auto layer_id : plane.GetSourceLayers()) {
OverlayLayer *layer = &(layers.at(layer_id));
media_state.layers_.emplace_back(layer);
}
} else {
comp = &plane;
plane.SwapSurfaceIfNeeded();
std::vector<CompositionRegion> &comp_regions =
plane.GetCompositionRegion();
bool regions_empty = comp_regions.empty();
NativeSurface *surface = plane.GetOffScreenTarget();
if (surface == NULL) {
ETRACE("GetOffScreenTarget() returned NULL pointer 'surface'.");
return false;
}
if (!regions_empty &&
(surface->ClearSurface() || surface->IsPartialClear() ||
surface->IsSurfaceDamageChanged())) {
plane.ResetCompositionRegion();
regions_empty = true;
}

if (surface->ClearSurface()) {
plane.UpdateDamage(plane.GetDisplayFrame());
}

if (regions_empty) {
SeparateLayers(dedicated_layers, comp->GetSourceLayers(), display_frame,
surface->GetSurfaceDamage(), comp_regions);
}

std::vector<size_t>().swap(dedicated_layers);
if (comp_regions.empty())
continue;

draw_state.emplace_back();
DrawState &state = draw_state.back();
state.surface_ = surface;
size_t num_regions = comp_regions.size();
state.states_.reserve(num_regions);
bool use_plane_transform = false;
if (plane.GetRotationType() ==
DisplayPlaneState::RotationType::kGPURotation) {
use_plane_transform = true;
}

CalculateRenderState(layers, comp_regions, state,
plane.GetDownScalingFactor(),
plane.IsUsingPlaneScalar(), use_plane_transform);

if (state.states_.empty()) {
draw_state.pop_back();
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion common/compositor/renderstate.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ struct RenderState {
};

struct MediaState {
const OverlayLayer *layer_;
std::vector<OverlayLayer*> layers_;
HWCColorMap colors_;
HWCDeinterlaceProp deinterlace_;
uint32_t scaling_mode_;
Expand Down
175 changes: 98 additions & 77 deletions common/compositor/va/varenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <drm_fourcc.h>
#include <math.h>

#include "hwcutils.h"
#include "hwctrace.h"
#include "nativesurface.h"
#include "overlaybuffer.h"
Expand Down Expand Up @@ -243,107 +244,127 @@ bool VARenderer::Draw(const MediaState& state, NativeSurface* surface) {
}
}

// Get Input Surface.
OverlayBuffer* buffer_in = state.layer_->GetBuffer();
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());
layer_out->GetBuffer()->GetMediaResource(
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);

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;

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);

for (auto itr = state.colors_.begin(); itr != state.colors_.end(); itr++) {
SetVAProcFilterColorValue(itr->first, itr->second);
}
VAStatus ret = VA_STATUS_SUCCESS;
ret = vaBeginPicture(va_display_, va_context_, surface_out);

SetVAProcFilterDeinterlaceMode(state.deinterlace_, buffer_in);
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);
ScopedVABufferID& pipeline_buffer = pipeline_buffers.at(i);
// Get Input Surface.
OverlayBuffer* buffer_in = layer_in->GetBuffer();
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;
}

if (!UpdateCaps()) {
ETRACE("Failed to update capabailities. \n");
return false;
}
// Set the protected status to output layer if input layer is protected
if (layer_in->IsProtected()) {
layer_out->SetProtected(true);
}

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());

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();


VABlendState bs = {};
bs.flags = VA_BLEND_PREMULTIPLIED_ALPHA;

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;
pipe_param.blend_state = &bs;

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);

#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(
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;
}

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 (!pipeline_buffer.CreateBuffer(
va_context_, VAProcPipelineParameterBufferType,
sizeof(VAProcPipelineParameterBuffer), 1, &pipe_param)) {
return false;
}
return false;
}

VAStatus ret = VA_STATUS_SUCCESS;
ret = vaBeginPicture(va_display_, va_context_, surface_out);
ret |=
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);
}

ret |= vaEndPicture(va_display_, va_context_);

// reviewer: How to resolve this?
// 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
14 changes: 14 additions & 0 deletions common/compositor/va/vautils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ int DrmFormatToVAFormat(int format) {
return VA_FOURCC_YUY2;
case DRM_FORMAT_P010:
return VA_FOURCC_P010;
// reviewer: please check this
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 +76,13 @@ int DrmFormatToRTFormat(int format) {
return VA_RT_FORMAT_YUV444;
case DRM_FORMAT_P010:
return VA_RT_FORMAT_YUV420_10BPP;
// reviewer: please check this
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