From d90166854b15e422d344015080938f3eaf8c2834 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 12 Aug 2024 16:11:44 -0700 Subject: [PATCH 01/15] [Impeller] migrate blur tests to display list. --- display_list/dl_color.h | 3 + impeller/aiks/aiks_blur_unittests.cc | 389 ---------------- impeller/display_list/BUILD.gn | 1 + .../display_list/aiks_dl_blur_unittests.cc | 425 ++++++++++++++++++ 4 files changed, 429 insertions(+), 389 deletions(-) create mode 100644 impeller/display_list/aiks_dl_blur_unittests.cc diff --git a/display_list/dl_color.h b/display_list/dl_color.h index c7fd49b0857ac..5c9434366c063 100644 --- a/display_list/dl_color.h +++ b/display_list/dl_color.h @@ -58,6 +58,9 @@ struct DlColor { static constexpr DlColor kCornflowerBlue() {return DlColor(0xFF6495ED);}; static constexpr DlColor kCrimson() {return DlColor(0xFFFF5733);}; static constexpr DlColor kAqua() {return DlColor(0xFF00FFFF);}; + static constexpr DlColor kOrange() {return DlColor(0xFFFFA500);}; + static constexpr DlColor kPurple() {return DlColor(0xFF800080);}; + static constexpr DlColor kLimeGreen() {return DlColor(0xFF32CD32);}; // clang-format on constexpr bool isOpaque() const { return getAlpha() == 0xFF; } diff --git a/impeller/aiks/aiks_blur_unittests.cc b/impeller/aiks/aiks_blur_unittests.cc index 95d7b1d10f568..ac6b669be2db2 100644 --- a/impeller/aiks/aiks_blur_unittests.cc +++ b/impeller/aiks/aiks_blur_unittests.cc @@ -5,7 +5,6 @@ #include "flutter/impeller/aiks/aiks_unittests.h" #include "impeller/aiks/canvas.h" -#include "impeller/entity/contents/filters/gaussian_blur_filter_contents.h" #include "impeller/entity/render_target_cache.h" #include "impeller/geometry/path_builder.h" #include "impeller/playground/widgets.h" @@ -20,210 +19,6 @@ namespace impeller { namespace testing { -TEST_P(AiksTest, CanRenderMaskBlurHugeSigma) { - Canvas canvas; - canvas.DrawCircle({400, 400}, 300, - {.color = Color::Green(), - .mask_blur_descriptor = Paint::MaskBlurDescriptor{ - .style = FilterContents::BlurStyle::kNormal, - .sigma = Sigma(99999), - }}); - canvas.Restore(); - - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -TEST_P(AiksTest, CanRenderForegroundBlendWithMaskBlur) { - // This case triggers the ForegroundPorterDuffBlend path. The color filter - // should apply to the color only, and respect the alpha mask. - Canvas canvas; - canvas.ClipRect(Rect::MakeXYWH(100, 150, 400, 400)); - canvas.DrawCircle({400, 400}, 200, - { - .color = Color::White(), - .color_filter = ColorFilter::MakeBlend( - BlendMode::kSource, Color::Green()), - .mask_blur_descriptor = - Paint::MaskBlurDescriptor{ - .style = FilterContents::BlurStyle::kNormal, - .sigma = Radius(20), - }, - }); - canvas.Restore(); - - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -TEST_P(AiksTest, CanRenderForegroundAdvancedBlendWithMaskBlur) { - // This case triggers the ForegroundAdvancedBlend path. The color filter - // should apply to the color only, and respect the alpha mask. - Canvas canvas; - canvas.ClipRect(Rect::MakeXYWH(100, 150, 400, 400)); - canvas.DrawCircle({400, 400}, 200, - { - .color = Color::Grey(), - .color_filter = ColorFilter::MakeBlend( - BlendMode::kColor, Color::Green()), - .mask_blur_descriptor = - Paint::MaskBlurDescriptor{ - .style = FilterContents::BlurStyle::kNormal, - .sigma = Radius(20), - }, - }); - canvas.Restore(); - - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -TEST_P(AiksTest, CanRenderBackdropBlurInteractive) { - auto callback = [&](AiksContext& renderer) -> std::optional { - static PlaygroundPoint point_a(Point(50, 50), 30, Color::White()); - static PlaygroundPoint point_b(Point(300, 200), 30, Color::White()); - auto [a, b] = DrawPlaygroundLine(point_a, point_b); - - Canvas canvas; - canvas.DrawCircle({100, 100}, 50, {.color = Color::CornflowerBlue()}); - canvas.DrawCircle({300, 200}, 100, {.color = Color::GreenYellow()}); - canvas.DrawCircle({140, 170}, 75, {.color = Color::DarkMagenta()}); - canvas.DrawCircle({180, 120}, 100, {.color = Color::OrangeRed()}); - canvas.ClipRRect(Rect::MakeLTRB(a.x, a.y, b.x, b.y), {20, 20}); - canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt, - ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0), - FilterContents::BlurStyle::kNormal, - Entity::TileMode::kClamp)); - canvas.Restore(); - - return canvas.EndRecordingAsPicture(); - }; - - ASSERT_TRUE(OpenPlaygroundHere(callback)); -} - -TEST_P(AiksTest, CanRenderBackdropBlur) { - Canvas canvas; - canvas.DrawCircle({100, 100}, 50, {.color = Color::CornflowerBlue()}); - canvas.DrawCircle({300, 200}, 100, {.color = Color::GreenYellow()}); - canvas.DrawCircle({140, 170}, 75, {.color = Color::DarkMagenta()}); - canvas.DrawCircle({180, 120}, 100, {.color = Color::OrangeRed()}); - canvas.ClipRRect(Rect::MakeLTRB(75, 50, 375, 275), {20, 20}); - canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt, - ImageFilter::MakeBlur(Sigma(30.0), Sigma(30.0), - FilterContents::BlurStyle::kNormal, - Entity::TileMode::kClamp)); - canvas.Restore(); - - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -TEST_P(AiksTest, CanRenderBackdropBlurHugeSigma) { - Canvas canvas; - canvas.DrawCircle({400, 400}, 300, {.color = Color::Green()}); - canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt, - ImageFilter::MakeBlur(Sigma(999999), Sigma(999999), - FilterContents::BlurStyle::kNormal, - Entity::TileMode::kClamp)); - canvas.Restore(); - - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -TEST_P(AiksTest, CanRenderClippedBlur) { - Canvas canvas; - canvas.ClipRect(Rect::MakeXYWH(100, 150, 400, 400)); - canvas.DrawCircle( - {400, 400}, 200, - { - .color = Color::Green(), - .image_filter = ImageFilter::MakeBlur( - Sigma(20.0), Sigma(20.0), FilterContents::BlurStyle::kNormal, - Entity::TileMode::kDecal), - }); - canvas.Restore(); - - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -TEST_P(AiksTest, ClippedBlurFilterRendersCorrectlyInteractive) { - auto callback = [&](AiksContext& renderer) -> std::optional { - static PlaygroundPoint playground_point(Point(400, 400), 20, - Color::Green()); - auto point = DrawPlaygroundPoint(playground_point); - - Canvas canvas; - canvas.Translate(point - Point(400, 400)); - Paint paint; - paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{ - .style = FilterContents::BlurStyle::kNormal, - .sigma = Radius{120 * 3}, - }; - paint.color = Color::Red(); - PathBuilder builder{}; - builder.AddRect(Rect::MakeLTRB(0, 0, 800, 800)); - canvas.DrawPath(builder.TakePath(), paint); - return canvas.EndRecordingAsPicture(); - }; - ASSERT_TRUE(OpenPlaygroundHere(callback)); -} - -TEST_P(AiksTest, ClippedBlurFilterRendersCorrectly) { - Canvas canvas; - canvas.Translate(Point(0, -400)); - Paint paint; - paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{ - .style = FilterContents::BlurStyle::kNormal, - .sigma = Radius{120 * 3}, - }; - paint.color = Color::Red(); - PathBuilder builder{}; - builder.AddRect(Rect::MakeLTRB(0, 0, 800, 800)); - canvas.DrawPath(builder.TakePath(), paint); - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -TEST_P(AiksTest, ClearBlendWithBlur) { - Canvas canvas; - Paint white; - white.color = Color::Blue(); - canvas.DrawRect(Rect::MakeXYWH(0, 0, 600.0, 600.0), white); - - Paint clear; - clear.blend_mode = BlendMode::kClear; - clear.mask_blur_descriptor = Paint::MaskBlurDescriptor{ - .style = FilterContents::BlurStyle::kNormal, - .sigma = Sigma(20), - }; - - canvas.DrawCircle(Point::MakeXY(300.0, 300.0), 200.0, clear); - - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -TEST_P(AiksTest, BlurHasNoEdge) { - Scalar sigma = 47.6; - auto callback = [&](AiksContext& renderer) -> std::optional { - if (AiksTest::ImGuiBegin("Controls", nullptr, - ImGuiWindowFlags_AlwaysAutoResize)) { - ImGui::SliderFloat("Sigma", &sigma, 0, 50); - ImGui::End(); - } - Canvas canvas; - canvas.Scale(GetContentScale()); - canvas.DrawPaint({}); - Paint blur = { - .color = Color::Green(), - .mask_blur_descriptor = - Paint::MaskBlurDescriptor{ - .style = FilterContents::BlurStyle::kNormal, - .sigma = Sigma(sigma), - }, - }; - canvas.DrawRect(Rect::MakeXYWH(300, 300, 200, 200), blur); - return canvas.EndRecordingAsPicture(); - }; - - ASSERT_TRUE(OpenPlaygroundHere(callback)); -} - TEST_P(AiksTest, BlurredRectangleWithShader) { Canvas canvas; canvas.Scale(GetContentScale()); @@ -274,190 +69,6 @@ TEST_P(AiksTest, BlurredRectangleWithShader) { ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); } -TEST_P(AiksTest, MaskBlurWithZeroSigmaIsSkipped) { - Canvas canvas; - - Paint paint = { - .color = Color::Blue(), - .mask_blur_descriptor = - Paint::MaskBlurDescriptor{ - .style = FilterContents::BlurStyle::kNormal, - .sigma = Sigma(0), - }, - }; - - canvas.DrawCircle({300, 300}, 200, paint); - canvas.DrawRect(Rect::MakeLTRB(100, 300, 500, 600), paint); - - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -struct MaskBlurTestConfig { - FilterContents::BlurStyle style = FilterContents::BlurStyle::kNormal; - Scalar sigma = 1.0f; - Scalar alpha = 1.0f; - std::shared_ptr image_filter; - bool invert_colors = false; - BlendMode blend_mode = BlendMode::kSourceOver; -}; - -static Picture MaskBlurVariantTest(const AiksTest& test_context, - const MaskBlurTestConfig& config) { - Canvas canvas; - canvas.Scale(test_context.GetContentScale()); - canvas.Scale(Vector2{0.8f, 0.8f}); - Paint paint; - paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{ - .style = FilterContents::BlurStyle::kNormal, - .sigma = Sigma{1}, - }; - - canvas.DrawPaint({.color = Color::AntiqueWhite()}); - - paint.mask_blur_descriptor->style = config.style; - paint.mask_blur_descriptor->sigma = Sigma{config.sigma}; - paint.image_filter = config.image_filter; - paint.invert_colors = config.invert_colors; - paint.blend_mode = config.blend_mode; - - const Scalar x = 50; - const Scalar radius = 20.0f; - const Scalar y_spacing = 100.0f; - - Scalar y = 50; - paint.color = Color::Crimson().WithAlpha(config.alpha); - canvas.DrawRect(Rect::MakeXYWH(x + 25 - radius / 2, y + radius / 2, // - radius, 60.0f - radius), - paint); - - y += y_spacing; - paint.color = Color::Blue().WithAlpha(config.alpha); - canvas.DrawCircle({x + 25, y + 25}, radius, paint); - - y += y_spacing; - paint.color = Color::Green().WithAlpha(config.alpha); - canvas.DrawOval(Rect::MakeXYWH(x + 25 - radius / 2, y + radius / 2, // - radius, 60.0f - radius), - paint); - - y += y_spacing; - paint.color = Color::Purple().WithAlpha(config.alpha); - canvas.DrawRRect(Rect::MakeXYWH(x, y, 60.0f, 60.0f), // - {radius, radius}, // - paint); - - y += y_spacing; - paint.color = Color::Orange().WithAlpha(config.alpha); - canvas.DrawRRect(Rect::MakeXYWH(x, y, 60.0f, 60.0f), // - {radius, 5.0f}, paint); - - y += y_spacing; - paint.color = Color::Maroon().WithAlpha(config.alpha); - canvas.DrawPath(PathBuilder{} - .MoveTo({x + 0, y + 60}) - .LineTo({x + 30, y + 0}) - .LineTo({x + 60, y + 60}) - .Close() - .TakePath(), - paint); - - y += y_spacing; - paint.color = Color::Maroon().WithAlpha(config.alpha); - canvas.DrawPath(PathBuilder{} - .AddArc(Rect::MakeXYWH(x + 5, y, 50, 50), - Radians{kPi / 2}, Radians{kPi}) - .AddArc(Rect::MakeXYWH(x + 25, y, 50, 50), - Radians{kPi / 2}, Radians{kPi}) - .Close() - .TakePath(), - paint); - - return canvas.EndRecordingAsPicture(); -} - -static const std::map kPaintVariations = { - // 1. Normal style, translucent, zero sigma. - {"NormalTranslucentZeroSigma", - {.style = FilterContents::BlurStyle::kNormal, - .sigma = 0.0f, - .alpha = 0.5f}}, - // 2. Normal style, translucent. - {"NormalTranslucent", - {.style = FilterContents::BlurStyle::kNormal, - .sigma = 8.0f, - .alpha = 0.5f}}, - // 3. Solid style, translucent. - {"SolidTranslucent", - {.style = FilterContents::BlurStyle::kSolid, - .sigma = 8.0f, - .alpha = 0.5f}}, - // 4. Solid style, opaque. - {"SolidOpaque", - {.style = FilterContents::BlurStyle::kSolid, .sigma = 8.0f}}, - // 5. Solid style, translucent, color & image filtered. - {"SolidTranslucentWithFilters", - {.style = FilterContents::BlurStyle::kSolid, - .sigma = 8.0f, - .alpha = 0.5f, - .image_filter = ImageFilter::MakeBlur(Sigma{3}, - Sigma{3}, - FilterContents::BlurStyle::kNormal, - Entity::TileMode::kClamp), - .invert_colors = true}}, - // 6. Solid style, translucent, exclusion blended. - {"SolidTranslucentExclusionBlend", - {.style = FilterContents::BlurStyle::kSolid, - .sigma = 8.0f, - .alpha = 0.5f, - .blend_mode = BlendMode::kExclusion}}, - // 7. Inner style, translucent. - {"InnerTranslucent", - {.style = FilterContents::BlurStyle::kInner, - .sigma = 8.0f, - .alpha = 0.5f}}, - // 8. Inner style, translucent, blurred. - {"InnerTranslucentWithBlurImageFilter", - {.style = FilterContents::BlurStyle::kInner, - .sigma = 8.0f, - .alpha = 0.5f, - .image_filter = ImageFilter::MakeBlur(Sigma{3}, - Sigma{3}, - FilterContents::BlurStyle::kNormal, - Entity::TileMode::kClamp)}}, - // 9. Outer style, translucent. - {"OuterTranslucent", - {.style = FilterContents::BlurStyle::kOuter, - .sigma = 8.0f, - .alpha = 0.5f}}, - // 10. Outer style, opaque, image filtered. - {"OuterOpaqueWithBlurImageFilter", - {.style = FilterContents::BlurStyle::kOuter, - .sigma = 8.0f, - .image_filter = ImageFilter::MakeBlur(Sigma{3}, - Sigma{3}, - FilterContents::BlurStyle::kNormal, - Entity::TileMode::kClamp)}}, -}; - -#define MASK_BLUR_VARIANT_TEST(config) \ - TEST_P(AiksTest, MaskBlurVariantTest##config) { \ - ASSERT_TRUE(OpenPlaygroundHere( \ - MaskBlurVariantTest(*this, kPaintVariations.at(#config)))); \ - } - -MASK_BLUR_VARIANT_TEST(NormalTranslucentZeroSigma) -MASK_BLUR_VARIANT_TEST(NormalTranslucent) -MASK_BLUR_VARIANT_TEST(SolidTranslucent) -MASK_BLUR_VARIANT_TEST(SolidOpaque) -MASK_BLUR_VARIANT_TEST(SolidTranslucentWithFilters) -MASK_BLUR_VARIANT_TEST(SolidTranslucentExclusionBlend) -MASK_BLUR_VARIANT_TEST(InnerTranslucent) -MASK_BLUR_VARIANT_TEST(InnerTranslucentWithBlurImageFilter) -MASK_BLUR_VARIANT_TEST(OuterTranslucent) -MASK_BLUR_VARIANT_TEST(OuterOpaqueWithBlurImageFilter) - -#undef MASK_BLUR_VARIANT_TEST - TEST_P(AiksTest, GaussianBlurAtPeripheryVertical) { Canvas canvas; diff --git a/impeller/display_list/BUILD.gn b/impeller/display_list/BUILD.gn index 712e1bb723974..e60ec4e9f37de 100644 --- a/impeller/display_list/BUILD.gn +++ b/impeller/display_list/BUILD.gn @@ -55,6 +55,7 @@ template("display_list_unittests_component") { "aiks_dl_atlas_unittests.cc", "aiks_dl_basic_unittests.cc", "aiks_dl_blend_unittests.cc", + "aiks_dl_blur_unittests.cc", "aiks_dl_clip_unittests.cc", "aiks_dl_gradient_unittests.cc", "aiks_dl_opacity_unittests.cc", diff --git a/impeller/display_list/aiks_dl_blur_unittests.cc b/impeller/display_list/aiks_dl_blur_unittests.cc new file mode 100644 index 0000000000000..ecdc8df5ae46a --- /dev/null +++ b/impeller/display_list/aiks_dl_blur_unittests.cc @@ -0,0 +1,425 @@ +// 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 "display_list/display_list.h" +#include "display_list/dl_blend_mode.h" +#include "display_list/dl_builder.h" +#include "display_list/dl_color.h" +#include "display_list/dl_paint.h" +#include "display_list/dl_tile_mode.h" +#include "display_list/effects/dl_color_filter.h" +#include "display_list/effects/dl_image_filter.h" +#include "display_list/effects/dl_mask_filter.h" +#include "flutter/impeller/aiks/aiks_unittests.h" + +#include "impeller/playground/widgets.h" +#include "include/core/SkRRect.h" +#include "third_party/imgui/imgui.h" + +//////////////////////////////////////////////////////////////////////////////// +// This is for tests of Canvas that are interested the results of rendering +// blurs. +//////////////////////////////////////////////////////////////////////////////// + +namespace impeller { +namespace testing { + +using namespace flutter; + +TEST_P(AiksTest, CanRenderMaskBlurHugeSigma) { + DisplayListBuilder builder; + + DlPaint paint; + paint.setColor(DlColor::kGreen()); + paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 99999)); + builder.DrawCircle({400, 400}, 300, paint); + builder.Restore(); + + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +TEST_P(AiksTest, CanRenderForegroundBlendWithMaskBlur) { + // This case triggers the ForegroundPorterDuffBlend path. The color filter + // should apply to the color only, and respect the alpha mask. + DisplayListBuilder builder; + builder.ClipRect(SkRect::MakeXYWH(100, 150, 400, 400)); + + DlPaint paint; + paint.setColor(DlColor::kWhite()); + paint.setMaskFilter( + DlBlurMaskFilter::Make(DlBlurStyle::kNormal, Sigma(Radius(20)).sigma)); + paint.setColorFilter( + DlBlendColorFilter::Make(DlColor::kGreen(), DlBlendMode::kSrc)); + builder.DrawCircle({400, 400}, 200, paint); + builder.Restore(); + + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +TEST_P(AiksTest, CanRenderForegroundAdvancedBlendWithMaskBlur) { + // This case triggers the ForegroundAdvancedBlend path. The color filter + // should apply to the color only, and respect the alpha mask. + DisplayListBuilder builder; + builder.ClipRect(SkRect::MakeXYWH(100, 150, 400, 400)); + + DlPaint paint; + paint.setColor(DlColor::kLightGrey()); + paint.setMaskFilter( + DlBlurMaskFilter::Make(DlBlurStyle::kNormal, Sigma(Radius(20)).sigma)); + builder.DrawCircle({400, 400}, 200, paint); + builder.Restore(); + + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +TEST_P(AiksTest, CanRenderBackdropBlurInteractive) { + auto callback = [&]() -> sk_sp { + static PlaygroundPoint point_a(Point(50, 50), 30, Color::White()); + static PlaygroundPoint point_b(Point(300, 200), 30, Color::White()); + auto [a, b] = DrawPlaygroundLine(point_a, point_b); + + DisplayListBuilder builder; + DlPaint paint; + paint.setColor(DlColor::kCornflowerBlue()); + builder.DrawCircle({100, 100}, 50, paint); + + paint.setColor( + DlColor::RGBA(Color::GreenYellow().red, Color::GreenYellow().green, + Color::GreenYellow().blue, Color::GreenYellow().alpha)); + builder.DrawCircle({300, 200}, 100, paint); + + paint.setColor( + DlColor::RGBA(Color::DarkMagenta().red, Color::DarkMagenta().green, + Color::DarkMagenta().blue, Color::DarkMagenta().alpha)); + builder.DrawCircle({140, 170}, 75, paint); + + paint.setColor( + DlColor::RGBA(Color::OrangeRed().red, Color::OrangeRed().green, + Color::OrangeRed().blue, Color::OrangeRed().alpha)); + builder.DrawCircle({180, 120}, 100, paint); + + SkRRect rrect = + SkRRect::MakeRectXY(SkRect::MakeLTRB(a.x, a.y, b.x, b.y), 20, 20); + builder.ClipRRect(rrect); + + DlPaint save_paint; + save_paint.setBlendMode(DlBlendMode::kSrc); + + auto backdrop_filter = DlBlurImageFilter::Make(20, 20, DlTileMode::kClamp); + builder.SaveLayer(nullptr, &save_paint, backdrop_filter.get()); + builder.Restore(); + + return builder.Build(); + }; + + ASSERT_TRUE(OpenPlaygroundHere(callback)); +} + +TEST_P(AiksTest, CanRenderBackdropBlur) { + DisplayListBuilder builder; + + DlPaint paint; + paint.setColor(DlColor::kCornflowerBlue()); + builder.DrawCircle({100, 100}, 50, paint); + + paint.setColor( + DlColor::RGBA(Color::GreenYellow().red, Color::GreenYellow().green, + Color::GreenYellow().blue, Color::GreenYellow().alpha)); + builder.DrawCircle({300, 200}, 100, paint); + + paint.setColor( + DlColor::RGBA(Color::DarkMagenta().red, Color::DarkMagenta().green, + Color::DarkMagenta().blue, Color::DarkMagenta().alpha)); + builder.DrawCircle({140, 170}, 75, paint); + + paint.setColor(DlColor::RGBA(Color::OrangeRed().red, Color::OrangeRed().green, + Color::OrangeRed().blue, + Color::OrangeRed().alpha)); + builder.DrawCircle({180, 120}, 100, paint); + + SkRRect rrect = + SkRRect::MakeRectXY(SkRect::MakeLTRB(75, 50, 375, 275), 20, 20); + builder.ClipRRect(rrect); + + DlPaint save_paint; + save_paint.setBlendMode(DlBlendMode::kSrc); + auto backdrop_filter = DlBlurImageFilter::Make(30, 30, DlTileMode::kClamp); + builder.SaveLayer(nullptr, &save_paint, backdrop_filter.get()); + builder.Restore(); + + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +TEST_P(AiksTest, CanRenderBackdropBlurHugeSigma) { + DisplayListBuilder builder; + + DlPaint paint; + paint.setColor(DlColor::kGreen()); + builder.DrawCircle({400, 400}, 300, paint); + + DlPaint save_paint; + save_paint.setBlendMode(DlBlendMode::kSrc); + + auto backdrop_filter = + DlBlurImageFilter::Make(999999, 999999, DlTileMode::kClamp); + builder.SaveLayer(nullptr, &save_paint, backdrop_filter.get()); + builder.Restore(); + + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +TEST_P(AiksTest, CanRenderClippedBlur) { + DisplayListBuilder builder; + builder.ClipRect(SkRect::MakeXYWH(100, 150, 400, 400)); + + DlPaint paint; + paint.setColor(DlColor::kGreen()); + paint.setImageFilter(DlBlurImageFilter::Make(20, 20, DlTileMode::kDecal)); + builder.DrawCircle({400, 400}, 200, paint); + builder.Restore(); + + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +TEST_P(AiksTest, ClippedBlurFilterRendersCorrectlyInteractive) { + auto callback = [&]() -> sk_sp { + static PlaygroundPoint playground_point(Point(400, 400), 20, + Color::Green()); + auto point = DrawPlaygroundPoint(playground_point); + + DisplayListBuilder builder; + auto location = point - Point(400, 400); + builder.Translate(location.x, location.y); + + DlPaint paint; + paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, + Sigma(Radius(120 * 3)).sigma)); + paint.setColor(DlColor::kRed()); + + SkPath path = SkPath::Rect(SkRect::MakeLTRB(0, 0, 800, 800)); + builder.DrawPath(path, paint); + return builder.Build(); + }; + ASSERT_TRUE(OpenPlaygroundHere(callback)); +} + +TEST_P(AiksTest, ClippedBlurFilterRendersCorrectly) { + DisplayListBuilder builder; + builder.Translate(0, -400); + DlPaint paint; + paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, + Sigma(Radius(120 * 3)).sigma)); + paint.setColor(DlColor::kRed()); + + SkPath path = SkPath::Rect(SkRect::MakeLTRB(0, 0, 800, 800)); + builder.DrawPath(path, paint); + + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +TEST_P(AiksTest, ClearBlendWithBlur) { + DisplayListBuilder builder; + DlPaint paint; + paint.setColor(DlColor::kBlue()); + builder.DrawRect(SkRect::MakeXYWH(0, 0, 600.0, 600.0), paint); + + DlPaint clear; + clear.setBlendMode(DlBlendMode::kClear); + clear.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 20)); + + builder.DrawCircle({300.0, 300.0}, 200.0, clear); + + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +TEST_P(AiksTest, BlurHasNoEdge) { + Scalar sigma = 47.6; + auto callback = [&]() -> sk_sp { + if (AiksTest::ImGuiBegin("Controls", nullptr, + ImGuiWindowFlags_AlwaysAutoResize)) { + ImGui::SliderFloat("Sigma", &sigma, 0, 50); + ImGui::End(); + } + DisplayListBuilder builder; + builder.Scale(GetContentScale().x, GetContentScale().y); + builder.DrawPaint({}); + + DlPaint paint; + paint.setColor(DlColor::kGreen()); + paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma)); + + builder.DrawRect(SkRect::MakeXYWH(300, 300, 200, 200), paint); + return builder.Build(); + }; + + ASSERT_TRUE(OpenPlaygroundHere(callback)); +} + +TEST_P(AiksTest, MaskBlurWithZeroSigmaIsSkipped) { + DisplayListBuilder builder; + + DlPaint paint; + paint.setColor(DlColor::kBlue()); + paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 0)); + + builder.DrawCircle({300, 300}, 200, paint); + builder.DrawRect(SkRect::MakeLTRB(100, 300, 500, 600), paint); + + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +struct MaskBlurTestConfig { + DlBlurStyle style = DlBlurStyle::kNormal; + Scalar sigma = 1.0f; + Scalar alpha = 1.0f; + std::shared_ptr image_filter; + bool invert_colors = false; + DlBlendMode blend_mode = DlBlendMode::kSrcOver; +}; + +static sk_sp MaskBlurVariantTest( + const AiksTest& test_context, + const MaskBlurTestConfig& config) { + DisplayListBuilder builder; + builder.Scale(test_context.GetContentScale().x, + test_context.GetContentScale().y); + builder.Scale(0.8f, 0.8f); + + DlPaint draw_paint; + draw_paint.setColor( + DlColor::RGBA(Color::AntiqueWhite().red, Color::AntiqueWhite().green, + Color::AntiqueWhite().blue, Color::AntiqueWhite().alpha)); + builder.DrawPaint(draw_paint); + + DlPaint paint; + paint.setMaskFilter(DlBlurMaskFilter::Make(config.style, config.sigma)); + paint.setInvertColors(config.invert_colors); + paint.setImageFilter(config.image_filter); + paint.setBlendMode(config.blend_mode); + + const Scalar x = 50; + const Scalar radius = 20.0f; + const Scalar y_spacing = 100.0f; + Scalar alpha = config.alpha * 255; + + Scalar y = 50; + paint.setColor(DlColor::kCrimson().withAlpha(alpha)); + builder.DrawRect(SkRect::MakeXYWH(x + 25 - radius / 2, y + radius / 2, // + radius, 60.0f - radius), + paint); + + y += y_spacing; + paint.setColor(DlColor::kBlue().withAlpha(alpha)); + builder.DrawCircle({x + 25, y + 25}, radius, paint); + + y += y_spacing; + paint.setColor(DlColor::kGreen().withAlpha(alpha)); + builder.DrawOval(SkRect::MakeXYWH(x + 25 - radius / 2, y + radius / 2, // + radius, 60.0f - radius), + paint); + + y += y_spacing; + paint.setColor(DlColor::kPurple().withAlpha(alpha)); + SkRRect rrect = + SkRRect::MakeRectXY(SkRect::MakeXYWH(x, y, 60.0f, 60.0f), radius, radius); + builder.DrawRRect(rrect, paint); + + y += y_spacing; + paint.setColor(DlColor::kOrange().withAlpha(alpha)); + + rrect = + SkRRect::MakeRectXY(SkRect::MakeXYWH(x, y, 60.0f, 60.0f), radius, 5.0); + builder.DrawRRect(rrect, paint); + + y += y_spacing; + paint.setColor(DlColor::kMaroon().withAlpha(alpha)); + + { + SkPath path; + path.moveTo(x + 0, y + 60); + path.lineTo(x + 30, y + 0); + path.lineTo(x + 60, y + 60); + path.close(); + + builder.DrawPath(path, paint); + } + + y += y_spacing; + paint.setColor(DlColor::kMaroon().withAlpha(alpha)); + { + SkPath path; + path.addArc(SkRect::MakeXYWH(x + 5, y, 50, 50), 90, 180); + path.addArc(SkRect::MakeXYWH(x + 25, y, 50, 50), 90, 180); + path.close(); + builder.DrawPath(path, paint); + } + + return builder.Build(); +} + +static const std::map kPaintVariations = { + // 1. Normal style, translucent, zero sigma. + {"NormalTranslucentZeroSigma", + {.style = DlBlurStyle::kNormal, .sigma = 0.0f, .alpha = 0.5f}}, + // 2. Normal style, translucent. + {"NormalTranslucent", + {.style = DlBlurStyle::kNormal, .sigma = 8.0f, .alpha = 0.5f}}, + // 3. Solid style, translucent. + {"SolidTranslucent", + {.style = DlBlurStyle::kSolid, .sigma = 8.0f, .alpha = 0.5f}}, + // 4. Solid style, opaque. + {"SolidOpaque", {.style = DlBlurStyle::kSolid, .sigma = 8.0f}}, + // 5. Solid style, translucent, color & image filtered. + {"SolidTranslucentWithFilters", + {.style = DlBlurStyle::kSolid, + .sigma = 8.0f, + .alpha = 0.5f, + .image_filter = DlBlurImageFilter::Make(3, 3, DlTileMode::kClamp), + .invert_colors = true}}, + // 6. Solid style, translucent, exclusion blended. + {"SolidTranslucentExclusionBlend", + {.style = DlBlurStyle::kSolid, + .sigma = 8.0f, + .alpha = 0.5f, + .blend_mode = DlBlendMode::kExclusion}}, + // 7. Inner style, translucent. + {"InnerTranslucent", + {.style = DlBlurStyle::kInner, .sigma = 8.0f, .alpha = 0.5f}}, + // 8. Inner style, translucent, blurred. + {"InnerTranslucentWithBlurImageFilter", + {.style = DlBlurStyle::kInner, + .sigma = 8.0f, + .alpha = 0.5f, + .image_filter = DlBlurImageFilter::Make(3, 3, DlTileMode::kClamp)}}, + // 9. Outer style, translucent. + {"OuterTranslucent", + {.style = DlBlurStyle::kOuter, .sigma = 8.0f, .alpha = 0.5f}}, + // 10. Outer style, opaque, image filtered. + {"OuterOpaqueWithBlurImageFilter", + {.style = DlBlurStyle::kOuter, + .sigma = 8.0f, + .image_filter = DlBlurImageFilter::Make(3, 3, DlTileMode::kClamp)}}, +}; + +#define MASK_BLUR_VARIANT_TEST(config) \ + TEST_P(AiksTest, MaskBlurVariantTest##config) { \ + ASSERT_TRUE(OpenPlaygroundHere( \ + MaskBlurVariantTest(*this, kPaintVariations.at(#config)))); \ + } + +MASK_BLUR_VARIANT_TEST(NormalTranslucentZeroSigma) +MASK_BLUR_VARIANT_TEST(NormalTranslucent) +MASK_BLUR_VARIANT_TEST(SolidTranslucent) +MASK_BLUR_VARIANT_TEST(SolidOpaque) +MASK_BLUR_VARIANT_TEST(SolidTranslucentWithFilters) +MASK_BLUR_VARIANT_TEST(SolidTranslucentExclusionBlend) +MASK_BLUR_VARIANT_TEST(InnerTranslucent) +MASK_BLUR_VARIANT_TEST(InnerTranslucentWithBlurImageFilter) +MASK_BLUR_VARIANT_TEST(OuterTranslucent) +MASK_BLUR_VARIANT_TEST(OuterOpaqueWithBlurImageFilter) + +#undef MASK_BLUR_VARIANT_TEST + +} // namespace testing +} // namespace impeller From beb1c4a330b9fa27268f2f6f051aa7b28cb47516 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 12 Aug 2024 17:00:18 -0700 Subject: [PATCH 02/15] ++ --- display_list/dl_color.h | 5 +- impeller/aiks/aiks_blur_unittests.cc | 173 ---------------- .../display_list/aiks_dl_blur_unittests.cc | 193 +++++++++++++++--- 3 files changed, 172 insertions(+), 199 deletions(-) diff --git a/display_list/dl_color.h b/display_list/dl_color.h index 5c9434366c063..bc9f8787d6dd5 100644 --- a/display_list/dl_color.h +++ b/display_list/dl_color.h @@ -55,12 +55,15 @@ struct DlColor { static constexpr DlColor kFuchsia() {return DlColor(0xFFFF00FF);}; static constexpr DlColor kMaroon() {return DlColor(0xFF800000);}; static constexpr DlColor kSkyBlue() {return DlColor(0xFF87CEEB);}; - static constexpr DlColor kCornflowerBlue() {return DlColor(0xFF6495ED);}; + static constexpr DlColor kCornflowerBlue() {return DlColor(0xFFFF5733);}; static constexpr DlColor kCrimson() {return DlColor(0xFFFF5733);}; static constexpr DlColor kAqua() {return DlColor(0xFF00FFFF);}; static constexpr DlColor kOrange() {return DlColor(0xFFFFA500);}; static constexpr DlColor kPurple() {return DlColor(0xFF800080);}; static constexpr DlColor kLimeGreen() {return DlColor(0xFF32CD32);}; + static constexpr DlColor kGreenYellow() {return DlColor(0xFFADFF2F);}; + static constexpr DlColor kDarkMagenta() {return DlColor(0xFF8B008B);}; + static constexpr DlColor kOrangeRed() {return DlColor(0xFFFF4500);}; // clang-format on constexpr bool isOpaque() const { return getAlpha() == 0xFF; } diff --git a/impeller/aiks/aiks_blur_unittests.cc b/impeller/aiks/aiks_blur_unittests.cc index ac6b669be2db2..683e8ed036a46 100644 --- a/impeller/aiks/aiks_blur_unittests.cc +++ b/impeller/aiks/aiks_blur_unittests.cc @@ -514,178 +514,5 @@ TEST_P(AiksTest, GaussianBlurStyleOuterGradient) { ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); } -TEST_P(AiksTest, GaussianBlurStyleInner) { - Canvas canvas; - canvas.Scale(GetContentScale()); - - canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)}); - - Paint paint; - paint.color = Color::Green(); - paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{ - .style = FilterContents::BlurStyle::kInner, - .sigma = Sigma(30), - }; - canvas.DrawPath(PathBuilder() - .MoveTo({200, 200}) - .LineTo({300, 400}) - .LineTo({100, 400}) - .Close() - .TakePath(), - paint); - - // Draw another thing to make sure the clip area is reset. - Paint red; - red.color = Color::Red(); - canvas.DrawRect(Rect::MakeXYWH(0, 0, 200, 200), red); - - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -TEST_P(AiksTest, GaussianBlurStyleOuter) { - Canvas canvas; - canvas.Scale(GetContentScale()); - - canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)}); - - Paint paint; - paint.color = Color::Green(); - paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{ - .style = FilterContents::BlurStyle::kOuter, - .sigma = Sigma(30), - }; - canvas.DrawPath(PathBuilder() - .MoveTo({200, 200}) - .LineTo({300, 400}) - .LineTo({100, 400}) - .Close() - .TakePath(), - paint); - - // Draw another thing to make sure the clip area is reset. - Paint red; - red.color = Color::Red(); - canvas.DrawRect(Rect::MakeXYWH(0, 0, 200, 200), red); - - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -TEST_P(AiksTest, GaussianBlurStyleSolid) { - Canvas canvas; - canvas.Scale(GetContentScale()); - - canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)}); - - Paint paint; - paint.color = Color::Green(); - paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{ - .style = FilterContents::BlurStyle::kSolid, - .sigma = Sigma(30), - }; - canvas.DrawPath(PathBuilder() - .MoveTo({200, 200}) - .LineTo({300, 400}) - .LineTo({100, 400}) - .Close() - .TakePath(), - paint); - - // Draw another thing to make sure the clip area is reset. - Paint red; - red.color = Color::Red(); - canvas.DrawRect(Rect::MakeXYWH(0, 0, 200, 200), red); - - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -TEST_P(AiksTest, MaskBlurTexture) { - Scalar sigma = 30; - auto callback = [&](AiksContext& renderer) -> std::optional { - if (AiksTest::ImGuiBegin("Controls", nullptr, - ImGuiWindowFlags_AlwaysAutoResize)) { - ImGui::SliderFloat("Sigma", &sigma, 0, 500); - ImGui::End(); - } - Canvas canvas; - canvas.Scale(GetContentScale()); - Paint paint; - paint.color = Color::Green(); - paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{ - .style = FilterContents::BlurStyle::kNormal, - .sigma = Sigma(sigma), - }; - std::shared_ptr boston = CreateTextureForFixture("boston.jpg"); - canvas.DrawImage(std::make_shared(boston), {200, 200}, paint); - Paint red; - red.color = Color::Red(); - canvas.DrawRect(Rect::MakeXYWH(0, 0, 200, 200), red); - return canvas.EndRecordingAsPicture(); - }; - ASSERT_TRUE(OpenPlaygroundHere(callback)); -} - -TEST_P(AiksTest, GuassianBlurUpdatesMipmapContents) { - // This makes sure if mip maps are recycled across invocations of blurs the - // contents get updated each frame correctly. If they aren't updated the color - // inside the blur and outside the blur will be different. - // - // If there is some change to render target caching this could display a false - // positive in the future. Also, if the LOD that is rendered is 1 it could - // present a false positive. - int32_t count = 0; - auto callback = [&](AiksContext& renderer) -> std::optional { - Canvas canvas; - if (count++ == 0) { - canvas.DrawCircle({100, 100}, 50, {.color = Color::CornflowerBlue()}); - } else { - canvas.DrawCircle({100, 100}, 50, {.color = Color::Chartreuse()}); - } - canvas.ClipRRect(Rect::MakeLTRB(75, 50, 375, 275), {20, 20}); - canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt, - ImageFilter::MakeBlur(Sigma(30.0), Sigma(30.0), - FilterContents::BlurStyle::kNormal, - Entity::TileMode::kClamp)); - canvas.Restore(); - return canvas.EndRecordingAsPicture(); - }; - - ASSERT_TRUE(OpenPlaygroundHere(callback)); -} - -TEST_P(AiksTest, MaskBlurDoesntStretchContents) { - Scalar sigma = 70; - auto callback = [&](AiksContext& renderer) -> std::optional { - if (AiksTest::ImGuiBegin("Controls", nullptr, - ImGuiWindowFlags_AlwaysAutoResize)) { - ImGui::SliderFloat("Sigma", &sigma, 0, 500); - ImGui::End(); - } - Canvas canvas; - canvas.Scale(GetContentScale()); - canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)}); - - std::shared_ptr boston = CreateTextureForFixture("boston.jpg"); - ColorSource image_source = ColorSource::MakeImage( - boston, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {}, {}); - - canvas.Transform(Matrix::MakeTranslation({100, 100, 0}) * - Matrix::MakeScale({0.5, 0.5, 1.0})); - Paint paint = { - .color_source = image_source, - .mask_blur_descriptor = - Paint::MaskBlurDescriptor{ - .style = FilterContents::BlurStyle::kNormal, - .sigma = Sigma(sigma), - }, - }; - canvas.DrawRect( - Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height), - paint); - - return canvas.EndRecordingAsPicture(); - }; - ASSERT_TRUE(OpenPlaygroundHere(callback)); -} - } // namespace testing } // namespace impeller diff --git a/impeller/display_list/aiks_dl_blur_unittests.cc b/impeller/display_list/aiks_dl_blur_unittests.cc index ecdc8df5ae46a..40b0359f0cef2 100644 --- a/impeller/display_list/aiks_dl_blur_unittests.cc +++ b/impeller/display_list/aiks_dl_blur_unittests.cc @@ -7,12 +7,15 @@ #include "display_list/dl_builder.h" #include "display_list/dl_color.h" #include "display_list/dl_paint.h" +#include "display_list/dl_sampling_options.h" #include "display_list/dl_tile_mode.h" #include "display_list/effects/dl_color_filter.h" +#include "display_list/effects/dl_color_source.h" #include "display_list/effects/dl_image_filter.h" #include "display_list/effects/dl_mask_filter.h" #include "flutter/impeller/aiks/aiks_unittests.h" +#include "impeller/display_list/dl_image_impeller.h" #include "impeller/playground/widgets.h" #include "include/core/SkRRect.h" #include "third_party/imgui/imgui.h" @@ -47,8 +50,10 @@ TEST_P(AiksTest, CanRenderForegroundBlendWithMaskBlur) { DlPaint paint; paint.setColor(DlColor::kWhite()); + + Sigma sigma = Radius(20); paint.setMaskFilter( - DlBlurMaskFilter::Make(DlBlurStyle::kNormal, Sigma(Radius(20)).sigma)); + DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma.sigma)); paint.setColorFilter( DlBlendColorFilter::Make(DlColor::kGreen(), DlBlendMode::kSrc)); builder.DrawCircle({400, 400}, 200, paint); @@ -64,9 +69,12 @@ TEST_P(AiksTest, CanRenderForegroundAdvancedBlendWithMaskBlur) { builder.ClipRect(SkRect::MakeXYWH(100, 150, 400, 400)); DlPaint paint; - paint.setColor(DlColor::kLightGrey()); + paint.setColor( + DlColor::RGBA(128.0f / 255.0f, 128.0f / 255.0f, 128.0f / 255.0f, 1.0f)); + + Sigma sigma = Radius(20); paint.setMaskFilter( - DlBlurMaskFilter::Make(DlBlurStyle::kNormal, Sigma(Radius(20)).sigma)); + DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma.sigma)); builder.DrawCircle({400, 400}, 200, paint); builder.Restore(); @@ -84,19 +92,13 @@ TEST_P(AiksTest, CanRenderBackdropBlurInteractive) { paint.setColor(DlColor::kCornflowerBlue()); builder.DrawCircle({100, 100}, 50, paint); - paint.setColor( - DlColor::RGBA(Color::GreenYellow().red, Color::GreenYellow().green, - Color::GreenYellow().blue, Color::GreenYellow().alpha)); + paint.setColor(DlColor::kGreenYellow()); builder.DrawCircle({300, 200}, 100, paint); - paint.setColor( - DlColor::RGBA(Color::DarkMagenta().red, Color::DarkMagenta().green, - Color::DarkMagenta().blue, Color::DarkMagenta().alpha)); + paint.setColor(DlColor::kDarkMagenta()); builder.DrawCircle({140, 170}, 75, paint); - paint.setColor( - DlColor::RGBA(Color::OrangeRed().red, Color::OrangeRed().green, - Color::OrangeRed().blue, Color::OrangeRed().alpha)); + paint.setColor(DlColor::kOrangeRed()); builder.DrawCircle({180, 120}, 100, paint); SkRRect rrect = @@ -123,19 +125,13 @@ TEST_P(AiksTest, CanRenderBackdropBlur) { paint.setColor(DlColor::kCornflowerBlue()); builder.DrawCircle({100, 100}, 50, paint); - paint.setColor( - DlColor::RGBA(Color::GreenYellow().red, Color::GreenYellow().green, - Color::GreenYellow().blue, Color::GreenYellow().alpha)); + paint.setColor(DlColor::kGreenYellow()); builder.DrawCircle({300, 200}, 100, paint); - paint.setColor( - DlColor::RGBA(Color::DarkMagenta().red, Color::DarkMagenta().green, - Color::DarkMagenta().blue, Color::DarkMagenta().alpha)); + paint.setColor(DlColor::kDarkMagenta()); builder.DrawCircle({140, 170}, 75, paint); - paint.setColor(DlColor::RGBA(Color::OrangeRed().red, Color::OrangeRed().green, - Color::OrangeRed().blue, - Color::OrangeRed().alpha)); + paint.setColor(DlColor::kOrangeRed()); builder.DrawCircle({180, 120}, 100, paint); SkRRect rrect = @@ -193,8 +189,9 @@ TEST_P(AiksTest, ClippedBlurFilterRendersCorrectlyInteractive) { builder.Translate(location.x, location.y); DlPaint paint; - paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, - Sigma(Radius(120 * 3)).sigma)); + Sigma sigma = Radius(120 * 3); + paint.setMaskFilter( + DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma.sigma)); paint.setColor(DlColor::kRed()); SkPath path = SkPath::Rect(SkRect::MakeLTRB(0, 0, 800, 800)); @@ -208,8 +205,9 @@ TEST_P(AiksTest, ClippedBlurFilterRendersCorrectly) { DisplayListBuilder builder; builder.Translate(0, -400); DlPaint paint; - paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, - Sigma(Radius(120 * 3)).sigma)); + Sigma sigma = Radius(120 * 3); + paint.setMaskFilter( + DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma.sigma)); paint.setColor(DlColor::kRed()); SkPath path = SkPath::Rect(SkRect::MakeLTRB(0, 0, 800, 800)); @@ -421,5 +419,150 @@ MASK_BLUR_VARIANT_TEST(OuterOpaqueWithBlurImageFilter) #undef MASK_BLUR_VARIANT_TEST +TEST_P(AiksTest, GaussianBlurStyleInner) { + DisplayListBuilder builder; + builder.Scale(GetContentScale().x, GetContentScale().y); + + DlPaint paint; + paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1)); + builder.DrawPaint(paint); + + paint.setColor(DlColor::kGreen()); + paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kInner, 30)); + + SkPath path; + path.moveTo(200, 200); + path.lineTo(300, 400); + path.lineTo(100, 400); + path.close(); + + builder.DrawPath(path, paint); + + // Draw another thing to make sure the clip area is reset. + DlPaint red; + red.setColor(DlColor::kRed()); + builder.DrawRect(SkRect::MakeXYWH(0, 0, 200, 200), red); + + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +TEST_P(AiksTest, GaussianBlurStyleOuter) { + DisplayListBuilder builder; + builder.Scale(GetContentScale().x, GetContentScale().y); + + DlPaint paint; + paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1.0)); + builder.DrawPaint(paint); + + paint.setColor(DlColor::kGreen()); + paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kOuter, 30)); + + SkPath path; + path.moveTo(200, 200); + path.lineTo(300, 400); + path.lineTo(100, 400); + path.close(); + + builder.DrawPath(path, paint); + + // Draw another thing to make sure the clip area is reset. + DlPaint red; + red.setColor(DlColor::kRed()); + builder.DrawRect(SkRect::MakeXYWH(0, 0, 200, 200), red); + + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +TEST_P(AiksTest, GaussianBlurStyleSolid) { + DisplayListBuilder builder; + builder.Scale(GetContentScale().x, GetContentScale().y); + + DlPaint paint; + paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1.0)); + builder.DrawPaint(paint); + + paint.setColor(DlColor::kGreen()); + paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kSolid, 30)); + + SkPath path; + path.moveTo(200, 200); + path.lineTo(300, 400); + path.lineTo(100, 400); + path.close(); + + builder.DrawPath(path, paint); + + // Draw another thing to make sure the clip area is reset. + DlPaint red; + red.setColor(DlColor::kRed()); + builder.DrawRect(SkRect::MakeXYWH(0, 0, 200, 200), red); + + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +TEST_P(AiksTest, MaskBlurTexture) { + Scalar sigma = 30; + auto callback = [&]() -> sk_sp { + if (AiksTest::ImGuiBegin("Controls", nullptr, + ImGuiWindowFlags_AlwaysAutoResize)) { + ImGui::SliderFloat("Sigma", &sigma, 0, 500); + ImGui::End(); + } + + DisplayListBuilder builder; + builder.Scale(GetContentScale().x, GetContentScale().y); + + DlPaint paint; + paint.setColor(DlColor::kGreen()); + paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma)); + + builder.DrawImage( + DlImageImpeller::Make(CreateTextureForFixture("boston.jpg")), + {200, 200}, DlImageSampling::kNearestNeighbor, &paint); + + DlPaint red; + red.setColor(DlColor::kRed()); + builder.DrawRect(SkRect::MakeXYWH(0, 0, 200, 200), red); + + return builder.Build(); + }; + ASSERT_TRUE(OpenPlaygroundHere(callback)); +} + +TEST_P(AiksTest, MaskBlurDoesntStretchContents) { + Scalar sigma = 70; + auto callback = [&]() -> sk_sp { + if (AiksTest::ImGuiBegin("Controls", nullptr, + ImGuiWindowFlags_AlwaysAutoResize)) { + ImGui::SliderFloat("Sigma", &sigma, 0, 500); + ImGui::End(); + } + + DisplayListBuilder builder; + builder.Scale(GetContentScale().x, GetContentScale().y); + + DlPaint paint; + paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1.0)); + builder.DrawPaint(paint); + + std::shared_ptr boston = CreateTextureForFixture("boston.jpg"); + + builder.Transform(SkMatrix::Translate(100, 100) * + SkMatrix::Scale(0.5, 0.5)); + + paint.setColorSource(std::make_shared( + DlImageImpeller::Make(boston), DlTileMode::kRepeat, + DlTileMode::kRepeat)); + paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma)); + + builder.DrawRect(SkRect::MakeXYWH(0, 0, boston->GetSize().width, + boston->GetSize().height), + paint); + + return builder.Build(); + }; + ASSERT_TRUE(OpenPlaygroundHere(callback)); +} + } // namespace testing } // namespace impeller From 30087bc4239303f66608241cfc12665b3e0f3f38 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 12 Aug 2024 18:16:50 -0700 Subject: [PATCH 03/15] more changes. --- ci/licenses_golden/excluded_files | 1 + impeller/aiks/aiks_blur_unittests.cc | 181 --------------- .../display_list/aiks_dl_blur_unittests.cc | 212 ++++++++++++++++++ testing/impeller_golden_tests_output.txt | 3 - 4 files changed, 213 insertions(+), 184 deletions(-) diff --git a/ci/licenses_golden/excluded_files b/ci/licenses_golden/excluded_files index 22f71de36d258..91e80b6015968 100644 --- a/ci/licenses_golden/excluded_files +++ b/ci/licenses_golden/excluded_files @@ -145,6 +145,7 @@ ../../../flutter/impeller/display_list/aiks_dl_atlas_unittests.cc ../../../flutter/impeller/display_list/aiks_dl_basic_unittests.cc ../../../flutter/impeller/display_list/aiks_dl_blend_unittests.cc +../../../flutter/impeller/display_list/aiks_dl_blur_unittests.cc ../../../flutter/impeller/display_list/aiks_dl_clip_unittests.cc ../../../flutter/impeller/display_list/aiks_dl_gradient_unittests.cc ../../../flutter/impeller/display_list/aiks_dl_opacity_unittests.cc diff --git a/impeller/aiks/aiks_blur_unittests.cc b/impeller/aiks/aiks_blur_unittests.cc index 683e8ed036a46..800d96e285162 100644 --- a/impeller/aiks/aiks_blur_unittests.cc +++ b/impeller/aiks/aiks_blur_unittests.cc @@ -69,44 +69,6 @@ TEST_P(AiksTest, BlurredRectangleWithShader) { ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); } -TEST_P(AiksTest, GaussianBlurAtPeripheryVertical) { - Canvas canvas; - - canvas.Scale(GetContentScale()); - canvas.DrawRRect(Rect::MakeLTRB(0, 0, GetWindowSize().width, 100), - Size(10, 10), Paint{.color = Color::LimeGreen()}); - canvas.DrawRRect(Rect::MakeLTRB(0, 110, GetWindowSize().width, 210), - Size(10, 10), Paint{.color = Color::Magenta()}); - canvas.ClipRect(Rect::MakeLTRB(100, 0, 200, GetWindowSize().height)); - canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt, - ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0), - FilterContents::BlurStyle::kNormal, - Entity::TileMode::kClamp)); - canvas.Restore(); - - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -TEST_P(AiksTest, GaussianBlurAtPeripheryHorizontal) { - Canvas canvas; - - canvas.Scale(GetContentScale()); - std::shared_ptr boston = CreateTextureForFixture("boston.jpg"); - canvas.DrawImageRect( - std::make_shared(boston), - Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height), - Rect::MakeLTRB(0, 0, GetWindowSize().width, 100), Paint{}); - canvas.DrawRRect(Rect::MakeLTRB(0, 110, GetWindowSize().width, 210), - Size(10, 10), Paint{.color = Color::Magenta()}); - canvas.ClipRect(Rect::MakeLTRB(0, 50, GetWindowSize().width, 150)); - canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt, - ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0), - FilterContents::BlurStyle::kNormal, - Entity::TileMode::kClamp)); - canvas.Restore(); - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - #define FLT_FORWARD(mock, real, method) \ EXPECT_CALL(*mock, method()) \ .WillRepeatedly(::testing::Return(real->method())); @@ -371,148 +333,5 @@ TEST_P(AiksTest, GaussianBlurBackdropTinyMipMap) { } } -TEST_P(AiksTest, GaussianBlurAnimatedBackdrop) { - // This test is for checking out how stable rendering is when content is - // translated underneath a blur. Animating under a blur can cause - // *shimmering* to happen as a result of pixel alignment. - // See also: https://github.com/flutter/flutter/issues/140193 - auto boston = std::make_shared( - CreateTextureForFixture("boston.jpg", /*enable_mipmapping=*/true)); - ASSERT_TRUE(boston); - int64_t count = 0; - Scalar sigma = 20.0; - Scalar freq = 0.1; - Scalar amp = 50.0; - auto callback = [&](AiksContext& renderer) -> std::optional { - if (AiksTest::ImGuiBegin("Controls", nullptr, - ImGuiWindowFlags_AlwaysAutoResize)) { - ImGui::SliderFloat("Sigma", &sigma, 0, 200); - ImGui::SliderFloat("Frequency", &freq, 0.01, 2.0); - ImGui::SliderFloat("Amplitude", &, 1, 100); - ImGui::End(); - } - - Canvas canvas; - canvas.Scale(GetContentScale()); - Scalar y = amp * sin(freq * 2.0 * M_PI * count / 60); - canvas.DrawImage(boston, - Point(1024 / 2 - boston->GetSize().width / 2, - (768 / 2 - boston->GetSize().height / 2) + y), - {}); - static PlaygroundPoint point_a(Point(100, 100), 20, Color::Red()); - static PlaygroundPoint point_b(Point(900, 700), 20, Color::Red()); - auto [handle_a, handle_b] = DrawPlaygroundLine(point_a, point_b); - canvas.ClipRect( - Rect::MakeLTRB(handle_a.x, handle_a.y, handle_b.x, handle_b.y)); - canvas.ClipRect(Rect::MakeLTRB(100, 100, 900, 700)); - canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt, - ImageFilter::MakeBlur(Sigma(sigma), Sigma(sigma), - FilterContents::BlurStyle::kNormal, - Entity::TileMode::kClamp)); - count += 1; - return canvas.EndRecordingAsPicture(); - }; - ASSERT_TRUE(OpenPlaygroundHere(callback)); -} - -TEST_P(AiksTest, GaussianBlurStyleInnerGradient) { - Canvas canvas; - canvas.Scale(GetContentScale()); - - canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)}); - - std::vector colors = {Color{0.9568, 0.2627, 0.2118, 1.0}, - Color{0.7568, 0.2627, 0.2118, 1.0}}; - std::vector stops = {0.0, 1.0}; - - Paint paint; - paint.color_source = ColorSource::MakeLinearGradient( - {0, 0}, {200, 200}, std::move(colors), std::move(stops), - Entity::TileMode::kMirror, {}); - paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{ - .style = FilterContents::BlurStyle::kInner, - .sigma = Sigma(30), - }; - canvas.DrawPath(PathBuilder() - .MoveTo({200, 200}) - .LineTo({300, 400}) - .LineTo({100, 400}) - .Close() - .TakePath(), - paint); - - // Draw another thing to make sure the clip area is reset. - Paint red; - red.color = Color::Red(); - canvas.DrawRect(Rect::MakeXYWH(0, 0, 200, 200), red); - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -TEST_P(AiksTest, GaussianBlurStyleSolidGradient) { - Canvas canvas; - canvas.Scale(GetContentScale()); - - canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)}); - - std::vector colors = {Color{0.9568, 0.2627, 0.2118, 1.0}, - Color{0.7568, 0.2627, 0.2118, 1.0}}; - std::vector stops = {0.0, 1.0}; - - Paint paint; - paint.color_source = ColorSource::MakeLinearGradient( - {0, 0}, {200, 200}, std::move(colors), std::move(stops), - Entity::TileMode::kMirror, {}); - paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{ - .style = FilterContents::BlurStyle::kSolid, - .sigma = Sigma(30), - }; - canvas.DrawPath(PathBuilder() - .MoveTo({200, 200}) - .LineTo({300, 400}) - .LineTo({100, 400}) - .Close() - .TakePath(), - paint); - - // Draw another thing to make sure the clip area is reset. - Paint red; - red.color = Color::Red(); - canvas.DrawRect(Rect::MakeXYWH(0, 0, 200, 200), red); - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -TEST_P(AiksTest, GaussianBlurStyleOuterGradient) { - Canvas canvas; - canvas.Scale(GetContentScale()); - - canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)}); - - std::vector colors = {Color{0.9568, 0.2627, 0.2118, 1.0}, - Color{0.7568, 0.2627, 0.2118, 1.0}}; - std::vector stops = {0.0, 1.0}; - - Paint paint; - paint.color_source = ColorSource::MakeLinearGradient( - {0, 0}, {200, 200}, std::move(colors), std::move(stops), - Entity::TileMode::kMirror, {}); - paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{ - .style = FilterContents::BlurStyle::kOuter, - .sigma = Sigma(30), - }; - canvas.DrawPath(PathBuilder() - .MoveTo({200, 200}) - .LineTo({300, 400}) - .LineTo({100, 400}) - .Close() - .TakePath(), - paint); - - // Draw another thing to make sure the clip area is reset. - Paint red; - red.color = Color::Red(); - canvas.DrawRect(Rect::MakeXYWH(0, 0, 200, 200), red); - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - } // namespace testing } // namespace impeller diff --git a/impeller/display_list/aiks_dl_blur_unittests.cc b/impeller/display_list/aiks_dl_blur_unittests.cc index 40b0359f0cef2..7b59a342fb6c6 100644 --- a/impeller/display_list/aiks_dl_blur_unittests.cc +++ b/impeller/display_list/aiks_dl_blur_unittests.cc @@ -564,5 +564,217 @@ TEST_P(AiksTest, MaskBlurDoesntStretchContents) { ASSERT_TRUE(OpenPlaygroundHere(callback)); } +TEST_P(AiksTest, GaussianBlurAtPeripheryVertical) { + DisplayListBuilder builder; + + DlPaint paint; + builder.Scale(GetContentScale().x, GetContentScale().y); + + paint.setColor(DlColor::kLimeGreen()); + SkRRect rrect = SkRRect::MakeRectXY( + SkRect::MakeLTRB(0, 0, GetWindowSize().width, 100), 10, 10); + builder.DrawRRect(rrect, paint); + + paint.setColor(DlColor::kMagenta()); + rrect = SkRRect::MakeRectXY( + SkRect::MakeLTRB(0, 110, GetWindowSize().width, 210), 10, 10); + builder.DrawRRect(rrect, paint); + builder.ClipRect(SkRect::MakeLTRB(100, 0, 200, GetWindowSize().height)); + + DlPaint save_paint; + save_paint.setBlendMode(DlBlendMode::kSrc); + save_paint.setImageFilter( + DlBlurImageFilter::Make(20, 20, DlTileMode::kClamp)); + builder.SaveLayer(nullptr, &save_paint); + builder.Restore(); + + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +TEST_P(AiksTest, GaussianBlurAtPeripheryHorizontal) { + DisplayListBuilder builder; + + builder.Scale(GetContentScale().x, GetContentScale().y); + std::shared_ptr boston = CreateTextureForFixture("boston.jpg"); + builder.DrawImageRect( + DlImageImpeller::Make(boston), + SkRect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height), + SkRect::MakeLTRB(0, 0, GetWindowSize().width, 100), + DlImageSampling::kNearestNeighbor); + + DlPaint paint; + paint.setColor(DlColor::kMagenta()); + + SkRRect rrect = SkRRect::MakeRectXY( + SkRect::MakeLTRB(0, 110, GetWindowSize().width, 210), 10, 10); + builder.DrawRRect(rrect, paint); + builder.ClipRect(SkRect::MakeLTRB(0, 50, GetWindowSize().width, 150)); + + DlPaint save_paint; + save_paint.setBlendMode(DlBlendMode::kSrc); + save_paint.setImageFilter( + DlBlurImageFilter::Make(20, 20, DlTileMode::kClamp)); + builder.SaveLayer(nullptr, &save_paint); + + builder.Restore(); + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +TEST_P(AiksTest, GaussianBlurAnimatedBackdrop) { + // This test is for checking out how stable rendering is when content is + // translated underneath a blur. Animating under a blur can cause + // *shimmering* to happen as a result of pixel alignment. + // See also: https://github.com/flutter/flutter/issues/140193 + auto boston = + CreateTextureForFixture("boston.jpg", /*enable_mipmapping=*/true); + ASSERT_TRUE(boston); + int64_t count = 0; + Scalar sigma = 20.0; + Scalar freq = 0.1; + Scalar amp = 50.0; + auto callback = [&]() -> sk_sp { + if (AiksTest::ImGuiBegin("Controls", nullptr, + ImGuiWindowFlags_AlwaysAutoResize)) { + ImGui::SliderFloat("Sigma", &sigma, 0, 200); + ImGui::SliderFloat("Frequency", &freq, 0.01, 2.0); + ImGui::SliderFloat("Amplitude", &, 1, 100); + ImGui::End(); + } + + DisplayListBuilder builder; + builder.Scale(GetContentScale().x, GetContentScale().y); + Scalar y = amp * sin(freq * 2.0 * M_PI * count / 60); + builder.DrawImage( + DlImageImpeller::Make(boston), + SkPoint::Make(1024 / 2 - boston->GetSize().width / 2, + (768 / 2 - boston->GetSize().height / 2) + y), + DlImageSampling::kMipmapLinear); + static PlaygroundPoint point_a(Point(100, 100), 20, Color::Red()); + static PlaygroundPoint point_b(Point(900, 700), 20, Color::Red()); + auto [handle_a, handle_b] = DrawPlaygroundLine(point_a, point_b); + + builder.ClipRect( + SkRect::MakeLTRB(handle_a.x, handle_a.y, handle_b.x, handle_b.y)); + builder.ClipRect(SkRect::MakeLTRB(100, 100, 900, 700)); + + DlPaint paint; + paint.setBlendMode(DlBlendMode::kSrc); + paint.setImageFilter( + DlBlurImageFilter::Make(sigma, sigma, DlTileMode::kClamp)); + builder.SaveLayer(nullptr, &paint); + count += 1; + return builder.Build(); + }; + ASSERT_TRUE(OpenPlaygroundHere(callback)); +} + +TEST_P(AiksTest, GaussianBlurStyleInnerGradient) { + DisplayListBuilder builder; + + builder.Scale(GetContentScale().x, GetContentScale().y); + + DlPaint paint; + paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1.0)); + builder.DrawPaint(paint); + + std::vector colors = {DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0), + DlColor::RGBA(0.7568, 0.2627, 0.2118, 1.0)}; + std::vector stops = {0.0, 1.0}; + + paint = DlPaint{}; + paint.setColorSource(DlColorSource::MakeLinear( + /*start_point=*/{0, 0}, + /*end_point=*/{200, 200}, + /*stop_count=*/colors.size(), + /*colors=*/colors.data(), + /*stops=*/stops.data(), + /*tile_mode=*/DlTileMode::kMirror)); + paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kInner, 30)); + + SkPath path; + path.moveTo(200, 200); + path.lineTo(300, 400); + path.lineTo(100, 400); + path.close(); + builder.DrawPath(path, paint); + + // Draw another thing to make sure the clip area is reset. + DlPaint red; + red.setColor(DlColor::kRed()); + builder.DrawRect(SkRect::MakeXYWH(0, 0, 200, 200), red); + + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +TEST_P(AiksTest, GaussianBlurStyleSolidGradient) { + DisplayListBuilder builder; + builder.Scale(GetContentScale().x, GetContentScale().y); + + DlPaint paint; + paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1.0)); + builder.DrawPaint(paint); + + std::vector colors = {DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0), + DlColor::RGBA(0.7568, 0.2627, 0.2118, 1.0)}; + std::vector stops = {0.0, 1.0}; + + paint = DlPaint{}; + paint.setColorSource(DlColorSource::MakeLinear( + /*start_point=*/{0, 0}, + /*end_point=*/{200, 200}, + /*stop_count=*/colors.size(), + /*colors=*/colors.data(), + /*stops=*/stops.data(), + /*tile_mode=*/DlTileMode::kMirror)); + paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kSolid, 30)); + + SkPath path; + path.moveTo(200, 200); + path.lineTo(300, 400); + path.lineTo(100, 400); + path.close(); + builder.DrawPath(path, paint); + + // Draw another thing to make sure the clip area is reset. + DlPaint red; + red.setColor(DlColor::kRed()); + builder.DrawRect(SkRect::MakeXYWH(0, 0, 200, 200), red); +} + +TEST_P(AiksTest, GaussianBlurStyleOuterGradient) { + DisplayListBuilder builder; + builder.Scale(GetContentScale().x, GetContentScale().y); + + DlPaint paint; + paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1.0)); + builder.DrawPaint(paint); + + std::vector colors = {DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0), + DlColor::RGBA(0.7568, 0.2627, 0.2118, 1.0)}; + std::vector stops = {0.0, 1.0}; + + paint = DlPaint{}; + paint.setColorSource(DlColorSource::MakeLinear( + /*start_point=*/{0, 0}, + /*end_point=*/{200, 200}, + /*stop_count=*/colors.size(), + /*colors=*/colors.data(), + /*stops=*/stops.data(), + /*tile_mode=*/DlTileMode::kMirror)); + paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kOuter, 30)); + + SkPath path; + path.moveTo(200, 200); + path.lineTo(300, 400); + path.lineTo(100, 400); + path.close(); + builder.DrawPath(path, paint); + + // Draw another thing to make sure the clip area is reset. + DlPaint red; + red.setColor(DlColor::kRed()); + builder.DrawRect(SkRect::MakeXYWH(0, 0, 200, 200), red); +} + } // namespace testing } // namespace impeller diff --git a/testing/impeller_golden_tests_output.txt b/testing/impeller_golden_tests_output.txt index 8feb287d4003c..568b9d445f3a5 100644 --- a/testing/impeller_golden_tests_output.txt +++ b/testing/impeller_golden_tests_output.txt @@ -696,9 +696,6 @@ impeller_Play_AiksTest_GaussianBlurWithoutDecalSupport_Metal.png impeller_Play_AiksTest_GradientStrokesRenderCorrectly_Metal.png impeller_Play_AiksTest_GradientStrokesRenderCorrectly_OpenGLES.png impeller_Play_AiksTest_GradientStrokesRenderCorrectly_Vulkan.png -impeller_Play_AiksTest_GuassianBlurUpdatesMipmapContents_Metal.png -impeller_Play_AiksTest_GuassianBlurUpdatesMipmapContents_OpenGLES.png -impeller_Play_AiksTest_GuassianBlurUpdatesMipmapContents_Vulkan.png impeller_Play_AiksTest_ImageColorSourceEffectTransform_Metal.png impeller_Play_AiksTest_ImageColorSourceEffectTransform_OpenGLES.png impeller_Play_AiksTest_ImageColorSourceEffectTransform_Vulkan.png From 8936b8705c7fd81eadd59f4391f00e6b82bd3868 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 12 Aug 2024 19:10:26 -0700 Subject: [PATCH 04/15] ++ --- impeller/aiks/aiks_blur_unittests.cc | 73 --------------- .../display_list/aiks_dl_blur_unittests.cc | 91 +++++++++++++++++++ 2 files changed, 91 insertions(+), 73 deletions(-) diff --git a/impeller/aiks/aiks_blur_unittests.cc b/impeller/aiks/aiks_blur_unittests.cc index 800d96e285162..878347ea0533f 100644 --- a/impeller/aiks/aiks_blur_unittests.cc +++ b/impeller/aiks/aiks_blur_unittests.cc @@ -165,79 +165,6 @@ TEST_P(AiksTest, GaussianBlurRotatedAndClipped) { ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); } -TEST_P(AiksTest, GaussianBlurScaledAndClipped) { - Canvas canvas; - std::shared_ptr boston = CreateTextureForFixture("boston.jpg"); - Rect bounds = - Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height); - Vector2 image_center = Vector2(bounds.GetSize() / 2); - Paint paint = {.image_filter = - ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0), - FilterContents::BlurStyle::kNormal, - Entity::TileMode::kDecal)}; - Vector2 clip_size = {150, 75}; - Vector2 center = Vector2(1024, 768) / 2; - canvas.Scale(GetContentScale()); - canvas.ClipRect( - Rect::MakeLTRB(center.x, center.y, center.x, center.y).Expand(clip_size)); - canvas.Translate({center.x, center.y, 0}); - canvas.Scale({0.6, 0.6, 1}); - - canvas.DrawImageRect(std::make_shared(boston), /*source=*/bounds, - /*dest=*/bounds.Shift(-image_center), paint); - - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -TEST_P(AiksTest, GaussianBlurRotatedAndClippedInteractive) { - std::shared_ptr boston = CreateTextureForFixture("boston.jpg"); - - auto callback = [&](AiksContext& renderer) -> std::optional { - const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"}; - const Entity::TileMode tile_modes[] = { - Entity::TileMode::kClamp, Entity::TileMode::kRepeat, - Entity::TileMode::kMirror, Entity::TileMode::kDecal}; - - static float rotation = 0; - static float scale = 0.6; - static int selected_tile_mode = 3; - - if (AiksTest::ImGuiBegin("Controls", nullptr, - ImGuiWindowFlags_AlwaysAutoResize)) { - ImGui::SliderFloat("Rotation (degrees)", &rotation, -180, 180); - ImGui::SliderFloat("Scale", &scale, 0, 2.0); - ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names, - sizeof(tile_mode_names) / sizeof(char*)); - ImGui::End(); - } - - Canvas canvas; - Rect bounds = - Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height); - Vector2 image_center = Vector2(bounds.GetSize() / 2); - Paint paint = {.image_filter = - ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0), - FilterContents::BlurStyle::kNormal, - tile_modes[selected_tile_mode])}; - static PlaygroundPoint point_a(Point(362, 309), 20, Color::Red()); - static PlaygroundPoint point_b(Point(662, 459), 20, Color::Red()); - auto [handle_a, handle_b] = DrawPlaygroundLine(point_a, point_b); - Vector2 center = Vector2(1024, 768) / 2; - canvas.Scale(GetContentScale()); - canvas.ClipRect( - Rect::MakeLTRB(handle_a.x, handle_a.y, handle_b.x, handle_b.y)); - canvas.Translate({center.x, center.y, 0}); - canvas.Scale({scale, scale, 1}); - canvas.Rotate(Degrees(rotation)); - - canvas.DrawImageRect(std::make_shared(boston), /*source=*/bounds, - /*dest=*/bounds.Shift(-image_center), paint); - return canvas.EndRecordingAsPicture(); - }; - - ASSERT_TRUE(OpenPlaygroundHere(callback)); -} - TEST_P(AiksTest, GaussianBlurRotatedNonUniform) { auto callback = [&](AiksContext& renderer) -> std::optional { const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"}; diff --git a/impeller/display_list/aiks_dl_blur_unittests.cc b/impeller/display_list/aiks_dl_blur_unittests.cc index 7b59a342fb6c6..da8e701f76cf4 100644 --- a/impeller/display_list/aiks_dl_blur_unittests.cc +++ b/impeller/display_list/aiks_dl_blur_unittests.cc @@ -18,6 +18,7 @@ #include "impeller/display_list/dl_image_impeller.h" #include "impeller/playground/widgets.h" #include "include/core/SkRRect.h" +#include "include/core/SkRect.h" #include "third_party/imgui/imgui.h" //////////////////////////////////////////////////////////////////////////////// @@ -739,6 +740,7 @@ TEST_P(AiksTest, GaussianBlurStyleSolidGradient) { DlPaint red; red.setColor(DlColor::kRed()); builder.DrawRect(SkRect::MakeXYWH(0, 0, 200, 200), red); + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); } TEST_P(AiksTest, GaussianBlurStyleOuterGradient) { @@ -774,6 +776,95 @@ TEST_P(AiksTest, GaussianBlurStyleOuterGradient) { DlPaint red; red.setColor(DlColor::kRed()); builder.DrawRect(SkRect::MakeXYWH(0, 0, 200, 200), red); + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +TEST_P(AiksTest, GaussianBlurScaledAndClipped) { + DisplayListBuilder builder; + std::shared_ptr boston = CreateTextureForFixture("boston.jpg"); + Rect bounds = + Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height); + Vector2 image_center = Vector2(bounds.GetSize() / 2); + + DlPaint paint; + paint.setImageFilter(DlBlurImageFilter::Make(20, 20, DlTileMode::kDecal)); + + Vector2 clip_size = {150, 75}; + Vector2 center = Vector2(1024, 768) / 2; + builder.Scale(GetContentScale().x, GetContentScale().y); + + auto rect = + Rect::MakeLTRB(center.x, center.y, center.x, center.y).Expand(clip_size); + builder.ClipRect(SkRect::MakeLTRB(rect.GetLeft(), rect.GetTop(), + rect.GetRight(), rect.GetBottom())); + builder.Translate(center.x, center.y); + builder.Scale(0.6, 0.6); + + SkRect sk_bounds = SkRect::MakeLTRB(bounds.GetLeft(), bounds.GetTop(), + bounds.GetRight(), bounds.GetBottom()); + Rect dest = bounds.Shift(-image_center); + SkRect sk_dst = SkRect::MakeLTRB(dest.GetLeft(), dest.GetTop(), + dest.GetRight(), dest.GetBottom()); + builder.DrawImageRect(DlImageImpeller::Make(boston), /*source=*/sk_bounds, + /*dst=*/sk_dst, DlImageSampling::kNearestNeighbor, + &paint); + + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +TEST_P(AiksTest, GaussianBlurRotatedAndClippedInteractive) { + std::shared_ptr boston = CreateTextureForFixture("boston.jpg"); + + auto callback = [&]() -> sk_sp { + const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"}; + const DlTileMode tile_modes[] = {DlTileMode::kClamp, DlTileMode::kRepeat, + DlTileMode::kMirror, DlTileMode::kDecal}; + + static float rotation = 0; + static float scale = 0.6; + static int selected_tile_mode = 3; + + if (AiksTest::ImGuiBegin("Controls", nullptr, + ImGuiWindowFlags_AlwaysAutoResize)) { + ImGui::SliderFloat("Rotation (degrees)", &rotation, -180, 180); + ImGui::SliderFloat("Scale", &scale, 0, 2.0); + ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names, + sizeof(tile_mode_names) / sizeof(char*)); + ImGui::End(); + } + + DisplayListBuilder builder; + Rect bounds = + Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height); + Vector2 image_center = Vector2(bounds.GetSize() / 2); + DlPaint paint; + paint.setImageFilter( + DlBlurImageFilter::Make(20, 20, tile_modes[selected_tile_mode])); + + static PlaygroundPoint point_a(Point(362, 309), 20, Color::Red()); + static PlaygroundPoint point_b(Point(662, 459), 20, Color::Red()); + auto [handle_a, handle_b] = DrawPlaygroundLine(point_a, point_b); + Vector2 center = Vector2(1024, 768) / 2; + + builder.Scale(GetContentScale().x, GetContentScale().y); + builder.ClipRect( + SkRect::MakeLTRB(handle_a.x, handle_a.y, handle_b.x, handle_b.y)); + builder.Translate(center.x, center.y); + builder.Scale(scale, scale); + builder.Rotate(rotation); + + SkRect sk_bounds = SkRect::MakeLTRB(bounds.GetLeft(), bounds.GetTop(), + bounds.GetRight(), bounds.GetBottom()); + Rect dest = bounds.Shift(-image_center); + SkRect sk_dst = SkRect::MakeLTRB(dest.GetLeft(), dest.GetTop(), + dest.GetRight(), dest.GetBottom()); + builder.DrawImageRect(DlImageImpeller::Make(boston), /*source=*/sk_bounds, + /*dst=*/sk_dst, DlImageSampling::kNearestNeighbor, + &paint); + return builder.Build(); + }; + + ASSERT_TRUE(OpenPlaygroundHere(callback)); } } // namespace testing From 4e6b98cd3cc3c763209cac6c89b25ebbdf9e0e1f Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Mon, 12 Aug 2024 21:33:56 -0700 Subject: [PATCH 05/15] Update dl_color.h --- display_list/dl_color.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/display_list/dl_color.h b/display_list/dl_color.h index bc9f8787d6dd5..be13257740a56 100644 --- a/display_list/dl_color.h +++ b/display_list/dl_color.h @@ -55,7 +55,7 @@ struct DlColor { static constexpr DlColor kFuchsia() {return DlColor(0xFFFF00FF);}; static constexpr DlColor kMaroon() {return DlColor(0xFF800000);}; static constexpr DlColor kSkyBlue() {return DlColor(0xFF87CEEB);}; - static constexpr DlColor kCornflowerBlue() {return DlColor(0xFFFF5733);}; + static constexpr DlColor kCornflowerBlue() {return DlColor(0xFF6495ED);}; static constexpr DlColor kCrimson() {return DlColor(0xFFFF5733);}; static constexpr DlColor kAqua() {return DlColor(0xFF00FFFF);}; static constexpr DlColor kOrange() {return DlColor(0xFFFFA500);}; From 1576e982c1612afaaa5df00d9dd4a7b1e43ce8be Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Tue, 13 Aug 2024 07:48:39 -0700 Subject: [PATCH 06/15] ++ --- impeller/display_list/aiks_dl_blur_unittests.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/impeller/display_list/aiks_dl_blur_unittests.cc b/impeller/display_list/aiks_dl_blur_unittests.cc index da8e701f76cf4..de66722f22ddd 100644 --- a/impeller/display_list/aiks_dl_blur_unittests.cc +++ b/impeller/display_list/aiks_dl_blur_unittests.cc @@ -805,7 +805,7 @@ TEST_P(AiksTest, GaussianBlurScaledAndClipped) { Rect dest = bounds.Shift(-image_center); SkRect sk_dst = SkRect::MakeLTRB(dest.GetLeft(), dest.GetTop(), dest.GetRight(), dest.GetBottom()); - builder.DrawImageRect(DlImageImpeller::Make(boston), /*source=*/sk_bounds, + builder.DrawImageRect(DlImageImpeller::Make(boston), /*src=*/sk_bounds, /*dst=*/sk_dst, DlImageSampling::kNearestNeighbor, &paint); @@ -858,7 +858,7 @@ TEST_P(AiksTest, GaussianBlurRotatedAndClippedInteractive) { Rect dest = bounds.Shift(-image_center); SkRect sk_dst = SkRect::MakeLTRB(dest.GetLeft(), dest.GetTop(), dest.GetRight(), dest.GetBottom()); - builder.DrawImageRect(DlImageImpeller::Make(boston), /*source=*/sk_bounds, + builder.DrawImageRect(DlImageImpeller::Make(boston), /*src=*/sk_bounds, /*dst=*/sk_dst, DlImageSampling::kNearestNeighbor, &paint); return builder.Build(); From eb9bbb32448389836960c9ea43f52a1d04711086 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Tue, 13 Aug 2024 07:53:14 -0700 Subject: [PATCH 07/15] ++ --- impeller/display_list/aiks_dl_blur_unittests.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/impeller/display_list/aiks_dl_blur_unittests.cc b/impeller/display_list/aiks_dl_blur_unittests.cc index de66722f22ddd..6cb3455e709b8 100644 --- a/impeller/display_list/aiks_dl_blur_unittests.cc +++ b/impeller/display_list/aiks_dl_blur_unittests.cc @@ -76,6 +76,7 @@ TEST_P(AiksTest, CanRenderForegroundAdvancedBlendWithMaskBlur) { Sigma sigma = Radius(20); paint.setMaskFilter( DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma.sigma)); + paint.setColorFilter(DlBlendColorFilter::Make(DlColor::kGreen(), DlBlendMode::kColor)); builder.DrawCircle({400, 400}, 200, paint); builder.Restore(); From 85e42bcce58ed5dfd0e89aa21d3eb7cdbe53dd08 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Tue, 13 Aug 2024 07:55:26 -0700 Subject: [PATCH 08/15] ++ --- impeller/display_list/aiks_dl_blur_unittests.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/impeller/display_list/aiks_dl_blur_unittests.cc b/impeller/display_list/aiks_dl_blur_unittests.cc index 6cb3455e709b8..e69425eeeded7 100644 --- a/impeller/display_list/aiks_dl_blur_unittests.cc +++ b/impeller/display_list/aiks_dl_blur_unittests.cc @@ -76,7 +76,8 @@ TEST_P(AiksTest, CanRenderForegroundAdvancedBlendWithMaskBlur) { Sigma sigma = Radius(20); paint.setMaskFilter( DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma.sigma)); - paint.setColorFilter(DlBlendColorFilter::Make(DlColor::kGreen(), DlBlendMode::kColor)); + paint.setColorFilter( + DlBlendColorFilter::Make(DlColor::kGreen(), DlBlendMode::kColor)); builder.DrawCircle({400, 400}, 200, paint); builder.Restore(); From 173a1e4a9479db2244d4ff6ee43fbf2829703e31 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Tue, 13 Aug 2024 10:11:44 -0700 Subject: [PATCH 09/15] ++ --- .../display_list/aiks_dl_blur_unittests.cc | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/impeller/display_list/aiks_dl_blur_unittests.cc b/impeller/display_list/aiks_dl_blur_unittests.cc index e69425eeeded7..14b6e572096d1 100644 --- a/impeller/display_list/aiks_dl_blur_unittests.cc +++ b/impeller/display_list/aiks_dl_blur_unittests.cc @@ -554,8 +554,8 @@ TEST_P(AiksTest, MaskBlurDoesntStretchContents) { SkMatrix::Scale(0.5, 0.5)); paint.setColorSource(std::make_shared( - DlImageImpeller::Make(boston), DlTileMode::kRepeat, - DlTileMode::kRepeat)); + DlImageImpeller::Make(boston), DlTileMode::kRepeat, DlTileMode::kRepeat, + DlImageSampling::kMipmapLinear)); paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma)); builder.DrawRect(SkRect::MakeXYWH(0, 0, boston->GetSize().width, @@ -586,9 +586,10 @@ TEST_P(AiksTest, GaussianBlurAtPeripheryVertical) { DlPaint save_paint; save_paint.setBlendMode(DlBlendMode::kSrc); - save_paint.setImageFilter( - DlBlurImageFilter::Make(20, 20, DlTileMode::kClamp)); - builder.SaveLayer(nullptr, &save_paint); + + auto backdrop_filter = DlBlurImageFilter::Make(20, 20, DlTileMode::kClamp); + + builder.SaveLayer(nullptr, &save_paint, backdrop_filter.get()); builder.Restore(); ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); @@ -615,9 +616,9 @@ TEST_P(AiksTest, GaussianBlurAtPeripheryHorizontal) { DlPaint save_paint; save_paint.setBlendMode(DlBlendMode::kSrc); - save_paint.setImageFilter( - DlBlurImageFilter::Make(20, 20, DlTileMode::kClamp)); - builder.SaveLayer(nullptr, &save_paint); + + auto backdrop_filter = DlBlurImageFilter::Make(20, 20, DlTileMode::kClamp); + builder.SaveLayer(nullptr, &save_paint, backdrop_filter.get()); builder.Restore(); ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); @@ -662,9 +663,10 @@ TEST_P(AiksTest, GaussianBlurAnimatedBackdrop) { DlPaint paint; paint.setBlendMode(DlBlendMode::kSrc); - paint.setImageFilter( - DlBlurImageFilter::Make(sigma, sigma, DlTileMode::kClamp)); - builder.SaveLayer(nullptr, &paint); + + auto backdrop_filter = + DlBlurImageFilter::Make(sigma, sigma, DlTileMode::kClamp); + builder.SaveLayer(nullptr, &paint, backdrop_filter.get()); count += 1; return builder.Build(); }; From 23d11874037bebd450d3881bcb5236d41d1a80d9 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Tue, 13 Aug 2024 10:27:51 -0700 Subject: [PATCH 10/15] migrate even more tests. --- impeller/aiks/aiks_blur_unittests.cc | 83 --------------- .../display_list/aiks_dl_blur_unittests.cc | 100 ++++++++++++++++++ 2 files changed, 100 insertions(+), 83 deletions(-) diff --git a/impeller/aiks/aiks_blur_unittests.cc b/impeller/aiks/aiks_blur_unittests.cc index 878347ea0533f..640d8281ec5dd 100644 --- a/impeller/aiks/aiks_blur_unittests.cc +++ b/impeller/aiks/aiks_blur_unittests.cc @@ -121,89 +121,6 @@ TEST_P(AiksTest, GaussianBlurWithoutDecalSupport) { ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); } -TEST_P(AiksTest, GaussianBlurOneDimension) { - Canvas canvas; - - canvas.Scale(GetContentScale()); - canvas.Scale({0.5, 0.5, 1.0}); - std::shared_ptr boston = CreateTextureForFixture("boston.jpg"); - canvas.DrawImage(std::make_shared(boston), Point(100, 100), Paint{}); - canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt, - ImageFilter::MakeBlur(Sigma(50.0), Sigma(0.0), - FilterContents::BlurStyle::kNormal, - Entity::TileMode::kClamp)); - canvas.Restore(); - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -// Smoketest to catch issues with the coverage hint. -// Draws a rotated blurred image within a rectangle clip. The center of the clip -// rectangle is the center of the rotated image. The entire area of the clip -// rectangle should be filled with opaque colors output by the blur. -TEST_P(AiksTest, GaussianBlurRotatedAndClipped) { - Canvas canvas; - std::shared_ptr boston = CreateTextureForFixture("boston.jpg"); - Rect bounds = - Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height); - Vector2 image_center = Vector2(bounds.GetSize() / 2); - Paint paint = {.image_filter = - ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0), - FilterContents::BlurStyle::kNormal, - Entity::TileMode::kDecal)}; - Vector2 clip_size = {150, 75}; - Vector2 center = Vector2(1024, 768) / 2; - canvas.Scale(GetContentScale()); - canvas.ClipRect( - Rect::MakeLTRB(center.x, center.y, center.x, center.y).Expand(clip_size)); - canvas.Translate({center.x, center.y, 0}); - canvas.Scale({0.6, 0.6, 1}); - canvas.Rotate(Degrees(25)); - - canvas.DrawImageRect(std::make_shared(boston), /*source=*/bounds, - /*dest=*/bounds.Shift(-image_center), paint); - - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -TEST_P(AiksTest, GaussianBlurRotatedNonUniform) { - auto callback = [&](AiksContext& renderer) -> std::optional { - const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"}; - const Entity::TileMode tile_modes[] = { - Entity::TileMode::kClamp, Entity::TileMode::kRepeat, - Entity::TileMode::kMirror, Entity::TileMode::kDecal}; - - static float rotation = 45; - static float scale = 0.6; - static int selected_tile_mode = 3; - - if (AiksTest::ImGuiBegin("Controls", nullptr, - ImGuiWindowFlags_AlwaysAutoResize)) { - ImGui::SliderFloat("Rotation (degrees)", &rotation, -180, 180); - ImGui::SliderFloat("Scale", &scale, 0, 2.0); - ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names, - sizeof(tile_mode_names) / sizeof(char*)); - ImGui::End(); - } - - Canvas canvas; - Paint paint = {.color = Color::Green(), - .image_filter = - ImageFilter::MakeBlur(Sigma(50.0), Sigma(0.0), - FilterContents::BlurStyle::kNormal, - tile_modes[selected_tile_mode])}; - Vector2 center = Vector2(1024, 768) / 2; - canvas.Scale(GetContentScale()); - canvas.Translate({center.x, center.y, 0}); - canvas.Scale({scale, scale, 1}); - canvas.Rotate(Degrees(rotation)); - - canvas.DrawRRect(Rect::MakeXYWH(-100, -100, 200, 200), Size(10, 10), paint); - return canvas.EndRecordingAsPicture(); - }; - - ASSERT_TRUE(OpenPlaygroundHere(callback)); -} - // This addresses a bug where tiny blurs could result in mip maps that beyond // the limits for the textures used for blurring. // See also: b/323402168 diff --git a/impeller/display_list/aiks_dl_blur_unittests.cc b/impeller/display_list/aiks_dl_blur_unittests.cc index 14b6e572096d1..03e3370a4ee77 100644 --- a/impeller/display_list/aiks_dl_blur_unittests.cc +++ b/impeller/display_list/aiks_dl_blur_unittests.cc @@ -871,5 +871,105 @@ TEST_P(AiksTest, GaussianBlurRotatedAndClippedInteractive) { ASSERT_TRUE(OpenPlaygroundHere(callback)); } +TEST_P(AiksTest, GaussianBlurOneDimension) { + DisplayListBuilder builder; + + builder.Scale(GetContentScale().x, GetContentScale().y); + builder.Scale(0.5, 0.5); + + std::shared_ptr boston = CreateTextureForFixture("boston.jpg"); + builder.DrawImage(DlImageImpeller::Make(boston), {100, 100}, {}); + + DlPaint paint; + paint.setBlendMode(DlBlendMode::kSrc); + + auto backdrop_filter = DlBlurImageFilter::Make(50, 0, DlTileMode::kClamp); + builder.SaveLayer(nullptr, &paint, backdrop_filter.get()); + builder.Restore(); + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +// Smoketest to catch issues with the coverage hint. +// Draws a rotated blurred image within a rectangle clip. The center of the clip +// rectangle is the center of the rotated image. The entire area of the clip +// rectangle should be filled with opaque colors output by the blur. +TEST_P(AiksTest, GaussianBlurRotatedAndClipped) { + DisplayListBuilder builder; + + std::shared_ptr boston = CreateTextureForFixture("boston.jpg"); + Rect bounds = + Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height); + + DlPaint paint; + paint.setImageFilter(DlBlurImageFilter::Make(20, 20, DlTileMode::kDecal)); + + Vector2 image_center = Vector2(bounds.GetSize() / 2); + Vector2 clip_size = {150, 75}; + Vector2 center = Vector2(1024, 768) / 2; + builder.Scale(GetContentScale().x, GetContentScale().y); + + auto clip_bounds = + Rect::MakeLTRB(center.x, center.y, center.x, center.y).Expand(clip_size); + builder.ClipRect(SkRect::MakeLTRB(clip_bounds.GetLeft(), clip_bounds.GetTop(), + clip_bounds.GetRight(), + clip_bounds.GetBottom())); + builder.Translate(center.x, center.y); + builder.Scale(0.6, 0.6); + builder.Rotate(25); + + auto dst_rect = bounds.Shift(-image_center); + builder.DrawImageRect( + DlImageImpeller::Make(boston), /*src=*/ + SkRect::MakeLTRB(bounds.GetLeft(), bounds.GetTop(), bounds.GetRight(), + bounds.GetBottom()), + /*dst=*/ + SkRect::MakeLTRB(dst_rect.GetLeft(), dst_rect.GetTop(), + dst_rect.GetRight(), dst_rect.GetBottom()), + DlImageSampling::kMipmapLinear, &paint); + + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +TEST_P(AiksTest, GaussianBlurRotatedNonUniform) { + auto callback = [&]() -> sk_sp { + const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"}; + const DlTileMode tile_modes[] = {DlTileMode::kClamp, DlTileMode::kRepeat, + DlTileMode::kMirror, DlTileMode::kDecal}; + + static float rotation = 45; + static float scale = 0.6; + static int selected_tile_mode = 3; + + if (AiksTest::ImGuiBegin("Controls", nullptr, + ImGuiWindowFlags_AlwaysAutoResize)) { + ImGui::SliderFloat("Rotation (degrees)", &rotation, -180, 180); + ImGui::SliderFloat("Scale", &scale, 0, 2.0); + ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names, + sizeof(tile_mode_names) / sizeof(char*)); + ImGui::End(); + } + + DisplayListBuilder builder; + + DlPaint paint; + paint.setColor(DlColor::kGreen()); + paint.setImageFilter( + DlBlurImageFilter::Make(50, 50, tile_modes[selected_tile_mode])); + + Vector2 center = Vector2(1024, 768) / 2; + builder.Scale(GetContentScale().x, GetContentScale().y); + builder.Translate(center.x, center.y); + builder.Scale(scale, scale); + builder.Rotate(rotation); + + SkRRect rrect = + SkRRect::MakeRectXY(SkRect::MakeXYWH(-100, -100, 200, 200), 10, 10); + builder.DrawRRect(rrect, paint); + return builder.Build(); + }; + + ASSERT_TRUE(OpenPlaygroundHere(callback)); +} + } // namespace testing } // namespace impeller From c4793446369df29df81c889e698ae7eba4fa5345 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Tue, 13 Aug 2024 10:49:03 -0700 Subject: [PATCH 11/15] ++ --- .../display_list/aiks_dl_blur_unittests.cc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/impeller/display_list/aiks_dl_blur_unittests.cc b/impeller/display_list/aiks_dl_blur_unittests.cc index 03e3370a4ee77..a6d23a26de4a3 100644 --- a/impeller/display_list/aiks_dl_blur_unittests.cc +++ b/impeller/display_list/aiks_dl_blur_unittests.cc @@ -52,9 +52,9 @@ TEST_P(AiksTest, CanRenderForegroundBlendWithMaskBlur) { DlPaint paint; paint.setColor(DlColor::kWhite()); - Sigma sigma = Radius(20); + Scalar sigma = 1 + (20) / 2; paint.setMaskFilter( - DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma.sigma)); + DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma)); paint.setColorFilter( DlBlendColorFilter::Make(DlColor::kGreen(), DlBlendMode::kSrc)); builder.DrawCircle({400, 400}, 200, paint); @@ -73,9 +73,9 @@ TEST_P(AiksTest, CanRenderForegroundAdvancedBlendWithMaskBlur) { paint.setColor( DlColor::RGBA(128.0f / 255.0f, 128.0f / 255.0f, 128.0f / 255.0f, 1.0f)); - Sigma sigma = Radius(20); + Scalar sigma = 1 + 20 / 2; paint.setMaskFilter( - DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma.sigma)); + DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma)); paint.setColorFilter( DlBlendColorFilter::Make(DlColor::kGreen(), DlBlendMode::kColor)); builder.DrawCircle({400, 400}, 200, paint); @@ -192,9 +192,9 @@ TEST_P(AiksTest, ClippedBlurFilterRendersCorrectlyInteractive) { builder.Translate(location.x, location.y); DlPaint paint; - Sigma sigma = Radius(120 * 3); + Scalar sigma = 1 + (120 * 3) / 2; paint.setMaskFilter( - DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma.sigma)); + DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma)); paint.setColor(DlColor::kRed()); SkPath path = SkPath::Rect(SkRect::MakeLTRB(0, 0, 800, 800)); @@ -208,9 +208,9 @@ TEST_P(AiksTest, ClippedBlurFilterRendersCorrectly) { DisplayListBuilder builder; builder.Translate(0, -400); DlPaint paint; - Sigma sigma = Radius(120 * 3); + Scalar sigma = 1 + (120 * 3) / 2; paint.setMaskFilter( - DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma.sigma)); + DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma)); paint.setColor(DlColor::kRed()); SkPath path = SkPath::Rect(SkRect::MakeLTRB(0, 0, 800, 800)); @@ -954,7 +954,7 @@ TEST_P(AiksTest, GaussianBlurRotatedNonUniform) { DlPaint paint; paint.setColor(DlColor::kGreen()); paint.setImageFilter( - DlBlurImageFilter::Make(50, 50, tile_modes[selected_tile_mode])); + DlBlurImageFilter::Make(50, 0, tile_modes[selected_tile_mode])); Vector2 center = Vector2(1024, 768) / 2; builder.Scale(GetContentScale().x, GetContentScale().y); From ab97fbe6c414181de29702521f8b10fce20cbd88 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Tue, 13 Aug 2024 10:50:09 -0700 Subject: [PATCH 12/15] ++ --- impeller/display_list/aiks_dl_blur_unittests.cc | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/impeller/display_list/aiks_dl_blur_unittests.cc b/impeller/display_list/aiks_dl_blur_unittests.cc index a6d23a26de4a3..403b88285bec7 100644 --- a/impeller/display_list/aiks_dl_blur_unittests.cc +++ b/impeller/display_list/aiks_dl_blur_unittests.cc @@ -53,8 +53,7 @@ TEST_P(AiksTest, CanRenderForegroundBlendWithMaskBlur) { paint.setColor(DlColor::kWhite()); Scalar sigma = 1 + (20) / 2; - paint.setMaskFilter( - DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma)); + paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma)); paint.setColorFilter( DlBlendColorFilter::Make(DlColor::kGreen(), DlBlendMode::kSrc)); builder.DrawCircle({400, 400}, 200, paint); @@ -74,8 +73,7 @@ TEST_P(AiksTest, CanRenderForegroundAdvancedBlendWithMaskBlur) { DlColor::RGBA(128.0f / 255.0f, 128.0f / 255.0f, 128.0f / 255.0f, 1.0f)); Scalar sigma = 1 + 20 / 2; - paint.setMaskFilter( - DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma)); + paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma)); paint.setColorFilter( DlBlendColorFilter::Make(DlColor::kGreen(), DlBlendMode::kColor)); builder.DrawCircle({400, 400}, 200, paint); @@ -193,8 +191,7 @@ TEST_P(AiksTest, ClippedBlurFilterRendersCorrectlyInteractive) { DlPaint paint; Scalar sigma = 1 + (120 * 3) / 2; - paint.setMaskFilter( - DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma)); + paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma)); paint.setColor(DlColor::kRed()); SkPath path = SkPath::Rect(SkRect::MakeLTRB(0, 0, 800, 800)); @@ -209,8 +206,7 @@ TEST_P(AiksTest, ClippedBlurFilterRendersCorrectly) { builder.Translate(0, -400); DlPaint paint; Scalar sigma = 1 + (120 * 3) / 2; - paint.setMaskFilter( - DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma)); + paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma)); paint.setColor(DlColor::kRed()); SkPath path = SkPath::Rect(SkRect::MakeLTRB(0, 0, 800, 800)); From 9f5cd2c1cc371119f88b2cc5a5fe4987dd6f8bce Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Wed, 14 Aug 2024 17:33:20 -0700 Subject: [PATCH 13/15] adjustments. --- .../display_list/aiks_dl_blur_unittests.cc | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/impeller/display_list/aiks_dl_blur_unittests.cc b/impeller/display_list/aiks_dl_blur_unittests.cc index 403b88285bec7..0319bba01ddba 100644 --- a/impeller/display_list/aiks_dl_blur_unittests.cc +++ b/impeller/display_list/aiks_dl_blur_unittests.cc @@ -52,12 +52,12 @@ TEST_P(AiksTest, CanRenderForegroundBlendWithMaskBlur) { DlPaint paint; paint.setColor(DlColor::kWhite()); - Scalar sigma = 1 + (20) / 2; - paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma)); + Sigma sigma = Radius(20); + paint.setMaskFilter( + DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma.sigma)); paint.setColorFilter( DlBlendColorFilter::Make(DlColor::kGreen(), DlBlendMode::kSrc)); builder.DrawCircle({400, 400}, 200, paint); - builder.Restore(); ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); } @@ -72,8 +72,9 @@ TEST_P(AiksTest, CanRenderForegroundAdvancedBlendWithMaskBlur) { paint.setColor( DlColor::RGBA(128.0f / 255.0f, 128.0f / 255.0f, 128.0f / 255.0f, 1.0f)); - Scalar sigma = 1 + 20 / 2; - paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma)); + Sigma sigma = Radius(20); + paint.setMaskFilter( + DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma.sigma)); paint.setColorFilter( DlBlendColorFilter::Make(DlColor::kGreen(), DlBlendMode::kColor)); builder.DrawCircle({400, 400}, 200, paint); @@ -190,11 +191,13 @@ TEST_P(AiksTest, ClippedBlurFilterRendersCorrectlyInteractive) { builder.Translate(location.x, location.y); DlPaint paint; - Scalar sigma = 1 + (120 * 3) / 2; - paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma)); + Sigma sigma = Radius{120 * 3}; + paint.setMaskFilter( + DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma.sigma)); paint.setColor(DlColor::kRed()); SkPath path = SkPath::Rect(SkRect::MakeLTRB(0, 0, 800, 800)); + path.addCircle(0, 0, 0.5); builder.DrawPath(path, paint); return builder.Build(); }; @@ -205,11 +208,14 @@ TEST_P(AiksTest, ClippedBlurFilterRendersCorrectly) { DisplayListBuilder builder; builder.Translate(0, -400); DlPaint paint; - Scalar sigma = 1 + (120 * 3) / 2; - paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma)); + + Sigma sigma = Radius{120 * 3}; + paint.setMaskFilter( + DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma.sigma)); paint.setColor(DlColor::kRed()); SkPath path = SkPath::Rect(SkRect::MakeLTRB(0, 0, 800, 800)); + path.addCircle(0, 0, 0.5); builder.DrawPath(path, paint); ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); From d4527028d07e9d79b55c81226d92ad0b45f2f226 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Wed, 14 Aug 2024 17:37:14 -0700 Subject: [PATCH 14/15] fix alpha. --- impeller/display_list/aiks_dl_blur_unittests.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/impeller/display_list/aiks_dl_blur_unittests.cc b/impeller/display_list/aiks_dl_blur_unittests.cc index 0319bba01ddba..174a184a8ee0f 100644 --- a/impeller/display_list/aiks_dl_blur_unittests.cc +++ b/impeller/display_list/aiks_dl_blur_unittests.cc @@ -307,36 +307,36 @@ static sk_sp MaskBlurVariantTest( Scalar alpha = config.alpha * 255; Scalar y = 50; - paint.setColor(DlColor::kCrimson().withAlpha(alpha)); + paint.setColor(DlColor::kCrimson().withAlpha(255 * alpha)); builder.DrawRect(SkRect::MakeXYWH(x + 25 - radius / 2, y + radius / 2, // radius, 60.0f - radius), paint); y += y_spacing; - paint.setColor(DlColor::kBlue().withAlpha(alpha)); + paint.setColor(DlColor::kBlue().withAlpha(255 * alpha)); builder.DrawCircle({x + 25, y + 25}, radius, paint); y += y_spacing; - paint.setColor(DlColor::kGreen().withAlpha(alpha)); + paint.setColor(DlColor::kGreen().withAlpha(255 * alpha)); builder.DrawOval(SkRect::MakeXYWH(x + 25 - radius / 2, y + radius / 2, // radius, 60.0f - radius), paint); y += y_spacing; - paint.setColor(DlColor::kPurple().withAlpha(alpha)); + paint.setColor(DlColor::kPurple().withAlpha(255 * alpha)); SkRRect rrect = SkRRect::MakeRectXY(SkRect::MakeXYWH(x, y, 60.0f, 60.0f), radius, radius); builder.DrawRRect(rrect, paint); y += y_spacing; - paint.setColor(DlColor::kOrange().withAlpha(alpha)); + paint.setColor(DlColor::kOrange().withAlpha(255 * alpha)); rrect = SkRRect::MakeRectXY(SkRect::MakeXYWH(x, y, 60.0f, 60.0f), radius, 5.0); builder.DrawRRect(rrect, paint); y += y_spacing; - paint.setColor(DlColor::kMaroon().withAlpha(alpha)); + paint.setColor(DlColor::kMaroon().withAlpha(255 * alpha)); { SkPath path; From f600638569414c23be6d12794952168540d3f71a Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Wed, 14 Aug 2024 19:42:53 -0700 Subject: [PATCH 15/15] ++ --- impeller/display_list/aiks_dl_blur_unittests.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/impeller/display_list/aiks_dl_blur_unittests.cc b/impeller/display_list/aiks_dl_blur_unittests.cc index 174a184a8ee0f..0319bba01ddba 100644 --- a/impeller/display_list/aiks_dl_blur_unittests.cc +++ b/impeller/display_list/aiks_dl_blur_unittests.cc @@ -307,36 +307,36 @@ static sk_sp MaskBlurVariantTest( Scalar alpha = config.alpha * 255; Scalar y = 50; - paint.setColor(DlColor::kCrimson().withAlpha(255 * alpha)); + paint.setColor(DlColor::kCrimson().withAlpha(alpha)); builder.DrawRect(SkRect::MakeXYWH(x + 25 - radius / 2, y + radius / 2, // radius, 60.0f - radius), paint); y += y_spacing; - paint.setColor(DlColor::kBlue().withAlpha(255 * alpha)); + paint.setColor(DlColor::kBlue().withAlpha(alpha)); builder.DrawCircle({x + 25, y + 25}, radius, paint); y += y_spacing; - paint.setColor(DlColor::kGreen().withAlpha(255 * alpha)); + paint.setColor(DlColor::kGreen().withAlpha(alpha)); builder.DrawOval(SkRect::MakeXYWH(x + 25 - radius / 2, y + radius / 2, // radius, 60.0f - radius), paint); y += y_spacing; - paint.setColor(DlColor::kPurple().withAlpha(255 * alpha)); + paint.setColor(DlColor::kPurple().withAlpha(alpha)); SkRRect rrect = SkRRect::MakeRectXY(SkRect::MakeXYWH(x, y, 60.0f, 60.0f), radius, radius); builder.DrawRRect(rrect, paint); y += y_spacing; - paint.setColor(DlColor::kOrange().withAlpha(255 * alpha)); + paint.setColor(DlColor::kOrange().withAlpha(alpha)); rrect = SkRRect::MakeRectXY(SkRect::MakeXYWH(x, y, 60.0f, 60.0f), radius, 5.0); builder.DrawRRect(rrect, paint); y += y_spacing; - paint.setColor(DlColor::kMaroon().withAlpha(255 * alpha)); + paint.setColor(DlColor::kMaroon().withAlpha(alpha)); { SkPath path;