Commit f48c7056 authored by Michael Ludwig's avatar Michael Ludwig Committed by Commit Bot

SkiaRenderer: Support texture quads bypassing RenderPasses

In the most common case, texture draw quads are just images and
can be bypassed very much like tiles or video quads. When it has
a background blend, we can still apply the RPDQ parameters but it's
no longer appropriate to merge the background alpha with the layer's
opacity.

Unfortunately, it starts getting really tricky to sort out the
proper order of operations for per-vertex opacity, layer opacity, and
other forms of masking. This seems like a pretty rare corner case
for texture quad usage (I only found unit tests and one place in
Chrome that uses it), so CanPassBeDrawnDirectly just prevents quads
with per-vertex opacities form being bypassed.

Bug: 1013735
Change-Id: I504d9492f5261c4930776c8d91504c9b71e1df70
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1863590
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: default avatarweiliangc <weiliangc@chromium.org>
Cr-Commit-Position: refs/heads/master@{#709897}
parent 7f140f85
...@@ -965,9 +965,7 @@ void SkiaRenderer::DrawQuadInternal(const DrawQuad* quad, ...@@ -965,9 +965,7 @@ void SkiaRenderer::DrawQuadInternal(const DrawQuad* quad,
params); params);
break; break;
case DrawQuad::Material::kTextureContent: case DrawQuad::Material::kTextureContent:
// TODO(michaelludwig) - Support texture quads bypassing a renderpass DrawTextureQuad(TextureDrawQuad::MaterialCast(quad), rpdq_params, params);
DCHECK(rpdq_params == nullptr);
DrawTextureQuad(TextureDrawQuad::MaterialCast(quad), params);
break; break;
case DrawQuad::Material::kTiledContent: case DrawQuad::Material::kTiledContent:
DrawTileDrawQuad(TileDrawQuad::MaterialCast(quad), rpdq_params, params); DrawTileDrawQuad(TileDrawQuad::MaterialCast(quad), rpdq_params, params);
...@@ -1279,13 +1277,24 @@ const DrawQuad* SkiaRenderer::CanPassBeDrawnDirectly(const RenderPass* pass) { ...@@ -1279,13 +1277,24 @@ const DrawQuad* SkiaRenderer::CanPassBeDrawnDirectly(const RenderPass* pass) {
return nullptr; return nullptr;
const DrawQuad* quad = *pass->quad_list.BackToFrontBegin(); const DrawQuad* quad = *pass->quad_list.BackToFrontBegin();
// TODO(michaelludwig) - With additional caveats, kTexture can be drawn direct // For simplicity in their draw implementations, debug borders, picture quads,
// and nested render passes cannot bypass a render pass
// (their draw functions do not accept DrawRPDQParams either).
if (quad->material == DrawQuad::Material::kRenderPass || if (quad->material == DrawQuad::Material::kRenderPass ||
quad->material == DrawQuad::Material::kDebugBorder || quad->material == DrawQuad::Material::kDebugBorder ||
quad->material == DrawQuad::Material::kPictureContent || quad->material == DrawQuad::Material::kPictureContent)
quad->material == DrawQuad::Material::kTextureContent)
return nullptr; return nullptr;
if (quad->material == DrawQuad::Material::kTextureContent) {
// Per-vertex opacities complicate bypassing the RP and alpha blending the
// texture with image filters, so punt under that rare circumstance.
const TextureDrawQuad* tex = TextureDrawQuad::MaterialCast(quad);
if (tex->vertex_opacity[0] < 1.f || tex->vertex_opacity[1] < 1.f ||
tex->vertex_opacity[2] < 1.f || tex->vertex_opacity[3] < 1.f) {
return nullptr;
}
}
// In order to concatenate the bypass'ed quads transform with RP itself, it // In order to concatenate the bypass'ed quads transform with RP itself, it
// needs to be invertible. // needs to be invertible.
if (!quad->shared_quad_state->quad_to_target_transform.IsInvertible()) if (!quad->shared_quad_state->quad_to_target_transform.IsInvertible())
...@@ -1720,6 +1729,7 @@ void SkiaRenderer::DrawStreamVideoQuad(const StreamVideoDrawQuad* quad, ...@@ -1720,6 +1729,7 @@ void SkiaRenderer::DrawStreamVideoQuad(const StreamVideoDrawQuad* quad,
} }
void SkiaRenderer::DrawTextureQuad(const TextureDrawQuad* quad, void SkiaRenderer::DrawTextureQuad(const TextureDrawQuad* quad,
const DrawRPDQParams* rpdq_params,
DrawQuadParams* params) { DrawQuadParams* params) {
ScopedSkImageBuilder builder( ScopedSkImageBuilder builder(
this, quad->resource_id(), this, quad->resource_id(),
...@@ -1750,21 +1760,33 @@ void SkiaRenderer::DrawTextureQuad(const TextureDrawQuad* quad, ...@@ -1750,21 +1760,33 @@ void SkiaRenderer::DrawTextureQuad(const TextureDrawQuad* quad,
quad->vertex_opacity[0] < 1.f || quad->vertex_opacity[1] < 1.f || quad->vertex_opacity[0] < 1.f || quad->vertex_opacity[1] < 1.f ||
quad->vertex_opacity[2] < 1.f || quad->vertex_opacity[3] < 1.f; quad->vertex_opacity[2] < 1.f || quad->vertex_opacity[3] < 1.f;
if (!blend_background && !vertex_alpha) { if (!blend_background && !vertex_alpha && !rpdq_params) {
// This is a simple texture draw and can go into the batching system // This is a simple texture draw and can go into the batching system
DCHECK(!MustFlushBatchedQuads(quad, nullptr, *params)); DCHECK(!MustFlushBatchedQuads(quad, rpdq_params, *params));
AddQuadToBatch(image, valid_texel_bounds, params); AddQuadToBatch(image, valid_texel_bounds, params);
return; return;
} }
// This needs a color filter for background blending and/or a mask filter // This needs a color filter for background blending and/or a mask filter
// to simulate the vertex opacity, which requires configuring a full SkPaint // to simulate the vertex opacity, which requires configuring a full SkPaint
// and is incompatible with anything batched // and is incompatible with anything batched, but since MustFlushBatchedQuads
// was optimistic for TextureQuad's, we're responsible for flushing now.
if (!batched_quads_.empty()) if (!batched_quads_.empty())
FlushBatchedQuads(); FlushBatchedQuads();
SkPaint paint = params->paint(); SkPaint paint = params->paint();
float quad_alpha = params->opacity; float quad_alpha;
params->opacity = 1.f; if (rpdq_params) {
// The added color filters for background blending will not apply the
// layer's opacity, but make sure there's no vertex_alpha since
// CanPassBeDrawnDirectly() should have caught that case.
DCHECK(!vertex_alpha);
quad_alpha = 1.f;
} else {
// We will entirely handle the quad's opacity with the mask or color filter
quad_alpha = params->opacity;
params->opacity = 1.f;
}
if (vertex_alpha) { if (vertex_alpha) {
// If they are all the same value, combine it with the overall opacity, // If they are all the same value, combine it with the overall opacity,
// otherwise use a mask filter to emulate vertex opacity interpolation // otherwise use a mask filter to emulate vertex opacity interpolation
...@@ -1827,10 +1849,13 @@ void SkiaRenderer::DrawTextureQuad(const TextureDrawQuad* quad, ...@@ -1827,10 +1849,13 @@ void SkiaRenderer::DrawTextureQuad(const TextureDrawQuad* quad,
paint.setColorFilter(std::move(cf)); paint.setColorFilter(std::move(cf));
} }
// Override the default paint opacity since it may not be params.opacity if (!rpdq_params) {
paint.setAlphaf(quad_alpha); // Reset the paint's alpha, since it started as params.opacity and that
// is now applied outside of the paint's alpha.
paint.setAlphaf(quad_alpha);
}
DrawSingleImage(image, valid_texel_bounds, nullptr, &paint, params); DrawSingleImage(image, valid_texel_bounds, rpdq_params, &paint, params);
} }
void SkiaRenderer::DrawTileDrawQuad(const TileDrawQuad* quad, void SkiaRenderer::DrawTileDrawQuad(const TileDrawQuad* quad,
......
...@@ -193,7 +193,9 @@ class VIZ_SERVICE_EXPORT SkiaRenderer : public DirectRenderer { ...@@ -193,7 +193,9 @@ class VIZ_SERVICE_EXPORT SkiaRenderer : public DirectRenderer {
void DrawStreamVideoQuad(const StreamVideoDrawQuad* quad, void DrawStreamVideoQuad(const StreamVideoDrawQuad* quad,
const DrawRPDQParams* rpdq_params, const DrawRPDQParams* rpdq_params,
DrawQuadParams* params); DrawQuadParams* params);
void DrawTextureQuad(const TextureDrawQuad* quad, DrawQuadParams* params); void DrawTextureQuad(const TextureDrawQuad* quad,
const DrawRPDQParams* rpdq_params,
DrawQuadParams* params);
void DrawTileDrawQuad(const TileDrawQuad* quad, void DrawTileDrawQuad(const TileDrawQuad* quad,
const DrawRPDQParams* rpdq_params, const DrawRPDQParams* rpdq_params,
DrawQuadParams* params); DrawQuadParams* params);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment