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"