5 #include "flutter/display_list/display_list.h"
6 #include "flutter/display_list/dl_blend_mode.h"
7 #include "flutter/display_list/dl_builder.h"
8 #include "flutter/display_list/dl_color.h"
9 #include "flutter/display_list/dl_paint.h"
10 #include "flutter/display_list/dl_sampling_options.h"
11 #include "flutter/display_list/dl_tile_mode.h"
12 #include "flutter/display_list/effects/dl_color_filter.h"
13 #include "flutter/display_list/effects/dl_color_source.h"
14 #include "flutter/display_list/effects/dl_image_filter.h"
15 #include "flutter/display_list/effects/dl_mask_filter.h"
16 #include "flutter/display_list/effects/image_filters/dl_blur_image_filter.h"
17 #include "flutter/display_list/geometry/dl_path_builder.h"
20 #include "gmock/gmock.h"
24 #include "impeller/renderer/testing/mocks.h"
25 #include "third_party/imgui/imgui.h"
40 DisplayListBuilder builder;
41 builder.Scale(GetContentScale().
x, GetContentScale().y);
43 std::vector<float> sigmas = {0.0, 0.01, 1.0};
44 std::vector<DlColor> colors = {DlColor::kGreen(), DlColor::kYellow(),
46 for (uint32_t i = 0; i < sigmas.size(); ++i) {
48 paint.setColor(colors[i]);
50 DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigmas[i]));
53 builder.Translate(100 + (i * 100), 100);
55 DlRoundRect::MakeRectXY(DlRect::MakeXYWH(0, 0, 60.0f, 160.0f), 50, 100);
56 builder.DrawRoundRect(rrect, paint);
60 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
66 DisplayListBuilder builder;
67 builder.Scale(content_Scale.
x, content_Scale.
y);
69 DlPaint background_paint;
70 background_paint.setColor(DlColor(1, 0.1, 0.1, 0.1, DlColorSpace::kSRGB));
71 builder.DrawPaint(background_paint);
73 std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue()};
74 std::vector<Scalar> stops = {0.0, 1.0};
77 paint.setMaskFilter(DlBlurMaskFilter::Make(style, sigma));
78 auto gradient = DlColorSource::MakeLinear(
79 {0, 0}, {200, 200}, 2, colors.data(), stops.data(), DlTileMode::kClamp);
80 paint.setColorSource(gradient);
81 paint.setColor(DlColor::kWhite());
82 paint.setDrawStyle(DlDrawStyle::kStroke);
83 paint.setStrokeWidth(20);
86 builder.Translate(100, 100);
90 line_paint.setColor(DlColor::kWhite());
96 DlRoundRect::MakeRectXY(DlRect::MakeXYWH(0, 0, 200.0f, 60.0f), 50, 100);
97 builder.DrawRoundRect(rrect, paint);
100 return builder.Build();
106 GetContentScale(), 10, DlBlurStyle::kNormal)));
111 GetContentScale(), 0, DlBlurStyle::kNormal)));
116 GetContentScale(), 10, DlBlurStyle::kOuter)));
121 GetContentScale(), 10, DlBlurStyle::kInner)));
126 GetContentScale(), 10, DlBlurStyle::kSolid)));
130 DisplayListBuilder builder;
131 builder.Scale(GetContentScale().
x, GetContentScale().y);
133 std::vector<float> sigmas = {0.0, 0.01, 1.0};
134 std::vector<DlColor> colors = {DlColor::kGreen(), DlColor::kYellow(),
136 for (uint32_t i = 0; i < sigmas.size(); ++i) {
138 paint.setColor(colors[i]);
140 DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigmas[i]));
143 builder.Translate(100 + (i * 100), 100);
145 DlRect::MakeXYWH(0, 0, 100.0f, 100.0f), 100, 100);
146 builder.DrawRoundRect(rrect, paint);
150 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
154 DisplayListBuilder builder;
157 paint.setColor(DlColor::kGreen());
158 paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 99999));
159 builder.DrawCircle(
DlPoint(400, 400), 300, paint);
162 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
168 DisplayListBuilder builder;
169 builder.ClipRect(DlRect::MakeXYWH(100, 150, 400, 400));
172 paint.setColor(DlColor::kWhite());
176 DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma.
sigma));
177 paint.setColorFilter(
178 DlColorFilter::MakeBlend(DlColor::kGreen(), DlBlendMode::kSrc));
179 builder.DrawCircle(
DlPoint(400, 400), 200, paint);
181 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
187 DisplayListBuilder builder;
188 builder.ClipRect(DlRect::MakeXYWH(100, 150, 400, 400));
192 DlColor::RGBA(128.0f / 255.0f, 128.0f / 255.0f, 128.0f / 255.0f, 1.0f));
196 DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma.
sigma));
197 paint.setColorFilter(
198 DlColorFilter::MakeBlend(DlColor::kGreen(), DlBlendMode::kColor));
199 builder.DrawCircle(
DlPoint(400, 400), 200, paint);
202 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
206 auto callback = [&]() -> sk_sp<DisplayList> {
211 DisplayListBuilder builder;
213 paint.setColor(DlColor::kCornflowerBlue());
214 builder.DrawCircle(
DlPoint(100, 100), 50, paint);
216 paint.setColor(DlColor::kGreenYellow());
217 builder.DrawCircle(
DlPoint(300, 200), 100, paint);
219 paint.setColor(DlColor::kDarkMagenta());
220 builder.DrawCircle(
DlPoint(140, 170), 75, paint);
222 paint.setColor(DlColor::kOrangeRed());
223 builder.DrawCircle(
DlPoint(180, 120), 100, paint);
226 DlRoundRect::MakeRectXY(DlRect::MakeLTRB(a.x, a.y,
b.x,
b.y), 20, 20);
227 builder.ClipRoundRect(rrect);
230 save_paint.setBlendMode(DlBlendMode::kSrc);
232 auto backdrop_filter = DlImageFilter::MakeBlur(20, 20, DlTileMode::kClamp);
233 builder.SaveLayer(std::nullopt, &save_paint, backdrop_filter.get());
236 return builder.Build();
239 ASSERT_TRUE(OpenPlaygroundHere(callback));
243 DisplayListBuilder builder;
246 paint.setColor(DlColor::kCornflowerBlue());
247 builder.DrawCircle(
DlPoint(100, 100), 50, paint);
249 paint.setColor(DlColor::kGreenYellow());
250 builder.DrawCircle(
DlPoint(300, 200), 100, paint);
252 paint.setColor(DlColor::kDarkMagenta());
253 builder.DrawCircle(
DlPoint(140, 170), 75, paint);
255 paint.setColor(DlColor::kOrangeRed());
256 builder.DrawCircle(
DlPoint(180, 120), 100, paint);
259 DlRoundRect::MakeRectXY(DlRect::MakeLTRB(75, 50, 375, 275), 20, 20);
260 builder.ClipRoundRect(rrect);
263 save_paint.setBlendMode(DlBlendMode::kSrc);
264 auto backdrop_filter = DlImageFilter::MakeBlur(30, 30, DlTileMode::kClamp);
265 builder.SaveLayer(std::nullopt, &save_paint, backdrop_filter.get());
268 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
274 DisplayListBuilder builder;
277 builder.DrawImage(image,
DlPoint(50.0, 50.0),
278 DlImageSampling::kNearestNeighbor, &paint);
281 DlRoundRect::MakeRectXY(DlRect::MakeXYWH(50, 250, 100, 100), 20, 20);
283 builder.ClipRoundRect(rrect);
286 save_paint.setBlendMode(DlBlendMode::kSrc);
287 auto backdrop_filter = DlImageFilter::MakeBlur(30, 30, DlTileMode::kClamp);
288 builder.SaveLayer(std::nullopt, &save_paint, backdrop_filter.get(),
293 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
299 DisplayListBuilder builder;
302 builder.DrawImage(image,
DlPoint(50.0, 50.0),
303 DlImageSampling::kNearestNeighbor, &paint);
305 for (
int i = 0; i < 6; i++) {
307 DlRect::MakeXYWH(50 + (i * 100), 250, 100, 100), 20, 20);
309 builder.ClipRoundRect(rrect);
312 save_paint.setBlendMode(DlBlendMode::kSrc);
313 auto backdrop_filter = DlImageFilter::MakeBlur(30, 30, DlTileMode::kClamp);
314 builder.SaveLayer(std::nullopt, &save_paint, backdrop_filter.get(),
320 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
324 CanRenderMultipleBackdropBlurWithSingleBackdropIdAndDistinctFilters) {
327 DisplayListBuilder builder;
330 builder.DrawImage(image,
DlPoint(50.0, 50.0),
331 DlImageSampling::kNearestNeighbor, &paint);
333 for (
int i = 0; i < 6; i++) {
335 DlRect::MakeXYWH(50 + (i * 100), 250, 100, 100), 20, 20);
337 builder.ClipRoundRect(rrect);
340 save_paint.setBlendMode(DlBlendMode::kSrc);
341 auto backdrop_filter =
342 DlImageFilter::MakeBlur(30 + i, 30, DlTileMode::kClamp);
343 builder.SaveLayer(std::nullopt, &save_paint, backdrop_filter.get(),
349 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
353 DisplayListBuilder builder;
356 paint.setColor(DlColor::kGreen());
357 builder.DrawCircle(
DlPoint(400, 400), 300, paint);
360 save_paint.setBlendMode(DlBlendMode::kSrc);
362 auto backdrop_filter =
363 DlImageFilter::MakeBlur(999999, 999999, DlTileMode::kClamp);
364 builder.SaveLayer(std::nullopt, &save_paint, backdrop_filter.get());
367 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
373 DisplayListBuilder builder;
376 builder.DrawImage(image,
DlPoint(0.0, 0.0), DlImageSampling::kNearestNeighbor,
380 save_paint.setBlendMode(DlBlendMode::kSrcOver);
386 builder.Scale(1.1, 1.2);
388 DlRect rect1 = DlRect::MakeLTRB(70, 70, 313, 170);
389 builder.ClipRect(rect1);
390 auto backdrop_filter1 =
391 DlBlurImageFilter::Make(20, 20, DlTileMode::kDecal, rect1);
392 builder.SaveLayer(std::nullopt, &save_paint, backdrop_filter1.get());
399 builder.Scale(1.1, 1.2);
401 DlRect rect2 = DlRect::MakeLTRB(55, 190, 298, 290);
402 builder.ClipRect(rect2);
403 auto backdrop_filter2 =
404 DlBlurImageFilter::Make(20, 20, DlTileMode::kDecal, rect2);
405 builder.SaveLayer(std::nullopt, &save_paint, backdrop_filter2.get());
409 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
413 DisplayListBuilder builder;
414 builder.ClipRect(DlRect::MakeXYWH(100, 150, 400, 400));
417 paint.setColor(DlColor::kGreen());
418 paint.setImageFilter(DlImageFilter::MakeBlur(20, 20, DlTileMode::kDecal));
419 builder.DrawCircle(
DlPoint(400, 400), 200, paint);
422 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
426 DisplayListBuilder builder;
429 background.setColor(DlColor(1.0, 0.1, 0.1, 0.1, DlColorSpace::kSRGB));
430 builder.DrawPaint(background);
433 paint.setColor(DlColor::kGreen());
440 std::shared_ptr<DlImageFilter> color_filter =
441 DlImageFilter::MakeColorFilter(DlColorFilter::MakeMatrix(matrix));
442 std::shared_ptr<DlImageFilter> blur =
443 DlImageFilter::MakeBlur(20, 20, DlTileMode::kDecal);
444 paint.setImageFilter(DlImageFilter::MakeCompose(blur, color_filter));
445 builder.DrawCircle(
DlPoint(400, 400), 200, paint);
447 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
451 DisplayListBuilder builder;
454 background.setColor(DlColor(1.0, 0.1, 0.1, 0.1, DlColorSpace::kSRGB));
455 builder.DrawPaint(background);
458 paint.setColor(DlColor::kGreen());
465 std::shared_ptr<DlImageFilter> color_filter =
466 DlImageFilter::MakeColorFilter(DlColorFilter::MakeMatrix(matrix));
467 std::shared_ptr<DlImageFilter> blur =
468 DlImageFilter::MakeBlur(20, 20, DlTileMode::kDecal);
469 paint.setImageFilter(DlImageFilter::MakeCompose(color_filter, blur));
470 builder.DrawCircle(
DlPoint(400, 400), 200, paint);
472 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
476 auto callback = [&]() -> sk_sp<DisplayList> {
481 DisplayListBuilder builder;
488 DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma.
sigma));
489 paint.setColor(DlColor::kRed());
491 DlPath path = DlPath::MakeRect(DlRect::MakeLTRB(0, 0, 800, 800));
492 path = path + DlPath::MakeCircle(
DlPoint(0, 0), 0.5);
493 builder.DrawPath(path, paint);
494 return builder.Build();
496 ASSERT_TRUE(OpenPlaygroundHere(callback));
500 DisplayListBuilder builder;
501 builder.Translate(0, -400);
506 DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma.
sigma));
507 paint.setColor(DlColor::kRed());
509 DlPath path = DlPath::MakeRect(DlRect::MakeLTRB(0, 0, 800, 800));
510 path = path + DlPath::MakeCircle(
DlPoint(0, 0), 0.5);
511 builder.DrawPath(path, paint);
513 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
517 DisplayListBuilder builder;
519 paint.setColor(DlColor::kBlue());
520 builder.DrawRect(DlRect::MakeXYWH(0, 0, 600.0, 600.0), paint);
523 clear.setBlendMode(DlBlendMode::kClear);
524 clear.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 20));
526 builder.DrawCircle(
DlPoint(300.0, 300.0), 200.0, clear);
528 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
533 auto callback = [&]() -> sk_sp<DisplayList> {
535 ImGuiWindowFlags_AlwaysAutoResize)) {
536 ImGui::SliderFloat(
"Sigma", &sigma, 0, 50);
539 DisplayListBuilder builder;
540 builder.Scale(GetContentScale().
x, GetContentScale().y);
541 builder.DrawPaint({});
544 paint.setColor(DlColor::kGreen());
545 paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma));
547 builder.DrawRect(DlRect::MakeXYWH(300, 300, 200, 200), paint);
548 return builder.Build();
551 ASSERT_TRUE(OpenPlaygroundHere(callback));
555 DisplayListBuilder builder;
558 paint.setColor(DlColor::kBlue());
559 paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 0));
561 builder.DrawCircle(
DlPoint(300, 300), 200, paint);
562 builder.DrawRect(DlRect::MakeLTRB(100, 300, 500, 600), paint);
564 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
570 if (!EnsureContextSupportsWideGamut()) {
571 GTEST_SKIP() <<
"This backend doesn't yet support wide gamut.";
575 EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
578 DisplayListBuilder builder;
579 builder.DrawColor(DlColor::kWhite(), DlBlendMode::kSrc);
582 paint.setColor(DlColor::kBlue());
583 paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 10));
586 builder.DrawRect(DlRect::MakeLTRB(100, 250, 500, 250), paint);
588 builder.DrawRect(DlRect::MakeLTRB(100, 300, 500, 600), paint);
590 builder.DrawRect(DlRect::MakeLTRB(550, 300, 550, 600), paint);
592 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
596 DlBlurStyle style = DlBlurStyle::kNormal;
600 bool invert_colors =
false;
601 DlBlendMode blend_mode = DlBlendMode::kSrcOver;
607 DisplayListBuilder builder;
610 builder.Scale(0.8f, 0.8f);
611 builder.Translate(50.f, 50.f);
617 builder.DrawPaint(draw_paint);
620 paint.setMaskFilter(DlBlurMaskFilter::Make(config.
style, config.
sigma));
626 const Scalar radius = 20.0f;
627 const Scalar y_spacing = 100.0f;
631 paint.setColor(DlColor::kCrimson().withAlpha(alpha));
632 builder.DrawRect(DlRect::MakeXYWH(
x + 25 - radius / 2, y + radius / 2,
633 radius, 60.0f - radius),
637 paint.setColor(DlColor::kBlue().withAlpha(alpha));
638 builder.DrawCircle(
DlPoint{
x + 25, y + 25}, radius, paint);
641 paint.setColor(DlColor::kGreen().withAlpha(alpha));
642 builder.DrawOval(DlRect::MakeXYWH(
x + 25 - radius / 2, y + radius / 2,
643 radius, 60.0f - radius),
647 paint.setColor(DlColor::kPurple().withAlpha(alpha));
649 DlRect::MakeXYWH(
x, y, 60.0f, 60.0f), radius, radius);
650 builder.DrawRoundRect(rrect, paint);
653 paint.setColor(DlColor::kOrange().withAlpha(alpha));
655 rrect = DlRoundRect::MakeRectXY(DlRect::MakeXYWH(
x, y, 60.0f, 60.0f),
657 builder.DrawRoundRect(rrect, paint);
660 paint.setColor(DlColor::kMaroon().withAlpha(alpha));
663 DlPathBuilder path_builder;
664 path_builder.MoveTo(
DlPoint(
x + 0, y + 60));
665 path_builder.LineTo(
DlPoint(
x + 30, y + 0));
666 path_builder.LineTo(
DlPoint(
x + 60, y + 60));
667 path_builder.Close();
669 builder.DrawPath(path_builder.TakePath(), paint);
673 paint.setColor(DlColor::kMaroon().withAlpha(alpha));
679 builder.DrawPath(path, paint);
682 return builder.Build();
687 {
"NormalTranslucentZeroSigma",
688 {.style = DlBlurStyle::kNormal, .sigma = 0.0f, .alpha = 0.5f}},
690 {
"NormalTranslucent",
691 {.style = DlBlurStyle::kNormal, .sigma = 8.0f, .alpha = 0.5f}},
694 {.style = DlBlurStyle::kSolid, .sigma = 8.0f, .alpha = 0.5f}},
696 {
"SolidOpaque", {.style = DlBlurStyle::kSolid, .sigma = 8.0f}},
698 {
"SolidTranslucentWithFilters",
699 {.style = DlBlurStyle::kSolid,
702 .image_filter = DlImageFilter::MakeBlur(3, 3, DlTileMode::kClamp),
703 .invert_colors =
true}},
705 {
"SolidTranslucentExclusionBlend",
706 {.style = DlBlurStyle::kSolid,
709 .blend_mode = DlBlendMode::kExclusion}},
712 {.style = DlBlurStyle::kInner, .sigma = 8.0f, .alpha = 0.5f}},
714 {
"InnerTranslucentWithBlurImageFilter",
715 {.style = DlBlurStyle::kInner,
718 .image_filter = DlImageFilter::MakeBlur(3, 3, DlTileMode::kClamp)}},
721 {.style = DlBlurStyle::kOuter, .sigma = 8.0f, .alpha = 0.5f}},
723 {
"OuterOpaqueWithBlurImageFilter",
724 {.style = DlBlurStyle::kOuter,
726 .image_filter = DlImageFilter::MakeBlur(3, 3, DlTileMode::kClamp)}}};
728 #define MASK_BLUR_VARIANT_TEST(config) \
729 TEST_P(AiksTest, MaskBlurVariantTest##config) { \
730 ASSERT_TRUE(OpenPlaygroundHere( \
731 MaskBlurVariantTest(*this, kPaintVariations.at(#config)))); \
745 #undef MASK_BLUR_VARIANT_TEST
748 DisplayListBuilder builder;
749 builder.Scale(GetContentScale().
x, GetContentScale().y);
752 paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1));
753 builder.DrawPaint(paint);
755 paint.setColor(DlColor::kGreen());
756 paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kInner, 30));
758 DlPathBuilder path_builder;
759 path_builder.MoveTo(
DlPoint(200, 200));
760 path_builder.LineTo(
DlPoint(300, 400));
761 path_builder.LineTo(
DlPoint(100, 400));
762 path_builder.Close();
764 builder.DrawPath(path_builder.TakePath(), paint);
768 red.setColor(DlColor::kRed());
769 builder.DrawRect(DlRect::MakeXYWH(0, 0, 200, 200), red);
771 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
775 DisplayListBuilder builder;
776 builder.Scale(GetContentScale().
x, GetContentScale().y);
779 paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1.0));
780 builder.DrawPaint(paint);
782 paint.setColor(DlColor::kGreen());
783 paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kOuter, 30));
785 DlPathBuilder path_builder;
786 path_builder.MoveTo(
DlPoint(200, 200));
787 path_builder.LineTo(
DlPoint(300, 400));
788 path_builder.LineTo(
DlPoint(100, 400));
789 path_builder.Close();
791 builder.DrawPath(path_builder.TakePath(), paint);
795 red.setColor(DlColor::kRed());
796 builder.DrawRect(DlRect::MakeXYWH(0, 0, 200, 200), red);
798 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
802 DisplayListBuilder builder;
803 builder.Scale(GetContentScale().
x, GetContentScale().y);
806 paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1.0));
807 builder.DrawPaint(paint);
809 paint.setColor(DlColor::kGreen());
810 paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kSolid, 30));
812 DlPathBuilder path_builder;
813 path_builder.MoveTo(
DlPoint(200, 200));
814 path_builder.LineTo(
DlPoint(300, 400));
815 path_builder.LineTo(
DlPoint(100, 400));
816 path_builder.Close();
818 builder.DrawPath(path_builder.TakePath(), paint);
822 red.setColor(DlColor::kRed());
823 builder.DrawRect(DlRect::MakeXYWH(0, 0, 200, 200), red);
825 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
830 auto callback = [&]() -> sk_sp<DisplayList> {
832 ImGuiWindowFlags_AlwaysAutoResize)) {
833 ImGui::SliderFloat(
"Sigma", &sigma, 0, 500);
837 DisplayListBuilder builder;
838 builder.Scale(GetContentScale().
x, GetContentScale().y);
841 paint.setColor(DlColor::kGreen());
842 paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma));
846 DlPoint(200, 200), DlImageSampling::kNearestNeighbor, &paint);
849 red.setColor(DlColor::kRed());
850 builder.DrawRect(DlRect::MakeXYWH(0, 0, 200, 200), red);
852 return builder.Build();
854 ASSERT_TRUE(OpenPlaygroundHere(callback));
859 auto callback = [&]() -> sk_sp<DisplayList> {
861 ImGuiWindowFlags_AlwaysAutoResize)) {
862 ImGui::SliderFloat(
"Sigma", &sigma, 0, 500);
866 DisplayListBuilder builder;
867 builder.Scale(GetContentScale().
x, GetContentScale().y);
870 paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1.0));
871 builder.DrawPaint(paint);
873 std::shared_ptr<Texture> boston = CreateTextureForFixture(
"boston.jpg");
878 paint.setColorSource(DlColorSource::MakeImage(
880 DlImageSampling::kMipmapLinear));
881 paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma));
883 builder.DrawRect(DlRect::MakeXYWH(0, 0, boston->GetSize().width,
884 boston->GetSize().height),
887 return builder.Build();
889 ASSERT_TRUE(OpenPlaygroundHere(callback));
893 DisplayListBuilder builder;
896 builder.Scale(GetContentScale().
x, GetContentScale().y);
898 paint.setColor(DlColor::kLimeGreen());
900 DlRect::MakeLTRB(0, 0, GetWindowSize().width, 100), 10, 10);
901 builder.DrawRoundRect(rrect, paint);
903 paint.setColor(DlColor::kMagenta());
904 rrect = DlRoundRect::MakeRectXY(
905 DlRect::MakeLTRB(0, 110, GetWindowSize().width, 210), 10, 10);
906 builder.DrawRoundRect(rrect, paint);
907 builder.ClipRect(DlRect::MakeLTRB(100, 0, 200, GetWindowSize().height));
910 save_paint.setBlendMode(DlBlendMode::kSrc);
912 auto backdrop_filter = DlImageFilter::MakeBlur(20, 20, DlTileMode::kClamp);
914 builder.SaveLayer(std::nullopt, &save_paint, backdrop_filter.get());
917 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
921 DisplayListBuilder builder;
923 builder.Scale(GetContentScale().
x, GetContentScale().y);
924 std::shared_ptr<Texture> boston = CreateTextureForFixture(
"boston.jpg");
925 builder.DrawImageRect(
927 DlRect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height),
928 DlRect::MakeLTRB(0, 0, GetWindowSize().width, 100),
929 DlImageSampling::kNearestNeighbor);
932 paint.setColor(DlColor::kMagenta());
935 DlRect::MakeLTRB(0, 110, GetWindowSize().width, 210), 10, 10);
936 builder.DrawRoundRect(rrect, paint);
937 builder.ClipRect(DlRect::MakeLTRB(0, 50, GetWindowSize().width, 150));
940 save_paint.setBlendMode(DlBlendMode::kSrc);
942 auto backdrop_filter = DlImageFilter::MakeBlur(20, 20, DlTileMode::kClamp);
943 builder.SaveLayer(std::nullopt, &save_paint, backdrop_filter.get());
946 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
955 CreateTextureForFixture(
"boston.jpg",
true);
961 auto callback = [&]() -> sk_sp<DisplayList> {
963 ImGuiWindowFlags_AlwaysAutoResize)) {
964 ImGui::SliderFloat(
"Sigma", &sigma, 0, 200);
965 ImGui::SliderFloat(
"Frequency", &freq, 0.01, 2.0);
966 ImGui::SliderFloat(
"Amplitude", &, 1, 100);
970 DisplayListBuilder builder;
971 builder.Scale(GetContentScale().
x, GetContentScale().y);
972 Scalar y = amp * sin(freq * 2.0 * M_PI * count / 60);
974 DlPoint(1024 / 2 - boston->GetSize().width / 2,
975 (768 / 2 - boston->GetSize().height / 2) + y),
976 DlImageSampling::kMipmapLinear);
982 DlRect::MakeLTRB(handle_a.x, handle_a.y, handle_b.x, handle_b.y));
983 builder.ClipRect(DlRect::MakeLTRB(100, 100, 900, 700));
986 paint.setBlendMode(DlBlendMode::kSrc);
988 auto backdrop_filter =
989 DlImageFilter::MakeBlur(sigma, sigma, DlTileMode::kClamp);
990 builder.SaveLayer(std::nullopt, &paint, backdrop_filter.get());
992 return builder.Build();
994 ASSERT_TRUE(OpenPlaygroundHere(callback));
998 DisplayListBuilder builder;
1000 builder.Scale(GetContentScale().
x, GetContentScale().y);
1003 paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1.0));
1004 builder.DrawPaint(paint);
1006 std::vector<DlColor> colors = {DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0),
1007 DlColor::RGBA(0.7568, 0.2627, 0.2118, 1.0)};
1008 std::vector<Scalar> stops = {0.0, 1.0};
1011 paint.setColorSource(DlColorSource::MakeLinear(
1017 DlTileMode::kMirror));
1018 paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kInner, 30));
1020 DlPathBuilder path_builder;
1021 path_builder.MoveTo(
DlPoint(200, 200));
1022 path_builder.LineTo(
DlPoint(300, 400));
1023 path_builder.LineTo(
DlPoint(100, 400));
1024 path_builder.Close();
1025 builder.DrawPath(path_builder.TakePath(), paint);
1029 red.setColor(DlColor::kRed());
1030 builder.DrawRect(DlRect::MakeXYWH(0, 0, 200, 200), red);
1032 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1036 DisplayListBuilder builder;
1037 builder.Scale(GetContentScale().
x, GetContentScale().y);
1040 paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1.0));
1041 builder.DrawPaint(paint);
1043 std::vector<DlColor> colors = {DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0),
1044 DlColor::RGBA(0.7568, 0.2627, 0.2118, 1.0)};
1045 std::vector<Scalar> stops = {0.0, 1.0};
1048 paint.setColorSource(DlColorSource::MakeLinear(
1054 DlTileMode::kMirror));
1055 paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kSolid, 30));
1057 DlPathBuilder path_builder;
1058 path_builder.MoveTo(
DlPoint(200, 200));
1059 path_builder.LineTo(
DlPoint(300, 400));
1060 path_builder.LineTo(
DlPoint(100, 400));
1061 path_builder.Close();
1062 builder.DrawPath(path_builder.TakePath(), paint);
1066 red.setColor(DlColor::kRed());
1067 builder.DrawRect(DlRect::MakeXYWH(0, 0, 200, 200), red);
1068 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1072 DisplayListBuilder builder;
1073 builder.Scale(GetContentScale().
x, GetContentScale().y);
1076 paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1.0));
1077 builder.DrawPaint(paint);
1079 std::vector<DlColor> colors = {DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0),
1080 DlColor::RGBA(0.7568, 0.2627, 0.2118, 1.0)};
1081 std::vector<Scalar> stops = {0.0, 1.0};
1084 paint.setColorSource(DlColorSource::MakeLinear(
1090 DlTileMode::kMirror));
1091 paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kOuter, 30));
1093 DlPathBuilder path_builder;
1094 path_builder.MoveTo(
DlPoint(200, 200));
1095 path_builder.LineTo(
DlPoint(300, 400));
1096 path_builder.LineTo(
DlPoint(100, 400));
1097 path_builder.Close();
1098 builder.DrawPath(path_builder.TakePath(), paint);
1102 red.setColor(DlColor::kRed());
1103 builder.DrawRect(DlRect::MakeXYWH(0, 0, 200, 200), red);
1104 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1108 DisplayListBuilder builder;
1109 std::shared_ptr<Texture> boston = CreateTextureForFixture(
"boston.jpg");
1111 Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height);
1115 paint.setImageFilter(DlImageFilter::MakeBlur(20, 20, DlTileMode::kDecal));
1117 Vector2 clip_size = {150, 75};
1119 builder.Scale(GetContentScale().
x, GetContentScale().y);
1122 builder.ClipRect(DlRect::MakeLTRB(rect.GetLeft(), rect.GetTop(),
1123 rect.GetRight(), rect.GetBottom()));
1124 builder.Translate(center.
x, center.
y);
1125 builder.Scale(0.6, 0.6);
1129 Rect dest = bounds.
Shift(-image_center);
1133 sk_dst, DlImageSampling::kNearestNeighbor,
1136 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1140 std::shared_ptr<Texture> boston = CreateTextureForFixture(
"boston.jpg");
1142 auto callback = [&]() -> sk_sp<DisplayList> {
1143 const char* tile_mode_names[] = {
"Clamp",
"Repeat",
"Mirror",
"Decal"};
1144 const DlTileMode tile_modes[] = {DlTileMode::kClamp, DlTileMode::kRepeat,
1145 DlTileMode::kMirror, DlTileMode::kDecal};
1147 static float rotation = 0;
1148 static float scale = 0.6;
1149 static int selected_tile_mode = 3;
1152 ImGuiWindowFlags_AlwaysAutoResize)) {
1153 ImGui::SliderFloat(
"Rotation (degrees)", &rotation, -180, 180);
1154 ImGui::SliderFloat(
"Scale", &scale, 0, 2.0);
1155 ImGui::Combo(
"Tile mode", &selected_tile_mode, tile_mode_names,
1156 sizeof(tile_mode_names) /
sizeof(
char*));
1160 DisplayListBuilder builder;
1162 Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height);
1165 paint.setImageFilter(
1166 DlImageFilter::MakeBlur(20, 20, tile_modes[selected_tile_mode]));
1173 builder.Scale(GetContentScale().
x, GetContentScale().y);
1175 DlRect::MakeLTRB(handle_a.x, handle_a.y, handle_b.x, handle_b.y));
1176 builder.Translate(center.
x, center.
y);
1177 builder.Scale(scale, scale);
1178 builder.
Rotate(rotation);
1182 Rect dest = bounds.
Shift(-image_center);
1186 sk_dst, DlImageSampling::kNearestNeighbor,
1188 return builder.Build();
1191 ASSERT_TRUE(OpenPlaygroundHere(callback));
1195 DisplayListBuilder builder;
1197 builder.Scale(GetContentScale().
x, GetContentScale().y);
1198 builder.Scale(0.5, 0.5);
1200 std::shared_ptr<Texture> boston = CreateTextureForFixture(
"boston.jpg");
1204 paint.setBlendMode(DlBlendMode::kSrc);
1206 auto backdrop_filter = DlImageFilter::MakeBlur(50, 0, DlTileMode::kClamp);
1207 builder.SaveLayer(std::nullopt, &paint, backdrop_filter.get());
1209 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1217 DisplayListBuilder builder;
1219 std::shared_ptr<Texture> boston = CreateTextureForFixture(
"boston.jpg");
1221 Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height);
1224 paint.setImageFilter(DlImageFilter::MakeBlur(20, 20, DlTileMode::kDecal));
1227 Vector2 clip_size = {150, 75};
1229 builder.Scale(GetContentScale().
x, GetContentScale().y);
1232 builder.ClipRect(DlRect::MakeLTRB(clip_bounds.GetLeft(), clip_bounds.GetTop(),
1233 clip_bounds.GetRight(),
1234 clip_bounds.GetBottom()));
1235 builder.Translate(center.
x, center.
y);
1236 builder.Scale(0.6, 0.6);
1239 auto dst_rect = bounds.
Shift(-image_center);
1240 builder.DrawImageRect(
1245 DlRect::MakeLTRB(dst_rect.GetLeft(), dst_rect.GetTop(),
1246 dst_rect.GetRight(), dst_rect.GetBottom()),
1247 DlImageSampling::kMipmapLinear, &paint);
1249 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1253 auto callback = [&]() -> sk_sp<DisplayList> {
1254 const char* tile_mode_names[] = {
"Clamp",
"Repeat",
"Mirror",
"Decal"};
1255 const DlTileMode tile_modes[] = {DlTileMode::kClamp, DlTileMode::kRepeat,
1256 DlTileMode::kMirror, DlTileMode::kDecal};
1258 static float rotation = 45;
1259 static float scale = 0.6;
1260 static int selected_tile_mode = 3;
1263 ImGuiWindowFlags_AlwaysAutoResize)) {
1264 ImGui::SliderFloat(
"Rotation (degrees)", &rotation, -180, 180);
1265 ImGui::SliderFloat(
"Scale", &scale, 0, 2.0);
1266 ImGui::Combo(
"Tile mode", &selected_tile_mode, tile_mode_names,
1267 sizeof(tile_mode_names) /
sizeof(
char*));
1271 DisplayListBuilder builder;
1274 paint.setColor(DlColor::kGreen());
1275 paint.setImageFilter(
1276 DlImageFilter::MakeBlur(50, 0, tile_modes[selected_tile_mode]));
1279 builder.Scale(GetContentScale().
x, GetContentScale().y);
1280 builder.Translate(center.
x, center.
y);
1281 builder.Scale(scale, scale);
1282 builder.
Rotate(rotation);
1285 DlRoundRect::MakeRectXY(DlRect::MakeCircleBounds({0, 0}, 100), 10, 10);
1286 builder.DrawRoundRect(rrect, paint);
1287 return builder.Build();
1290 ASSERT_TRUE(OpenPlaygroundHere(callback));
1294 DisplayListBuilder builder;
1295 builder.Scale(GetContentScale().
x, GetContentScale().y);
1297 auto paint_lines = [&builder](
Scalar dx,
Scalar dy, DlPaint paint) {
1299 DlPath line = DlPath::MakeLine(a,
b);
1300 builder.DrawPath(line, paint);
1302 paint.setStrokeWidth(5);
1303 paint.setDrawStyle(DlDrawStyle::kStroke);
1304 draw_line(
DlPoint(dx + 100, dy + 100),
DlPoint(dx + 200, dy + 200));
1305 draw_line(
DlPoint(dx + 100, dy + 200),
DlPoint(dx + 200, dy + 100));
1306 draw_line(
DlPoint(dx + 150, dy + 100),
DlPoint(dx + 200, dy + 150));
1307 draw_line(
DlPoint(dx + 100, dy + 150),
DlPoint(dx + 150, dy + 200));
1311 DisplayListBuilder recorder_builder;
1312 for (
int x = 0;
x < 5; ++
x) {
1313 for (
int y = 0; y < 5; ++y) {
1314 DlRect rect = DlRect::MakeXYWH(
x * 20, y * 20, 20, 20);
1316 paint.setColor(((
x + y) & 1) == 0 ? DlColor::kYellow()
1317 : DlColor::kBlue());
1319 recorder_builder.DrawRect(rect, paint);
1325 auto image_source = DlColorSource::MakeImage(
1327 auto blur_filter = DlImageFilter::MakeBlur(5, 5, DlTileMode::kDecal);
1330 paint.setColor(DlColor::kDarkGreen());
1331 builder.DrawRect(DlRect::MakeLTRB(0, 0, 300, 600), paint);
1333 paint.setColorSource(image_source);
1334 builder.DrawRect(DlRect::MakeLTRB(100, 100, 200, 200), paint);
1336 paint.setColorSource(
nullptr);
1337 paint.setColor(DlColor::kRed());
1338 builder.DrawRect(DlRect::MakeLTRB(300, 0, 600, 600), paint);
1340 paint.setColorSource(image_source);
1341 paint.setImageFilter(blur_filter);
1342 builder.DrawRect(DlRect::MakeLTRB(400, 100, 500, 200), paint);
1344 paint.setImageFilter(
nullptr);
1345 paint_lines(0, 300, paint);
1347 paint.setImageFilter(blur_filter);
1348 paint_lines(300, 300, paint);
1350 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1359 for (int32_t i = 1; i < 5; ++i) {
1360 DisplayListBuilder builder;
1362 DlPathBuilder path_builder;
1363 path_builder.MoveTo(
DlPoint(100, 100));
1364 path_builder.LineTo(
DlPoint(100 + fi, 100 + fi));
1367 paint.setColor(DlColor::kChartreuse());
1368 auto blur_filter = DlImageFilter::MakeBlur(0.1, 0.1, DlTileMode::kClamp);
1369 paint.setImageFilter(blur_filter);
1371 builder.DrawPath(path_builder.TakePath(), paint);
1374 EXPECT_TRUE(image) <<
" length " << i;
1383 for (int32_t i = 1; i < 5; ++i) {
1384 DisplayListBuilder builder;
1389 DlRect::MakeXYWH(400, 400, clip_size.
width, clip_size.
height));
1392 paint.setColor(DlColor::kGreen());
1393 auto blur_filter = DlImageFilter::MakeBlur(0.1, 0.1, DlTileMode::kDecal);
1394 paint.setImageFilter(blur_filter);
1396 builder.DrawCircle(
DlPoint(400, 400), 200, paint);
1400 EXPECT_TRUE(image) <<
" length " << i;
1405 CanRenderMultipleBackdropBlurWithSingleBackdropIdDifferentLayers) {
1408 DisplayListBuilder builder;
1411 builder.DrawImage(image,
DlPoint(50.0, 50.0),
1412 DlImageSampling::kNearestNeighbor, &paint);
1414 for (
int i = 0; i < 6; i++) {
1417 paint.setColor(DlColor::kWhite().withAlphaF(0.95));
1418 builder.SaveLayer(std::nullopt, &paint);
1421 DlRect::MakeXYWH(50 + (i * 100), 250, 100, 100), 20, 20);
1423 builder.ClipRoundRect(rrect);
1426 save_paint.setBlendMode(DlBlendMode::kSrc);
1427 auto backdrop_filter = DlImageFilter::MakeBlur(30, 30, DlTileMode::kClamp);
1428 builder.SaveLayer(std::nullopt, &save_paint, backdrop_filter.get(),
1437 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1441 DisplayListBuilder builder;
1442 builder.Scale(GetContentScale().
x, GetContentScale().y);
1444 std::vector<DlColor> colors = {DlColor(0xFFFF0000), DlColor(0xFF00FF00)};
1445 std::vector<Scalar> stops = {0.0, 1.0};
1447 auto gradient = DlColorSource::MakeLinear(
1448 {0, 0}, {400, 400}, 2, colors.data(), stops.data(), DlTileMode::kClamp);
1451 save_paint.setOpacity(0.5);
1452 builder.SaveLayer(std::nullopt, &save_paint);
1455 paint.setColorSource(gradient);
1456 paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 1));
1457 builder.DrawRect(DlRect::MakeXYWH(100, 100, 200, 200), paint);
1461 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1470 auto callback = [&]() -> sk_sp<DisplayList> {
1471 DisplayListBuilder builder;
1475 Scalar offset = amp * sin(freq * 2.0 * M_PI * count / 60.0);
1479 paint.setColor(DlColor::kCornflowerBlue());
1480 builder.DrawCircle(
DlPoint(100 + offset, 100), 50, paint);
1481 paint.setColor(DlColor::kGreenYellow());
1482 builder.DrawCircle(
DlPoint(300, 200 + offset), 100, paint);
1483 paint.setColor(DlColor::kDarkMagenta());
1484 builder.DrawCircle(
DlPoint(140, 170), 75, paint);
1485 paint.setColor(DlColor::kOrangeRed());
1486 builder.DrawCircle(
DlPoint(180 + offset, 120 + offset), 100, paint);
1489 auto backdrop_filter1 = DlImageFilter::MakeBlur(15, 15, DlTileMode::kClamp);
1490 builder.SaveLayer(std::nullopt,
nullptr, backdrop_filter1.get());
1493 DlPaint transparent_paint;
1494 transparent_paint.setColor(DlColor::kWhite().withAlpha(0.1 * 255));
1495 builder.DrawPaint(transparent_paint);
1499 auto backdrop_filter2 =
1500 DlImageFilter::MakeBlur(10, 10, DlTileMode::kClamp);
1502 builder.ClipRect(DlRect::MakeXYWH(150, 150, 300, 300));
1503 builder.SaveLayer(std::nullopt,
nullptr, backdrop_filter2.get());
1511 return builder.Build();
1513 ASSERT_TRUE(OpenPlaygroundHere(callback));
1517 DisplayListBuilder builder;
1518 builder.Scale(GetContentScale().
x, GetContentScale().y);
1520 builder.DrawRect(DlRect::MakeXYWH(0, 0, 350, 350),
1521 DlPaint().setColor(DlColor::kWhite()));
1524 builder.Scale(-1, 1);
1526 paint.setImageFilter(DlBlurImageFilter::Make(10, 10, DlTileMode::kDecal));
1527 builder.SaveLayer(DlRect::MakeLTRB(-150, 100, 150, 200), &paint);
1528 builder.DrawRect(DlRect::MakeLTRB(-150, 0, 150, 300),
1529 DlPaint().setColor(DlColor::kRed()));
1533 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
#define MASK_BLUR_VARIANT_TEST(config)
static bool ImGuiBegin(const char *name, bool *p_open, ImGuiWindowFlags flags)
static sk_sp< DlImageImpeller > Make(std::shared_ptr< Texture > texture, OwningContext owning_context=OwningContext::kIO)
Point GetContentScale() const
sk_sp< flutter::DisplayList > DoGradientOvalStrokeMaskBlur(Vector2 content_Scale, Scalar sigma, DlBlurStyle style)
static sk_sp< DisplayList > MaskBlurVariantTest(const AiksTest &test_context, const MaskBlurTestConfig &config)
TEST_P(AiksTest, DrawAtlasNoColor)
static const std::map< std::string, MaskBlurTestConfig > kPaintVariations
Point DrawPlaygroundPoint(PlaygroundPoint &point)
std::tuple< Point, Point > DrawPlaygroundLine(PlaygroundPoint &point_a, PlaygroundPoint &point_b)
std::shared_ptr< Texture > DisplayListToTexture(const sk_sp< flutter::DisplayList > &display_list, ISize size, AiksContext &context, bool reset_host_buffer, bool generate_mips, std::optional< PixelFormat > target_pixel_format)
Render the provided display list to a texture with the given size.
flutter::DlRoundRect DlRoundRect
static constexpr Color White()
static constexpr Color Red()
static constexpr Color AntiqueWhite()
static constexpr Color Green()
static constexpr Matrix MakeTranslation(const Vector3 &t)
static constexpr Matrix MakeScale(const Vector3 &s)
For convolution filters, the "radius" is the size of the convolution kernel to use on the local space...
In filters that use Gaussian distributions, "sigma" is a size of one standard deviation in terms of t...
constexpr TPoint Rotate(const Radians &angle) const
constexpr auto GetBottom() const
constexpr auto GetTop() const
constexpr auto GetLeft() const
constexpr TSize< Type > GetSize() const
Returns the size of the rectangle which may be negative in either width or height and may have been c...
constexpr auto GetRight() const
constexpr static TRect MakeXYWH(Type x, Type y, Type width, Type height)
constexpr TRect< T > Shift(T dx, T dy) const
Returns a new rectangle translated by the given offset.
constexpr static TRect MakeEllipseBounds(const TPoint< Type > ¢er, const TSize< Type > &radii)
std::shared_ptr< DlImageFilter > image_filter