From 2a55c9edd89cea66108ea68b0846c54ff81700cd Mon Sep 17 00:00:00 2001 From: Jim Graham Date: Tue, 26 Nov 2024 12:48:20 -0800 Subject: [PATCH] [DisplayList] migrate DlColorFilter objects to new source layout (flutter/engine#56785) A new source code/header structure was introduced when the DlColorSource and DlImageFilter objects were migrated to Impeller geometry classes. Even though the DlColorFilter objects did not depend on Skia geometry objects, they need to be updated to the new source layout for consistency. --- .../ci/licenses_golden/licenses_flutter | 18 ++ engine/src/flutter/display_list/BUILD.gn | 10 + .../display_list/display_list_unittests.cc | 30 +-- engine/src/flutter/display_list/dl_builder.cc | 1 + .../display_list/dl_paint_unittests.cc | 14 +- .../color_filters/dl_blend_color_filter.cc | 126 +++++++++++ .../color_filters/dl_blend_color_filter.h | 60 +++++ .../dl_linear_to_srgb_gamma_color_filter.cc | 13 ++ .../dl_linear_to_srgb_gamma_color_filter.h | 46 ++++ .../color_filters/dl_matrix_color_filter.cc | 74 ++++++ .../color_filters/dl_matrix_color_filter.h | 72 ++++++ .../dl_srgb_to_linear_gamma_color_filter.cc | 13 ++ .../dl_srgb_to_linear_gamma_color_filter.h | 46 ++++ .../display_list/effects/dl_color_filter.cc | 198 ++-------------- .../display_list/effects/dl_color_filter.h | 212 ++++-------------- .../effects/dl_color_filter_unittests.cc | 6 +- .../display_list/effects/dl_color_filters.h | 13 ++ .../effects/dl_image_filter_unittests.cc | 2 +- .../display_list/skia/dl_sk_conversions.cc | 1 + .../skia/dl_sk_conversions_unittests.cc | 7 +- .../testing/dl_rendering_unittests.cc | 56 ++--- .../display_list/testing/dl_test_equality.h | 8 +- .../display_list/testing/dl_test_snippets.cc | 26 ++- .../display_list/testing/dl_test_snippets.h | 21 +- .../display_list/utils/dl_comparable.h | 74 +++--- .../layers/color_filter_layer_unittests.cc | 22 +- .../layers/layer_state_stack_unittests.cc | 23 +- .../display_list/aiks_dl_basic_unittests.cc | 10 +- .../display_list/aiks_dl_blend_unittests.cc | 20 +- .../display_list/aiks_dl_blur_unittests.cc | 4 +- .../aiks_dl_gradient_unittests.cc | 2 +- .../display_list/aiks_dl_path_unittests.cc | 2 +- .../display_list/aiks_dl_unittests.cc | 22 +- .../impeller/display_list/color_filter.cc | 2 +- .../impeller/display_list/dl_unittests.cc | 44 ++-- .../impeller/toolkit/interop/color_filter.cc | 10 +- .../impeller/toolkit/interop/color_filter.h | 6 +- .../flutter/lib/ui/painting/color_filter.cc | 8 +- .../lib/ui/painting/paint_unittests.cc | 2 +- .../flutter/testing/display_list_testing.cc | 1 + 40 files changed, 772 insertions(+), 553 deletions(-) create mode 100644 engine/src/flutter/display_list/effects/color_filters/dl_blend_color_filter.cc create mode 100644 engine/src/flutter/display_list/effects/color_filters/dl_blend_color_filter.h create mode 100644 engine/src/flutter/display_list/effects/color_filters/dl_linear_to_srgb_gamma_color_filter.cc create mode 100644 engine/src/flutter/display_list/effects/color_filters/dl_linear_to_srgb_gamma_color_filter.h create mode 100644 engine/src/flutter/display_list/effects/color_filters/dl_matrix_color_filter.cc create mode 100644 engine/src/flutter/display_list/effects/color_filters/dl_matrix_color_filter.h create mode 100644 engine/src/flutter/display_list/effects/color_filters/dl_srgb_to_linear_gamma_color_filter.cc create mode 100644 engine/src/flutter/display_list/effects/color_filters/dl_srgb_to_linear_gamma_color_filter.h create mode 100644 engine/src/flutter/display_list/effects/dl_color_filters.h diff --git a/engine/src/flutter/ci/licenses_golden/licenses_flutter b/engine/src/flutter/ci/licenses_golden/licenses_flutter index c20489d122..15bb63481a 100644 --- a/engine/src/flutter/ci/licenses_golden/licenses_flutter +++ b/engine/src/flutter/ci/licenses_golden/licenses_flutter @@ -42532,6 +42532,14 @@ ORIGIN: ../../../flutter/display_list/dl_storage.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/display_list/dl_tile_mode.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/display_list/dl_vertices.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/display_list/dl_vertices.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/display_list/effects/color_filters/dl_blend_color_filter.cc + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/display_list/effects/color_filters/dl_blend_color_filter.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/display_list/effects/color_filters/dl_linear_to_srgb_gamma_color_filter.cc + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/display_list/effects/color_filters/dl_linear_to_srgb_gamma_color_filter.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/display_list/effects/color_filters/dl_matrix_color_filter.cc + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/display_list/effects/color_filters/dl_matrix_color_filter.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/display_list/effects/color_filters/dl_srgb_to_linear_gamma_color_filter.cc + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/display_list/effects/color_filters/dl_srgb_to_linear_gamma_color_filter.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/display_list/effects/color_sources/dl_color_color_source.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/display_list/effects/color_sources/dl_color_color_source.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/display_list/effects/color_sources/dl_conical_gradient_color_source.cc + ../../../flutter/LICENSE @@ -42550,6 +42558,7 @@ ORIGIN: ../../../flutter/display_list/effects/color_sources/dl_sweep_gradient_co ORIGIN: ../../../flutter/display_list/effects/color_sources/dl_sweep_gradient_color_source.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/display_list/effects/dl_color_filter.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/display_list/effects/dl_color_filter.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/display_list/effects/dl_color_filters.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/display_list/effects/dl_color_source.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/display_list/effects/dl_color_source.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/display_list/effects/dl_color_sources.h + ../../../flutter/LICENSE @@ -45450,6 +45459,14 @@ FILE: ../../../flutter/display_list/dl_storage.h FILE: ../../../flutter/display_list/dl_tile_mode.h FILE: ../../../flutter/display_list/dl_vertices.cc FILE: ../../../flutter/display_list/dl_vertices.h +FILE: ../../../flutter/display_list/effects/color_filters/dl_blend_color_filter.cc +FILE: ../../../flutter/display_list/effects/color_filters/dl_blend_color_filter.h +FILE: ../../../flutter/display_list/effects/color_filters/dl_linear_to_srgb_gamma_color_filter.cc +FILE: ../../../flutter/display_list/effects/color_filters/dl_linear_to_srgb_gamma_color_filter.h +FILE: ../../../flutter/display_list/effects/color_filters/dl_matrix_color_filter.cc +FILE: ../../../flutter/display_list/effects/color_filters/dl_matrix_color_filter.h +FILE: ../../../flutter/display_list/effects/color_filters/dl_srgb_to_linear_gamma_color_filter.cc +FILE: ../../../flutter/display_list/effects/color_filters/dl_srgb_to_linear_gamma_color_filter.h FILE: ../../../flutter/display_list/effects/color_sources/dl_color_color_source.cc FILE: ../../../flutter/display_list/effects/color_sources/dl_color_color_source.h FILE: ../../../flutter/display_list/effects/color_sources/dl_conical_gradient_color_source.cc @@ -45468,6 +45485,7 @@ FILE: ../../../flutter/display_list/effects/color_sources/dl_sweep_gradient_colo FILE: ../../../flutter/display_list/effects/color_sources/dl_sweep_gradient_color_source.h FILE: ../../../flutter/display_list/effects/dl_color_filter.cc FILE: ../../../flutter/display_list/effects/dl_color_filter.h +FILE: ../../../flutter/display_list/effects/dl_color_filters.h FILE: ../../../flutter/display_list/effects/dl_color_source.cc FILE: ../../../flutter/display_list/effects/dl_color_source.h FILE: ../../../flutter/display_list/effects/dl_color_sources.h diff --git a/engine/src/flutter/display_list/BUILD.gn b/engine/src/flutter/display_list/BUILD.gn index c1c9f94fcf..b8b863d81f 100644 --- a/engine/src/flutter/display_list/BUILD.gn +++ b/engine/src/flutter/display_list/BUILD.gn @@ -47,6 +47,14 @@ source_set("display_list") { "dl_tile_mode.h", "dl_vertices.cc", "dl_vertices.h", + "effects/color_filters/dl_blend_color_filter.cc", + "effects/color_filters/dl_blend_color_filter.h", + "effects/color_filters/dl_linear_to_srgb_gamma_color_filter.cc", + "effects/color_filters/dl_linear_to_srgb_gamma_color_filter.h", + "effects/color_filters/dl_matrix_color_filter.cc", + "effects/color_filters/dl_matrix_color_filter.h", + "effects/color_filters/dl_srgb_to_linear_gamma_color_filter.cc", + "effects/color_filters/dl_srgb_to_linear_gamma_color_filter.h", "effects/color_sources/dl_color_color_source.cc", "effects/color_sources/dl_color_color_source.h", "effects/color_sources/dl_conical_gradient_color_source.cc", @@ -63,8 +71,10 @@ source_set("display_list") { "effects/color_sources/dl_sweep_gradient_color_source.h", "effects/dl_color_filter.cc", "effects/dl_color_filter.h", + "effects/dl_color_filters.h", "effects/dl_color_source.cc", "effects/dl_color_source.h", + "effects/dl_color_sources.h", "effects/dl_image_filter.cc", "effects/dl_image_filter.h", "effects/dl_image_filters.h", diff --git a/engine/src/flutter/display_list/display_list_unittests.cc b/engine/src/flutter/display_list/display_list_unittests.cc index c26c9bd77e..d7307d5373 100644 --- a/engine/src/flutter/display_list/display_list_unittests.cc +++ b/engine/src/flutter/display_list/display_list_unittests.cc @@ -518,7 +518,7 @@ TEST_F(DisplayListTest, BuildRestoresAttributes) { builder.Build(); check_defaults(builder, cull_rect); - receiver.setColorFilter(&kTestMatrixColorFilter1); + receiver.setColorFilter(kTestMatrixColorFilter1.get()); builder.Build(); check_defaults(builder, cull_rect); @@ -940,7 +940,7 @@ TEST_F(DisplayListTest, DisplayListSaveLayerBoundsWithAlphaFilter) { 0, 0, 0, 1, 0, }; // clang-format on - DlMatrixColorFilter base_color_filter(color_matrix); + auto base_color_filter = DlColorFilter::MakeMatrix(color_matrix); // clang-format off const float alpha_matrix[] = { 0, 0, 0, 0, 0, @@ -949,7 +949,7 @@ TEST_F(DisplayListTest, DisplayListSaveLayerBoundsWithAlphaFilter) { 0, 0, 0, 0, 1, }; // clang-format on - DlMatrixColorFilter alpha_color_filter(alpha_matrix); + auto alpha_color_filter = DlColorFilter::MakeMatrix(alpha_matrix); sk_sp sk_alpha_color_filter = SkColorFilters::Matrix(alpha_matrix); @@ -967,7 +967,7 @@ TEST_F(DisplayListTest, DisplayListSaveLayerBoundsWithAlphaFilter) { // Now checking that a normal color filter still produces rect bounds DisplayListBuilder builder(build_bounds); DlPaint save_paint; - save_paint.setColorFilter(&base_color_filter); + save_paint.setColorFilter(base_color_filter); builder.SaveLayer(&save_bounds, &save_paint); builder.DrawRect(rect, DlPaint()); builder.Restore(); @@ -999,7 +999,7 @@ TEST_F(DisplayListTest, DisplayListSaveLayerBoundsWithAlphaFilter) { // save layer that modifies an unbounded region DisplayListBuilder builder(build_bounds); DlPaint save_paint; - save_paint.setColorFilter(&alpha_color_filter); + save_paint.setColorFilter(alpha_color_filter); builder.SaveLayer(&save_bounds, &save_paint); builder.DrawRect(rect, DlPaint()); builder.Restore(); @@ -1012,7 +1012,7 @@ TEST_F(DisplayListTest, DisplayListSaveLayerBoundsWithAlphaFilter) { // to the behavior in the previous example DisplayListBuilder builder(build_bounds); DlPaint save_paint; - save_paint.setColorFilter(&alpha_color_filter); + save_paint.setColorFilter(alpha_color_filter); builder.SaveLayer(nullptr, &save_paint); builder.DrawRect(rect, DlPaint()); builder.Restore(); @@ -1668,7 +1668,7 @@ TEST_F(DisplayListTest, SaveLayerColorFilterDoesNotInheritOpacity) { DisplayListBuilder builder; DlPaint save_paint; save_paint.setColor(DlColor(SkColorSetARGB(127, 255, 255, 255))); - save_paint.setColorFilter(&kTestMatrixColorFilter1); + save_paint.setColorFilter(kTestMatrixColorFilter1); builder.SaveLayer(nullptr, &save_paint); builder.DrawRect(SkRect{10, 10, 20, 20}, DlPaint()); builder.Restore(); @@ -1720,7 +1720,7 @@ TEST_F(DisplayListTest, SaveLayerColorFilterOnChildDoesNotInheritOpacity) { save_paint.setColor(DlColor(SkColorSetARGB(127, 255, 255, 255))); builder.SaveLayer(nullptr, &save_paint); DlPaint draw_paint = save_paint; - draw_paint.setColorFilter(&kTestMatrixColorFilter1); + draw_paint.setColorFilter(kTestMatrixColorFilter1); builder.DrawRect(SkRect{10, 10, 20, 20}, draw_paint); builder.Restore(); @@ -2671,7 +2671,7 @@ TEST_F(DisplayListTest, RemoveUnnecessarySaveRestorePairsInSetPaint) { 0, 0, 0, 0, 1, }; // clang-format on - DlMatrixColorFilter alpha_color_filter(alpha_matrix); + auto alpha_color_filter = DlColorFilter::MakeMatrix(alpha_matrix); // Making sure hiding a problematic ColorFilter as an ImageFilter // will generate the same behavior as setting it as a ColorFilter @@ -3957,7 +3957,7 @@ TEST_F(DisplayListTest, FloodingSaveLayerBoundsComputationOfSimpleRect) { SkRect rect = SkRect::MakeLTRB(100.0f, 100.0f, 200.0f, 200.0f); DlPaint save_paint; auto color_filter = - DlBlendColorFilter::Make(DlColor::kRed(), DlBlendMode::kSrc); + DlColorFilter::MakeBlend(DlColor::kRed(), DlBlendMode::kSrc); ASSERT_TRUE(color_filter->modifies_transparent_black()); save_paint.setColorFilter(color_filter); SkRect clip_rect = rect.makeOutset(100.0f, 100.0f); @@ -3983,7 +3983,7 @@ TEST_F(DisplayListTest, NestedFloodingSaveLayerBoundsComputationOfSimpleRect) { SkRect rect = SkRect::MakeLTRB(100.0f, 100.0f, 200.0f, 200.0f); DlPaint save_paint; auto color_filter = - DlBlendColorFilter::Make(DlColor::kRed(), DlBlendMode::kSrc); + DlColorFilter::MakeBlend(DlColor::kRed(), DlBlendMode::kSrc); ASSERT_TRUE(color_filter->modifies_transparent_black()); save_paint.setColorFilter(color_filter); SkRect clip_rect = rect.makeOutset(100.0f, 100.0f); @@ -4016,7 +4016,7 @@ TEST_F(DisplayListTest, SaveLayerBoundsComputationOfFloodingImageFilter) { SkRect rect = SkRect::MakeLTRB(100.0f, 100.0f, 200.0f, 200.0f); DlPaint draw_paint; auto color_filter = - DlBlendColorFilter::Make(DlColor::kRed(), DlBlendMode::kSrc); + DlColorFilter::MakeBlend(DlColor::kRed(), DlBlendMode::kSrc); ASSERT_TRUE(color_filter->modifies_transparent_black()); auto image_filter = DlImageFilter::MakeColorFilter(color_filter); draw_paint.setImageFilter(image_filter); @@ -4043,7 +4043,7 @@ TEST_F(DisplayListTest, SaveLayerBoundsComputationOfFloodingColorFilter) { SkRect rect = SkRect::MakeLTRB(100.0f, 100.0f, 200.0f, 200.0f); DlPaint draw_paint; auto color_filter = - DlBlendColorFilter::Make(DlColor::kRed(), DlBlendMode::kSrc); + DlColorFilter::MakeBlend(DlColor::kRed(), DlBlendMode::kSrc); ASSERT_TRUE(color_filter->modifies_transparent_black()); draw_paint.setColorFilter(color_filter); SkRect clip_rect = rect.makeOutset(100.0f, 100.0f); @@ -4233,7 +4233,7 @@ TEST_F(DisplayListTest, FloodingFilteredLayerPushesRestoreOpIndex) { 0.5f, 0.0f, 0.0f, 0.0f, 0.5f }; // clang-format on - auto color_filter = DlMatrixColorFilter::Make(matrix); + auto color_filter = DlColorFilter::MakeMatrix(matrix); save_paint.setImageFilter(DlImageFilter::MakeColorFilter(color_filter)); builder.SaveLayer(nullptr, &save_paint); int save_layer_id = DisplayListBuilderTestingLastOpIndex(builder); @@ -5817,7 +5817,7 @@ TEST_F(DisplayListTest, UnboundedRenderOpsAreReportedUnlessClipped) { 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, }; // clang-format on - auto unbounded_cf = DlMatrixColorFilter::Make(matrix); + auto unbounded_cf = DlColorFilter::MakeMatrix(matrix); // ColorFilter must modify transparent black to be "unbounded" ASSERT_TRUE(unbounded_cf->modifies_transparent_black()); auto unbounded_if = DlImageFilter::MakeColorFilter(unbounded_cf); diff --git a/engine/src/flutter/display_list/dl_builder.cc b/engine/src/flutter/display_list/dl_builder.cc index afce8d3913..a6ff898c42 100644 --- a/engine/src/flutter/display_list/dl_builder.cc +++ b/engine/src/flutter/display_list/dl_builder.cc @@ -8,6 +8,7 @@ #include "flutter/display_list/dl_blend_mode.h" #include "flutter/display_list/dl_op_flags.h" #include "flutter/display_list/dl_op_records.h" +#include "flutter/display_list/effects/dl_color_filters.h" #include "flutter/display_list/effects/dl_color_source.h" #include "flutter/display_list/effects/dl_image_filters.h" #include "flutter/display_list/utils/dl_accumulation_rect.h" diff --git a/engine/src/flutter/display_list/dl_paint_unittests.cc b/engine/src/flutter/display_list/dl_paint_unittests.cc index 9320c64865..617a7b5bd0 100644 --- a/engine/src/flutter/display_list/dl_paint_unittests.cc +++ b/engine/src/flutter/display_list/dl_paint_unittests.cc @@ -4,6 +4,7 @@ #include "flutter/display_list/dl_paint.h" +#include "flutter/display_list/testing/dl_test_equality.h" #include "flutter/display_list/utils/dl_comparable.h" #include "gtest/gtest.h" @@ -58,8 +59,9 @@ TEST(DisplayListPaint, ConstructorDefaults) { auto color_source = DlColorSource::MakeColor(DlColor::kMagenta()); EXPECT_NE(paint, DlPaint().setColorSource(color_source)); - DlBlendColorFilter color_filter(DlColor::kYellow(), DlBlendMode::kDstIn); - EXPECT_NE(paint, DlPaint().setColorFilter(color_filter.shared())); + auto color_filter = + DlColorFilter::MakeBlend(DlColor::kYellow(), DlBlendMode::kDstATop); + EXPECT_NE(paint, DlPaint().setColorFilter(color_filter)); auto image_filter = DlImageFilter::MakeBlur(1.3, 4.7, DlTileMode::kClamp); EXPECT_NE(paint, DlPaint().setImageFilter(image_filter)); @@ -107,8 +109,7 @@ TEST(DisplayListPaint, ChainingConstructor) { .setStrokeMiter(1.5) // .setColorSource(DlColorSource::MakeColor(DlColor::kMagenta())) // .setColorFilter( - DlBlendColorFilter(DlColor::kYellow(), DlBlendMode::kDstIn) - .shared()) + DlColorFilter::MakeBlend(DlColor::kYellow(), DlBlendMode::kDstIn)) .setImageFilter(DlImageFilter::MakeBlur(1.3, 4.7, DlTileMode::kClamp)) .setMaskFilter(DlBlurMaskFilter(DlBlurStyle::kInner, 3.14).shared()); EXPECT_TRUE(paint.isAntiAlias()); @@ -123,8 +124,9 @@ TEST(DisplayListPaint, ChainingConstructor) { EXPECT_EQ(paint.getStrokeMiter(), 1.5); EXPECT_TRUE(Equals(paint.getColorSource(), DlColorSource::MakeColor(DlColor::kMagenta()))); - EXPECT_EQ(*paint.getColorFilter(), - DlBlendColorFilter(DlColor::kYellow(), DlBlendMode::kDstIn)); + EXPECT_TRUE(Equals( + paint.getColorFilter(), + DlColorFilter::MakeBlend(DlColor::kYellow(), DlBlendMode::kDstIn))); EXPECT_TRUE(Equals(paint.getImageFilter(), DlImageFilter::MakeBlur(1.3, 4.7, DlTileMode::kClamp))); EXPECT_EQ(*paint.getMaskFilter(), diff --git a/engine/src/flutter/display_list/effects/color_filters/dl_blend_color_filter.cc b/engine/src/flutter/display_list/effects/color_filters/dl_blend_color_filter.cc new file mode 100644 index 0000000000..98f1af11c0 --- /dev/null +++ b/engine/src/flutter/display_list/effects/color_filters/dl_blend_color_filter.cc @@ -0,0 +1,126 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/display_list/effects/color_filters/dl_blend_color_filter.h" + +namespace flutter { + +std::shared_ptr DlBlendColorFilter::Make( + DlColor color, + DlBlendMode mode) { + switch (mode) { + case DlBlendMode::kDst: { + return nullptr; + } + case DlBlendMode::kSrcOver: { + if (color.isTransparent()) { + return nullptr; + } + if (color.isOpaque()) { + mode = DlBlendMode::kSrc; + } + break; + } + case DlBlendMode::kDstOver: + case DlBlendMode::kDstOut: + case DlBlendMode::kSrcATop: + case DlBlendMode::kXor: + case DlBlendMode::kDarken: { + if (color.isTransparent()) { + return nullptr; + } + break; + } + case DlBlendMode::kDstIn: { + if (color.isOpaque()) { + return nullptr; + } + break; + } + default: + break; + } + return std::make_shared(color, mode); +} + +bool DlBlendColorFilter::modifies_transparent_black() const { + switch (mode_) { + // These modes all act like kSrc when the dest is all 0s. + // So they modify transparent black when the src color is + // not transparent. + case DlBlendMode::kSrc: + case DlBlendMode::kSrcOver: + case DlBlendMode::kDstOver: + case DlBlendMode::kSrcOut: + case DlBlendMode::kDstATop: + case DlBlendMode::kXor: + case DlBlendMode::kPlus: + case DlBlendMode::kScreen: + case DlBlendMode::kOverlay: + case DlBlendMode::kDarken: + case DlBlendMode::kLighten: + case DlBlendMode::kColorDodge: + case DlBlendMode::kColorBurn: + case DlBlendMode::kHardLight: + case DlBlendMode::kSoftLight: + case DlBlendMode::kDifference: + case DlBlendMode::kExclusion: + case DlBlendMode::kMultiply: + case DlBlendMode::kHue: + case DlBlendMode::kSaturation: + case DlBlendMode::kColor: + case DlBlendMode::kLuminosity: + return !color_.isTransparent(); + + // These modes are all like kDst when the dest is all 0s. + // So they never modify transparent black. + case DlBlendMode::kClear: + case DlBlendMode::kDst: + case DlBlendMode::kSrcIn: + case DlBlendMode::kDstIn: + case DlBlendMode::kDstOut: + case DlBlendMode::kSrcATop: + case DlBlendMode::kModulate: + return false; + } +} + +bool DlBlendColorFilter::can_commute_with_opacity() const { + switch (mode_) { + case DlBlendMode::kClear: + case DlBlendMode::kDst: + case DlBlendMode::kSrcIn: + case DlBlendMode::kDstIn: + case DlBlendMode::kDstOut: + case DlBlendMode::kSrcATop: + case DlBlendMode::kModulate: + return true; + + case DlBlendMode::kSrc: + case DlBlendMode::kSrcOver: + case DlBlendMode::kDstOver: + case DlBlendMode::kSrcOut: + case DlBlendMode::kDstATop: + case DlBlendMode::kXor: + case DlBlendMode::kPlus: + case DlBlendMode::kScreen: + case DlBlendMode::kOverlay: + case DlBlendMode::kDarken: + case DlBlendMode::kLighten: + case DlBlendMode::kColorDodge: + case DlBlendMode::kColorBurn: + case DlBlendMode::kHardLight: + case DlBlendMode::kSoftLight: + case DlBlendMode::kDifference: + case DlBlendMode::kExclusion: + case DlBlendMode::kMultiply: + case DlBlendMode::kHue: + case DlBlendMode::kSaturation: + case DlBlendMode::kColor: + case DlBlendMode::kLuminosity: + return color_.isTransparent(); + } +} + +} // namespace flutter diff --git a/engine/src/flutter/display_list/effects/color_filters/dl_blend_color_filter.h b/engine/src/flutter/display_list/effects/color_filters/dl_blend_color_filter.h new file mode 100644 index 0000000000..f79f82ed1a --- /dev/null +++ b/engine/src/flutter/display_list/effects/color_filters/dl_blend_color_filter.h @@ -0,0 +1,60 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_DISPLAY_LIST_EFFECTS_COLOR_FILTERS_DL_BLEND_COLOR_FILTER_H_ +#define FLUTTER_DISPLAY_LIST_EFFECTS_COLOR_FILTERS_DL_BLEND_COLOR_FILTER_H_ + +#include "flutter/display_list/effects/dl_color_filter.h" + +namespace flutter { + +// The Blend type of ColorFilter which specifies modifying the +// colors as if the color specified in the Blend filter is the +// source color and the color drawn by the rendering operation +// is the destination color. The mode parameter of the Blend +// filter is then used to combine those colors. +class DlBlendColorFilter final : public DlColorFilter { + public: + DlBlendColorFilter(DlColor color, DlBlendMode mode) + : color_(color), mode_(mode) {} + DlBlendColorFilter(const DlBlendColorFilter& filter) + : DlBlendColorFilter(filter.color_, filter.mode_) {} + explicit DlBlendColorFilter(const DlBlendColorFilter* filter) + : DlBlendColorFilter(filter->color_, filter->mode_) {} + + DlColorFilterType type() const override { return DlColorFilterType::kBlend; } + size_t size() const override { return sizeof(*this); } + + bool modifies_transparent_black() const override; + bool can_commute_with_opacity() const override; + + std::shared_ptr shared() const override { + return std::make_shared(this); + } + + const DlBlendColorFilter* asBlend() const override { return this; } + + DlColor color() const { return color_; } + DlBlendMode mode() const { return mode_; } + + protected: + bool equals_(DlColorFilter const& other) const override { + FML_DCHECK(other.type() == DlColorFilterType::kBlend); + auto that = static_cast(&other); + return color_ == that->color_ && mode_ == that->mode_; + } + + private: + static std::shared_ptr Make(DlColor color, + DlBlendMode mode); + + DlColor color_; + DlBlendMode mode_; + + friend class DlColorFilter; +}; + +} // namespace flutter + +#endif // FLUTTER_DISPLAY_LIST_EFFECTS_COLOR_FILTERS_DL_BLEND_COLOR_FILTER_H_ diff --git a/engine/src/flutter/display_list/effects/color_filters/dl_linear_to_srgb_gamma_color_filter.cc b/engine/src/flutter/display_list/effects/color_filters/dl_linear_to_srgb_gamma_color_filter.cc new file mode 100644 index 0000000000..b2dc9e51dd --- /dev/null +++ b/engine/src/flutter/display_list/effects/color_filters/dl_linear_to_srgb_gamma_color_filter.cc @@ -0,0 +1,13 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/display_list/effects/color_filters/dl_linear_to_srgb_gamma_color_filter.h" + +namespace flutter { + +const std::shared_ptr + DlLinearToSrgbGammaColorFilter::kInstance = + std::make_shared(); + +} // namespace flutter diff --git a/engine/src/flutter/display_list/effects/color_filters/dl_linear_to_srgb_gamma_color_filter.h b/engine/src/flutter/display_list/effects/color_filters/dl_linear_to_srgb_gamma_color_filter.h new file mode 100644 index 0000000000..b3c6ef1094 --- /dev/null +++ b/engine/src/flutter/display_list/effects/color_filters/dl_linear_to_srgb_gamma_color_filter.h @@ -0,0 +1,46 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_DISPLAY_LIST_EFFECTS_COLOR_FILTERS_DL_LINEAR_TO_SRGB_GAMMA_COLOR_FILTER_H_ +#define FLUTTER_DISPLAY_LIST_EFFECTS_COLOR_FILTERS_DL_LINEAR_TO_SRGB_GAMMA_COLOR_FILTER_H_ + +#include "flutter/display_list/effects/dl_color_filter.h" + +namespace flutter { + +// The LinearToSrgb type of ColorFilter that applies the sRGB gamma curve +// to the rendered pixels. +class DlLinearToSrgbGammaColorFilter final : public DlColorFilter { + public: + DlLinearToSrgbGammaColorFilter() {} + DlLinearToSrgbGammaColorFilter(const DlLinearToSrgbGammaColorFilter& filter) + : DlLinearToSrgbGammaColorFilter() {} + explicit DlLinearToSrgbGammaColorFilter( + const DlLinearToSrgbGammaColorFilter* filter) + : DlLinearToSrgbGammaColorFilter() {} + + DlColorFilterType type() const override { + return DlColorFilterType::kLinearToSrgbGamma; + } + size_t size() const override { return sizeof(*this); } + bool modifies_transparent_black() const override { return false; } + bool can_commute_with_opacity() const override { return true; } + + std::shared_ptr shared() const override { return kInstance; } + + protected: + bool equals_(const DlColorFilter& other) const override { + FML_DCHECK(other.type() == DlColorFilterType::kLinearToSrgbGamma); + return true; + } + + private: + static const std::shared_ptr kInstance; + + friend class DlColorFilter; +}; + +} // namespace flutter + +#endif // FLUTTER_DISPLAY_LIST_EFFECTS_COLOR_FILTERS_DL_LINEAR_TO_SRGB_GAMMA_COLOR_FILTER_H_ diff --git a/engine/src/flutter/display_list/effects/color_filters/dl_matrix_color_filter.cc b/engine/src/flutter/display_list/effects/color_filters/dl_matrix_color_filter.cc new file mode 100644 index 0000000000..8837c71bac --- /dev/null +++ b/engine/src/flutter/display_list/effects/color_filters/dl_matrix_color_filter.cc @@ -0,0 +1,74 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/display_list/effects/color_filters/dl_matrix_color_filter.h" + +namespace flutter { + +std::shared_ptr DlMatrixColorFilter::Make( + const float matrix[20]) { + float product = 0; + for (int i = 0; i < 20; i++) { + product *= matrix[i]; + } + // If any of the elements of the matrix are infinity or NaN, then + // |product| will be NaN, otherwise 0. + if (product == 0) { + return std::make_shared(matrix); + } + return nullptr; +} + +bool DlMatrixColorFilter::modifies_transparent_black() const { + // Values are considered in non-premultiplied form when the matrix is + // applied, but we only care about this answer for whether it leaves + // an incoming color with a transparent alpha as transparent on output. + // Thus, we only need to consider the alpha part of the matrix equation, + // which is the last row. Since the incoming alpha value is 0, the last + // equation ends up becoming A' = matrix_[19]. Negative results will be + // clamped to the range [0,1] so we only care about positive values. + // Non-finite values are clamped to a zero alpha. + return (std::isfinite(matrix_[19]) && matrix_[19] > 0); +} + +bool DlMatrixColorFilter::can_commute_with_opacity() const { + // We need to check if: + // filter(color) * opacity == filter(color * opacity). + // + // filter(RGBA) = R' = [ R*m[ 0] + G*m[ 1] + B*m[ 2] + A*m[ 3] + m[ 4] ] + // G' = [ R*m[ 5] + G*m[ 6] + B*m[ 7] + A*m[ 8] + m[ 9] ] + // B' = [ R*m[10] + G*m[11] + B*m[12] + A*m[13] + m[14] ] + // A' = [ R*m[15] + G*m[16] + B*m[17] + A*m[18] + m[19] ] + // + // Applying the opacity only affects the alpha value since the operations + // are performed on non-premultiplied colors. (If the data is stored in + // premultiplied form, though, there may be rounding errors due to + // premul->unpremul->premul conversions.) + + // We test for the successful cases and return false if they fail so that + // we fail and return false if any matrix values are NaN. + + // If any of the alpha column are non-zero then the prior alpha affects + // the result color, so applying opacity before the filter will change + // the incoming alpha and therefore the colors that are produced. + if (!(matrix_[3] == 0 && // A does not affect R' + matrix_[8] == 0 && // A does not affect G' + matrix_[13] == 0)) { // A does not affect B' + return false; + } + + // Similarly, if any of the alpha row are non-zero then the prior colors + // affect the result alpha in a way that prevents opacity from commuting + // through the filter operation. + if (!(matrix_[15] == 0 && // R does not affect A' + matrix_[16] == 0 && // G does not affect A' + matrix_[17] == 0 && // B does not affect A' + matrix_[19] == 0)) { // A' is not offset by an absolute value + return false; + } + + return true; +} + +} // namespace flutter diff --git a/engine/src/flutter/display_list/effects/color_filters/dl_matrix_color_filter.h b/engine/src/flutter/display_list/effects/color_filters/dl_matrix_color_filter.h new file mode 100644 index 0000000000..271fa8cac9 --- /dev/null +++ b/engine/src/flutter/display_list/effects/color_filters/dl_matrix_color_filter.h @@ -0,0 +1,72 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_DISPLAY_LIST_EFFECTS_COLOR_FILTERS_DL_MATRIX_COLOR_FILTER_H_ +#define FLUTTER_DISPLAY_LIST_EFFECTS_COLOR_FILTERS_DL_MATRIX_COLOR_FILTER_H_ + +#include "flutter/display_list/effects/dl_color_filter.h" + +namespace flutter { + +// The Matrix type of ColorFilter which runs every pixel drawn by +// the rendering operation [iR,iG,iB,iA] through a vector/matrix +// multiplication, as in: +// +// [ oR ] [ m[ 0] m[ 1] m[ 2] m[ 3] m[ 4] ] [ iR ] +// [ oG ] [ m[ 5] m[ 6] m[ 7] m[ 8] m[ 9] ] [ iG ] +// [ oB ] = [ m[10] m[11] m[12] m[13] m[14] ] x [ iB ] +// [ oA ] [ m[15] m[16] m[17] m[18] m[19] ] [ iA ] +// [ 1 ] +// +// The resulting color [oR,oG,oB,oA] is then clamped to the range of +// valid pixel components before storing in the output. +// +// The incoming and outgoing [iR,iG,iB,iA] and [oR,oG,oB,oA] are +// considered to be non-premultiplied. When working on premultiplied +// pixel data, the necessary pre<->non-pre conversions must be performed. +class DlMatrixColorFilter final : public DlColorFilter { + public: + explicit DlMatrixColorFilter(const float matrix[20]) { + memcpy(matrix_, matrix, sizeof(matrix_)); + } + DlMatrixColorFilter(const DlMatrixColorFilter& filter) + : DlMatrixColorFilter(filter.matrix_) {} + explicit DlMatrixColorFilter(const DlMatrixColorFilter* filter) + : DlMatrixColorFilter(filter->matrix_) {} + + DlColorFilterType type() const override { return DlColorFilterType::kMatrix; } + size_t size() const override { return sizeof(*this); } + + bool modifies_transparent_black() const override; + bool can_commute_with_opacity() const override; + + std::shared_ptr shared() const override { + return std::make_shared(this); + } + + const DlMatrixColorFilter* asMatrix() const override { return this; } + + const float& operator[](int index) const { return matrix_[index]; } + void get_matrix(float matrix[20]) const { + memcpy(matrix, matrix_, sizeof(matrix_)); + } + + protected: + bool equals_(const DlColorFilter& other) const override { + FML_DCHECK(other.type() == DlColorFilterType::kMatrix); + auto that = static_cast(&other); + return memcmp(matrix_, that->matrix_, sizeof(matrix_)) == 0; + } + + private: + static std::shared_ptr Make(const float matrix[20]); + + float matrix_[20]; + + friend class DlColorFilter; +}; + +} // namespace flutter + +#endif // FLUTTER_DISPLAY_LIST_EFFECTS_COLOR_FILTERS_DL_MATRIX_COLOR_FILTER_H_ diff --git a/engine/src/flutter/display_list/effects/color_filters/dl_srgb_to_linear_gamma_color_filter.cc b/engine/src/flutter/display_list/effects/color_filters/dl_srgb_to_linear_gamma_color_filter.cc new file mode 100644 index 0000000000..30b3db2017 --- /dev/null +++ b/engine/src/flutter/display_list/effects/color_filters/dl_srgb_to_linear_gamma_color_filter.cc @@ -0,0 +1,13 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/display_list/effects/color_filters/dl_srgb_to_linear_gamma_color_filter.h" + +namespace flutter { + +const std::shared_ptr + DlSrgbToLinearGammaColorFilter::kInstance = + std::make_shared(); + +} // namespace flutter diff --git a/engine/src/flutter/display_list/effects/color_filters/dl_srgb_to_linear_gamma_color_filter.h b/engine/src/flutter/display_list/effects/color_filters/dl_srgb_to_linear_gamma_color_filter.h new file mode 100644 index 0000000000..393d8feee3 --- /dev/null +++ b/engine/src/flutter/display_list/effects/color_filters/dl_srgb_to_linear_gamma_color_filter.h @@ -0,0 +1,46 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_DISPLAY_LIST_EFFECTS_COLOR_FILTERS_DL_SRGB_TO_LINEAR_GAMMA_COLOR_FILTER_H_ +#define FLUTTER_DISPLAY_LIST_EFFECTS_COLOR_FILTERS_DL_SRGB_TO_LINEAR_GAMMA_COLOR_FILTER_H_ + +#include "flutter/display_list/effects/dl_color_filter.h" + +namespace flutter { + +// The SrgbToLinear type of ColorFilter that applies the inverse of the sRGB +// gamma curve to the rendered pixels. +class DlSrgbToLinearGammaColorFilter final : public DlColorFilter { + public: + DlSrgbToLinearGammaColorFilter() {} + DlSrgbToLinearGammaColorFilter(const DlSrgbToLinearGammaColorFilter& filter) + : DlSrgbToLinearGammaColorFilter() {} + explicit DlSrgbToLinearGammaColorFilter( + const DlSrgbToLinearGammaColorFilter* filter) + : DlSrgbToLinearGammaColorFilter() {} + + DlColorFilterType type() const override { + return DlColorFilterType::kSrgbToLinearGamma; + } + size_t size() const override { return sizeof(*this); } + bool modifies_transparent_black() const override { return false; } + bool can_commute_with_opacity() const override { return true; } + + std::shared_ptr shared() const override { return kInstance; } + + protected: + bool equals_(const DlColorFilter& other) const override { + FML_DCHECK(other.type() == DlColorFilterType::kSrgbToLinearGamma); + return true; + } + + private: + static const std::shared_ptr kInstance; + + friend class DlColorFilter; +}; + +} // namespace flutter + +#endif // FLUTTER_DISPLAY_LIST_EFFECTS_COLOR_FILTERS_DL_SRGB_TO_LINEAR_GAMMA_COLOR_FILTER_H_ diff --git a/engine/src/flutter/display_list/effects/dl_color_filter.cc b/engine/src/flutter/display_list/effects/dl_color_filter.cc index 2ad15e0ab9..c78cfa3ca2 100644 --- a/engine/src/flutter/display_list/effects/dl_color_filter.cc +++ b/engine/src/flutter/display_list/effects/dl_color_filter.cc @@ -5,196 +5,34 @@ #include "flutter/display_list/effects/dl_color_filter.h" #include "flutter/display_list/dl_color.h" +#include "flutter/display_list/effects/color_filters/dl_blend_color_filter.h" +#include "flutter/display_list/effects/color_filters/dl_linear_to_srgb_gamma_color_filter.h" +#include "flutter/display_list/effects/color_filters/dl_matrix_color_filter.h" +#include "flutter/display_list/effects/color_filters/dl_srgb_to_linear_gamma_color_filter.h" namespace flutter { -std::shared_ptr DlBlendColorFilter::Make(DlColor color, - DlBlendMode mode) { - switch (mode) { - case DlBlendMode::kDst: { - return nullptr; - } - case DlBlendMode::kSrcOver: { - if (color.isTransparent()) { - return nullptr; - } - if (color.isOpaque()) { - mode = DlBlendMode::kSrc; - } - break; - } - case DlBlendMode::kDstOver: - case DlBlendMode::kDstOut: - case DlBlendMode::kSrcATop: - case DlBlendMode::kXor: - case DlBlendMode::kDarken: { - if (color.isTransparent()) { - return nullptr; - } - break; - } - case DlBlendMode::kDstIn: { - if (color.isOpaque()) { - return nullptr; - } - break; - } - default: - break; - } - return std::make_shared(color, mode); +std::shared_ptr DlColorFilter::MakeBlend( + DlColor color, + DlBlendMode mode) { + // Delegate to a method private to DlBlendColorFilter due to private + // constructor preventing |make_shared| from here. + return DlBlendColorFilter::Make(color, mode); } -bool DlBlendColorFilter::modifies_transparent_black() const { - switch (mode_) { - // These modes all act like kSrc when the dest is all 0s. - // So they modify transparent black when the src color is - // not transparent. - case DlBlendMode::kSrc: - case DlBlendMode::kSrcOver: - case DlBlendMode::kDstOver: - case DlBlendMode::kSrcOut: - case DlBlendMode::kDstATop: - case DlBlendMode::kXor: - case DlBlendMode::kPlus: - case DlBlendMode::kScreen: - case DlBlendMode::kOverlay: - case DlBlendMode::kDarken: - case DlBlendMode::kLighten: - case DlBlendMode::kColorDodge: - case DlBlendMode::kColorBurn: - case DlBlendMode::kHardLight: - case DlBlendMode::kSoftLight: - case DlBlendMode::kDifference: - case DlBlendMode::kExclusion: - case DlBlendMode::kMultiply: - case DlBlendMode::kHue: - case DlBlendMode::kSaturation: - case DlBlendMode::kColor: - case DlBlendMode::kLuminosity: - return !color_.isTransparent(); - - // These modes are all like kDst when the dest is all 0s. - // So they never modify transparent black. - case DlBlendMode::kClear: - case DlBlendMode::kDst: - case DlBlendMode::kSrcIn: - case DlBlendMode::kDstIn: - case DlBlendMode::kDstOut: - case DlBlendMode::kSrcATop: - case DlBlendMode::kModulate: - return false; - } -} - -bool DlBlendColorFilter::can_commute_with_opacity() const { - switch (mode_) { - case DlBlendMode::kClear: - case DlBlendMode::kDst: - case DlBlendMode::kSrcIn: - case DlBlendMode::kDstIn: - case DlBlendMode::kDstOut: - case DlBlendMode::kSrcATop: - case DlBlendMode::kModulate: - return true; - - case DlBlendMode::kSrc: - case DlBlendMode::kSrcOver: - case DlBlendMode::kDstOver: - case DlBlendMode::kSrcOut: - case DlBlendMode::kDstATop: - case DlBlendMode::kXor: - case DlBlendMode::kPlus: - case DlBlendMode::kScreen: - case DlBlendMode::kOverlay: - case DlBlendMode::kDarken: - case DlBlendMode::kLighten: - case DlBlendMode::kColorDodge: - case DlBlendMode::kColorBurn: - case DlBlendMode::kHardLight: - case DlBlendMode::kSoftLight: - case DlBlendMode::kDifference: - case DlBlendMode::kExclusion: - case DlBlendMode::kMultiply: - case DlBlendMode::kHue: - case DlBlendMode::kSaturation: - case DlBlendMode::kColor: - case DlBlendMode::kLuminosity: - return color_.isTransparent(); - } -} - -std::shared_ptr DlMatrixColorFilter::Make( +std::shared_ptr DlColorFilter::MakeMatrix( const float matrix[20]) { - float product = 0; - for (int i = 0; i < 20; i++) { - product *= matrix[i]; - } - // If any of the elements of the matrix are infinity or NaN, then - // |product| will be NaN, otherwise 0. - if (product == 0) { - return std::make_shared(matrix); - } - return nullptr; + // Delegate to a method private to DlBlendColorFilter due to private + // constructor preventing |make_shared| from here. + return DlMatrixColorFilter::Make(matrix); } -bool DlMatrixColorFilter::modifies_transparent_black() const { - // Values are considered in non-premultiplied form when the matrix is - // applied, but we only care about this answer for whether it leaves - // an incoming color with a transparent alpha as transparent on output. - // Thus, we only need to consider the alpha part of the matrix equation, - // which is the last row. Since the incoming alpha value is 0, the last - // equation ends up becoming A' = matrix_[19]. Negative results will be - // clamped to the range [0,1] so we only care about positive values. - // Non-finite values are clamped to a zero alpha. - return (std::isfinite(matrix_[19]) && matrix_[19] > 0); +std::shared_ptr DlColorFilter::MakeSrgbToLinearGamma() { + return DlSrgbToLinearGammaColorFilter::kInstance; } -bool DlMatrixColorFilter::can_commute_with_opacity() const { - // We need to check if: - // filter(color) * opacity == filter(color * opacity). - // - // filter(RGBA) = R' = [ R*m[ 0] + G*m[ 1] + B*m[ 2] + A*m[ 3] + m[ 4] ] - // G' = [ R*m[ 5] + G*m[ 6] + B*m[ 7] + A*m[ 8] + m[ 9] ] - // B' = [ R*m[10] + G*m[11] + B*m[12] + A*m[13] + m[14] ] - // A' = [ R*m[15] + G*m[16] + B*m[17] + A*m[18] + m[19] ] - // - // Applying the opacity only affects the alpha value since the operations - // are performed on non-premultiplied colors. (If the data is stored in - // premultiplied form, though, there may be rounding errors due to - // premul->unpremul->premul conversions.) - - // We test for the successful cases and return false if they fail so that - // we fail and return false if any matrix values are NaN. - - // If any of the alpha column are non-zero then the prior alpha affects - // the result color, so applying opacity before the filter will change - // the incoming alpha and therefore the colors that are produced. - if (!(matrix_[3] == 0 && // A does not affect R' - matrix_[8] == 0 && // A does not affect G' - matrix_[13] == 0)) { // A does not affect B' - return false; - } - - // Similarly, if any of the alpha row are non-zero then the prior colors - // affect the result alpha in a way that prevents opacity from commuting - // through the filter operation. - if (!(matrix_[15] == 0 && // R does not affect A' - matrix_[16] == 0 && // G does not affect A' - matrix_[17] == 0 && // B does not affect A' - matrix_[19] == 0)) { // A' is not offset by an absolute value - return false; - } - - return true; +std::shared_ptr DlColorFilter::MakeLinearToSrgbGamma() { + return DlLinearToSrgbGammaColorFilter::kInstance; } -const std::shared_ptr - DlSrgbToLinearGammaColorFilter::kInstance = - std::make_shared(); - -const std::shared_ptr - DlLinearToSrgbGammaColorFilter::kInstance = - std::make_shared(); - } // namespace flutter diff --git a/engine/src/flutter/display_list/effects/dl_color_filter.h b/engine/src/flutter/display_list/effects/dl_color_filter.h index 42a4845e0a..c3c0d64241 100644 --- a/engine/src/flutter/display_list/effects/dl_color_filter.h +++ b/engine/src/flutter/display_list/effects/dl_color_filter.h @@ -15,10 +15,6 @@ namespace flutter { class DlBlendColorFilter; class DlMatrixColorFilter; -// The DisplayList ColorFilter class. This class implements all of the -// facilities and adheres to the design goals of the |DlAttribute| base -// class. - // An enumerated type for the supported ColorFilter operations. enum class DlColorFilterType { kBlend, @@ -27,8 +23,51 @@ enum class DlColorFilterType { kLinearToSrgbGamma, }; +/// The DisplayList ColorFilter base class. This class implements all of the +/// facilities and adheres to the design goals of the |DlAttribute| base +/// class. class DlColorFilter : public DlAttribute { public: + /// Return a shared pointer to a DlColorFilter that acts as if blending + /// the specified color over the rendered colors using the specified + /// blend mode, or a nullptr if the operation would be a NOP. + /// + /// The blend mode takes the color from the filter as the source color and + /// the rendered color as the destination color. + static std::shared_ptr MakeBlend(DlColor color, + DlBlendMode mode); + + /// Return a shared pointer to a DlColorFilter which transforms each + /// rendered color using a per-component equation specified by the + /// contents of the specified 5 column by 4 row matrix specified in + /// row major order, or a null pointer if the operation would be a NOP. + /// + /// The filter runs every pixel drawn by the rendering operation + /// [iR,iG,iB,iA] through a vector/matrix multiplication, as in: + /// + /// [ oR ] [ m[ 0] m[ 1] m[ 2] m[ 3] m[ 4] ] [ iR ] + /// [ oG ] [ m[ 5] m[ 6] m[ 7] m[ 8] m[ 9] ] [ iG ] + /// [ oB ] = [ m[10] m[11] m[12] m[13] m[14] ] x [ iB ] + /// [ oA ] [ m[15] m[16] m[17] m[18] m[19] ] [ iA ] + /// [ 1 ] + /// + /// The resulting color [oR,oG,oB,oA] is then clamped to the range of + /// valid pixel components before storing in the output. + /// + /// The incoming and outgoing [iR,iG,iB,iA] and [oR,oG,oB,oA] are + /// considered to be non-premultiplied. When working on premultiplied + /// pixel data, the necessary pre<->non-pre conversions must be performed. + static std::shared_ptr MakeMatrix( + const float matrix[20]); + + /// Return a shared pointer to a singleton DlColorFilter that transforms + /// each rendered pixel from Srgb to Linear gamma space. + static std::shared_ptr MakeSrgbToLinearGamma(); + + /// Return a shared pointer to a singleton DlColorFilter that transforms + /// each rendered pixel from Linear to Srgb gamma space. + static std::shared_ptr MakeLinearToSrgbGamma(); + // Return a boolean indicating whether the color filtering operation will // modify transparent black. This is typically used to determine if applying // the ColorFilter to a temporary saveLayer buffer will turn the surrounding @@ -48,173 +87,10 @@ class DlColorFilter : public DlAttribute { // type of ColorFilter, otherwise return nullptr. virtual const DlMatrixColorFilter* asMatrix() const { return nullptr; } - // asSrgb<->Linear is not needed because it has no properties to query. + // asSrgb<->Linear are not needed because it has no properties to query. // Its type fully specifies its operation. }; -// The Blend type of ColorFilter which specifies modifying the -// colors as if the color specified in the Blend filter is the -// source color and the color drawn by the rendering operation -// is the destination color. The mode parameter of the Blend -// filter is then used to combine those colors. -class DlBlendColorFilter final : public DlColorFilter { - public: - DlBlendColorFilter(DlColor color, DlBlendMode mode) - : color_(color), mode_(mode) {} - DlBlendColorFilter(const DlBlendColorFilter& filter) - : DlBlendColorFilter(filter.color_, filter.mode_) {} - explicit DlBlendColorFilter(const DlBlendColorFilter* filter) - : DlBlendColorFilter(filter->color_, filter->mode_) {} - - static std::shared_ptr Make(DlColor color, DlBlendMode mode); - - DlColorFilterType type() const override { return DlColorFilterType::kBlend; } - size_t size() const override { return sizeof(*this); } - - bool modifies_transparent_black() const override; - bool can_commute_with_opacity() const override; - - std::shared_ptr shared() const override { - return std::make_shared(this); - } - - const DlBlendColorFilter* asBlend() const override { return this; } - - DlColor color() const { return color_; } - DlBlendMode mode() const { return mode_; } - - protected: - bool equals_(DlColorFilter const& other) const override { - FML_DCHECK(other.type() == DlColorFilterType::kBlend); - auto that = static_cast(&other); - return color_ == that->color_ && mode_ == that->mode_; - } - - private: - DlColor color_; - DlBlendMode mode_; -}; - -// The Matrix type of ColorFilter which runs every pixel drawn by -// the rendering operation [iR,iG,iB,iA] through a vector/matrix -// multiplication, as in: -// -// [ oR ] [ m[ 0] m[ 1] m[ 2] m[ 3] m[ 4] ] [ iR ] -// [ oG ] [ m[ 5] m[ 6] m[ 7] m[ 8] m[ 9] ] [ iG ] -// [ oB ] = [ m[10] m[11] m[12] m[13] m[14] ] x [ iB ] -// [ oA ] [ m[15] m[16] m[17] m[18] m[19] ] [ iA ] -// [ 1 ] -// -// The resulting color [oR,oG,oB,oA] is then clamped to the range of -// valid pixel components before storing in the output. -// -// The incoming and outgoing [iR,iG,iB,iA] and [oR,oG,oB,oA] are -// considered to be non-premultiplied. When working on premultiplied -// pixel data, the necessary pre<->non-pre conversions must be performed. -class DlMatrixColorFilter final : public DlColorFilter { - public: - explicit DlMatrixColorFilter(const float matrix[20]) { - memcpy(matrix_, matrix, sizeof(matrix_)); - } - DlMatrixColorFilter(const DlMatrixColorFilter& filter) - : DlMatrixColorFilter(filter.matrix_) {} - explicit DlMatrixColorFilter(const DlMatrixColorFilter* filter) - : DlMatrixColorFilter(filter->matrix_) {} - - static std::shared_ptr Make(const float matrix[20]); - - DlColorFilterType type() const override { return DlColorFilterType::kMatrix; } - size_t size() const override { return sizeof(*this); } - - bool modifies_transparent_black() const override; - bool can_commute_with_opacity() const override; - - std::shared_ptr shared() const override { - return std::make_shared(this); - } - - const DlMatrixColorFilter* asMatrix() const override { return this; } - - const float& operator[](int index) const { return matrix_[index]; } - void get_matrix(float matrix[20]) const { - memcpy(matrix, matrix_, sizeof(matrix_)); - } - - protected: - bool equals_(const DlColorFilter& other) const override { - FML_DCHECK(other.type() == DlColorFilterType::kMatrix); - auto that = static_cast(&other); - return memcmp(matrix_, that->matrix_, sizeof(matrix_)) == 0; - } - - private: - float matrix_[20]; -}; - -// The SrgbToLinear type of ColorFilter that applies the inverse of the sRGB -// gamma curve to the rendered pixels. -class DlSrgbToLinearGammaColorFilter final : public DlColorFilter { - public: - static const std::shared_ptr kInstance; - - DlSrgbToLinearGammaColorFilter() {} - DlSrgbToLinearGammaColorFilter(const DlSrgbToLinearGammaColorFilter& filter) - : DlSrgbToLinearGammaColorFilter() {} - explicit DlSrgbToLinearGammaColorFilter( - const DlSrgbToLinearGammaColorFilter* filter) - : DlSrgbToLinearGammaColorFilter() {} - - DlColorFilterType type() const override { - return DlColorFilterType::kSrgbToLinearGamma; - } - size_t size() const override { return sizeof(*this); } - bool modifies_transparent_black() const override { return false; } - bool can_commute_with_opacity() const override { return true; } - - std::shared_ptr shared() const override { return kInstance; } - - protected: - bool equals_(const DlColorFilter& other) const override { - FML_DCHECK(other.type() == DlColorFilterType::kSrgbToLinearGamma); - return true; - } - - private: - friend class DlColorFilter; -}; - -// The LinearToSrgb type of ColorFilter that applies the sRGB gamma curve -// to the rendered pixels. -class DlLinearToSrgbGammaColorFilter final : public DlColorFilter { - public: - static const std::shared_ptr kInstance; - - DlLinearToSrgbGammaColorFilter() {} - DlLinearToSrgbGammaColorFilter(const DlLinearToSrgbGammaColorFilter& filter) - : DlLinearToSrgbGammaColorFilter() {} - explicit DlLinearToSrgbGammaColorFilter( - const DlLinearToSrgbGammaColorFilter* filter) - : DlLinearToSrgbGammaColorFilter() {} - - DlColorFilterType type() const override { - return DlColorFilterType::kLinearToSrgbGamma; - } - size_t size() const override { return sizeof(*this); } - bool modifies_transparent_black() const override { return false; } - bool can_commute_with_opacity() const override { return true; } - - std::shared_ptr shared() const override { return kInstance; } - - protected: - bool equals_(const DlColorFilter& other) const override { - FML_DCHECK(other.type() == DlColorFilterType::kLinearToSrgbGamma); - return true; - } - - private: - friend class DlColorFilter; -}; - } // namespace flutter #endif // FLUTTER_DISPLAY_LIST_EFFECTS_DL_COLOR_FILTER_H_ diff --git a/engine/src/flutter/display_list/effects/dl_color_filter_unittests.cc b/engine/src/flutter/display_list/effects/dl_color_filter_unittests.cc index 157348f3cf..524b8fb481 100644 --- a/engine/src/flutter/display_list/effects/dl_color_filter_unittests.cc +++ b/engine/src/flutter/display_list/effects/dl_color_filter_unittests.cc @@ -3,6 +3,8 @@ // found in the LICENSE file. #include "flutter/display_list/effects/dl_color_filter.h" + +#include "flutter/display_list/effects/dl_color_filters.h" #include "flutter/display_list/testing/dl_test_equality.h" namespace flutter { @@ -135,7 +137,7 @@ TEST(DisplayListColorFilter, SrgbToLinearEquals) { DlSrgbToLinearGammaColorFilter filter1; DlSrgbToLinearGammaColorFilter filter2; TestEquals(filter1, filter2); - TestEquals(filter1, *DlSrgbToLinearGammaColorFilter::kInstance); + TestEquals(filter1, *DlColorFilter::MakeSrgbToLinearGamma()); } TEST(DisplayListColorFilter, LinearToSrgbConstructor) { @@ -152,7 +154,7 @@ TEST(DisplayListColorFilter, LinearToSrgbEquals) { DlLinearToSrgbGammaColorFilter filter1; DlLinearToSrgbGammaColorFilter filter2; TestEquals(filter1, filter2); - TestEquals(filter1, *DlLinearToSrgbGammaColorFilter::kInstance); + TestEquals(filter1, *DlColorFilter::MakeLinearToSrgbGamma()); } } // namespace testing diff --git a/engine/src/flutter/display_list/effects/dl_color_filters.h b/engine/src/flutter/display_list/effects/dl_color_filters.h new file mode 100644 index 0000000000..48bb78ae67 --- /dev/null +++ b/engine/src/flutter/display_list/effects/dl_color_filters.h @@ -0,0 +1,13 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_DISPLAY_LIST_EFFECTS_DL_COLOR_FILTERS_H_ +#define FLUTTER_DISPLAY_LIST_EFFECTS_DL_COLOR_FILTERS_H_ + +#include "flutter/display_list/effects/color_filters/dl_blend_color_filter.h" +#include "flutter/display_list/effects/color_filters/dl_linear_to_srgb_gamma_color_filter.h" +#include "flutter/display_list/effects/color_filters/dl_matrix_color_filter.h" +#include "flutter/display_list/effects/color_filters/dl_srgb_to_linear_gamma_color_filter.h" + +#endif // FLUTTER_DISPLAY_LIST_EFFECTS_DL_COLOR_FILTERS_H_ diff --git a/engine/src/flutter/display_list/effects/dl_image_filter_unittests.cc b/engine/src/flutter/display_list/effects/dl_image_filter_unittests.cc index b9996f34f3..150e85c078 100644 --- a/engine/src/flutter/display_list/effects/dl_image_filter_unittests.cc +++ b/engine/src/flutter/display_list/effects/dl_image_filter_unittests.cc @@ -7,7 +7,7 @@ #include "flutter/display_list/dl_color.h" #include "flutter/display_list/dl_sampling_options.h" #include "flutter/display_list/dl_tile_mode.h" -#include "flutter/display_list/effects/dl_color_filter.h" +#include "flutter/display_list/effects/dl_color_filters.h" #include "flutter/display_list/effects/dl_image_filters.h" #include "flutter/display_list/testing/dl_test_equality.h" #include "flutter/display_list/utils/dl_comparable.h" diff --git a/engine/src/flutter/display_list/skia/dl_sk_conversions.cc b/engine/src/flutter/display_list/skia/dl_sk_conversions.cc index b97b7d584a..67fc7b3fbc 100644 --- a/engine/src/flutter/display_list/skia/dl_sk_conversions.cc +++ b/engine/src/flutter/display_list/skia/dl_sk_conversions.cc @@ -4,6 +4,7 @@ #include "flutter/display_list/skia/dl_sk_conversions.h" +#include "flutter/display_list/effects/dl_color_filters.h" #include "flutter/display_list/effects/dl_color_sources.h" #include "flutter/display_list/effects/dl_image_filters.h" #include "third_party/skia/include/core/SkColorFilter.h" diff --git a/engine/src/flutter/display_list/skia/dl_sk_conversions_unittests.cc b/engine/src/flutter/display_list/skia/dl_sk_conversions_unittests.cc index 7d3ad72b54..81606246e7 100644 --- a/engine/src/flutter/display_list/skia/dl_sk_conversions_unittests.cc +++ b/engine/src/flutter/display_list/skia/dl_sk_conversions_unittests.cc @@ -7,6 +7,7 @@ #include "flutter/display_list/dl_sampling_options.h" #include "flutter/display_list/dl_tile_mode.h" #include "flutter/display_list/dl_vertices.h" +#include "flutter/display_list/effects/dl_color_filters.h" #include "flutter/display_list/effects/dl_color_sources.h" #include "flutter/display_list/effects/dl_image_filters.h" #include "flutter/display_list/skia/dl_sk_conversions.h" @@ -158,7 +159,7 @@ TEST(DisplayListSkConversions, BlendColorFilterModifiesTransparency) { DlBlendColorFilter filter(color, mode); auto srgb = SkColorSpace::MakeSRGB(); if (filter.modifies_transparent_black()) { - auto dl_filter = DlBlendColorFilter::Make(color, mode); + auto dl_filter = DlColorFilter::MakeBlend(color, mode); auto sk_filter = ToSk(filter); ASSERT_NE(dl_filter, nullptr) << desc; ASSERT_NE(sk_filter, nullptr) << desc; @@ -167,7 +168,7 @@ TEST(DisplayListSkConversions, BlendColorFilterModifiesTransparency) { SkColors::kTransparent) << desc; } else { - auto dl_filter = DlBlendColorFilter::Make(color, mode); + auto dl_filter = DlColorFilter::MakeBlend(color, mode); auto sk_filter = ToSk(filter); EXPECT_EQ(dl_filter == nullptr, sk_filter == nullptr) << desc; ASSERT_TRUE(sk_filter == nullptr || @@ -267,7 +268,7 @@ TEST(DisplayListSkConversions, MatrixColorFilterModifiesTransparency) { "matrix[" + std::to_string(element) + "] = " + std::to_string(value); matrix[element] = value; DlMatrixColorFilter filter(matrix); - auto dl_filter = DlMatrixColorFilter::Make(matrix); + auto dl_filter = DlColorFilter::MakeMatrix(matrix); auto sk_filter = ToSk(filter); auto srgb = SkColorSpace::MakeSRGB(); EXPECT_EQ(dl_filter == nullptr, sk_filter == nullptr); diff --git a/engine/src/flutter/display_list/testing/dl_rendering_unittests.cc b/engine/src/flutter/display_list/testing/dl_rendering_unittests.cc index 0419c11c48..399e51c8b1 100644 --- a/engine/src/flutter/display_list/testing/dl_rendering_unittests.cc +++ b/engine/src/flutter/display_list/testing/dl_rendering_unittests.cc @@ -8,6 +8,7 @@ #include "flutter/display_list/dl_builder.h" #include "flutter/display_list/dl_op_flags.h" #include "flutter/display_list/dl_sampling_options.h" +#include "flutter/display_list/effects/color_filters/dl_matrix_color_filter.h" #include "flutter/display_list/effects/dl_image_filter.h" #include "flutter/display_list/skia/dl_sk_canvas.h" #include "flutter/display_list/skia/dl_sk_conversions.h" @@ -1387,7 +1388,8 @@ class CanvasCompareTester { 0, 0, 0, 0.5, 0, }; // clang-format on - DlMatrixColorFilter dl_alpha_rotate_filter(rotate_alpha_color_matrix); + auto dl_alpha_rotate_filter = + DlColorFilter::MakeMatrix(rotate_alpha_color_matrix); auto sk_alpha_rotate_filter = SkColorFilters::Matrix(rotate_alpha_color_matrix); { @@ -1402,7 +1404,7 @@ class CanvasCompareTester { }, [=](const DlSetupContext& ctx) { DlPaint save_p; - save_p.setColorFilter(&dl_alpha_rotate_filter); + save_p.setColorFilter(dl_alpha_rotate_filter); ctx.canvas->SaveLayer(nullptr, &save_p); ctx.paint.setStrokeWidth(5.0); }) @@ -1420,7 +1422,7 @@ class CanvasCompareTester { }, [=](const DlSetupContext& ctx) { DlPaint save_p; - save_p.setColorFilter(&dl_alpha_rotate_filter); + save_p.setColorFilter(dl_alpha_rotate_filter); ctx.canvas->SaveLayer(&kRenderBounds, &save_p); ctx.paint.setStrokeWidth(5.0); }) @@ -1437,8 +1439,8 @@ class CanvasCompareTester { 0, 0, 0, 1, 0, }; // clang-format on - DlMatrixColorFilter dl_color_filter(color_matrix); - DlColorFilterImageFilter dl_cf_image_filter(dl_color_filter); + auto dl_color_filter = DlColorFilter::MakeMatrix(color_matrix); + auto dl_cf_image_filter = DlImageFilter::MakeColorFilter(dl_color_filter); auto sk_cf_image_filter = SkImageFilters::ColorFilter( SkColorFilters::Matrix(color_matrix), nullptr); { @@ -1453,7 +1455,7 @@ class CanvasCompareTester { }, [=](const DlSetupContext& ctx) { DlPaint save_p; - save_p.setImageFilter(&dl_cf_image_filter); + save_p.setImageFilter(dl_cf_image_filter); ctx.canvas->SaveLayer(nullptr, &save_p); ctx.paint.setStrokeWidth(5.0); }) @@ -1471,7 +1473,7 @@ class CanvasCompareTester { }, [=](const DlSetupContext& ctx) { DlPaint save_p; - save_p.setImageFilter(&dl_cf_image_filter); + save_p.setImageFilter(dl_cf_image_filter); ctx.canvas->SaveLayer(&kRenderBounds, &save_p); ctx.paint.setStrokeWidth(5.0); }) @@ -1709,7 +1711,7 @@ class CanvasCompareTester { 1.0, 1.0, 1.0, 1.0, 0, }; // clang-format on - DlMatrixColorFilter dl_color_filter(rotate_color_matrix); + auto dl_color_filter = DlColorFilter::MakeMatrix(rotate_color_matrix); auto sk_color_filter = SkColorFilters::Matrix(rotate_color_matrix); { DlColor bg = DlColor::kWhite(); @@ -1722,7 +1724,7 @@ class CanvasCompareTester { }, [=](const DlSetupContext& ctx) { ctx.paint.setColor(DlColor::kYellow()); - ctx.paint.setColorFilter(&dl_color_filter); + ctx.paint.setColorFilter(dl_color_filter); }) .with_bg(bg)); } @@ -3954,13 +3956,12 @@ TEST_F(DisplayListRendering, SaveLayerConsolidation) { 0.5f, SK_Scalar1, }; - std::vector> color_filters = { - std::make_shared(DlColor::kCyan(), - DlBlendMode::kSrcATop), - std::make_shared(commutable_color_matrix), - std::make_shared(non_commutable_color_matrix), - DlSrgbToLinearGammaColorFilter::kInstance, - DlLinearToSrgbGammaColorFilter::kInstance, + std::vector> color_filters = { + DlColorFilter::MakeBlend(DlColor::kCyan(), DlBlendMode::kSrcATop), + DlColorFilter::MakeMatrix(commutable_color_matrix), + DlColorFilter::MakeMatrix(non_commutable_color_matrix), + DlColorFilter::MakeSrgbToLinearGamma(), + DlColorFilter::MakeLinearToSrgbGamma(), }; std::vector> image_filters = { DlImageFilter::MakeBlur(5.0f, 5.0f, DlTileMode::kDecal), @@ -4131,8 +4132,13 @@ TEST_F(DisplayListRendering, MatrixColorFilterModifyTransparencyCheck) { "matrix[" + std::to_string(element) + "] = " + std::to_string(value); float original_value = matrix[element]; matrix[element] = value; + // Here we instantiate a DlMatrixColorFilter directly so that it is + // not affected by the "NOP" detection in the factory. We sould not + // need to do this if we tested by just rendering the filter color + // over the source color with the filter blend mode instead of + // rendering via a ColorFilter, but this test is more "black box". DlMatrixColorFilter filter(matrix); - auto dl_filter = DlMatrixColorFilter::Make(matrix); + auto dl_filter = DlColorFilter::MakeMatrix(matrix); bool is_identity = (dl_filter == nullptr || original_value == value); DlPaint paint(DlColor(0x7f7f7f7f)); @@ -4200,7 +4206,7 @@ TEST_F(DisplayListRendering, MatrixColorFilterOpacityCommuteCheck) { std::string desc = "matrix[" + std::to_string(element) + "] = " + std::to_string(value); matrix[element] = value; - auto filter = DlMatrixColorFilter::Make(matrix); + auto filter = DlColorFilter::MakeMatrix(matrix); EXPECT_EQ(std::isfinite(value), filter != nullptr); DlPaint paint(DlColor(0x80808080)); @@ -4308,7 +4314,7 @@ TEST_F(DisplayListRendering, BlendColorFilterModifyTransparencyCheck) { std::string desc = desc_str.str(); DlBlendColorFilter filter(color, mode); if (filter.modifies_transparent_black()) { - ASSERT_NE(DlBlendColorFilter::Make(color, mode), nullptr) << desc; + ASSERT_NE(DlColorFilter::MakeBlend(color, mode), nullptr) << desc; } DlPaint paint(DlColor(0x7f7f7f7f)); @@ -4369,7 +4375,7 @@ TEST_F(DisplayListRendering, BlendColorFilterOpacityCommuteCheck) { // If it can commute with opacity, then it might also be a NOP, // so we won't necessarily get a non-null return from |::Make()| } else { - ASSERT_NE(DlBlendColorFilter::Make(color, mode), nullptr) << desc; + ASSERT_NE(DlColorFilter::MakeBlend(color, mode), nullptr) << desc; } DlPaint paint(DlColor(0x80808080)); @@ -4469,8 +4475,8 @@ class DisplayListNopTest : public DisplayListRendering { 0.0001, 0.0001, 0.0001, 0.9997, 0.0, // 0.0001, 0.0001, 0.0001, 0.9997, 0.1, // }; - color_filter_nomtb = DlMatrixColorFilter::Make(color_filter_matrix_nomtb); - color_filter_mtb = DlMatrixColorFilter::Make(color_filter_matrix_mtb); + color_filter_nomtb = DlColorFilter::MakeMatrix(color_filter_matrix_nomtb); + color_filter_mtb = DlColorFilter::MakeMatrix(color_filter_matrix_mtb); EXPECT_FALSE(color_filter_nomtb->modifies_transparent_black()); EXPECT_TRUE(color_filter_mtb->modifies_transparent_black()); @@ -4526,8 +4532,8 @@ class DisplayListNopTest : public DisplayListRendering { std::vector test_src_colors; std::vector test_dst_colors; - std::shared_ptr color_filter_nomtb; - std::shared_ptr color_filter_mtb; + std::shared_ptr color_filter_nomtb; + std::shared_ptr color_filter_mtb; // A 1-row image containing every color in test_dst_colors std::unique_ptr test_data; @@ -4682,7 +4688,7 @@ class DisplayListNopTest : public DisplayListRendering { void test_attributes_image(DlBlendMode mode, DlColor color, - DlColorFilter* color_filter, + const DlColorFilter* color_filter, DlImageFilter* image_filter) { // if (true) { return; } std::stringstream desc_stream; diff --git a/engine/src/flutter/display_list/testing/dl_test_equality.h b/engine/src/flutter/display_list/testing/dl_test_equality.h index 84dcaff5e2..5fd8c6b370 100644 --- a/engine/src/flutter/display_list/testing/dl_test_equality.h +++ b/engine/src/flutter/display_list/testing/dl_test_equality.h @@ -12,8 +12,8 @@ namespace flutter { namespace testing { -template -static void TestEquals(T& source1, T& source2) { +template +static void TestEquals(const T& source1, const U& source2) { ASSERT_TRUE(source1 == source2); ASSERT_TRUE(source2 == source1); ASSERT_FALSE(source1 != source2); @@ -24,8 +24,8 @@ static void TestEquals(T& source1, T& source2) { ASSERT_TRUE(Equals(&source2, &source1)); } -template -static void TestNotEquals(T& source1, T& source2, const std::string& label) { +template +static void TestNotEquals(T& source1, U& source2, const std::string& label) { ASSERT_FALSE(source1 == source2) << label; ASSERT_FALSE(source2 == source1) << label; ASSERT_TRUE(source1 != source2) << label; diff --git a/engine/src/flutter/display_list/testing/dl_test_snippets.cc b/engine/src/flutter/display_list/testing/dl_test_snippets.cc index bc348dbaf0..7e23751f75 100644 --- a/engine/src/flutter/display_list/testing/dl_test_snippets.cc +++ b/engine/src/flutter/display_list/testing/dl_test_snippets.cc @@ -220,26 +220,32 @@ std::vector CreateAllAttributesOps() { {"SetColorFilter", { {0, 40, 0, - [](DlOpReceiver& r) { r.setColorFilter(&kTestBlendColorFilter1); }}, - {0, 40, 0, - [](DlOpReceiver& r) { r.setColorFilter(&kTestBlendColorFilter2); }}, - {0, 40, 0, - [](DlOpReceiver& r) { r.setColorFilter(&kTestBlendColorFilter3); }}, - {0, 96, 0, [](DlOpReceiver& r) { - r.setColorFilter(&kTestMatrixColorFilter1); + r.setColorFilter(kTestBlendColorFilter1.get()); + }}, + {0, 40, 0, + [](DlOpReceiver& r) { + r.setColorFilter(kTestBlendColorFilter2.get()); + }}, + {0, 40, 0, + [](DlOpReceiver& r) { + r.setColorFilter(kTestBlendColorFilter3.get()); }}, {0, 96, 0, [](DlOpReceiver& r) { - r.setColorFilter(&kTestMatrixColorFilter2); + r.setColorFilter(kTestMatrixColorFilter1.get()); + }}, + {0, 96, 0, + [](DlOpReceiver& r) { + r.setColorFilter(kTestMatrixColorFilter2.get()); }}, {0, 16, 0, [](DlOpReceiver& r) { - r.setColorFilter(DlSrgbToLinearGammaColorFilter::kInstance.get()); + r.setColorFilter(DlColorFilter::MakeSrgbToLinearGamma().get()); }}, {0, 16, 0, [](DlOpReceiver& r) { - r.setColorFilter(DlLinearToSrgbGammaColorFilter::kInstance.get()); + r.setColorFilter(DlColorFilter::MakeLinearToSrgbGamma().get()); }}, // Reset attribute to default as last entry diff --git a/engine/src/flutter/display_list/testing/dl_test_snippets.h b/engine/src/flutter/display_list/testing/dl_test_snippets.h index c0c5668bfc..08e08e4c64 100644 --- a/engine/src/flutter/display_list/testing/dl_test_snippets.h +++ b/engine/src/flutter/display_list/testing/dl_test_snippets.h @@ -7,6 +7,7 @@ #include "flutter/display_list/display_list.h" #include "flutter/display_list/dl_builder.h" +#include "flutter/display_list/effects/color_filters/dl_blend_color_filter.h" #include "flutter/display_list/effects/dl_color_sources.h" #include "flutter/display_list/effects/dl_image_filters.h" #include "flutter/testing/testing.h" @@ -126,14 +127,18 @@ static const std::shared_ptr kTestSource5 = kColors, kStops, DlTileMode::kDecal); -static const DlBlendColorFilter kTestBlendColorFilter1(DlColor::kRed(), - DlBlendMode::kDstATop); -static const DlBlendColorFilter kTestBlendColorFilter2(DlColor::kBlue(), - DlBlendMode::kDstATop); -static const DlBlendColorFilter kTestBlendColorFilter3(DlColor::kRed(), - DlBlendMode::kDstIn); -static const DlMatrixColorFilter kTestMatrixColorFilter1(kRotateColorMatrix); -static const DlMatrixColorFilter kTestMatrixColorFilter2(kInvertColorMatrix); + +static const auto kTestBlendColorFilter1 = + DlColorFilter::MakeBlend(DlColor::kRed(), DlBlendMode::kDstATop); +static const auto kTestBlendColorFilter2 = + DlColorFilter::MakeBlend(DlColor::kBlue(), DlBlendMode::kDstATop); +static const auto kTestBlendColorFilter3 = + DlColorFilter::MakeBlend(DlColor::kRed(), DlBlendMode::kDstOver); +static const auto kTestMatrixColorFilter1 = + DlColorFilter::MakeMatrix(kRotateColorMatrix); +static const auto kTestMatrixColorFilter2 = + DlColorFilter::MakeMatrix(kInvertColorMatrix); + static const DlBlurImageFilter kTestBlurImageFilter1(5.0, 5.0, DlTileMode::kClamp); diff --git a/engine/src/flutter/display_list/utils/dl_comparable.h b/engine/src/flutter/display_list/utils/dl_comparable.h index 6273bc703f..008da8d994 100644 --- a/engine/src/flutter/display_list/utils/dl_comparable.h +++ b/engine/src/flutter/display_list/utils/dl_comparable.h @@ -15,8 +15,8 @@ namespace flutter { // Any combination of shared_ptr or T* are supported and null pointers // are not equal to anything but another null pointer. -template -bool Equals(const T* a, const T* b) { +template +bool Equals(const T* a, const U* b) { if (a == b) { return true; } @@ -26,88 +26,88 @@ bool Equals(const T* a, const T* b) { return *a == *b; } -template -bool Equals(std::shared_ptr a, const T* b) { +template +bool Equals(std::shared_ptr a, const U* b) { return Equals(a.get(), b); } -template -bool Equals(std::shared_ptr a, const T* b) { +template +bool Equals(std::shared_ptr a, const U* b) { return Equals(a.get(), b); } -template -bool Equals(const T* a, std::shared_ptr b) { +template +bool Equals(const T* a, std::shared_ptr b) { return Equals(a, b.get()); } -template -bool Equals(const T* a, std::shared_ptr b) { +template +bool Equals(const T* a, std::shared_ptr b) { return Equals(a, b.get()); } -template -bool Equals(std::shared_ptr a, std::shared_ptr b) { +template +bool Equals(std::shared_ptr a, std::shared_ptr b) { return Equals(a.get(), b.get()); } -template -bool Equals(std::shared_ptr a, std::shared_ptr b) { +template +bool Equals(std::shared_ptr a, std::shared_ptr b) { return Equals(a.get(), b.get()); } -template -bool Equals(std::shared_ptr a, std::shared_ptr b) { +template +bool Equals(std::shared_ptr a, std::shared_ptr b) { return Equals(a.get(), b.get()); } -template -bool Equals(std::shared_ptr a, std::shared_ptr b) { +template +bool Equals(std::shared_ptr a, std::shared_ptr b) { return Equals(a.get(), b.get()); } -template -bool NotEquals(const T* a, const T* b) { - return !Equals(a, b); +template +bool NotEquals(const T* a, const U* b) { + return !Equals(a, b); } -template -bool NotEquals(std::shared_ptr a, const T* b) { +template +bool NotEquals(std::shared_ptr a, const U* b) { return !Equals(a.get(), b); } -template -bool NotEquals(std::shared_ptr a, const T* b) { +template +bool NotEquals(std::shared_ptr a, const U* b) { return !Equals(a.get(), b); } -template -bool NotEquals(const T* a, std::shared_ptr b) { +template +bool NotEquals(const T* a, std::shared_ptr b) { return !Equals(a, b.get()); } -template -bool NotEquals(const T* a, std::shared_ptr b) { +template +bool NotEquals(const T* a, std::shared_ptr b) { return !Equals(a, b.get()); } -template -bool NotEquals(std::shared_ptr a, std::shared_ptr b) { +template +bool NotEquals(std::shared_ptr a, std::shared_ptr b) { return !Equals(a.get(), b.get()); } -template -bool NotEquals(std::shared_ptr a, std::shared_ptr b) { +template +bool NotEquals(std::shared_ptr a, std::shared_ptr b) { return !Equals(a.get(), b.get()); } -template -bool NotEquals(std::shared_ptr a, std::shared_ptr b) { +template +bool NotEquals(std::shared_ptr a, std::shared_ptr b) { return !Equals(a.get(), b.get()); } -template -bool NotEquals(std::shared_ptr a, std::shared_ptr b) { +template +bool NotEquals(std::shared_ptr a, std::shared_ptr b) { return !Equals(a.get(), b.get()); } diff --git a/engine/src/flutter/flow/layers/color_filter_layer_unittests.cc b/engine/src/flutter/flow/layers/color_filter_layer_unittests.cc index 209ca2b227..c43ca5d6f9 100644 --- a/engine/src/flutter/flow/layers/color_filter_layer_unittests.cc +++ b/engine/src/flutter/flow/layers/color_filter_layer_unittests.cc @@ -89,7 +89,7 @@ TEST_F(ColorFilterLayerTest, SimpleFilter) { const SkPath child_path = SkPath().addRect(child_bounds); const DlPaint child_paint = DlPaint(DlColor::kYellow()); - auto dl_color_filter = DlLinearToSrgbGammaColorFilter::kInstance; + auto dl_color_filter = DlColorFilter::MakeLinearToSrgbGamma(); auto mock_layer = std::make_shared(child_path, child_paint); auto layer = std::make_shared(dl_color_filter); layer->Add(mock_layer); @@ -129,7 +129,7 @@ TEST_F(ColorFilterLayerTest, MultipleChildren) { const DlPaint child_paint2 = DlPaint(DlColor::kCyan()); auto mock_layer1 = std::make_shared(child_path1, child_paint1); auto mock_layer2 = std::make_shared(child_path2, child_paint2); - auto dl_color_filter = DlSrgbToLinearGammaColorFilter::kInstance; + auto dl_color_filter = DlColorFilter::MakeSrgbToLinearGamma(); auto layer = std::make_shared(dl_color_filter); layer->Add(mock_layer1); layer->Add(mock_layer2); @@ -179,7 +179,7 @@ TEST_F(ColorFilterLayerTest, Nested) { const DlPaint child_paint2 = DlPaint(DlColor::kCyan()); auto mock_layer1 = std::make_shared(child_path1, child_paint1); auto mock_layer2 = std::make_shared(child_path2, child_paint2); - auto dl_color_filter = DlSrgbToLinearGammaColorFilter::kInstance; + auto dl_color_filter = DlColorFilter::MakeSrgbToLinearGamma(); auto layer1 = std::make_shared(dl_color_filter); auto layer2 = std::make_shared(dl_color_filter); @@ -239,7 +239,7 @@ TEST_F(ColorFilterLayerTest, Readback) { // ColorFilterLayer does not read from surface auto layer = std::make_shared( - DlLinearToSrgbGammaColorFilter::kInstance); + DlColorFilter::MakeLinearToSrgbGamma()); preroll_context()->surface_needs_readback = false; preroll_context()->state_stack.set_preroll_delegate(initial_transform); layer->Preroll(preroll_context()); @@ -255,7 +255,7 @@ TEST_F(ColorFilterLayerTest, Readback) { } TEST_F(ColorFilterLayerTest, CacheChild) { - auto layer_filter = DlSrgbToLinearGammaColorFilter::kInstance; + auto layer_filter = DlColorFilter::MakeSrgbToLinearGamma(); auto initial_transform = SkMatrix::Translate(50.0, 25.5); auto other_transform = SkMatrix::Scale(1.0, 2.0); const SkPath child_path = SkPath().addRect(SkRect::MakeWH(5.0f, 5.0f)); @@ -296,7 +296,7 @@ TEST_F(ColorFilterLayerTest, CacheChild) { } TEST_F(ColorFilterLayerTest, CacheChildren) { - auto layer_filter = DlSrgbToLinearGammaColorFilter::kInstance; + auto layer_filter = DlColorFilter::MakeSrgbToLinearGamma(); auto initial_transform = SkMatrix::Translate(50.0, 25.5); auto other_transform = SkMatrix::Scale(1.0, 2.0); const SkPath child_path1 = SkPath().addRect(SkRect::MakeWH(5.0f, 5.0f)); @@ -342,7 +342,7 @@ TEST_F(ColorFilterLayerTest, CacheChildren) { } TEST_F(ColorFilterLayerTest, CacheColorFilterLayerSelf) { - auto layer_filter = DlSrgbToLinearGammaColorFilter::kInstance; + auto layer_filter = DlColorFilter::MakeSrgbToLinearGamma(); auto initial_transform = SkMatrix::Translate(50.0, 25.5); auto other_transform = SkMatrix::Scale(1.0, 2.0); const SkPath child_path1 = SkPath().addRect(SkRect::MakeWH(5.0f, 5.0f)); @@ -408,12 +408,12 @@ TEST_F(ColorFilterLayerTest, OpacityInheritance) { 0, 0, 0, 1, 0, }; // clang-format on - auto layer_filter = DlMatrixColorFilter(matrix); + auto layer_filter = DlColorFilter::MakeMatrix(matrix); auto initial_transform = SkMatrix::Translate(50.0, 25.5); const SkPath child_path = SkPath().addRect(SkRect::MakeWH(5.0f, 5.0f)); auto mock_layer = std::make_shared(child_path); - auto color_filter_layer = std::make_shared( - std::make_shared(matrix)); + auto color_filter_layer = + std::make_shared(DlColorFilter::MakeMatrix(matrix)); color_filter_layer->Add(mock_layer); PrerollContext* context = preroll_context(); @@ -440,7 +440,7 @@ TEST_F(ColorFilterLayerTest, OpacityInheritance) { /* ColorFilterLayer::Paint() */ { DlPaint dl_paint; dl_paint.setColor(DlColor(opacity_alpha << 24)); - dl_paint.setColorFilter(&layer_filter); + dl_paint.setColorFilter(layer_filter); expected_builder.SaveLayer(&child_path.getBounds(), &dl_paint); /* MockLayer::Paint() */ { expected_builder.DrawPath(child_path, DlPaint(DlColor(0xFF000000))); diff --git a/engine/src/flutter/flow/layers/layer_state_stack_unittests.cc b/engine/src/flutter/flow/layers/layer_state_stack_unittests.cc index 4e3f092270..bffe21ccf7 100644 --- a/engine/src/flutter/flow/layers/layer_state_stack_unittests.cc +++ b/engine/src/flutter/flow/layers/layer_state_stack_unittests.cc @@ -207,12 +207,10 @@ TEST(LayerStateStack, Opacity) { TEST(LayerStateStack, ColorFilter) { SkRect rect = {10, 10, 20, 20}; - std::shared_ptr outer_filter = - std::make_shared(DlColor::kYellow(), - DlBlendMode::kColorBurn); - std::shared_ptr inner_filter = - std::make_shared(DlColor::kRed(), - DlBlendMode::kColorBurn); + auto outer_filter = + DlColorFilter::MakeBlend(DlColor::kYellow(), DlBlendMode::kColorBurn); + auto inner_filter = + DlColorFilter::MakeBlend(DlColor::kRed(), DlBlendMode::kColorBurn); LayerStateStack state_stack; state_stack.set_preroll_delegate(SkRect::MakeLTRB(0, 0, 50, 50)); @@ -370,9 +368,8 @@ TEST(LayerStateStack, ImageFilter) { TEST(LayerStateStack, OpacityAndColorFilterInteraction) { SkRect rect = {10, 10, 20, 20}; - std::shared_ptr color_filter = - std::make_shared(DlColor::kYellow(), - DlBlendMode::kColorBurn); + auto color_filter = + DlColorFilter::MakeBlend(DlColor::kYellow(), DlBlendMode::kColorBurn); DisplayListBuilder builder; LayerStateStack state_stack; @@ -489,11 +486,9 @@ TEST(LayerStateStack, OpacityAndImageFilterInteraction) { TEST(LayerStateStack, ColorFilterAndImageFilterInteraction) { SkRect rect = {10, 10, 20, 20}; - std::shared_ptr color_filter = - std::make_shared(DlColor::kYellow(), - DlBlendMode::kColorBurn); - std::shared_ptr image_filter = - DlImageFilter::MakeBlur(2.0f, 2.0f, DlTileMode::kClamp); + auto color_filter = + DlColorFilter::MakeBlend(DlColor::kYellow(), DlBlendMode::kColorBurn); + auto image_filter = DlImageFilter::MakeBlur(2.0f, 2.0f, DlTileMode::kClamp); DisplayListBuilder builder; LayerStateStack state_stack; diff --git a/engine/src/flutter/impeller/display_list/aiks_dl_basic_unittests.cc b/engine/src/flutter/impeller/display_list/aiks_dl_basic_unittests.cc index d62d2ace32..281a33e7d0 100644 --- a/engine/src/flutter/impeller/display_list/aiks_dl_basic_unittests.cc +++ b/engine/src/flutter/impeller/display_list/aiks_dl_basic_unittests.cc @@ -58,7 +58,7 @@ TEST_P(AiksTest, CanRenderInvertedImageWithColorFilter) { DlPaint paint; paint.setColor(DlColor::kRed()); paint.setColorFilter( - DlBlendColorFilter::Make(DlColor::kYellow(), DlBlendMode::kSrcOver)); + DlColorFilter::MakeBlend(DlColor::kYellow(), DlBlendMode::kSrcOver)); paint.setInvertColors(true); auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg")); @@ -72,7 +72,7 @@ TEST_P(AiksTest, CanRenderColorFilterWithInvertColors) { DlPaint paint; paint.setColor(DlColor::kRed()); paint.setColorFilter( - DlBlendColorFilter::Make(DlColor::kYellow(), DlBlendMode::kSrcOver)); + DlColorFilter::MakeBlend(DlColor::kYellow(), DlBlendMode::kSrcOver)); paint.setInvertColors(true); builder.DrawRect(SkRect::MakeLTRB(0, 0, 100, 100), paint); @@ -84,7 +84,7 @@ TEST_P(AiksTest, CanRenderColorFilterWithInvertColorsDrawPaint) { DlPaint paint; paint.setColor(DlColor::kRed()); paint.setColorFilter( - DlBlendColorFilter::Make(DlColor::kYellow(), DlBlendMode::kSrcOver)); + DlColorFilter::MakeBlend(DlColor::kYellow(), DlBlendMode::kSrcOver)); paint.setInvertColors(true); builder.DrawPaint(paint); @@ -829,7 +829,7 @@ TEST_P(AiksTest, CanRenderClippedBackdropFilter) { DlPaint save_paint; auto backdrop_filter = DlImageFilter::MakeColorFilter( - DlBlendColorFilter::Make(DlColor::kRed(), DlBlendMode::kExclusion)); + DlColorFilter::MakeBlend(DlColor::kRed(), DlBlendMode::kExclusion)); builder.SaveLayer(&clip_rect, &save_paint, backdrop_filter.get()); ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); @@ -1513,7 +1513,7 @@ TEST_P(AiksTest, PipelineBlendSingleParameter) { paint.setColor(DlColor::kGreen()); paint.setBlendMode(DlBlendMode::kSrcOver); paint.setImageFilter(DlImageFilter::MakeColorFilter( - DlBlendColorFilter::Make(DlColor::kWhite(), DlBlendMode::kDst))); + DlColorFilter::MakeBlend(DlColor::kWhite(), DlBlendMode::kDst))); builder.DrawCircle(SkPoint::Make(200, 200), 200, paint); builder.Restore(); } diff --git a/engine/src/flutter/impeller/display_list/aiks_dl_blend_unittests.cc b/engine/src/flutter/impeller/display_list/aiks_dl_blend_unittests.cc index 143ef8312e..062a61b3f2 100644 --- a/engine/src/flutter/impeller/display_list/aiks_dl_blend_unittests.cc +++ b/engine/src/flutter/impeller/display_list/aiks_dl_blend_unittests.cc @@ -66,7 +66,7 @@ TEST_P(AiksTest, CanRenderAdvancedBlendColorFilterWithSaveLayer) { builder.ClipRect(layer_rect); DlPaint save_paint; - save_paint.setColorFilter(DlBlendColorFilter::Make( + save_paint.setColorFilter(DlColorFilter::MakeBlend( DlColor::RGBA(0, 1, 0, 0.5), DlBlendMode::kDifference)); builder.SaveLayer(&layer_rect, &save_paint); @@ -233,7 +233,7 @@ TEST_P(AiksTest, ColorFilterBlend) { srcPaint.setBlendMode(blend_modes[i]); if (has_color_filter) { std::shared_ptr color_filter = - DlBlendColorFilter::Make(DlColor::RGBA(0.9, 0.5, 0.0, 1.0), + DlColorFilter::MakeBlend(DlColor::RGBA(0.9, 0.5, 0.0, 1.0), DlBlendMode::kSrcIn); srcPaint.setColorFilter(color_filter); } @@ -290,7 +290,7 @@ TEST_P(AiksTest, ColorFilterAdvancedBlend) { srcPaint.setBlendMode(blend_modes[i]); if (has_color_filter) { std::shared_ptr color_filter = - DlBlendColorFilter::Make(DlColor::RGBA(0.9, 0.5, 0.0, 1.0), + DlColorFilter::MakeBlend(DlColor::RGBA(0.9, 0.5, 0.0, 1.0), DlBlendMode::kSrcIn); srcPaint.setColorFilter(color_filter); } @@ -382,7 +382,7 @@ TEST_P(AiksTest, ColorFilterAdvancedBlendNoFbFetch) { srcPaint.setBlendMode(blend_modes[i]); if (has_color_filter) { std::shared_ptr color_filter = - DlBlendColorFilter::Make(DlColor::RGBA(0.9, 0.5, 0.0, 1.0), + DlColorFilter::MakeBlend(DlColor::RGBA(0.9, 0.5, 0.0, 1.0), DlBlendMode::kMultiply); srcPaint.setColorFilter(color_filter); } @@ -445,7 +445,7 @@ TEST_P(AiksTest, BlendModePlusAlphaColorFilterWideGamut) { DlPaint save_paint; save_paint.setColorFilter( - DlBlendColorFilter::Make(DlColor::RGBA(1, 0, 0, 1), DlBlendMode::kPlus)); + DlColorFilter::MakeBlend(DlColor::RGBA(1, 0, 0, 1), DlBlendMode::kPlus)); builder.SaveLayer(nullptr, &save_paint); paint.setColor(DlColor::kRed()); @@ -471,7 +471,7 @@ TEST_P(AiksTest, ForegroundBlendSubpassCollapseOptimization) { DlPaint save_paint; save_paint.setColorFilter( - DlBlendColorFilter::Make(DlColor::kRed(), DlBlendMode::kColorDodge)); + DlColorFilter::MakeBlend(DlColor::kRed(), DlBlendMode::kColorDodge)); builder.SaveLayer(nullptr, &save_paint); builder.Translate(500, 300); @@ -721,7 +721,7 @@ TEST_P(AiksTest, ForegroundPipelineBlendAppliesTransformCorrectly) { builder.Rotate(30); DlPaint image_paint; - image_paint.setColorFilter(DlBlendColorFilter::Make( + image_paint.setColorFilter(DlColorFilter::MakeBlend( DlColor::RGBA(255.0f / 255.0f, 165.0f / 255.0f, 0.0f / 255.0f, 1.0f), DlBlendMode::kSrcIn)); @@ -739,7 +739,7 @@ TEST_P(AiksTest, ForegroundAdvancedBlendAppliesTransformCorrectly) { builder.Rotate(30); DlPaint image_paint; - image_paint.setColorFilter(DlBlendColorFilter::Make( + image_paint.setColorFilter(DlColorFilter::MakeBlend( DlColor::RGBA(255.0f / 255.0f, 165.0f / 255.0f, 0.0f / 255.0f, 1.0f), DlBlendMode::kColorDodge)); @@ -898,7 +898,7 @@ TEST_P(AiksTest, DestructiveBlendColorFilterFloodsClip) { DlPaint save_paint; save_paint.setColorFilter( - DlBlendColorFilter::Make(DlColor::kRed(), DlBlendMode::kSrc)); + DlColorFilter::MakeBlend(DlColor::kRed(), DlBlendMode::kSrc)); builder.SaveLayer(nullptr, &save_paint); builder.Restore(); @@ -913,7 +913,7 @@ TEST_P(AiksTest, AdvancedBlendColorFilterWithDestinationOpacity) { DlPaint save_paint; save_paint.setOpacity(0.3); - save_paint.setColorFilter(DlBlendColorFilter::Make(DlColor::kTransparent(), + save_paint.setColorFilter(DlColorFilter::MakeBlend(DlColor::kTransparent(), DlBlendMode::kSaturation)); builder.SaveLayer(nullptr, &save_paint); builder.DrawRect(SkRect::MakeXYWH(100, 100, 300, 300), 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 00d126560f..63a3d5443a 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 @@ -175,7 +175,7 @@ TEST_P(AiksTest, CanRenderForegroundBlendWithMaskBlur) { paint.setMaskFilter( DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma.sigma)); paint.setColorFilter( - DlBlendColorFilter::Make(DlColor::kGreen(), DlBlendMode::kSrc)); + DlColorFilter::MakeBlend(DlColor::kGreen(), DlBlendMode::kSrc)); builder.DrawCircle(SkPoint{400, 400}, 200, paint); ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); @@ -195,7 +195,7 @@ TEST_P(AiksTest, CanRenderForegroundAdvancedBlendWithMaskBlur) { paint.setMaskFilter( DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma.sigma)); paint.setColorFilter( - DlBlendColorFilter::Make(DlColor::kGreen(), DlBlendMode::kColor)); + DlColorFilter::MakeBlend(DlColor::kGreen(), DlBlendMode::kColor)); builder.DrawCircle(SkPoint{400, 400}, 200, paint); builder.Restore(); diff --git a/engine/src/flutter/impeller/display_list/aiks_dl_gradient_unittests.cc b/engine/src/flutter/impeller/display_list/aiks_dl_gradient_unittests.cc index 7e36201544..2f9c0f27ae 100644 --- a/engine/src/flutter/impeller/display_list/aiks_dl_gradient_unittests.cc +++ b/engine/src/flutter/impeller/display_list/aiks_dl_gradient_unittests.cc @@ -94,7 +94,7 @@ TEST_P(AiksTest, CanRenderLinearGradientDecalWithColorFilter) { // Overlay the gradient with 25% green. This should appear as the entire // rectangle being drawn with 25% green, including the border area outside the // decal gradient. - paint.setColorFilter(DlBlendColorFilter::Make(DlColor::kGreen().withAlpha(64), + paint.setColorFilter(DlColorFilter::MakeBlend(DlColor::kGreen().withAlpha(64), DlBlendMode::kSrcOver)); paint.setColor(DlColor::kWhite()); builder.DrawRect(SkRect::MakeXYWH(0, 0, 600, 600), paint); diff --git a/engine/src/flutter/impeller/display_list/aiks_dl_path_unittests.cc b/engine/src/flutter/impeller/display_list/aiks_dl_path_unittests.cc index 1d9d852836..953f193be9 100644 --- a/engine/src/flutter/impeller/display_list/aiks_dl_path_unittests.cc +++ b/engine/src/flutter/impeller/display_list/aiks_dl_path_unittests.cc @@ -38,7 +38,7 @@ TEST_P(AiksTest, RotateColorFilteredPath) { arrow_head.moveTo({50, 120}).lineTo({120, 190}).lineTo({190, 120}); auto filter = - DlBlendColorFilter::Make(DlColor::kAliceBlue(), DlBlendMode::kSrcIn); + DlColorFilter::MakeBlend(DlColor::kAliceBlue(), DlBlendMode::kSrcIn); DlPaint paint; paint.setStrokeWidth(15.0); diff --git a/engine/src/flutter/impeller/display_list/aiks_dl_unittests.cc b/engine/src/flutter/impeller/display_list/aiks_dl_unittests.cc index 0849f9b9a0..6c38998103 100644 --- a/engine/src/flutter/impeller/display_list/aiks_dl_unittests.cc +++ b/engine/src/flutter/impeller/display_list/aiks_dl_unittests.cc @@ -87,7 +87,7 @@ TEST_P(AiksTest, ColorMatrixFilterSubpassCollapseOptimization) { 0, 0, -1.0, 1.0, 0, // 1.0, 1.0, 1.0, 1.0, 0 // }; - auto filter = DlMatrixColorFilter::Make(matrix); + auto filter = DlColorFilter::MakeMatrix(matrix); DlPaint paint; paint.setColorFilter(filter); @@ -107,7 +107,7 @@ TEST_P(AiksTest, LinearToSrgbFilterSubpassCollapseOptimization) { DisplayListBuilder builder(GetCullRect(GetWindowSize())); DlPaint paint; - paint.setColorFilter(DlLinearToSrgbGammaColorFilter::kInstance); + paint.setColorFilter(DlColorFilter::MakeLinearToSrgbGamma()); builder.SaveLayer(nullptr, &paint); builder.Translate(500, 300); @@ -124,7 +124,7 @@ TEST_P(AiksTest, SrgbToLinearFilterSubpassCollapseOptimization) { DisplayListBuilder builder(GetCullRect(GetWindowSize())); DlPaint paint; - paint.setColorFilter(DlLinearToSrgbGammaColorFilter::kInstance); + paint.setColorFilter(DlColorFilter::MakeLinearToSrgbGamma()); builder.SaveLayer(nullptr, &paint); builder.Translate(500, 300); @@ -163,7 +163,7 @@ TEST_P(AiksTest, TranslucentSaveLayerWithBlendColorFilterDrawsCorrectly) { DlPaint save_paint; paint.setColor(DlColor::kBlack().withAlpha(128)); paint.setColorFilter( - DlBlendColorFilter::Make(DlColor::kRed(), DlBlendMode::kDstOver)); + DlColorFilter::MakeBlend(DlColor::kRed(), DlBlendMode::kDstOver)); builder.Save(); builder.ClipRect(SkRect::MakeXYWH(100, 500, 300, 300)); builder.SaveLayer(nullptr, &paint); @@ -187,7 +187,7 @@ TEST_P(AiksTest, TranslucentSaveLayerWithBlendImageFilterDrawsCorrectly) { DlPaint save_paint; save_paint.setColor(DlColor::kBlack().withAlpha(128)); save_paint.setImageFilter(DlImageFilter::MakeColorFilter( - DlBlendColorFilter::Make(DlColor::kRed(), DlBlendMode::kDstOver))); + DlColorFilter::MakeBlend(DlColor::kRed(), DlBlendMode::kDstOver))); builder.SaveLayer(nullptr, &save_paint); @@ -209,7 +209,7 @@ TEST_P(AiksTest, TranslucentSaveLayerWithColorAndImageFilterDrawsCorrectly) { DlPaint save_paint; save_paint.setColor(DlColor::kBlack().withAlpha(128)); save_paint.setColorFilter( - DlBlendColorFilter::Make(DlColor::kRed(), DlBlendMode::kDstOver)); + DlColorFilter::MakeBlend(DlColor::kRed(), DlBlendMode::kDstOver)); builder.Save(); builder.ClipRect(SkRect::MakeXYWH(100, 500, 300, 300)); builder.SaveLayer(nullptr, &save_paint); @@ -277,7 +277,7 @@ TEST_P(AiksTest, TranslucentSaveLayerWithColorMatrixColorFilterDrawsCorrectly) { }; DlPaint paint; paint.setColor(DlColor::kBlack().withAlpha(128)); - paint.setColorFilter(DlMatrixColorFilter::Make(matrix)); + paint.setColorFilter(DlColorFilter::MakeMatrix(matrix)); builder.SaveLayer(nullptr, &paint); builder.DrawImage(image, SkPoint{100, 500}, {}); builder.Restore(); @@ -299,7 +299,7 @@ TEST_P(AiksTest, TranslucentSaveLayerWithColorMatrixImageFilterDrawsCorrectly) { }; DlPaint paint; paint.setColor(DlColor::kBlack().withAlpha(128)); - paint.setColorFilter(DlMatrixColorFilter::Make(matrix)); + paint.setColorFilter(DlColorFilter::MakeMatrix(matrix)); builder.SaveLayer(nullptr, &paint); builder.DrawImage(image, SkPoint{100, 500}, {}); builder.Restore(); @@ -323,9 +323,9 @@ TEST_P(AiksTest, DlPaint paint; paint.setColor(DlColor::kBlack().withAlpha(128)); paint.setImageFilter( - DlImageFilter::MakeColorFilter(DlMatrixColorFilter::Make(matrix))); + DlImageFilter::MakeColorFilter(DlColorFilter::MakeMatrix(matrix))); paint.setColorFilter( - DlBlendColorFilter::Make(DlColor::kGreen(), DlBlendMode::kModulate)); + DlColorFilter::MakeBlend(DlColor::kGreen(), DlBlendMode::kModulate)); builder.SaveLayer(nullptr, &paint); builder.DrawImage(image, SkPoint{100, 500}, {}); builder.Restore(); @@ -723,7 +723,7 @@ TEST_P(AiksTest, ImageFilteredSaveLayerWithUnboundedContents) { 0, 0, 0, 1, 0 // }; auto rgb_swap_filter = - DlImageFilter::MakeColorFilter(std::make_shared(m)); + DlImageFilter::MakeColorFilter(DlColorFilter::MakeMatrix(m)); test(rgb_swap_filter); builder.Translate(200.0, 0.0); diff --git a/engine/src/flutter/impeller/display_list/color_filter.cc b/engine/src/flutter/impeller/display_list/color_filter.cc index e248ba6e09..f5050672f3 100644 --- a/engine/src/flutter/impeller/display_list/color_filter.cc +++ b/engine/src/flutter/impeller/display_list/color_filter.cc @@ -4,7 +4,7 @@ #include "impeller/display_list/color_filter.h" -#include "display_list/effects/dl_color_filter.h" +#include "display_list/effects/dl_color_filters.h" #include "fml/logging.h" #include "impeller/display_list/skia_conversions.h" #include "impeller/entity/contents/filters/color_filter_contents.h" diff --git a/engine/src/flutter/impeller/display_list/dl_unittests.cc b/engine/src/flutter/impeller/display_list/dl_unittests.cc index 06bb71d756..7ff0fa8405 100644 --- a/engine/src/flutter/impeller/display_list/dl_unittests.cc +++ b/engine/src/flutter/impeller/display_list/dl_unittests.cc @@ -522,18 +522,18 @@ TEST_P(DisplayListTest, CanDrawWithBlendColorFilter) { // Pipeline blended image. { - auto filter = flutter::DlBlendColorFilter(flutter::DlColor::kYellow(), - flutter::DlBlendMode::kModulate); - paint.setColorFilter(&filter); + auto filter = flutter::DlColorFilter::MakeBlend( + flutter::DlColor::kYellow(), flutter::DlBlendMode::kModulate); + paint.setColorFilter(filter); builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100), flutter::DlImageSampling::kNearestNeighbor, &paint); } // Advanced blended image. { - auto filter = flutter::DlBlendColorFilter(flutter::DlColor::kRed(), - flutter::DlBlendMode::kScreen); - paint.setColorFilter(&filter); + auto filter = flutter::DlColorFilter::MakeBlend( + flutter::DlColor::kRed(), flutter::DlBlendMode::kScreen); + paint.setColorFilter(filter); builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(250, 250), flutter::DlImageSampling::kNearestNeighbor, &paint); } @@ -552,17 +552,15 @@ TEST_P(DisplayListTest, CanDrawWithColorFilterImageFilter) { flutter::DisplayListBuilder builder; flutter::DlPaint paint; - auto color_filter = - std::make_shared(invert_color_matrix); - auto image_filter = - std::make_shared(color_filter); + auto color_filter = flutter::DlColorFilter::MakeMatrix(invert_color_matrix); + auto image_filter = flutter::DlImageFilter::MakeColorFilter(color_filter); - paint.setImageFilter(image_filter.get()); + paint.setImageFilter(image_filter); builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100), flutter::DlImageSampling::kNearestNeighbor, &paint); builder.Translate(0, 700); - paint.setColorFilter(color_filter.get()); + paint.setColorFilter(color_filter); builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100), flutter::DlImageSampling::kNearestNeighbor, &paint); ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); @@ -628,13 +626,11 @@ TEST_P(DisplayListTest, CanClampTheResultingColorOfColorMatrixFilter) { 0, 0, 0, 0.5, 0, // }; auto inner_color_filter = - std::make_shared(inner_color_matrix); + flutter::DlColorFilter::MakeMatrix(inner_color_matrix); auto outer_color_filter = - std::make_shared(outer_color_matrix); - auto inner = - std::make_shared(inner_color_filter); - auto outer = - std::make_shared(outer_color_filter); + flutter::DlColorFilter::MakeMatrix(outer_color_matrix); + auto inner = flutter::DlImageFilter::MakeColorFilter(inner_color_filter); + auto outer = flutter::DlImageFilter::MakeColorFilter(outer_color_filter); auto compose = std::make_shared(outer, inner); flutter::DisplayListBuilder builder; @@ -1109,13 +1105,11 @@ TEST_P(DisplayListTest, CanDrawRectWithLinearToSrgbColorFilter) { flutter::DlPaint paint; paint.setColor(flutter::DlColor(0xFF2196F3).withAlpha(128)); flutter::DisplayListBuilder builder; - paint.setColorFilter( - flutter::DlLinearToSrgbGammaColorFilter::kInstance.get()); + paint.setColorFilter(flutter::DlColorFilter::MakeLinearToSrgbGamma()); builder.DrawRect(SkRect::MakeXYWH(0, 0, 200, 200), paint); builder.Translate(0, 200); - paint.setColorFilter( - flutter::DlSrgbToLinearGammaColorFilter::kInstance.get()); + paint.setColorFilter(flutter::DlColorFilter::MakeSrgbToLinearGamma()); builder.DrawRect(SkRect::MakeXYWH(0, 0, 200, 200), paint); ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); @@ -1239,11 +1233,11 @@ TEST_P(DisplayListTest, CanDrawCorrectlyWithColorFilterAndImageFilter) { 0, 0, 0, 1, 0, // }; auto green_color_filter = - std::make_shared(green_color_matrix); + flutter::DlColorFilter::MakeMatrix(green_color_matrix); auto blue_color_filter = - std::make_shared(blue_color_matrix); + flutter::DlColorFilter::MakeMatrix(blue_color_matrix); auto blue_image_filter = - std::make_shared(blue_color_filter); + flutter::DlImageFilter::MakeColorFilter(blue_color_filter); flutter::DlPaint paint; paint.setColor(flutter::DlColor::kRed()); diff --git a/engine/src/flutter/impeller/toolkit/interop/color_filter.cc b/engine/src/flutter/impeller/toolkit/interop/color_filter.cc index 7e5b2da2b2..01825aa266 100644 --- a/engine/src/flutter/impeller/toolkit/interop/color_filter.cc +++ b/engine/src/flutter/impeller/toolkit/interop/color_filter.cc @@ -7,7 +7,7 @@ namespace impeller::interop { ScopedObject ColorFilter::MakeBlend(Color color, BlendMode mode) { - auto filter = flutter::DlBlendColorFilter::Make(ToDisplayListType(color), + auto filter = flutter::DlColorFilter::MakeBlend(ToDisplayListType(color), ToDisplayListType(mode)); if (!filter) { return nullptr; @@ -16,20 +16,20 @@ ScopedObject ColorFilter::MakeBlend(Color color, BlendMode mode) { } ScopedObject ColorFilter::MakeMatrix(const float matrix[20]) { - auto filter = flutter::DlMatrixColorFilter::Make(matrix); + auto filter = flutter::DlColorFilter::MakeMatrix(matrix); if (!filter) { return nullptr; } return Create(std::move(filter)); } -ColorFilter::ColorFilter(std::shared_ptr filter) +ColorFilter::ColorFilter(std::shared_ptr filter) : filter_(std::move(filter)) {} ColorFilter::~ColorFilter() = default; -const std::shared_ptr& ColorFilter::GetColorFilter() - const { +const std::shared_ptr& +ColorFilter::GetColorFilter() const { return filter_; } diff --git a/engine/src/flutter/impeller/toolkit/interop/color_filter.h b/engine/src/flutter/impeller/toolkit/interop/color_filter.h index 70c0c6ec98..2f0b066a98 100644 --- a/engine/src/flutter/impeller/toolkit/interop/color_filter.h +++ b/engine/src/flutter/impeller/toolkit/interop/color_filter.h @@ -20,7 +20,7 @@ class ColorFilter final static ScopedObject MakeMatrix(const float matrix[20]); - explicit ColorFilter(std::shared_ptr filter); + explicit ColorFilter(std::shared_ptr filter); ~ColorFilter() override; @@ -28,10 +28,10 @@ class ColorFilter final ColorFilter& operator=(const ColorFilter&) = delete; - const std::shared_ptr& GetColorFilter() const; + const std::shared_ptr& GetColorFilter() const; private: - std::shared_ptr filter_; + std::shared_ptr filter_; }; } // namespace impeller::interop diff --git a/engine/src/flutter/lib/ui/painting/color_filter.cc b/engine/src/flutter/lib/ui/painting/color_filter.cc index f0d780d272..e58cb65920 100644 --- a/engine/src/flutter/lib/ui/painting/color_filter.cc +++ b/engine/src/flutter/lib/ui/painting/color_filter.cc @@ -23,7 +23,7 @@ void ColorFilter::Create(Dart_Handle wrapper) { } void ColorFilter::initMode(int color, int blend_mode) { - filter_ = DlBlendColorFilter::Make(static_cast(color), + filter_ = DlColorFilter::MakeBlend(static_cast(color), static_cast(blend_mode)); } @@ -39,15 +39,15 @@ void ColorFilter::initMatrix(const tonic::Float32List& color_matrix) { matrix[9] *= 1.0f / 255; matrix[14] *= 1.0f / 255; matrix[19] *= 1.0f / 255; - filter_ = DlMatrixColorFilter::Make(matrix); + filter_ = DlColorFilter::MakeMatrix(matrix); } void ColorFilter::initLinearToSrgbGamma() { - filter_ = DlLinearToSrgbGammaColorFilter::kInstance; + filter_ = DlColorFilter::MakeLinearToSrgbGamma(); } void ColorFilter::initSrgbToLinearGamma() { - filter_ = DlSrgbToLinearGammaColorFilter::kInstance; + filter_ = DlColorFilter::MakeSrgbToLinearGamma(); } ColorFilter::~ColorFilter() = default; diff --git a/engine/src/flutter/lib/ui/painting/paint_unittests.cc b/engine/src/flutter/lib/ui/painting/paint_unittests.cc index 2b051f00b0..9d18dbed43 100644 --- a/engine/src/flutter/lib/ui/painting/paint_unittests.cc +++ b/engine/src/flutter/lib/ui/painting/paint_unittests.cc @@ -52,7 +52,7 @@ TEST_F(ShellTest, ConvertPaintToDlPaint) { ASSERT_EQ(dl_paint.getBlendMode(), DlBlendMode::kModulate); ASSERT_EQ(static_cast(dl_paint.getColor().argb()), 0x11223344u); ASSERT_EQ(*dl_paint.getColorFilter(), - DlBlendColorFilter(DlColor(0x55667788), DlBlendMode::kXor)); + *DlColorFilter::MakeBlend(DlColor(0x55667788), DlBlendMode::kXor)); ASSERT_EQ(*dl_paint.getMaskFilter(), DlBlurMaskFilter(DlBlurStyle::kInner, 0.75)); ASSERT_EQ(dl_paint.getDrawStyle(), DlDrawStyle::kStroke); diff --git a/engine/src/flutter/testing/display_list_testing.cc b/engine/src/flutter/testing/display_list_testing.cc index 7484373412..b969daa41c 100644 --- a/engine/src/flutter/testing/display_list_testing.cc +++ b/engine/src/flutter/testing/display_list_testing.cc @@ -8,6 +8,7 @@ #include #include "flutter/display_list/display_list.h" +#include "flutter/display_list/effects/dl_color_filters.h" #include "flutter/display_list/effects/dl_color_sources.h" #include "flutter/display_list/effects/dl_image_filters.h"