From 2bc09e284cd9fefd570e365b2ab7debcdf60a00a Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 20 Sep 2023 01:13:37 -0400 Subject: [PATCH] [Impeller] Use BlackTransparent clear color when backdrop filters are present. (flutter/engine#46085) Fix for https://github.com/flutter/flutter/issues/135053. We already duck out of the Entity absorbing part of the optimization, but we also need to duck here when computing clear colors, otherwise we end up double-applying the effect of clearing entities at the beginning of a pass in some cases. --- .../flutter/impeller/aiks/aiks_unittests.cc | 29 +++++++++++++++++++ .../flutter/impeller/entity/entity_pass.cc | 4 +++ 2 files changed, 33 insertions(+) diff --git a/engine/src/flutter/impeller/aiks/aiks_unittests.cc b/engine/src/flutter/impeller/aiks/aiks_unittests.cc index be7b50c8cb3..35207daa55d 100644 --- a/engine/src/flutter/impeller/aiks/aiks_unittests.cc +++ b/engine/src/flutter/impeller/aiks/aiks_unittests.cc @@ -2368,6 +2368,35 @@ TEST_P(AiksTest, ClipRectElidesNoOpClips) { ASSERT_EQ(render_pass->GetCommands().size(), 0llu); } +TEST_P(AiksTest, ClearColorOptimizationDoesNotApplyForBackdropFilters) { + Canvas canvas; + canvas.SaveLayer({}, std::nullopt, + ImageFilter::MakeBlur(Sigma(3), Sigma(3), + FilterContents::BlurStyle::kNormal, + Entity::TileMode::kClamp)); + canvas.DrawPaint({.color = Color::Red(), .blend_mode = BlendMode::kSource}); + canvas.DrawPaint({.color = Color::CornflowerBlue().WithAlpha(0.75), + .blend_mode = BlendMode::kSourceOver}); + canvas.Restore(); + + Picture picture = canvas.EndRecordingAsPicture(); + + std::optional actual_color; + picture.pass->IterateAllElements([&](EntityPass::Element& element) -> bool { + if (auto subpass = std::get_if>(&element)) { + actual_color = subpass->get()->GetClearColor(); + } + // Fail if the first element isn't a subpass. + return true; + }); + + ASSERT_TRUE(actual_color.has_value()); + if (!actual_color) { + return; + } + ASSERT_EQ(actual_color.value(), Color::BlackTransparent()); +} + TEST_P(AiksTest, CollapsedDrawPaintInSubpass) { Canvas canvas; canvas.DrawPaint( diff --git a/engine/src/flutter/impeller/entity/entity_pass.cc b/engine/src/flutter/impeller/entity/entity_pass.cc index 6b4017ad0a1..e4b36fee3a4 100644 --- a/engine/src/flutter/impeller/entity/entity_pass.cc +++ b/engine/src/flutter/impeller/entity/entity_pass.cc @@ -1091,6 +1091,10 @@ void EntityPass::SetBlendMode(BlendMode blend_mode) { Color EntityPass::GetClearColor(ISize target_size) const { Color result = Color::BlackTransparent(); + if (backdrop_filter_proc_) { + return result; + } + for (const Element& element : elements_) { auto [entity_color, blend_mode] = ElementAsBackgroundColor(element, target_size);