From 36dbd47ad6bed4fd4510c0468553d0f025b002cf Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Thu, 22 Jun 2023 10:30:32 -0700 Subject: [PATCH 1/3] [Impeller] fix and reland drawPaint collapsing optimization --- impeller/aiks/aiks_unittests.cc | 12 ++++++++++++ impeller/aiks/canvas.cc | 8 ++++++++ impeller/renderer/render_target.cc | 2 +- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/impeller/aiks/aiks_unittests.cc b/impeller/aiks/aiks_unittests.cc index 464dc000216a2..37b13e5817971 100644 --- a/impeller/aiks/aiks_unittests.cc +++ b/impeller/aiks/aiks_unittests.cc @@ -1992,6 +1992,18 @@ TEST_P(AiksTest, OpacityPeepHoleApplicationTest) { ASSERT_TRUE(delegate->CanCollapseIntoParentPass(entity_pass.get())); } +TEST_P(AiksTest, DrawPaintAbsorbsClears) { + Canvas canvas; + canvas.DrawPaint({.color = Color::Red(), .blend_mode = BlendMode::kSource}); + canvas.DrawPaint( + {.color = Color::CornflowerBlue(), .blend_mode = BlendMode::kSource}); + + Picture picture = canvas.EndRecordingAsPicture(); + + ASSERT_EQ(picture.pass->GetElementCount(), 0u); + ASSERT_EQ(picture.pass->GetClearColor(), Color::CornflowerBlue()); +} + TEST_P(AiksTest, ForegroundBlendSubpassCollapseOptimization) { Canvas canvas; diff --git a/impeller/aiks/canvas.cc b/impeller/aiks/canvas.cc index 3e2962ea18983..272c6c2770894 100644 --- a/impeller/aiks/canvas.cc +++ b/impeller/aiks/canvas.cc @@ -172,6 +172,14 @@ void Canvas::DrawPath(const Path& path, const Paint& paint) { } void Canvas::DrawPaint(const Paint& paint) { + if (xformation_stack_.size() == 1 && // If we're recording the root pass, + GetCurrentPass().GetElementCount() == 0 && // and this is the first item, + paint.blend_mode == BlendMode::kSourceOver && paint.color.alpha >= 1.0f) { + // Then we can absorb this drawPaint as the clear color of the pass. + GetCurrentPass().SetClearColor(paint.color); + return; + } + Entity entity; entity.SetTransformation(GetCurrentTransformation()); entity.SetStencilDepth(GetStencilDepth()); diff --git a/impeller/renderer/render_target.cc b/impeller/renderer/render_target.cc index 67c18d95386e6..55ce503b59291 100644 --- a/impeller/renderer/render_target.cc +++ b/impeller/renderer/render_target.cc @@ -303,7 +303,7 @@ RenderTarget RenderTarget::CreateOffscreenMSAA( // Color attachment. ColorAttachment color0; - color0.clear_color = Color::BlackTransparent(); + color0.clear_color = color_attachment_config.clear_color; color0.load_action = color_attachment_config.load_action; color0.store_action = color_attachment_config.store_action; color0.texture = color0_msaa_tex; From 7848976ef551705c9a768339b26e136877f8b289 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Thu, 22 Jun 2023 13:33:19 -0700 Subject: [PATCH 2/3] added kSource too --- impeller/aiks/canvas.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/impeller/aiks/canvas.cc b/impeller/aiks/canvas.cc index 272c6c2770894..204f8425d4d31 100644 --- a/impeller/aiks/canvas.cc +++ b/impeller/aiks/canvas.cc @@ -174,7 +174,9 @@ void Canvas::DrawPath(const Path& path, const Paint& paint) { void Canvas::DrawPaint(const Paint& paint) { if (xformation_stack_.size() == 1 && // If we're recording the root pass, GetCurrentPass().GetElementCount() == 0 && // and this is the first item, - paint.blend_mode == BlendMode::kSourceOver && paint.color.alpha >= 1.0f) { + (paint.blend_mode == BlendMode::kSourceOver || + paint.blend_mode == BlendMode::kSource) && + paint.color.alpha >= 1.0f) { // Then we can absorb this drawPaint as the clear color of the pass. GetCurrentPass().SetClearColor(paint.color); return; From 0362a950ad79dfa1326b41e200bf2c5dd3252003 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Thu, 22 Jun 2023 16:29:40 -0700 Subject: [PATCH 3/3] Made the clear color only apply to the top surface --- impeller/entity/entity_pass.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/impeller/entity/entity_pass.cc b/impeller/entity/entity_pass.cc index ddb0d443a0a8a..b32bd6bd46332 100644 --- a/impeller/entity/entity_pass.cc +++ b/impeller/entity/entity_pass.cc @@ -477,7 +477,7 @@ EntityPass::EntityResult EntityPass::GetEntityForElement( renderer, // renderer subpass_size, // size subpass->GetTotalPassReads(renderer) > 0, // readable - clear_color_.Premultiply()); // clear_color + Color::BlackTransparent()); // clear_color if (!subpass_target.IsValid()) { VALIDATION_LOG << "Subpass render target is invalid.";