From ca184ba159645352dfbb3f83703966133ee3f412 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Fri, 13 Oct 2023 09:20:56 -0700 Subject: [PATCH 1/2] [Impeller] fix clear color optimization for large subpasses. --- impeller/aiks/aiks_unittests.cc | 20 ++++++++++++++++++++ impeller/entity/entity_pass.cc | 5 +++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/impeller/aiks/aiks_unittests.cc b/impeller/aiks/aiks_unittests.cc index 1a50dbe3e9406..240ed2dc17220 100644 --- a/impeller/aiks/aiks_unittests.cc +++ b/impeller/aiks/aiks_unittests.cc @@ -3664,5 +3664,25 @@ TEST_P(AiksTest, ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); } +// This should be solid red, if you see a little red box this is broken. +TEST_P(AiksTest, ClearColorOptimizationWhenSubpassIsBiggerThanParentPass) { + SetWindowSize({400, 400}); + Canvas canvas; + canvas.Scale(GetContentScale()); + canvas.DrawRect(Rect::MakeLTRB(200, 200, 300, 300), {.color = Color::Red()}); + canvas.SaveLayer({ + .image_filter = std::make_shared( + Matrix::MakeScale({2, 2, 1}), SamplerDescriptor{}), + }); + // Draw a rectangle that would fully cover the parent pass size, but not + // the subpass that it is rendered in. + canvas.DrawRect(Rect::MakeLTRB(0, 0, 400, 400), {.color = Color::Green()}); + // Draw a bigger rectangle to force the subpass to be bigger. + canvas.DrawRect(Rect::MakeLTRB(0, 0, 800, 800), {.color = Color::Red()}); + canvas.Restore(); + + ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); +} + } // namespace testing } // namespace impeller diff --git a/impeller/entity/entity_pass.cc b/impeller/entity/entity_pass.cc index bb065b959e146..11219ad4937d5 100644 --- a/impeller/entity/entity_pass.cc +++ b/impeller/entity/entity_pass.cc @@ -726,9 +726,10 @@ bool EntityPass::OnRender( VALIDATION_LOG << SPrintF("Pass context invalid (Depth=%d)", pass_depth); return false; } + auto clear_color_size = pass_target.GetRenderTarget().GetRenderTargetSize(); if (!collapsed_parent_pass && - !GetClearColor(root_pass_size).IsTransparent()) { + !GetClearColor(clear_color_size).IsTransparent()) { // Force the pass context to create at least one new pass if the clear color // is present. pass_context.GetRenderPass(pass_depth); @@ -897,7 +898,7 @@ bool EntityPass::OnRender( // Skip elements that are incorporated into the clear color. if (is_collapsing_clear_colors) { auto [entity_color, _] = - ElementAsBackgroundColor(element, root_pass_size); + ElementAsBackgroundColor(element, clear_color_size); if (entity_color.has_value()) { continue; } From 81c3fe499abdb650842ab61a7135d4db4aa55014 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Fri, 13 Oct 2023 11:48:33 -0700 Subject: [PATCH 2/2] ++ --- impeller/aiks/aiks_unittests.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/impeller/aiks/aiks_unittests.cc b/impeller/aiks/aiks_unittests.cc index 240ed2dc17220..3dda081b04a74 100644 --- a/impeller/aiks/aiks_unittests.cc +++ b/impeller/aiks/aiks_unittests.cc @@ -2134,9 +2134,12 @@ TEST_P(AiksTest, CanRenderClippedLayers) { canvas.DrawRect(Rect::MakeSize(Size{400, 400}), {.color = Color::White()}); // Fill the layer with green, but do so with a color blend that can't be // collapsed into the parent pass. + // TODO(jonahwilliams): this blend mode was changed from color burn to + // hardlight to work around https://github.com/flutter/flutter/issues/136554 + // . canvas.DrawRect( Rect::MakeSize(Size{400, 400}), - {.color = Color::Green(), .blend_mode = BlendMode::kColorBurn}); + {.color = Color::Green(), .blend_mode = BlendMode::kHardLight}); } ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));