Skip to content
This repository was archived by the owner on Oct 8, 2024. It is now read-only.

Commit aa03dd7

Browse files
committed
Varenderer: Add support for blending multiple layers.
In cases where we fail to dedicate a separate plane for protected content, say we have only one HW plane, the layers must be composed using VAAPI as Mesa doesn't support composition of protected content. Jira: None Test: When we have only one plane for display, all the contents are properly rendered. Change-Id: I56da9b478a614d4f8c6746d8995ae7f3146b26ac Signed-off-by: Harish Krupo <harish.krupo.kps@intel.com>
1 parent 462aabf commit aa03dd7

File tree

3 files changed

+113
-78
lines changed

3 files changed

+113
-78
lines changed

common/compositor/renderstate.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ struct RenderState {
6060
};
6161

6262
struct MediaState {
63-
const OverlayLayer *layer_;
63+
std::vector<OverlayLayer*> layers_;
6464
HWCColorMap colors_;
6565
HWCDeinterlaceProp deinterlace_;
6666
uint32_t scaling_mode_;

common/compositor/va/varenderer.cpp

Lines changed: 98 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <drm_fourcc.h>
2222
#include <math.h>
2323

24+
#include "hwcutils.h"
2425
#include "hwctrace.h"
2526
#include "nativesurface.h"
2627
#include "overlaybuffer.h"
@@ -243,107 +244,127 @@ bool VARenderer::Draw(const MediaState& state, NativeSurface* surface) {
243244
}
244245
}
245246

246-
// Get Input Surface.
247-
OverlayBuffer* buffer_in = state.layer_->GetBuffer();
248-
const MediaResourceHandle& resource = buffer_in->GetMediaResource(
249-
va_display_, state.layer_->GetSourceCropWidth(),
250-
state.layer_->GetSourceCropHeight());
251-
VASurfaceID surface_in = resource.surface_;
252-
if (surface_in == VA_INVALID_ID) {
253-
ETRACE("Failed to create Va Input Surface. \n");
254-
return false;
255-
}
256-
257247
// Get Output Surface.
258248
OverlayLayer* layer_out = surface->GetLayer();
249+
HwcRect<int> layer_out_disp_frame = layer_out->GetDisplayFrame();
250+
int xtranslation = layer_out_disp_frame.left;
251+
int ytranslation = layer_out_disp_frame.top;
252+
259253
const MediaResourceHandle& out_resource =
260-
layer_out->GetBuffer()->GetMediaResource(
261-
va_display_, layer_out->GetSourceCropWidth(),
262-
layer_out->GetSourceCropHeight());
254+
layer_out->GetBuffer()->GetMediaResource(
255+
va_display_, layer_out->GetDisplayFrameWidth(),
256+
layer_out->GetDisplayFrameWidth());
263257
VASurfaceID surface_out = out_resource.surface_;
264258
if (surface_out == VA_INVALID_ID) {
265259
ETRACE("Failed to create Va Output Surface. \n");
266260
return false;
267261
}
268262

269-
// Set the protected status to output layer if input layer is protected
270-
if (state.layer_->IsProtected()) {
271-
layer_out->SetProtected(true);
272-
} else {
273-
layer_out->SetProtected(false);
274-
}
263+
layer_out->SetProtected(false);
275264

276-
VARectangle surface_region;
277-
const OverlayLayer* layer_in = state.layer_;
278-
const HwcRect<float>& source_crop = layer_in->GetSourceCrop();
279-
surface_region.x = static_cast<int>(source_crop.left);
280-
surface_region.y = static_cast<int>(source_crop.top);
281-
surface_region.width = layer_in->GetSourceCropWidth();
282-
surface_region.height = layer_in->GetSourceCropHeight();
283-
284-
VARectangle output_region;
285-
const HwcRect<float>& source_crop_out = layer_out->GetSourceCrop();
286-
output_region.x = static_cast<int>(source_crop_out.left);
287-
output_region.y = static_cast<int>(source_crop_out.top);
288-
output_region.width = layer_out->GetSourceCropWidth();
289-
output_region.height = layer_out->GetSourceCropHeight();
290-
291-
VAProcPipelineParameterBuffer pipe_param = {};
292-
pipe_param.surface = surface_in;
293-
pipe_param.surface_region = &surface_region;
294-
pipe_param.surface_color_standard = VAProcColorStandardBT601;
295-
pipe_param.output_region = &output_region;
296-
pipe_param.output_color_standard = VAProcColorStandardBT601;
297-
298-
DUMPTRACE("surface_region: (%d, %d, %d, %d)\n", surface_region.x,
299-
surface_region.y, surface_region.width, surface_region.height);
300-
DUMPTRACE("Layer DisplayFrame:(%d,%d,%d,%d)\n", output_region.x,
301-
output_region.y, output_region.width, output_region.height);
302-
303-
for (auto itr = state.colors_.begin(); itr != state.colors_.end(); itr++) {
304-
SetVAProcFilterColorValue(itr->first, itr->second);
305-
}
265+
VAStatus ret = VA_STATUS_SUCCESS;
266+
ret = vaBeginPicture(va_display_, va_context_, surface_out);
306267

