Skip to content

Commit

Permalink
gpu: Add support for texture quad dc layers
Browse files Browse the repository at this point in the history
This CL allows texture quads with overlay compatible resources to be
promoted to overlays as dc layers.  The overlay processor also supports
y flipped resources which is the case with swap chain backed textures.
The direct composition surface puts the swap chain associated with the
texture quad into a DC visual.

Tested with https://codepen.io/miguelao/pen/WKZaqd and flags:
--enable-direct-composition-layers --enable-webgl-swap-chain

Bug: 939658
Change-Id: I165302817f8caa895b70ea82aab44434dc65d598
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1746796
Commit-Queue: Sunny Sachanandani <sunnyps@chromium.org>
Reviewed-by: Kenneth Russell <kbr@chromium.org>
Reviewed-by: Maggie Chen <magchen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#686300}
  • Loading branch information
sunnyps authored and Commit Bot committed Aug 13, 2019
1 parent 1a9cce9 commit 57da925
Show file tree
Hide file tree
Showing 25 changed files with 411 additions and 178 deletions.
70 changes: 67 additions & 3 deletions components/viz/service/display/dc_layer_overlay.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "components/viz/common/quads/debug_border_draw_quad.h"
#include "components/viz/common/quads/render_pass_draw_quad.h"
#include "components/viz/common/quads/solid_color_draw_quad.h"
#include "components/viz/common/quads/texture_draw_quad.h"
#include "components/viz/common/quads/yuv_video_draw_quad.h"
#include "components/viz/service/display/display_resource_provider.h"
#include "components/viz/service/display/output_surface.h"
Expand Down Expand Up @@ -44,6 +45,12 @@ enum DCLayerResult {
kMaxValue = DC_LAYER_FAILED_NO_HW_OVERLAY_SUPPORT,
};

enum : size_t {
kTextureResourceIndex = 0,
kYPlaneResourceIndex = 0,
kUVPlaneResourceIndex = 1,
};

