From 8cca4b2421a2dac36e8352fd2b33ed9c749867e3 Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Wed, 30 Mar 2022 18:08:58 +0800 Subject: [PATCH 01/26] add dilate and erode at the Dart side --- lib/ui/painting.dart | 96 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/lib/ui/painting.dart b/lib/ui/painting.dart index 018dfd7cfcc97..debb6b3b6527d 100644 --- a/lib/ui/painting.dart +++ b/lib/ui/painting.dart @@ -3224,6 +3224,22 @@ abstract class ImageFilter { return _GaussianBlurImageFilter(sigmaX: sigmaX, sigmaY: sigmaY, tileMode: tileMode); } + /// Creates an image filter that dilates each input pixel's channel values + /// to the max value within the given radii along the x and y axes. + factory ImageFilter.dilate({ double radiusX = 0.0, double radiusY = 0.0 }) { + assert(radiusX != null); + assert(radiusY != null); + return _DilateImageFilter(radiusX: radiusX, radiusY: radiusY); + } + + /// Create a filter that erodes each input pixel's channel values + /// to the minimum channel value within the given radii along the x and y axes. + factory ImageFilter.erode({ double radiusX = 0.0, double radiusY = 0.0 }) { + assert(radiusX != null); + assert(radiusY != null); + return _ErodeImageFilter(radiusX: radiusX, radiusY: radiusY); + } + /// Creates an image filter that applies a matrix transformation. /// /// For example, applying a positive scale matrix (see [Matrix4.diagonal3]) @@ -3327,6 +3343,66 @@ class _GaussianBlurImageFilter implements ImageFilter { int get hashCode => hashValues(sigmaX, sigmaY); } +class _DilateImageFilter implements ImageFilter { + _DilateImageFilter({ required this.radiusX, required this.radiusY }); + + final double radiusX; + final double radiusY; + + // MakeBlurFilter + late final _ImageFilter nativeFilter = _ImageFilter.dilate(this); + @override + _ImageFilter _toNativeImageFilter() => nativeFilter; + + @override + String get _shortDescription => 'dilate($radiusX, $radiusY)'; + + @override + String toString() => 'ImageFilter.dilate($radiusX, $radiusY)'; + + @override + bool operator ==(Object other) { + if (other.runtimeType != runtimeType) + return false; + return other is _DilateImageFilter + && other.radiusX == radiusX + && other.radiusY == radiusY; + } + + @override + int get hashCode => hashValues(radiusX, radiusY); +} + +class _ErodeImageFilter implements ImageFilter { + _ErodeImageFilter({ required this.radiusX, required this.radiusY }); + + final double radiusX; + final double radiusY; + + // MakeBlurFilter + late final _ImageFilter nativeFilter = _ImageFilter.erode(this); + @override + _ImageFilter _toNativeImageFilter() => nativeFilter; + + @override + String get _shortDescription => 'erode($radiusX, $radiusY)'; + + @override + String toString() => 'ImageFilter.erode($radiusX, $radiusY)'; + + @override + bool operator ==(Object other) { + if (other.runtimeType != runtimeType) + return false; + return other is _ErodeImageFilter + && other.radiusX == radiusX + && other.radiusY == radiusY; + } + + @override + int get hashCode => hashValues(radiusX, radiusY); +} + class _ComposeImageFilter implements ImageFilter { _ComposeImageFilter({ required this.innerFilter, required this.outerFilter }); @@ -3374,6 +3450,26 @@ class _ImageFilter extends NativeFieldWrapperClass1 { } void _initBlur(double sigmaX, double sigmaY, int tileMode) native 'ImageFilter_initBlur'; + /// Creates an image filter that dilates each input pixel's channel values + /// to the max value within the given radii along the x and y axes. + _ImageFilter.dilate(_DilateImageFilter filter) + : assert(filter != null), + creator = filter { // ignore: prefer_initializing_formals + _constructor(); + _initDilate(filter.radiusX, filter.radiusY); + } + void _initDilate(double radiusX, double radiusY) native 'ImageFilter_initDilate'; + + /// Create a filter that erodes each input pixel's channel values + /// to the minimum channel value within the given radii along the x and y axes. + _ImageFilter.erode(_ErodeImageFilter filter) + : assert(filter != null), + creator = filter { // ignore: prefer_initializing_formals + _constructor(); + _initErode(filter.radiusX, filter.radiusY); + } + void _initErode(double radiusX, double radiusY) native 'ImageFilter_initErode'; + /// Creates an image filter that applies a matrix transformation. /// /// For example, applying a positive scale matrix (see [Matrix4.diagonal3]) From 59e8e8862a9a2988234723caeb7c301f2e1f5d7a Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Wed, 30 Mar 2022 18:11:55 +0800 Subject: [PATCH 02/26] add tests at dart side --- .../compositing/compositing_golden_test.dart | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/lib/web_ui/test/html/compositing/compositing_golden_test.dart b/lib/web_ui/test/html/compositing/compositing_golden_test.dart index b6e3601696cae..016c705f6f388 100644 --- a/lib/web_ui/test/html/compositing/compositing_golden_test.dart +++ b/lib/web_ui/test/html/compositing/compositing_golden_test.dart @@ -375,6 +375,32 @@ Future testMain() async { await matchGoldenFile('compositing_image_filter.png', region: region); }); + test('pushImageFilter dilate', () async { + final SurfaceSceneBuilder builder = SurfaceSceneBuilder(); + builder.pushImageFilter( + ui.ImageFilter.dilate(radiusX: 1, radiusY: 3), + ); + _drawTestPicture(builder); + builder.pop(); + + html.document.body!.append(builder.build().webOnlyRootElement!); + + await matchGoldenFile('compositing_image_filter_dilate.png', region: region); + }); + + test('pushImageFilter erode', () async { + final SurfaceSceneBuilder builder = SurfaceSceneBuilder(); + builder.pushImageFilter( + ui.ImageFilter.erode(radiusX: 1, radiusY: 3), + ); + _drawTestPicture(builder); + builder.pop(); + + html.document.body!.append(builder.build().webOnlyRootElement!); + + await matchGoldenFile('compositing_image_filter_erode.png', region: region); + }); + test('pushImageFilter matrix', () async { final SurfaceSceneBuilder builder = SurfaceSceneBuilder(); builder.pushImageFilter( From 03034dffc5219c6f3ac8b9e80d5e2f8c9ac8e619 Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Wed, 30 Mar 2022 18:14:00 +0800 Subject: [PATCH 03/26] change image_filter c++ --- lib/ui/painting/image_filter.cc | 14 ++++++++++++++ lib/ui/painting/image_filter.h | 2 ++ 2 files changed, 16 insertions(+) diff --git a/lib/ui/painting/image_filter.cc b/lib/ui/painting/image_filter.cc index b8780be7727dc..6e2707988e2c8 100644 --- a/lib/ui/painting/image_filter.cc +++ b/lib/ui/painting/image_filter.cc @@ -22,6 +22,8 @@ IMPLEMENT_WRAPPERTYPEINFO(ui, ImageFilter); #define FOR_EACH_BINDING(V) \ V(ImageFilter, initBlur) \ + V(ImageFilter, initDilate) \ + V(ImageFilter, initErode) \ V(ImageFilter, initMatrix) \ V(ImageFilter, initColorFilter) \ V(ImageFilter, initComposeFilter) @@ -74,6 +76,18 @@ void ImageFilter::initBlur(double sigma_x, std::make_shared(sigma_x, sigma_y, ToDl(tile_mode)); } +void ImageFilter::initDilate(double radius_x, + double radius_y, + SkTileMode tile_mode) { + filter_ = std::make_shared(radius_x, radius_y); +} + +void ImageFilter::initErode(double radius_x, + double radius_y, + SkTileMode tile_mode) { + filter_ = std::make_shared(radius_x, radius_y); +} + void ImageFilter::initMatrix(const tonic::Float64List& matrix4, int filterQualityIndex) { auto sampling = ImageFilter::SamplingFromIndex(filterQualityIndex); diff --git a/lib/ui/painting/image_filter.h b/lib/ui/painting/image_filter.h index 72d359b8e59b0..101162e779ea6 100644 --- a/lib/ui/painting/image_filter.h +++ b/lib/ui/painting/image_filter.h @@ -30,6 +30,8 @@ class ImageFilter : public RefCountedDartWrappable { static SkFilterMode FilterModeFromIndex(int index); void initBlur(double sigma_x, double sigma_y, SkTileMode tile_mode); + void initDilate(double radius_x, double radius_y); + void initErode(double radius_x, double radius_y); void initMatrix(const tonic::Float64List& matrix4, int filter_quality_index); void initColorFilter(ColorFilter* colorFilter); void initComposeFilter(ImageFilter* outer, ImageFilter* inner); From 229eefa5fa8c405d23e26cb3c2b7026d8289dad3 Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Wed, 30 Mar 2022 18:18:30 +0800 Subject: [PATCH 04/26] change display_list --- display_list/display_list_builder.cc | 14 +++ display_list/display_list_image_filter.h | 140 +++++++++++++++++++++++ 2 files changed, 154 insertions(+) diff --git a/display_list/display_list_builder.cc b/display_list/display_list_builder.cc index 08ba1091c2eca..a0c36b0974e5b 100644 --- a/display_list/display_list_builder.cc +++ b/display_list/display_list_builder.cc @@ -193,6 +193,20 @@ void DisplayListBuilder::onSetImageFilter(const DlImageFilter* filter) { new (pod) DlBlurImageFilter(blur_filter); break; } + case DlImageFilterType::kDilate: { + const DlDilateImageFilter* dilate_filter = filter->asDilate(); + FML_DCHECK(dilate_filter); + void* pod = Push(dilate_filter->size(), 0); + new (pod) DlDilateImageFilter(dilate_filter); + break; + } + case DlImageFilterType::kErode: { + const DlErodeImageFilter* erode_filter = filter->asErode(); + FML_DCHECK(erode_filter); + void* pod = Push(erode_filter->size(), 0); + new (pod) DlErodeImageFilter(erode_filter); + break; + } case DlImageFilterType::kMatrix: { const DlMatrixImageFilter* matrix_filter = filter->asMatrix(); FML_DCHECK(matrix_filter); diff --git a/display_list/display_list_image_filter.h b/display_list/display_list_image_filter.h index f576567b83ce6..c5b377dd61643 100644 --- a/display_list/display_list_image_filter.h +++ b/display_list/display_list_image_filter.h @@ -28,6 +28,8 @@ namespace flutter { // provided as a fallback. enum class DlImageFilterType { kBlur, + kDilate, + kErode, kMatrix, kComposeFilter, kColorFilter, @@ -35,6 +37,8 @@ enum class DlImageFilterType { }; class DlBlurImageFilter; +class DlDilateImageFilter; +class DlErodeImageFilter; class DlMatrixImageFilter; class DlComposeImageFilter; class DlColorFilterImageFilter; @@ -64,6 +68,14 @@ class DlImageFilter // type of ImageFilter, otherwise return nullptr. virtual const DlBlurImageFilter* asBlur() const { return nullptr; } + // Return a DlDilateImageFilter pointer to this object iff it is a Dilate + // type of ImageFilter, otherwise return nullptr. + virtual const DlDilateImageFilter* asDilate() const { return nullptr; } + + // Return a DlErodeImageFilter pointer to this object iff it is a Erode + // type of ImageFilter, otherwise return nullptr. + virtual const DlErodeImageFilter* asErode() const { return nullptr; } + // Return a DlMatrixImageFilter pointer to this object iff it is a Matrix // type of ImageFilter, otherwise return nullptr. virtual const DlMatrixImageFilter* asMatrix() const { return nullptr; } @@ -174,6 +186,134 @@ class DlBlurImageFilter final : public DlImageFilter { DlTileMode tile_mode_; }; +class DlDilateImageFilter final : public DlImageFilter { + public: + DlDilateImageFilter(SkScalar radius_x, SkScalar radius_y) + : radius_x_(radius_x), radius_y_(radius_y) {} + explicit DlDilateImageFilter(const DlDilateImageFilter* filter) + : DlDilateImageFilter(filter->radius_x_, + filter->radius_y_, + filter->tile_mode_) {} + explicit DlDilateImageFilter(const DlDilateImageFilter& filter) + : DlDilateImageFilter(&filter) {} + + std::shared_ptr shared() const override { + return std::make_shared(this); + } + + DlImageFilterType type() const override { return DlImageFilterType::kDilate; } + size_t size() const override { return sizeof(*this); } + + const DlDilateImageFilter* asDilate() const override { return this; } + + bool modifies_transparent_black() const override { return false; } + + SkRect* map_local_bounds(const SkRect& input_bounds, + SkRect& output_bounds) const override { + output_bounds = input_bounds.makeOutset(radius_x_ * 3, radius_y_ * 3); + return &output_bounds; + } + + SkIRect* map_device_bounds(const SkIRect& input_bounds, + const SkMatrix& ctm, + SkIRect& output_bounds) const override { + SkVector device_radius = ctm.mapVector(radius_x_, radius_y_); + if (!SkScalarIsFinite(device_radius.fX)) { + device_radius.fX = 0; + } + if (!SkScalarIsFinite(device_radius.fY)) { + device_radius.fY = 0; + } + output_bounds = input_bounds.makeOutset(ceil(abs(device_radius.fX)), + ceil(abs(device_radius.fY))); + return &output_bounds; + } + + SkScalar radius_x() const { return radius_x_; } + SkScalar radius_y() const { return radius_y_; } + + sk_sp skia_object() const override { + return SkImageFilters::Dilate(radius_x_, radius_y_, nullptr); + } + + protected: + bool equals_(const DlImageFilter& other) const override { + FML_DCHECK(other.type() == DlImageFilterType::kDilate); + auto that = static_cast(&other); + return (radius_x_ == that->radius_x_ && radius_y_ == that->radius_y_ && + tile_mode_ == that->tile_mode_); + } + + private: + SkScalar radius_x_; + SkScalar radius_y_; + DlTileMode tile_mode_; +}; + +class DlErodeImageFilter final : public DlImageFilter { + public: + DlErodeImageFilter(SkScalar radius_x, SkScalar radius_y) + : radius_x_(radius_x), radius_y_(radius_y) {} + explicit DlErodeImageFilter(const DlErodeImageFilter* filter) + : DlErodeImageFilter(filter->radius_x_, + filter->radius_y_, + filter->tile_mode_) {} + explicit DlErodeImageFilter(const DlErodeImageFilter& filter) + : DlErodeImageFilter(&filter) {} + + std::shared_ptr shared() const override { + return std::make_shared(this); + } + + DlImageFilterType type() const override { return DlImageFilterType::kErode; } + size_t size() const override { return sizeof(*this); } + + const DlErodeImageFilter* asErode() const override { return this; } + + bool modifies_transparent_black() const override { return false; } + + SkRect* map_local_bounds(const SkRect& input_bounds, + SkRect& output_bounds) const override { + output_bounds = input_bounds.makeOutset(radius_x_ * 3, radius_y_ * 3); + return &output_bounds; + } + + SkIRect* map_device_bounds(const SkIRect& input_bounds, + const SkMatrix& ctm, + SkIRect& output_bounds) const override { + SkVector device_radius = ctm.mapVector(radius_x_, radius_y_); + if (!SkScalarIsFinite(device_radius.fX)) { + device_radius.fX = 0; + } + if (!SkScalarIsFinite(device_radius.fY)) { + device_radius.fY = 0; + } + output_bounds = input_bounds.makeOutset(ceil(abs(device_radius.fX)), + ceil(abs(device_radius.fY))); + return &output_bounds; + } + + SkScalar radius_x() const { return radius_x_; } + SkScalar radius_y() const { return radius_y_; } + + sk_sp skia_object() const override { + return SkImageFilters::Erode(radius_x_, radius_y_, nullptr); + } + + protected: + bool equals_(const DlImageFilter& other) const override { + FML_DCHECK(other.type() == DlImageFilterType::kErode); + auto that = static_cast(&other); + return (radius_x_ == that->radius_x_ && radius_y_ == that->radius_y_ && + tile_mode_ == that->tile_mode_); + } + + private: + SkScalar radius_x_; + SkScalar radius_y_; + DlTileMode tile_mode_; +}; + class DlMatrixImageFilter final : public DlImageFilter { public: DlMatrixImageFilter(const SkMatrix& matrix, const SkSamplingOptions& sampling) From 406db8b104207abe6b5d0cf842e4a6482c1bfb7c Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Wed, 30 Mar 2022 18:24:06 +0800 Subject: [PATCH 05/26] add tests for display list --- .../display_list_image_filter_unittests.cc | 126 ++++++++++++++++++ 1 file changed, 126 insertions(+) diff --git a/display_list/display_list_image_filter_unittests.cc b/display_list/display_list_image_filter_unittests.cc index f55c29849120d..cc1f803ac1a12 100644 --- a/display_list/display_list_image_filter_unittests.cc +++ b/display_list/display_list_image_filter_unittests.cc @@ -43,6 +43,40 @@ TEST(DisplayListImageFilter, FromSkiaBlurImageFilter) { // We cannot recapture the blur parameters from an SkBlurImageFilter ASSERT_EQ(filter->asBlur(), nullptr); + ASSERT_EQ(filter->asDilate(), nullptr); + ASSERT_EQ(filter->asErode(), nullptr); + ASSERT_EQ(filter->asMatrix(), nullptr); + ASSERT_EQ(filter->asCompose(), nullptr); + ASSERT_EQ(filter->asColorFilter(), nullptr); +} + +TEST(DisplayListImageFilter, FromSkiaDilateImageFilter) { + sk_sp sk_image_filter = + SkImageFilters::Dilate(5.0, 5.0, nullptr); + std::shared_ptr filter = DlImageFilter::From(sk_image_filter); + + ASSERT_EQ(filter->type(), DlImageFilterType::kUnknown); + + // We cannot recapture the dilate parameters from an SkDilateImageFilter + ASSERT_EQ(filter->asDilate(), nullptr); + ASSERT_EQ(filter->asDilate(), nullptr); + ASSERT_EQ(filter->asErode(), nullptr); + ASSERT_EQ(filter->asMatrix(), nullptr); + ASSERT_EQ(filter->asCompose(), nullptr); + ASSERT_EQ(filter->asColorFilter(), nullptr); +} + +TEST(DisplayListImageFilter, FromSkiaErodeImageFilter) { + sk_sp sk_image_filter = + SkImageFilters::Erode(5.0, 5.0, nullptr); + std::shared_ptr filter = DlImageFilter::From(sk_image_filter); + + ASSERT_EQ(filter->type(), DlImageFilterType::kUnknown); + + // We cannot recapture the erode parameters from an SkErodeImageFilter + ASSERT_EQ(filter->asErode(), nullptr); + ASSERT_EQ(filter->asErode(), nullptr); + ASSERT_EQ(filter->asErode(), nullptr); ASSERT_EQ(filter->asMatrix(), nullptr); ASSERT_EQ(filter->asCompose(), nullptr); ASSERT_EQ(filter->asColorFilter(), nullptr); @@ -57,6 +91,8 @@ TEST(DisplayListImageFilter, FromSkiaMatrixImageFilter) { // We cannot recapture the blur parameters from an SkMatrixImageFilter ASSERT_EQ(filter->asBlur(), nullptr); + ASSERT_EQ(filter->asDilate(), nullptr); + ASSERT_EQ(filter->asErode(), nullptr); ASSERT_EQ(filter->asMatrix(), nullptr); ASSERT_EQ(filter->asCompose(), nullptr); ASSERT_EQ(filter->asColorFilter(), nullptr); @@ -75,6 +111,8 @@ TEST(DisplayListImageFilter, FromSkiaComposeImageFilter) { // We cannot recapture the blur parameters from an SkComposeImageFilter ASSERT_EQ(filter->asBlur(), nullptr); + ASSERT_EQ(filter->asDilate(), nullptr); + ASSERT_EQ(filter->asErode(), nullptr); ASSERT_EQ(filter->asMatrix(), nullptr); ASSERT_EQ(filter->asCompose(), nullptr); ASSERT_EQ(filter->asColorFilter(), nullptr); @@ -96,6 +134,8 @@ TEST(DisplayListImageFilter, FromSkiaColorFilterImageFilter) { ASSERT_EQ(*filter->asColorFilter()->color_filter(), dl_color_filter); ASSERT_EQ(filter->asBlur(), nullptr); + ASSERT_EQ(filter->asDilate(), nullptr); + ASSERT_EQ(filter->asErode(), nullptr); ASSERT_EQ(filter->asMatrix(), nullptr); ASSERT_EQ(filter->asCompose(), nullptr); ASSERT_NE(filter->asColorFilter(), nullptr); @@ -145,6 +185,92 @@ TEST(DisplayListImageFilter, BlurNotEquals) { TestNotEquals(filter1, filter4, "Tile Mode differs"); } +TEST(DisplayListImageFilter, DilateConstructor) { + DlDilateImageFilter filter(5.0, 6.0); +} + +TEST(DisplayListImageFilter, DilateShared) { + DlDilateImageFilter filter(5.0, 6.0); + + ASSERT_NE(filter.shared().get(), &filter); + ASSERT_EQ(*filter.shared(), filter); +} + +TEST(DisplayListImageFilter, DilateAsDilate) { + DlDilateImageFilter filter(5.0, 6.0); + + ASSERT_NE(filter.asDilate(), nullptr); + ASSERT_EQ(filter.asDilate(), &filter); +} + +TEST(DisplayListImageFilter, DilateContents) { + DlDilateImageFilter filter(5.0, 6.0); + + ASSERT_EQ(filter.radius_x(), 5.0); + ASSERT_EQ(filter.radius_y(), 6.0); +} + +TEST(DisplayListImageFilter, DilateEquals) { + DlDilateImageFilter filter1(5.0, 6.0); + DlDilateImageFilter filter2(5.0, 6.0); + + TestEquals(filter1, filter2); +} + +TEST(DisplayListImageFilter, DilateNotEquals) { + DlDilateImageFilter filter1(5.0, 6.0); + DlDilateImageFilter filter2(7.0, 6.0); + DlDilateImageFilter filter3(5.0, 8.0); + DlDilateImageFilter filter4(5.0, 6.0); + + TestNotEquals(filter1, filter2, "Radius X differs"); + TestNotEquals(filter1, filter3, "Radius Y differs"); + TestNotEquals(filter1, filter4, "Tile Mode differs"); +} + +TEST(DisplayListImageFilter, ErodeConstructor) { + DlErodeImageFilter filter(5.0, 6.0); +} + +TEST(DisplayListImageFilter, ErodeShared) { + DlErodeImageFilter filter(5.0, 6.0); + + ASSERT_NE(filter.shared().get(), &filter); + ASSERT_EQ(*filter.shared(), filter); +} + +TEST(DisplayListImageFilter, ErodeAsErode) { + DlErodeImageFilter filter(5.0, 6.0); + + ASSERT_NE(filter.asErode(), nullptr); + ASSERT_EQ(filter.asErode(), &filter); +} + +TEST(DisplayListImageFilter, ErodeContents) { + DlErodeImageFilter filter(5.0, 6.0); + + ASSERT_EQ(filter.radius_x(), 5.0); + ASSERT_EQ(filter.radius_y(), 6.0); +} + +TEST(DisplayListImageFilter, ErodeEquals) { + DlErodeImageFilter filter1(5.0, 6.0); + DlErodeImageFilter filter2(5.0, 6.0); + + TestEquals(filter1, filter2); +} + +TEST(DisplayListImageFilter, ErodeNotEquals) { + DlErodeImageFilter filter1(5.0, 6.0); + DlErodeImageFilter filter2(7.0, 6.0); + DlErodeImageFilter filter3(5.0, 8.0); + DlErodeImageFilter filter4(5.0, 6.0); + + TestNotEquals(filter1, filter2, "Radius X differs"); + TestNotEquals(filter1, filter3, "Radius Y differs"); + TestNotEquals(filter1, filter4, "Tile Mode differs"); +} + TEST(DisplayListImageFilter, MatrixConstructor) { DlMatrixImageFilter filter(SkMatrix::MakeAll(2.0, 0.0, 10, // 0.5, 3.0, 15, // From e37fe4efb5fb25387671e482291f3d1873bdd64f Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Wed, 30 Mar 2022 18:29:33 +0800 Subject: [PATCH 06/26] remove wrong files --- .../compositing/compositing_golden_test.dart | 26 ------------------- 1 file changed, 26 deletions(-) diff --git a/lib/web_ui/test/html/compositing/compositing_golden_test.dart b/lib/web_ui/test/html/compositing/compositing_golden_test.dart index 016c705f6f388..b6e3601696cae 100644 --- a/lib/web_ui/test/html/compositing/compositing_golden_test.dart +++ b/lib/web_ui/test/html/compositing/compositing_golden_test.dart @@ -375,32 +375,6 @@ Future testMain() async { await matchGoldenFile('compositing_image_filter.png', region: region); }); - test('pushImageFilter dilate', () async { - final SurfaceSceneBuilder builder = SurfaceSceneBuilder(); - builder.pushImageFilter( - ui.ImageFilter.dilate(radiusX: 1, radiusY: 3), - ); - _drawTestPicture(builder); - builder.pop(); - - html.document.body!.append(builder.build().webOnlyRootElement!); - - await matchGoldenFile('compositing_image_filter_dilate.png', region: region); - }); - - test('pushImageFilter erode', () async { - final SurfaceSceneBuilder builder = SurfaceSceneBuilder(); - builder.pushImageFilter( - ui.ImageFilter.erode(radiusX: 1, radiusY: 3), - ); - _drawTestPicture(builder); - builder.pop(); - - html.document.body!.append(builder.build().webOnlyRootElement!); - - await matchGoldenFile('compositing_image_filter_erode.png', region: region); - }); - test('pushImageFilter matrix', () async { final SurfaceSceneBuilder builder = SurfaceSceneBuilder(); builder.pushImageFilter( From c560791810b35f9052755c1fb4164bc571cf2bf4 Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Wed, 30 Mar 2022 18:32:44 +0800 Subject: [PATCH 07/26] add tests in display_list_canvas_unittests --- display_list/display_list_canvas_unittests.cc | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/display_list/display_list_canvas_unittests.cc b/display_list/display_list_canvas_unittests.cc index 3b43532726d2a..994db022a98c4 100644 --- a/display_list/display_list_canvas_unittests.cc +++ b/display_list/display_list_canvas_unittests.cc @@ -1121,6 +1121,64 @@ class CanvasCompareTester { } } + { + // Being able to see a dilate requires some non-default attributes, + // like a non-trivial stroke width and a shader rather than a color + // (for drawPaint) so we create a new environment for these tests. + RenderEnvironment dilate_env = RenderEnvironment::MakeN32(); + CvSetup cv_dilate_setup = [=](SkCanvas*, SkPaint& p) { + p.setShader(testImageColorSource.skia_object()); + p.setStrokeWidth(5.0); + }; + DlRenderer dl_dilate_setup = [=](DisplayListBuilder& b) { + b.setColorSource(&testImageColorSource); + b.setStrokeWidth(5.0); + }; + dilate_env.init_ref(cv_dilate_setup, testP.cv_renderer(), dl_dilate_setup); + DlDilateImageFilter filter_5(5.0, 5.0); + BoundsTolerance dilate5Tolerance = tolerance.addBoundsPadding(4, 4); + RenderWith(testP, dilate_env, dilate5Tolerance, + CaseParameters( + "ImageFilter == Dilate 5", + [=](SkCanvas* cv, SkPaint& p) { + cv_dilate_setup(cv, p); + p.setImageFilter(filter_5.skia_object()); + }, + [=](DisplayListBuilder& b) { + dl_dilate_setup(b); + b.setImageFilter(&filter_5); + })); + } + + { + // Being able to see a erode requires some non-default attributes, + // like a non-trivial stroke width and a shader rather than a color + // (for drawPaint) so we create a new environment for these tests. + RenderEnvironment erode_env = RenderEnvironment::MakeN32(); + CvSetup cv_erode_setup = [=](SkCanvas*, SkPaint& p) { + p.setShader(testImageColorSource.skia_object()); + p.setStrokeWidth(5.0); + }; + DlRenderer dl_erode_setup = [=](DisplayListBuilder& b) { + b.setColorSource(&testImageColorSource); + b.setStrokeWidth(5.0); + }; + erode_env.init_ref(cv_erode_setup, testP.cv_renderer(), dl_erode_setup); + DlErodeImageFilter filter_5(5.0, 5.0); + BoundsTolerance erode5Tolerance = tolerance.addBoundsPadding(4, 4); + RenderWith(testP, erode_env, erode5Tolerance, + CaseParameters( + "ImageFilter == Erode 5", + [=](SkCanvas* cv, SkPaint& p) { + cv_erode_setup(cv, p); + p.setImageFilter(filter_5.skia_object()); + }, + [=](DisplayListBuilder& b) { + dl_erode_setup(b); + b.setImageFilter(&filter_5); + })); + } + { // clang-format off constexpr float rotate_color_matrix[20] = { From f3c5ef739b72af0796f485d7ad9e1723c7e171dd Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Wed, 30 Mar 2022 18:35:49 +0800 Subject: [PATCH 08/26] add display_list_unittests --- display_list/display_list_unittests.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/display_list/display_list_unittests.cc b/display_list/display_list_unittests.cc index 6ca05b4bffef1..f9738589db2cc 100644 --- a/display_list/display_list_unittests.cc +++ b/display_list/display_list_unittests.cc @@ -149,6 +149,10 @@ static const DlBlurImageFilter TestBlurImageFilter3(5.0, static const DlBlurImageFilter TestBlurImageFilter4(5.0, 5.0, DlTileMode::kDecal); +static const DlDilateImageFilter TestDilateImageFilter1(5.0, + 5.0); +static const DlErodeImageFilter TestErodeImageFilter1(5.0, + 5.0); static const DlMatrixImageFilter TestMatrixImageFilter1(SkMatrix::RotateDeg(45), NearestSampling); static const DlMatrixImageFilter TestMatrixImageFilter2(SkMatrix::RotateDeg(85), @@ -391,6 +395,9 @@ std::vector allGroups = { {0, 32, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&TestBlurImageFilter2);}}, {0, 32, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&TestBlurImageFilter3);}}, {0, 32, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&TestBlurImageFilter4);}}, + // TODO what are the correct numbers? + {0, 32, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&TestDilateImageFilter1);}}, + {0, 32, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&TestErodeImageFilter1);}}, {0, 80, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&TestMatrixImageFilter1);}}, {0, 80, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&TestMatrixImageFilter2);}}, {0, 80, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&TestMatrixImageFilter3);}}, From a0cb3cd984499ef1ca1983ad95c50bd55d5ced9f Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Wed, 30 Mar 2022 18:38:56 +0800 Subject: [PATCH 09/26] add compositing test --- testing/dart/compositing_test.dart | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/testing/dart/compositing_test.dart b/testing/dart/compositing_test.dart index 72bf643d5721a..2b2b0be433ad6 100644 --- a/testing/dart/compositing_test.dart +++ b/testing/dart/compositing_test.dart @@ -394,6 +394,18 @@ void main() { oldLayer: oldLayer as ImageFilterEngineLayer?, ); }); + testNoSharing((SceneBuilder builder, EngineLayer? oldLayer) { + return builder.pushImageFilter( + ImageFilter.dilate(radiusX: 10.0, radiusY: 10.0), + oldLayer: oldLayer as ImageFilterEngineLayer?, + ); + }); + testNoSharing((SceneBuilder builder, EngineLayer? oldLayer) { + return builder.pushImageFilter( + ImageFilter.erode(radiusX: 10.0, radiusY: 10.0), + oldLayer: oldLayer as ImageFilterEngineLayer?, + ); + }); testNoSharing((SceneBuilder builder, EngineLayer? oldLayer) { return builder.pushImageFilter( ImageFilter.matrix(Float64List.fromList([ From dc2e6509e158f698f94e68d32abd0a4dd88de2d4 Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Wed, 30 Mar 2022 18:42:19 +0800 Subject: [PATCH 10/26] add image filter test, asserting pixel colors --- testing/dart/image_filter_test.dart | 30 +++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/testing/dart/image_filter_test.dart b/testing/dart/image_filter_test.dart index 87af30ab6e6af..e3971b28c3a6c 100644 --- a/testing/dart/image_filter_test.dart +++ b/testing/dart/image_filter_test.dart @@ -74,6 +74,12 @@ void main() { ImageFilter makeBlur(double sigmaX, double sigmaY, [TileMode tileMode = TileMode.clamp]) => ImageFilter.blur(sigmaX: sigmaX, sigmaY: sigmaY, tileMode: tileMode); + ImageFilter makeDilate(double radiusX, double radiusY) => + ImageFilter.dilate(radiusX: radiusX, radiusY: radiusY); + + ImageFilter makeErode(double radiusX, double radiusY) => + ImageFilter.erode(radiusX: radiusX, radiusY: radiusY); + ImageFilter makeScale(double scX, double scY, [double trX = 0.0, double trY = 0.0, FilterQuality quality = FilterQuality.low]) { @@ -105,6 +111,12 @@ void main() { makeBlur(10.0, 10.0, TileMode.decal), makeBlur(10.0, 20.0), makeBlur(20.0, 20.0), + makeDilate(10.0, 20.0), + makeDilate(20.0, 20.0), + makeDilate(20.0, 10.0), + makeErode(10.0, 20.0), + makeErode(20.0, 20.0), + makeErode(20.0, 10.0), makeScale(10.0, 10.0), makeScale(10.0, 20.0), makeScale(20.0, 10.0), @@ -170,6 +182,24 @@ void main() { checkBytes(bytes, greenCenterBlurred, greenSideBlurred, greenCornerBlurred); }); + test('ImageFilter - dilate', () async { + final Paint paint = Paint() + ..color = green + ..imageFilter = makeDilate(1.0, 1.0); + + final Uint32List bytes = await getBytesForPaint(paint); + checkBytes(bytes, green.value, green.value, green.value); + }); + + test('ImageFilter - erode', () async { + final Paint paint = Paint() + ..color = green + ..imageFilter = makeErode(1.0, 1.0); + + final Uint32List bytes = await getBytesForPaint(paint); + checkBytes(bytes, 0xFF000000, 0xFF000000, 0xFF000000); + }); + test('ImageFilter - matrix', () async { final Paint paint = Paint() ..color = green From d009caeffa1909df080c5406f5316b70298dec32 Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Wed, 30 Mar 2022 19:35:24 +0800 Subject: [PATCH 11/26] remove `tile_mode` --- display_list/display_list_image_filter.h | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/display_list/display_list_image_filter.h b/display_list/display_list_image_filter.h index c5b377dd61643..653810dfb75e2 100644 --- a/display_list/display_list_image_filter.h +++ b/display_list/display_list_image_filter.h @@ -191,9 +191,7 @@ class DlDilateImageFilter final : public DlImageFilter { DlDilateImageFilter(SkScalar radius_x, SkScalar radius_y) : radius_x_(radius_x), radius_y_(radius_y) {} explicit DlDilateImageFilter(const DlDilateImageFilter* filter) - : DlDilateImageFilter(filter->radius_x_, - filter->radius_y_, - filter->tile_mode_) {} + : DlDilateImageFilter(filter->radius_x_, filter->radius_y_) {} explicit DlDilateImageFilter(const DlDilateImageFilter& filter) : DlDilateImageFilter(&filter) {} @@ -240,14 +238,12 @@ class DlDilateImageFilter final : public DlImageFilter { bool equals_(const DlImageFilter& other) const override { FML_DCHECK(other.type() == DlImageFilterType::kDilate); auto that = static_cast(&other); - return (radius_x_ == that->radius_x_ && radius_y_ == that->radius_y_ && - tile_mode_ == that->tile_mode_); + return (radius_x_ == that->radius_x_ && radius_y_ == that->radius_y_); } private: SkScalar radius_x_; SkScalar radius_y_; - DlTileMode tile_mode_; }; class DlErodeImageFilter final : public DlImageFilter { @@ -255,9 +251,7 @@ class DlErodeImageFilter final : public DlImageFilter { DlErodeImageFilter(SkScalar radius_x, SkScalar radius_y) : radius_x_(radius_x), radius_y_(radius_y) {} explicit DlErodeImageFilter(const DlErodeImageFilter* filter) - : DlErodeImageFilter(filter->radius_x_, - filter->radius_y_, - filter->tile_mode_) {} + : DlErodeImageFilter(filter->radius_x_, filter->radius_y_) {} explicit DlErodeImageFilter(const DlErodeImageFilter& filter) : DlErodeImageFilter(&filter) {} @@ -304,14 +298,12 @@ class DlErodeImageFilter final : public DlImageFilter { bool equals_(const DlImageFilter& other) const override { FML_DCHECK(other.type() == DlImageFilterType::kErode); auto that = static_cast(&other); - return (radius_x_ == that->radius_x_ && radius_y_ == that->radius_y_ && - tile_mode_ == that->tile_mode_); + return (radius_x_ == that->radius_x_ && radius_y_ == that->radius_y_); } private: SkScalar radius_x_; SkScalar radius_y_; - DlTileMode tile_mode_; }; class DlMatrixImageFilter final : public DlImageFilter { From 087142ac4cefc863f5bd10fb28636b37af5966c5 Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Wed, 30 Mar 2022 19:42:42 +0800 Subject: [PATCH 12/26] further fix compile errors --- lib/ui/painting/image_filter.cc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/ui/painting/image_filter.cc b/lib/ui/painting/image_filter.cc index 6e2707988e2c8..2bcce098258b3 100644 --- a/lib/ui/painting/image_filter.cc +++ b/lib/ui/painting/image_filter.cc @@ -77,14 +77,12 @@ void ImageFilter::initBlur(double sigma_x, } void ImageFilter::initDilate(double radius_x, - double radius_y, - SkTileMode tile_mode) { + double radius_y) { filter_ = std::make_shared(radius_x, radius_y); } void ImageFilter::initErode(double radius_x, - double radius_y, - SkTileMode tile_mode) { + double radius_y) { filter_ = std::make_shared(radius_x, radius_y); } From bf2c86dee5de825be56c02a7056911b161585e4b Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Wed, 30 Mar 2022 19:53:04 +0800 Subject: [PATCH 13/26] fix formatting --- display_list/display_list_canvas_unittests.cc | 3 ++- display_list/display_list_unittests.cc | 6 ++---- lib/ui/painting.dart | 8 ++++---- lib/ui/painting/image_filter.cc | 6 ++---- 4 files changed, 10 insertions(+), 13 deletions(-) diff --git a/display_list/display_list_canvas_unittests.cc b/display_list/display_list_canvas_unittests.cc index 994db022a98c4..5ccc89b587349 100644 --- a/display_list/display_list_canvas_unittests.cc +++ b/display_list/display_list_canvas_unittests.cc @@ -1134,7 +1134,8 @@ class CanvasCompareTester { b.setColorSource(&testImageColorSource); b.setStrokeWidth(5.0); }; - dilate_env.init_ref(cv_dilate_setup, testP.cv_renderer(), dl_dilate_setup); + dilate_env.init_ref(cv_dilate_setup, testP.cv_renderer(), + dl_dilate_setup); DlDilateImageFilter filter_5(5.0, 5.0); BoundsTolerance dilate5Tolerance = tolerance.addBoundsPadding(4, 4); RenderWith(testP, dilate_env, dilate5Tolerance, diff --git a/display_list/display_list_unittests.cc b/display_list/display_list_unittests.cc index f9738589db2cc..14bb01be9dc35 100644 --- a/display_list/display_list_unittests.cc +++ b/display_list/display_list_unittests.cc @@ -149,10 +149,8 @@ static const DlBlurImageFilter TestBlurImageFilter3(5.0, static const DlBlurImageFilter TestBlurImageFilter4(5.0, 5.0, DlTileMode::kDecal); -static const DlDilateImageFilter TestDilateImageFilter1(5.0, - 5.0); -static const DlErodeImageFilter TestErodeImageFilter1(5.0, - 5.0); +static const DlDilateImageFilter TestDilateImageFilter1(5.0, 5.0); +static const DlErodeImageFilter TestErodeImageFilter1(5.0, 5.0); static const DlMatrixImageFilter TestMatrixImageFilter1(SkMatrix::RotateDeg(45), NearestSampling); static const DlMatrixImageFilter TestMatrixImageFilter2(SkMatrix::RotateDeg(85), diff --git a/lib/ui/painting.dart b/lib/ui/painting.dart index debb6b3b6527d..d6fb7c5f5a952 100644 --- a/lib/ui/painting.dart +++ b/lib/ui/painting.dart @@ -3224,7 +3224,7 @@ abstract class ImageFilter { return _GaussianBlurImageFilter(sigmaX: sigmaX, sigmaY: sigmaY, tileMode: tileMode); } - /// Creates an image filter that dilates each input pixel's channel values + /// Creates an image filter that dilates each input pixel's channel values /// to the max value within the given radii along the x and y axes. factory ImageFilter.dilate({ double radiusX = 0.0, double radiusY = 0.0 }) { assert(radiusX != null); @@ -3232,7 +3232,7 @@ abstract class ImageFilter { return _DilateImageFilter(radiusX: radiusX, radiusY: radiusY); } - /// Create a filter that erodes each input pixel's channel values + /// Create a filter that erodes each input pixel's channel values /// to the minimum channel value within the given radii along the x and y axes. factory ImageFilter.erode({ double radiusX = 0.0, double radiusY = 0.0 }) { assert(radiusX != null); @@ -3450,7 +3450,7 @@ class _ImageFilter extends NativeFieldWrapperClass1 { } void _initBlur(double sigmaX, double sigmaY, int tileMode) native 'ImageFilter_initBlur'; - /// Creates an image filter that dilates each input pixel's channel values + /// Creates an image filter that dilates each input pixel's channel values /// to the max value within the given radii along the x and y axes. _ImageFilter.dilate(_DilateImageFilter filter) : assert(filter != null), @@ -3460,7 +3460,7 @@ class _ImageFilter extends NativeFieldWrapperClass1 { } void _initDilate(double radiusX, double radiusY) native 'ImageFilter_initDilate'; - /// Create a filter that erodes each input pixel's channel values + /// Create a filter that erodes each input pixel's channel values /// to the minimum channel value within the given radii along the x and y axes. _ImageFilter.erode(_ErodeImageFilter filter) : assert(filter != null), diff --git a/lib/ui/painting/image_filter.cc b/lib/ui/painting/image_filter.cc index 2bcce098258b3..47132fc1b538f 100644 --- a/lib/ui/painting/image_filter.cc +++ b/lib/ui/painting/image_filter.cc @@ -76,13 +76,11 @@ void ImageFilter::initBlur(double sigma_x, std::make_shared(sigma_x, sigma_y, ToDl(tile_mode)); } -void ImageFilter::initDilate(double radius_x, - double radius_y) { +void ImageFilter::initDilate(double radius_x, double radius_y) { filter_ = std::make_shared(radius_x, radius_y); } -void ImageFilter::initErode(double radius_x, - double radius_y) { +void ImageFilter::initErode(double radius_x, double radius_y) { filter_ = std::make_shared(radius_x, radius_y); } From 6f39f28cf9a5ddbe0f76b3e4a8c46607eb868e31 Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Wed, 30 Mar 2022 20:01:22 +0800 Subject: [PATCH 14/26] fix wrong padding --- display_list/display_list_canvas_unittests.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/display_list/display_list_canvas_unittests.cc b/display_list/display_list_canvas_unittests.cc index 5ccc89b587349..a9bdedc9dff08 100644 --- a/display_list/display_list_canvas_unittests.cc +++ b/display_list/display_list_canvas_unittests.cc @@ -1137,7 +1137,7 @@ class CanvasCompareTester { dilate_env.init_ref(cv_dilate_setup, testP.cv_renderer(), dl_dilate_setup); DlDilateImageFilter filter_5(5.0, 5.0); - BoundsTolerance dilate5Tolerance = tolerance.addBoundsPadding(4, 4); + BoundsTolerance dilate5Tolerance = tolerance.addBoundsPadding(21, 21); RenderWith(testP, dilate_env, dilate5Tolerance, CaseParameters( "ImageFilter == Dilate 5", @@ -1166,7 +1166,7 @@ class CanvasCompareTester { }; erode_env.init_ref(cv_erode_setup, testP.cv_renderer(), dl_erode_setup); DlErodeImageFilter filter_5(5.0, 5.0); - BoundsTolerance erode5Tolerance = tolerance.addBoundsPadding(4, 4); + BoundsTolerance erode5Tolerance = tolerance.addBoundsPadding(21, 21); RenderWith(testP, erode_env, erode5Tolerance, CaseParameters( "ImageFilter == Erode 5", From 1cf28e2fcebef851415d4902542371b496d97adb Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Wed, 30 Mar 2022 20:10:59 +0800 Subject: [PATCH 15/26] fix tests --- display_list/display_list_unittests.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/display_list/display_list_unittests.cc b/display_list/display_list_unittests.cc index 14bb01be9dc35..8c34ed47ec7b3 100644 --- a/display_list/display_list_unittests.cc +++ b/display_list/display_list_unittests.cc @@ -393,9 +393,8 @@ std::vector allGroups = { {0, 32, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&TestBlurImageFilter2);}}, {0, 32, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&TestBlurImageFilter3);}}, {0, 32, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&TestBlurImageFilter4);}}, - // TODO what are the correct numbers? - {0, 32, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&TestDilateImageFilter1);}}, - {0, 32, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&TestErodeImageFilter1);}}, + {0, 24, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&TestDilateImageFilter1);}}, + {0, 24, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&TestErodeImageFilter1);}}, {0, 80, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&TestMatrixImageFilter1);}}, {0, 80, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&TestMatrixImageFilter2);}}, {0, 80, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&TestMatrixImageFilter3);}}, From e5d0cdf8d36fa66f2d324575759e6151d49bfa84 Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Wed, 30 Mar 2022 20:15:47 +0800 Subject: [PATCH 16/26] fix eroding too much --- display_list/display_list_canvas_unittests.cc | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/display_list/display_list_canvas_unittests.cc b/display_list/display_list_canvas_unittests.cc index a9bdedc9dff08..7e90b0109ca32 100644 --- a/display_list/display_list_canvas_unittests.cc +++ b/display_list/display_list_canvas_unittests.cc @@ -1158,25 +1158,27 @@ class CanvasCompareTester { RenderEnvironment erode_env = RenderEnvironment::MakeN32(); CvSetup cv_erode_setup = [=](SkCanvas*, SkPaint& p) { p.setShader(testImageColorSource.skia_object()); - p.setStrokeWidth(5.0); + p.setStrokeWidth(6.0); }; DlRenderer dl_erode_setup = [=](DisplayListBuilder& b) { b.setColorSource(&testImageColorSource); - b.setStrokeWidth(5.0); + b.setStrokeWidth(6.0); }; erode_env.init_ref(cv_erode_setup, testP.cv_renderer(), dl_erode_setup); - DlErodeImageFilter filter_5(5.0, 5.0); + // do not erode too much, because some tests assert there are enough + // pixels that are changed. + DlErodeImageFilter filter_1(1.0, 1.0); BoundsTolerance erode5Tolerance = tolerance.addBoundsPadding(21, 21); RenderWith(testP, erode_env, erode5Tolerance, CaseParameters( - "ImageFilter == Erode 5", + "ImageFilter == Erode 3", [=](SkCanvas* cv, SkPaint& p) { cv_erode_setup(cv, p); - p.setImageFilter(filter_5.skia_object()); + p.setImageFilter(filter_1.skia_object()); }, [=](DisplayListBuilder& b) { dl_erode_setup(b); - b.setImageFilter(&filter_5); + b.setImageFilter(&filter_1); })); } From ad2cd88094609f65bcfb9d17d847c6a304bc6963 Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Wed, 30 Mar 2022 20:17:40 +0800 Subject: [PATCH 17/26] remove nonsense test --- display_list/display_list_image_filter_unittests.cc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/display_list/display_list_image_filter_unittests.cc b/display_list/display_list_image_filter_unittests.cc index cc1f803ac1a12..5eeef4109afea 100644 --- a/display_list/display_list_image_filter_unittests.cc +++ b/display_list/display_list_image_filter_unittests.cc @@ -221,11 +221,9 @@ TEST(DisplayListImageFilter, DilateNotEquals) { DlDilateImageFilter filter1(5.0, 6.0); DlDilateImageFilter filter2(7.0, 6.0); DlDilateImageFilter filter3(5.0, 8.0); - DlDilateImageFilter filter4(5.0, 6.0); TestNotEquals(filter1, filter2, "Radius X differs"); TestNotEquals(filter1, filter3, "Radius Y differs"); - TestNotEquals(filter1, filter4, "Tile Mode differs"); } TEST(DisplayListImageFilter, ErodeConstructor) { @@ -264,11 +262,9 @@ TEST(DisplayListImageFilter, ErodeNotEquals) { DlErodeImageFilter filter1(5.0, 6.0); DlErodeImageFilter filter2(7.0, 6.0); DlErodeImageFilter filter3(5.0, 8.0); - DlErodeImageFilter filter4(5.0, 6.0); TestNotEquals(filter1, filter2, "Radius X differs"); TestNotEquals(filter1, filter3, "Radius Y differs"); - TestNotEquals(filter1, filter4, "Tile Mode differs"); } TEST(DisplayListImageFilter, MatrixConstructor) { From 26712747c1fe1355f4b7972e435b1fda48d73bd4 Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Wed, 30 Mar 2022 20:35:37 +0800 Subject: [PATCH 18/26] fix wrong assertions --- testing/dart/image_filter_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/dart/image_filter_test.dart b/testing/dart/image_filter_test.dart index e3971b28c3a6c..98435912f8f37 100644 --- a/testing/dart/image_filter_test.dart +++ b/testing/dart/image_filter_test.dart @@ -197,7 +197,7 @@ void main() { ..imageFilter = makeErode(1.0, 1.0); final Uint32List bytes = await getBytesForPaint(paint); - checkBytes(bytes, 0xFF000000, 0xFF000000, 0xFF000000); + checkBytes(bytes, 0, 0, 0); }); test('ImageFilter - matrix', () async { From 094c04ddffaf040de4795b50843dac504e32863b Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Wed, 30 Mar 2022 21:49:42 +0800 Subject: [PATCH 19/26] add web code --- lib/web_ui/lib/painting.dart | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/web_ui/lib/painting.dart b/lib/web_ui/lib/painting.dart index 98d53dda22455..c2bb63929fea0 100644 --- a/lib/web_ui/lib/painting.dart +++ b/lib/web_ui/lib/painting.dart @@ -405,6 +405,20 @@ class ImageFilter { return engine.EngineImageFilter.blur(sigmaX: sigmaX, sigmaY: sigmaY, tileMode: tileMode); } + // ignore: avoid_unused_constructor_parameters + factory ImageFilter.dilate({ double radiusX = 0.0, double radiusY = 0.0 }) { + // TODO(fzyzcjy): implement dilate. + throw UnimplementedError( + 'ImageFilter.dilate not implemented for web platform.'); + } + + // ignore: avoid_unused_constructor_parameters + factory ImageFilter.erode({ double radiusX = 0.0, double radiusY = 0.0 }) { + // TODO(fzyzcjy): implement erode. + throw UnimplementedError( + 'ImageFilter.erode not implemented for web platform.'); + } + factory ImageFilter.matrix(Float64List matrix4, {FilterQuality filterQuality = FilterQuality.low}) { if (matrix4.length != 16) throw ArgumentError('"matrix4" must have 16 entries.'); From 4b7dd3b92817c17f594442c8041cfbd2a3948036 Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Thu, 31 Mar 2022 08:23:07 +0800 Subject: [PATCH 20/26] fix comments --- display_list/display_list_image_filter.h | 2 +- lib/ui/painting.dart | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/display_list/display_list_image_filter.h b/display_list/display_list_image_filter.h index 653810dfb75e2..27417170872ee 100644 --- a/display_list/display_list_image_filter.h +++ b/display_list/display_list_image_filter.h @@ -72,7 +72,7 @@ class DlImageFilter // type of ImageFilter, otherwise return nullptr. virtual const DlDilateImageFilter* asDilate() const { return nullptr; } - // Return a DlErodeImageFilter pointer to this object iff it is a Erode + // Return a DlErodeImageFilter pointer to this object iff it is an Erode // type of ImageFilter, otherwise return nullptr. virtual const DlErodeImageFilter* asErode() const { return nullptr; } diff --git a/lib/ui/painting.dart b/lib/ui/painting.dart index d6fb7c5f5a952..67545e378885e 100644 --- a/lib/ui/painting.dart +++ b/lib/ui/painting.dart @@ -3349,7 +3349,6 @@ class _DilateImageFilter implements ImageFilter { final double radiusX; final double radiusY; - // MakeBlurFilter late final _ImageFilter nativeFilter = _ImageFilter.dilate(this); @override _ImageFilter _toNativeImageFilter() => nativeFilter; @@ -3379,7 +3378,6 @@ class _ErodeImageFilter implements ImageFilter { final double radiusX; final double radiusY; - // MakeBlurFilter late final _ImageFilter nativeFilter = _ImageFilter.erode(this); @override _ImageFilter _toNativeImageFilter() => nativeFilter; From 30afc078a6e42cb84b39b590f505647b16e5088e Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Thu, 31 Mar 2022 08:25:30 +0800 Subject: [PATCH 21/26] fix wrong map_local_bounds --- display_list/display_list_image_filter.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/display_list/display_list_image_filter.h b/display_list/display_list_image_filter.h index 27417170872ee..43b4275ccca4d 100644 --- a/display_list/display_list_image_filter.h +++ b/display_list/display_list_image_filter.h @@ -208,7 +208,7 @@ class DlDilateImageFilter final : public DlImageFilter { SkRect* map_local_bounds(const SkRect& input_bounds, SkRect& output_bounds) const override { - output_bounds = input_bounds.makeOutset(radius_x_ * 3, radius_y_ * 3); + output_bounds = input_bounds.makeOutset(radius_x_, radius_y_); return &output_bounds; } @@ -268,7 +268,7 @@ class DlErodeImageFilter final : public DlImageFilter { SkRect* map_local_bounds(const SkRect& input_bounds, SkRect& output_bounds) const override { - output_bounds = input_bounds.makeOutset(radius_x_ * 3, radius_y_ * 3); + output_bounds = input_bounds.makeOutset(radius_x_, radius_y_); return &output_bounds; } From 2e69c605f9c1c28bc4674157671c1782e2e5e9e9 Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Thu, 31 Mar 2022 08:27:21 +0800 Subject: [PATCH 22/26] fix DlBlurFilter which needs `*3` --- display_list/display_list_image_filter.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/display_list/display_list_image_filter.h b/display_list/display_list_image_filter.h index 43b4275ccca4d..25d2e93bb207c 100644 --- a/display_list/display_list_image_filter.h +++ b/display_list/display_list_image_filter.h @@ -152,7 +152,7 @@ class DlBlurImageFilter final : public DlImageFilter { SkIRect* map_device_bounds(const SkIRect& input_bounds, const SkMatrix& ctm, SkIRect& output_bounds) const override { - SkVector device_sigma = ctm.mapVector(sigma_x_, sigma_y_); + SkVector device_sigma = ctm.mapVector(sigma_x_ * 3, sigma_y_ * 3); if (!SkScalarIsFinite(device_sigma.fX)) { device_sigma.fX = 0; } From c558ea26275e92547cf2a4bbe207f2de54b10548 Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Thu, 31 Mar 2022 08:38:02 +0800 Subject: [PATCH 23/26] add github link --- lib/web_ui/lib/painting.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/web_ui/lib/painting.dart b/lib/web_ui/lib/painting.dart index c2bb63929fea0..09c249115e193 100644 --- a/lib/web_ui/lib/painting.dart +++ b/lib/web_ui/lib/painting.dart @@ -407,14 +407,14 @@ class ImageFilter { // ignore: avoid_unused_constructor_parameters factory ImageFilter.dilate({ double radiusX = 0.0, double radiusY = 0.0 }) { - // TODO(fzyzcjy): implement dilate. + // TODO(fzyzcjy): implement dilate. https://github.com/flutter/flutter/issues/101085 throw UnimplementedError( 'ImageFilter.dilate not implemented for web platform.'); } // ignore: avoid_unused_constructor_parameters factory ImageFilter.erode({ double radiusX = 0.0, double radiusY = 0.0 }) { - // TODO(fzyzcjy): implement erode. + // TODO(fzyzcjy): implement erode. https://github.com/flutter/flutter/issues/101085 throw UnimplementedError( 'ImageFilter.erode not implemented for web platform.'); } From ba08df3d83b1b81349e1de4e6c3f88e893897de6 Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Thu, 31 Mar 2022 08:38:52 +0800 Subject: [PATCH 24/26] fix typo --- display_list/display_list_canvas_unittests.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/display_list/display_list_canvas_unittests.cc b/display_list/display_list_canvas_unittests.cc index 7e90b0109ca32..9fb5c6e3e72d6 100644 --- a/display_list/display_list_canvas_unittests.cc +++ b/display_list/display_list_canvas_unittests.cc @@ -1152,7 +1152,7 @@ class CanvasCompareTester { } { - // Being able to see a erode requires some non-default attributes, + // Being able to see an erode requires some non-default attributes, // like a non-trivial stroke width and a shader rather than a color // (for drawPaint) so we create a new environment for these tests. RenderEnvironment erode_env = RenderEnvironment::MakeN32(); From 83c0be1cfb08ac3c575923732d413bf85fdaf4d2 Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Thu, 31 Mar 2022 08:41:09 +0800 Subject: [PATCH 25/26] add cases that differ by one param --- display_list/display_list_unittests.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/display_list/display_list_unittests.cc b/display_list/display_list_unittests.cc index 8c34ed47ec7b3..302751b2696bf 100644 --- a/display_list/display_list_unittests.cc +++ b/display_list/display_list_unittests.cc @@ -150,7 +150,11 @@ static const DlBlurImageFilter TestBlurImageFilter4(5.0, 5.0, DlTileMode::kDecal); static const DlDilateImageFilter TestDilateImageFilter1(5.0, 5.0); +static const DlDilateImageFilter TestDilateImageFilter2(6.0, 5.0); +static const DlDilateImageFilter TestDilateImageFilter3(5.0, 6.0); static const DlErodeImageFilter TestErodeImageFilter1(5.0, 5.0); +static const DlErodeImageFilter TestErodeImageFilter2(6.0, 5.0); +static const DlErodeImageFilter TestErodeImageFilter3(5.0, 6.0); static const DlMatrixImageFilter TestMatrixImageFilter1(SkMatrix::RotateDeg(45), NearestSampling); static const DlMatrixImageFilter TestMatrixImageFilter2(SkMatrix::RotateDeg(85), @@ -394,7 +398,11 @@ std::vector allGroups = { {0, 32, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&TestBlurImageFilter3);}}, {0, 32, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&TestBlurImageFilter4);}}, {0, 24, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&TestDilateImageFilter1);}}, + {0, 24, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&TestDilateImageFilter2);}}, + {0, 24, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&TestDilateImageFilter3);}}, {0, 24, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&TestErodeImageFilter1);}}, + {0, 24, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&TestErodeImageFilter2);}}, + {0, 24, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&TestErodeImageFilter3);}}, {0, 80, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&TestMatrixImageFilter1);}}, {0, 80, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&TestMatrixImageFilter2);}}, {0, 80, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&TestMatrixImageFilter3);}}, From 3de46a9bb6a9e3c2ddaba950797142d2655b337b Mon Sep 17 00:00:00 2001 From: fzyzcjy Date: Sat, 2 Apr 2022 08:39:02 +0800 Subject: [PATCH 26/26] fix more errors --- display_list/display_list_canvas_unittests.cc | 8 +++----- display_list/display_list_image_filter_unittests.cc | 6 +++--- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/display_list/display_list_canvas_unittests.cc b/display_list/display_list_canvas_unittests.cc index f94e9e7dd3f1c..a88d445b52e5e 100644 --- a/display_list/display_list_canvas_unittests.cc +++ b/display_list/display_list_canvas_unittests.cc @@ -1137,8 +1137,7 @@ class CanvasCompareTester { dilate_env.init_ref(cv_dilate_setup, testP.cv_renderer(), dl_dilate_setup); DlDilateImageFilter filter_5(5.0, 5.0); - BoundsTolerance dilate5Tolerance = tolerance.addBoundsPadding(21, 21); - RenderWith(testP, dilate_env, dilate5Tolerance, + RenderWith(testP, dilate_env, tolerance, CaseParameters( "ImageFilter == Dilate 5", [=](SkCanvas* cv, SkPaint& p) { @@ -1168,10 +1167,9 @@ class CanvasCompareTester { // do not erode too much, because some tests assert there are enough // pixels that are changed. DlErodeImageFilter filter_1(1.0, 1.0); - BoundsTolerance erode5Tolerance = tolerance.addBoundsPadding(21, 21); - RenderWith(testP, erode_env, erode5Tolerance, + RenderWith(testP, erode_env, tolerance, CaseParameters( - "ImageFilter == Erode 3", + "ImageFilter == Erode 1", [=](SkCanvas* cv, SkPaint& p) { cv_erode_setup(cv, p); p.setImageFilter(filter_1.skia_object()); diff --git a/display_list/display_list_image_filter_unittests.cc b/display_list/display_list_image_filter_unittests.cc index 5eeef4109afea..7e33bfb782488 100644 --- a/display_list/display_list_image_filter_unittests.cc +++ b/display_list/display_list_image_filter_unittests.cc @@ -58,7 +58,7 @@ TEST(DisplayListImageFilter, FromSkiaDilateImageFilter) { ASSERT_EQ(filter->type(), DlImageFilterType::kUnknown); // We cannot recapture the dilate parameters from an SkDilateImageFilter - ASSERT_EQ(filter->asDilate(), nullptr); + ASSERT_EQ(filter->asBlur(), nullptr); ASSERT_EQ(filter->asDilate(), nullptr); ASSERT_EQ(filter->asErode(), nullptr); ASSERT_EQ(filter->asMatrix(), nullptr); @@ -74,8 +74,8 @@ TEST(DisplayListImageFilter, FromSkiaErodeImageFilter) { ASSERT_EQ(filter->type(), DlImageFilterType::kUnknown); // We cannot recapture the erode parameters from an SkErodeImageFilter - ASSERT_EQ(filter->asErode(), nullptr); - ASSERT_EQ(filter->asErode(), nullptr); + ASSERT_EQ(filter->asBlur(), nullptr); + ASSERT_EQ(filter->asDilate(), nullptr); ASSERT_EQ(filter->asErode(), nullptr); ASSERT_EQ(filter->asMatrix(), nullptr); ASSERT_EQ(filter->asCompose(), nullptr);