307-
SetVAProcFilterDeinterlaceMode(state.deinterlace_, buffer_in);
268+
OverlayLayer* layer_in = NULL;
269+
uint32_t total_layers = state.layers_.size();
270+
std::vector<ScopedVABufferID> pipeline_buffers(total_layers, va_display_);
271+
272+
for (uint32_t i = 0; i < total_layers; i++) {
273+
layer_in = state.layers_.at(i);
274+
ScopedVABufferID& pipeline_buffer = pipeline_buffers.at(i);
275+
// Get Input Surface.
276+
OverlayBuffer* buffer_in = layer_in->GetBuffer();
277+
const MediaResourceHandle& resource = buffer_in->GetMediaResource(
278+
va_display_, layer_in->GetSourceCropWidth(),
279+
layer_in->GetSourceCropHeight());
280+
VASurfaceID surface_in = resource.surface_;
281+
if (surface_in == VA_INVALID_ID) {
282+
ETRACE("Failed to create Va Input Surface. \n");
283+
return false;
284+
}
308285

309-
if (!UpdateCaps()) {
310-
ETRACE("Failed to update capabailities. \n");
311-
return false;
312-
}
286+
// Set the protected status to output layer if input layer is protected
287+
if (layer_in->IsProtected()) {
288+
layer_out->SetProtected(true);
289+
}
313290

314-
pipe_param.filter_flags = GetVAProcFilterScalingMode(state.scaling_mode_);
315-
if (filters_.size()) {
316-
pipe_param.filters = filters_.data();
317-
}
318-
pipe_param.num_filters = static_cast<unsigned int>(filters_.size());
291+
292+
VARectangle surface_region;
293+
const HwcRect<float>& source_crop = layer_in->GetSourceCrop();
294+
surface_region.x = static_cast<int>(source_crop.left);
295+
surface_region.y = static_cast<int>(source_crop.top);
296+
surface_region.width = layer_in->GetSourceCropWidth();
297+
surface_region.height = layer_in->GetSourceCropHeight();
298+
299+
VARectangle output_region;
300+
HwcRect<int> display_frame = layer_in->GetDisplayFrame();
301+
display_frame = TranslateRect(display_frame, -xtranslation, -ytranslation);
302+
output_region.x = display_frame.left;
303+
output_region.y = display_frame.top;
304+
output_region.width = layer_in->GetDisplayFrameWidth();
305+
output_region.height = layer_in->GetDisplayFrameHeight();
306+
307+
308+
VABlendState bs = {};
309+
bs.flags = VA_BLEND_PREMULTIPLIED_ALPHA;
310+
311+
VAProcPipelineParameterBuffer pipe_param = {};
312+
pipe_param.surface = surface_in;
313+
pipe_param.surface_region = &surface_region;
314+
pipe_param.surface_color_standard = VAProcColorStandardBT601;
315+
pipe_param.output_region = &output_region;
316+
pipe_param.output_color_standard = VAProcColorStandardBT601;
317+
pipe_param.blend_state = &bs;
318+
319+
DUMPTRACE("surface_region: (%d, %d, %d, %d)\n", surface_region.x,
320+
surface_region.y, surface_region.width, surface_region.height);
321+
DUMPTRACE("Layer DisplayFrame:(%d,%d,%d,%d)\n", output_region.x,
322+
output_region.y, output_region.width, output_region.height);
319323

320324
#if VA_MAJOR_VERSION >= 1
321-
// currently rotation is only supported by VA on Android.
322-
uint32_t rotation = 0, mirror = 0;
323-
HWCTransformToVA(state.layer_->GetTransform(), rotation, mirror);
324-
pipe_param.rotation_state = rotation;
325-
pipe_param.mirror_state = mirror;
325+
// currently rotation is only supported by VA on Android.
326+
uint32_t rotation = 0, mirror = 0;
327+
HWCTransformToVA(layer_in->GetTransform(), rotation, mirror);
328+
pipe_param.rotation_state = rotation;
329+
pipe_param.mirror_state = mirror;
326330
#endif
327331

328-
ScopedVABufferID pipeline_buffer(va_display_);
329-
if (!pipeline_buffer.CreateBuffer(
332+
for (auto itr = state.colors_.begin(); itr != state.colors_.end(); itr++) {
333+
SetVAProcFilterColorValue(itr->first, itr->second);
334+
}
335+
SetVAProcFilterDeinterlaceMode(state.deinterlace_, buffer_in);
336+
337+
if (!UpdateCaps()) {
338+
ETRACE("Failed to update capabailities. \n");
339+
return false;
340+
}
341+
342+
pipe_param.filter_flags = GetVAProcFilterScalingMode(state.scaling_mode_);
343+
if (filters_.size()) {
344+
pipe_param.filters = filters_.data();
345+
}
346+
pipe_param.num_filters = static_cast<unsigned int>(filters_.size());
347+
348+
if (!pipeline_buffer.CreateBuffer(
330349
va_context_, VAProcPipelineParameterBufferType,
331350
sizeof(VAProcPipelineParameterBuffer), 1, &pipe_param)) {
332-
return false;
333-
}
351+
return false;
352+
}
334353

335-
VAStatus ret = VA_STATUS_SUCCESS;
336-
ret = vaBeginPicture(va_display_, va_context_, surface_out);
337-
ret |=
354+
ret |=
338355
vaRenderPicture(va_display_, va_context_, &pipeline_buffer.buffer(), 1);
339-
ret |= vaEndPicture(va_display_, va_context_);
340356

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

359+
ret |= vaEndPicture(va_display_, va_context_);
360+
361+
// reviewer: How to resolve this?
362+
// if (surface_region.width == 1920 && surface_region.height == 1080) {
363+
// // FIXME: WA for OAM-63127. Not sure why this is needed but seems
364+
// // to ensure we have consistent 60 fps.
365+
// vaSyncSurface(va_display_, surface_out);
366+
// }
367+
347368
surface->ResetDamage();
348369

349370
return ret == VA_STATUS_SUCCESS ? true : false;

common/compositor/va/vautils.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,13 @@ int DrmFormatToVAFormat(int format) {
4242
return VA_FOURCC_YUY2;
4343
case DRM_FORMAT_P010:
4444
return VA_FOURCC_P010;
45+
// reviewer: please check this
46+
case DRM_FORMAT_ABGR8888:
47+
return VA_FOURCC_RGBA;
48+
case DRM_FORMAT_XBGR8888:
49+
return VA_FOURCC_RGBX;
50+
case DRM_FORMAT_ARGB8888:
51+
return VA_FOURCC_ABGR;
4552
case DRM_FORMAT_YVYU:
4653
case DRM_FORMAT_VYUY:
4754
case DRM_FORMAT_YUV444:
@@ -69,6 +76,13 @@ int DrmFormatToRTFormat(int format) {
6976
return VA_RT_FORMAT_YUV444;
7077
case DRM_FORMAT_P010:
7178
return VA_RT_FORMAT_YUV420_10BPP;
79+
// reviewer: please check this
80+
case DRM_FORMAT_ABGR8888:
81+
return VA_RT_FORMAT_RGB32;
82+
case DRM_FORMAT_XBGR8888:
83+
return VA_RT_FORMAT_RGB32;
84+
case DRM_FORMAT_ARGB8888:
85+
return VA_RT_FORMAT_RGB32;
7286
default:
7387
ETRACE("Unable to convert to RTFormat from format %x", format);
7488
break;

0 commit comments

Comments
 (0)