From 6a8d77dccd4d2239ce82e367b91e475f678250c5 Mon Sep 17 00:00:00 2001 From: Jason Simmons Date: Thu, 23 Jan 2025 07:45:55 -0800 Subject: [PATCH] [Impeller] Implement inherited opacity for ColorFilterContents (#161834) Inherited opacity should be combined with the alpha of the ColorFilterContents when drawing objects with filters inside an opacity layer. --- .../display_list/aiks_dl_blur_unittests.cc | 24 +++++++++++++++++++ .../contents/filters/color_filter_contents.cc | 6 ++++- .../contents/filters/color_filter_contents.h | 4 ++++ .../testing/impeller_golden_tests_output.txt | 3 +++ 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/engine/src/flutter/impeller/display_list/aiks_dl_blur_unittests.cc b/engine/src/flutter/impeller/display_list/aiks_dl_blur_unittests.cc index 63a3d5443a..0d235b6142 100644 --- a/engine/src/flutter/impeller/display_list/aiks_dl_blur_unittests.cc +++ b/engine/src/flutter/impeller/display_list/aiks_dl_blur_unittests.cc @@ -1376,5 +1376,29 @@ TEST_P(AiksTest, ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); } +TEST_P(AiksTest, BlurGradientWithOpacity) { + DisplayListBuilder builder; + builder.Scale(GetContentScale().x, GetContentScale().y); + + std::vector colors = {DlColor(0xFFFF0000), DlColor(0xFF00FF00)}; + std::vector stops = {0.0, 1.0}; + + auto gradient = DlColorSource::MakeLinear( + {0, 0}, {400, 400}, 2, colors.data(), stops.data(), DlTileMode::kClamp); + + DlPaint save_paint; + save_paint.setOpacity(0.5); + builder.SaveLayer(nullptr, &save_paint); + + DlPaint paint; + paint.setColorSource(gradient); + paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 1)); + builder.DrawRect(SkRect::MakeXYWH(100, 100, 200, 200), paint); + + builder.Restore(); + + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + } // namespace testing } // namespace impeller diff --git a/engine/src/flutter/impeller/entity/contents/filters/color_filter_contents.cc b/engine/src/flutter/impeller/entity/contents/filters/color_filter_contents.cc index 489cc4b0cd..6c88925be3 100644 --- a/engine/src/flutter/impeller/entity/contents/filters/color_filter_contents.cc +++ b/engine/src/flutter/impeller/entity/contents/filters/color_filter_contents.cc @@ -96,7 +96,11 @@ void ColorFilterContents::SetAlpha(Scalar alpha) { } std::optional ColorFilterContents::GetAlpha() const { - return alpha_; + return alpha_.value_or(1.0) * inherited_opacity_; +} + +void ColorFilterContents::SetInheritedOpacity(Scalar opacity) { + inherited_opacity_ = opacity; } std::optional ColorFilterContents::GetFilterSourceCoverage( diff --git a/engine/src/flutter/impeller/entity/contents/filters/color_filter_contents.h b/engine/src/flutter/impeller/entity/contents/filters/color_filter_contents.h index 14d9cb8aa5..9acaec6b43 100644 --- a/engine/src/flutter/impeller/entity/contents/filters/color_filter_contents.h +++ b/engine/src/flutter/impeller/entity/contents/filters/color_filter_contents.h @@ -45,6 +45,9 @@ class ColorFilterContents : public FilterContents { std::optional GetAlpha() const; + // |Contents| + void SetInheritedOpacity(Scalar opacity) override; + // |FilterContents| std::optional GetFilterSourceCoverage( const Matrix& effect_transform, @@ -53,6 +56,7 @@ class ColorFilterContents : public FilterContents { private: AbsorbOpacity absorb_opacity_ = AbsorbOpacity::kNo; std::optional alpha_; + Scalar inherited_opacity_ = 1.0; ColorFilterContents(const ColorFilterContents&) = delete; diff --git a/engine/src/flutter/testing/impeller_golden_tests_output.txt b/engine/src/flutter/testing/impeller_golden_tests_output.txt index 431408e7c1..875ea2e436 100644 --- a/engine/src/flutter/testing/impeller_golden_tests_output.txt +++ b/engine/src/flutter/testing/impeller_golden_tests_output.txt @@ -185,6 +185,9 @@ impeller_Play_AiksTest_BlendModeSrcAlphaXor_Vulkan.png impeller_Play_AiksTest_BlendModeXor_Metal.png impeller_Play_AiksTest_BlendModeXor_OpenGLES.png impeller_Play_AiksTest_BlendModeXor_Vulkan.png +impeller_Play_AiksTest_BlurGradientWithOpacity_Metal.png +impeller_Play_AiksTest_BlurGradientWithOpacity_OpenGLES.png +impeller_Play_AiksTest_BlurGradientWithOpacity_Vulkan.png impeller_Play_AiksTest_BlurHasNoEdge_Metal.png impeller_Play_AiksTest_BlurHasNoEdge_OpenGLES.png impeller_Play_AiksTest_BlurHasNoEdge_Vulkan.png