DCLayerResult FromYUVQuad(const YUVVideoDrawQuad* quad,
const gfx::Transform& transform_to_root_target,
bool has_hw_overlay_support,
Expand Down Expand Up @@ -89,8 +96,8 @@ DCLayerResult FromYUVQuad(const YUVVideoDrawQuad* quad,
// one each for Y and UV planes.
DCHECK(quad->y_plane_resource_id() && quad->u_plane_resource_id());
DCHECK_EQ(quad->u_plane_resource_id(), quad->v_plane_resource_id());
dc_layer->y_resource_id = quad->y_plane_resource_id();
dc_layer->uv_resource_id = quad->u_plane_resource_id();
dc_layer->resources[kYPlaneResourceIndex] = quad->y_plane_resource_id();
dc_layer->resources[kUVPlaneResourceIndex] = quad->u_plane_resource_id();

dc_layer->z_order = 1;
dc_layer->content_rect = gfx::ToNearestRect(quad->ya_tex_coord_rect);
Expand All @@ -101,7 +108,7 @@ DCLayerResult FromYUVQuad(const YUVVideoDrawQuad* quad,
quad->shared_quad_state->quad_to_target_transform);
quad_to_root_transform.ConcatTransform(transform_to_root_target);
// Flatten transform to 2D since DirectComposition doesn't support 3D
// transforms.
// transforms. This only applies when non axis aligned overlays are enabled.
quad_to_root_transform.FlattenTo2d();
dc_layer->transform = quad_to_root_transform;

Expand All @@ -119,6 +126,58 @@ DCLayerResult FromYUVQuad(const YUVVideoDrawQuad* quad,
return DC_LAYER_SUCCESS;
}

DCLayerResult FromTextureQuad(const TextureDrawQuad* quad,
const gfx::Transform& transform_to_root_target,
DisplayResourceProvider* resource_provider,
DCLayerOverlay* dc_layer) {
// Check that resources are overlay compatible first so that subsequent
// assumptions are valid.
for (const auto& resource : quad->resources) {
if (!resource_provider->IsOverlayCandidate(resource))
return DC_LAYER_FAILED_TEXTURE_NOT_CANDIDATE;
}
if (quad->shared_quad_state->blend_mode != SkBlendMode::kSrcOver)
return DC_LAYER_FAILED_QUAD_BLEND_MODE;

if (!quad->shared_quad_state->quad_to_target_transform
.Preserves2dAxisAlignment() &&
!base::FeatureList::IsEnabled(
features::kDirectCompositionComplexOverlays)) {
return DC_LAYER_FAILED_COMPLEX_TRANSFORM;
}

dc_layer->resources[kTextureResourceIndex] = quad->resource_id();
dc_layer->z_order = 1;
dc_layer->content_rect = gfx::Rect(quad->resource_size_in_pixels());
dc_layer->quad_rect = quad->rect;
// Quad rect is in quad content space so both quad to target, and target to
// root transforms must be applied to it.
gfx::Transform quad_to_root_transform;
if (quad->y_flipped) {
quad_to_root_transform.Scale(1.0, -1.0);
quad_to_root_transform.PostTranslate(0.0, dc_layer->content_rect.height());
}
quad_to_root_transform.ConcatTransform(
quad->shared_quad_state->quad_to_target_transform);
quad_to_root_transform.ConcatTransform(transform_to_root_target);
// Flatten transform to 2D since DirectComposition doesn't support 3D
// transforms. This only applies when non axis aligned overlays are enabled.
quad_to_root_transform.FlattenTo2d();
dc_layer->transform = quad_to_root_transform;

dc_layer->is_clipped = quad->shared_quad_state->is_clipped;
if (dc_layer->is_clipped) {
// Clip rect is in quad target space, and must be transformed to root target
// space.
gfx::RectF clip_rect = gfx::RectF(quad->shared_quad_state->clip_rect);
transform_to_root_target.TransformRect(&clip_rect);
dc_layer->clip_rect = gfx::ToEnclosingRect(clip_rect);
}
dc_layer->color_space = gfx::ColorSpace::CreateSRGB();

return DC_LAYER_SUCCESS;
}

DCLayerResult IsUnderlayAllowed(const QuadList::Iterator& it,
bool is_root,
const DCLayerOverlay& dc_layer) {
Expand Down Expand Up @@ -412,6 +471,11 @@ void DCLayerOverlayProcessor::ProcessRenderPass(
uma_protected_video_type =
YUVVideoDrawQuad::MaterialCast(*it)->protected_video_type;
break;
case DrawQuad::Material::kTextureContent:
result = FromTextureQuad(TextureDrawQuad::MaterialCast(*it),
render_pass->transform_to_root_target,
resource_provider, &dc_layer);
break;
default:
result = DC_LAYER_FAILED_UNSUPPORTED_QUAD;
}
Expand Down
8 changes: 4 additions & 4 deletions components/viz/service/display/dc_layer_overlay.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ class VIZ_SERVICE_EXPORT DCLayerOverlay {
gfx::ProtectedVideoType::kHardwareProtected);
}

// Resource ids for video Y and UV planes. Can be the same resource.
// See DirectCompositionSurfaceWin for details.
ResourceId y_resource_id = 0;
ResourceId uv_resource_id = 0;
// Resource ids for video Y and UV planes, a single NV12 image, or a swap
// chain image. See DirectCompositionSurfaceWin for details.
enum : size_t { kNumResources = 2 };
ResourceId resources[kNumResources] = {kInvalidResourceId};

// Stacking order relative to backbuffer which has z-order 0.
int z_order = 1;
Expand Down
23 changes: 10 additions & 13 deletions components/viz/service/display/gl_renderer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3413,24 +3413,21 @@ void GLRenderer::ScheduleCALayers() {
void GLRenderer::ScheduleDCLayers() {
for (DCLayerOverlay& dc_layer_overlay :
current_frame()->dc_layer_overlay_list) {
ResourceId resource_ids[] = {dc_layer_overlay.y_resource_id,
dc_layer_overlay.uv_resource_id};
GLuint texture_ids[2] = {};
size_t i = 0;
for (ResourceId resource_id : resource_ids) {
DCHECK(resource_id);
DCHECK_EQ(DCLayerOverlay::kNumResources, 2u);
GLuint texture_ids[DCLayerOverlay::kNumResources] = {};
for (size_t i = 0; i < DCLayerOverlay::kNumResources; i++) {
ResourceId resource_id = dc_layer_overlay.resources[i];
if (resource_id == kInvalidResourceId)
break;
pending_overlay_resources_.push_back(
std::make_unique<DisplayResourceProvider::ScopedReadLockGL>(
resource_provider_, resource_id));
texture_ids[i++] = pending_overlay_resources_.back()->texture_id();
texture_ids[i] = pending_overlay_resources_.back()->texture_id();
}
GLuint y_texture_id = texture_ids[0];
GLuint uv_texture_id = texture_ids[1];
DCHECK(y_texture_id && uv_texture_id);

DCHECK(texture_ids[0]);
// TODO(sunnyps): Set color space in renderer like we do for tiles.
gl_->SetColorSpaceMetadataCHROMIUM(
y_texture_id,
texture_ids[0],
reinterpret_cast<GLColorSpace>(&dc_layer_overlay.color_space));

int z_order = dc_layer_overlay.z_order;
Expand All @@ -3444,7 +3441,7 @@ void GLRenderer::ScheduleDCLayers() {
static_cast<unsigned>(dc_layer_overlay.protected_video_type);

gl_->ScheduleDCLayerCHROMIUM(
y_texture_id, uv_texture_id, z_order, content_rect.x(),
texture_ids[0], texture_ids[1], z_order, content_rect.x(),
content_rect.y(), content_rect.width(), content_rect.height(),
quad_rect.x(), quad_rect.y(), quad_rect.width(), quad_rect.height(),
transform.get(0, 0), transform.get(0, 1), transform.get(1, 0),
Expand Down
2 changes: 1 addition & 1 deletion gpu/command_buffer/build_gles2_cmd_buffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -3927,7 +3927,7 @@
'unit_test': False,
},
'ScheduleDCLayerCHROMIUM': {
'cmd_args': 'GLuint y_texture_id, GLuint uv_texture_id, GLint z_order, '
'cmd_args': 'GLuint texture_0, GLuint texture_1, GLint z_order, '
'GLint content_x, GLint content_y, GLint content_width, '
'GLint content_height, GLint quad_x, GLint quad_y, '
'GLint quad_width, GLint quad_height, '
Expand Down
6 changes: 3 additions & 3 deletions gpu/command_buffer/client/gles2_c_lib_autogen.h
Original file line number Diff line number Diff line change
Expand Up @@ -1608,8 +1608,8 @@ void GL_APIENTRY GLES2FlushDriverCachesCHROMIUM() {
GLuint GL_APIENTRY GLES2GetLastFlushIdCHROMIUM() {
return gles2::GetGLContext()->GetLastFlushIdCHROMIUM();
}
void GL_APIENTRY GLES2ScheduleDCLayerCHROMIUM(GLuint y_texture_id,
GLuint uv_texture_id,
void GL_APIENTRY GLES2ScheduleDCLayerCHROMIUM(GLuint texture_0,
GLuint texture_1,
GLint z_order,
GLint content_x,
GLint content_y,
Expand All @@ -1632,7 +1632,7 @@ void GL_APIENTRY GLES2ScheduleDCLayerCHROMIUM(GLuint y_texture_id,
GLint clip_height,
GLuint protected_video_type) {
gles2::GetGLContext()->ScheduleDCLayerCHROMIUM(
y_texture_id, uv_texture_id, z_order, content_x, content_y, content_width,
texture_0, texture_1, z_order, content_x, content_y, content_width,
content_height, quad_x, quad_y, quad_width, quad_height, transform_c1r1,
transform_c2r1, transform_c1r2, transform_c2r2, transform_tx,
transform_ty, is_clipped, clip_x, clip_y, clip_width, clip_height,
Expand Down
14 changes: 7 additions & 7 deletions gpu/command_buffer/client/gles2_cmd_helper_autogen.h
Original file line number Diff line number Diff line change
Expand Up @@ -3002,8 +3002,8 @@ void FlushDriverCachesCHROMIUM() {
}
}

void ScheduleDCLayerCHROMIUM(GLuint y_texture_id,
GLuint uv_texture_id,
void ScheduleDCLayerCHROMIUM(GLuint texture_0,
GLuint texture_1,
GLint z_order,
GLint content_x,
GLint content_y,
Expand All @@ -3028,11 +3028,11 @@ void ScheduleDCLayerCHROMIUM(GLuint y_texture_id,
gles2::cmds::ScheduleDCLayerCHROMIUM* c =
GetCmdSpace<gles2::cmds::ScheduleDCLayerCHROMIUM>();
if (c) {
c->Init(y_texture_id, uv_texture_id, z_order, content_x, content_y,
content_width, content_height, quad_x, quad_y, quad_width,
quad_height, transform_c1r1, transform_c2r1, transform_c1r2,
transform_c2r2, transform_tx, transform_ty, is_clipped, clip_x,
clip_y, clip_width, clip_height, protected_video_type);
c->Init(texture_0, texture_1, z_order, content_x, content_y, content_width,
content_height, quad_x, quad_y, quad_width, quad_height,
transform_c1r1, transform_c2r1, transform_c1r2, transform_c2r2,
transform_tx, transform_ty, is_clipped, clip_x, clip_y, clip_width,
clip_height, protected_video_type);
}
}

Expand Down
4 changes: 2 additions & 2 deletions gpu/command_buffer/client/gles2_implementation_autogen.h
Original file line number Diff line number Diff line change
Expand Up @@ -1134,8 +1134,8 @@ void FlushDriverCachesCHROMIUM() override;

GLuint GetLastFlushIdCHROMIUM() override;

void ScheduleDCLayerCHROMIUM(GLuint y_texture_id,
GLuint uv_texture_id,
void ScheduleDCLayerCHROMIUM(GLuint texture_0,
GLuint texture_1,
GLint z_order,
GLint content_x,
GLint content_y,
Expand Down
20 changes: 10 additions & 10 deletions gpu/command_buffer/client/gles2_implementation_impl_autogen.h
Original file line number Diff line number Diff line change
Expand Up @@ -3472,8 +3472,8 @@ void GLES2Implementation::FlushDriverCachesCHROMIUM() {
CheckGLError();
}

void GLES2Implementation::ScheduleDCLayerCHROMIUM(GLuint y_texture_id,
GLuint uv_texture_id,
void GLES2Implementation::ScheduleDCLayerCHROMIUM(GLuint texture_0,
GLuint texture_1,
GLint z_order,
GLint content_x,
GLint content_y,
Expand All @@ -3497,18 +3497,18 @@ void GLES2Implementation::ScheduleDCLayerCHROMIUM(GLuint y_texture_id,
GLuint protected_video_type) {
GPU_CLIENT_SINGLE_THREAD_CHECK();
GPU_CLIENT_LOG(
"[" << GetLogPrefix() << "] glScheduleDCLayerCHROMIUM(" << y_texture_id
<< ", " << uv_texture_id << ", " << z_order << ", " << content_x
<< ", " << content_y << ", " << content_width << ", "
<< content_height << ", " << quad_x << ", " << quad_y << ", "
<< quad_width << ", " << quad_height << ", " << transform_c1r1 << ", "
<< transform_c2r1 << ", " << transform_c1r2 << ", " << transform_c2r2
<< ", " << transform_tx << ", " << transform_ty << ", "
"[" << GetLogPrefix() << "] glScheduleDCLayerCHROMIUM(" << texture_0
<< ", " << texture_1 << ", " << z_order << ", " << content_x << ", "
<< content_y << ", " << content_width << ", " << content_height
<< ", " << quad_x << ", " << quad_y << ", " << quad_width << ", "
<< quad_height << ", " << transform_c1r1 << ", " << transform_c2r1
<< ", " << transform_c1r2 << ", " << transform_c2r2 << ", "
<< transform_tx << ", " << transform_ty << ", "
<< GLES2Util::GetStringBool(is_clipped) << ", " << clip_x << ", "
<< clip_y << ", " << clip_width << ", " << clip_height << ", "
<< protected_video_type << ")");
helper_->ScheduleDCLayerCHROMIUM(
y_texture_id, uv_texture_id, z_order, content_x, content_y, content_width,
texture_0, texture_1, z_order, content_x, content_y, content_width,
content_height, quad_x, quad_y, quad_width, quad_height, transform_c1r1,
transform_c2r1, transform_c1r2, transform_c2r2, transform_tx,
transform_ty, is_clipped, clip_x, clip_y, clip_width, clip_height,
Expand Down
4 changes: 2 additions & 2 deletions gpu/command_buffer/client/gles2_interface_autogen.h
Original file line number Diff line number Diff line change
Expand Up @@ -844,8 +844,8 @@ virtual void CommitOverlayPlanesCHROMIUM(GLuint64 swap_id,
GLbitfield flags = 0) = 0;
virtual void FlushDriverCachesCHROMIUM() = 0;
virtual GLuint GetLastFlushIdCHROMIUM() = 0;
virtual void ScheduleDCLayerCHROMIUM(GLuint y_texture_id,
GLuint uv_texture_id,
virtual void ScheduleDCLayerCHROMIUM(GLuint texture_0,
GLuint texture_1,
GLint z_order,
GLint content_x,
GLint content_y,
Expand Down
4 changes: 2 additions & 2 deletions gpu/command_buffer/client/gles2_interface_stub_autogen.h
Original file line number Diff line number Diff line change
Expand Up @@ -819,8 +819,8 @@ void ScheduleCALayerInUseQueryCHROMIUM(GLsizei count,
void CommitOverlayPlanesCHROMIUM(GLuint64 swap_id, GLbitfield flags) override;
void FlushDriverCachesCHROMIUM() override;
GLuint GetLastFlushIdCHROMIUM() override;
void ScheduleDCLayerCHROMIUM(GLuint y_texture_id,
GLuint uv_texture_id,
void ScheduleDCLayerCHROMIUM(GLuint texture_0,
GLuint texture_1,
GLint z_order,
GLint content_x,
GLint content_y,
Expand Down
4 changes: 2 additions & 2 deletions gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
Original file line number Diff line number Diff line change
Expand Up @@ -1097,8 +1097,8 @@ GLuint GLES2InterfaceStub::GetLastFlushIdCHROMIUM() {
return 0;
}
void GLES2InterfaceStub::ScheduleDCLayerCHROMIUM(
GLuint /* y_texture_id */,
GLuint /* uv_texture_id */,
GLuint /* texture_0 */,
GLuint /* texture_1 */,
GLint /* z_order */,
GLint /* content_x */,
GLint /* content_y */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -819,8 +819,8 @@ void ScheduleCALayerInUseQueryCHROMIUM(GLsizei count,
void CommitOverlayPlanesCHROMIUM(GLuint64 swap_id, GLbitfield flags) override;
void FlushDriverCachesCHROMIUM() override;
GLuint GetLastFlushIdCHROMIUM() override;
void ScheduleDCLayerCHROMIUM(GLuint y_texture_id,
GLuint uv_texture_id,
void ScheduleDCLayerCHROMIUM(GLuint texture_0,
GLuint texture_1,
GLint z_order,
GLint content_x,
GLint content_y,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2314,8 +2314,8 @@ GLuint GLES2TraceImplementation::GetLastFlushIdCHROMIUM() {
}

void GLES2TraceImplementation::ScheduleDCLayerCHROMIUM(
GLuint y_texture_id,
GLuint uv_texture_id,
GLuint texture_0,
GLuint texture_1,
GLint z_order,
GLint content_x,
GLint content_y,
Expand All @@ -2339,7 +2339,7 @@ void GLES2TraceImplementation::ScheduleDCLayerCHROMIUM(
GLuint protected_video_type) {
TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::ScheduleDCLayerCHROMIUM");
gl_->ScheduleDCLayerCHROMIUM(
y_texture_id, uv_texture_id, z_order, content_x, content_y, content_width,
texture_0, texture_1, z_order, content_x, content_y, content_width,
content_height, quad_x, quad_y, quad_width, quad_height, transform_c1r1,
transform_c2r1, transform_c1r2, transform_c2r2, transform_tx,
transform_ty, is_clipped, clip_x, clip_y, clip_width, clip_height,
Expand Down

0 comments on commit 57da925

Please sign in to comment.