5#include "flutter/impeller/aiks/aiks_unittests.h"
13#include "third_party/imgui/imgui.h"
25 canvas.DrawCircle({400, 400}, 300,
29 .sigma =
Sigma(99999),
33 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
41 canvas.DrawCircle({400, 400}, 200,
46 .mask_blur_descriptor =
54 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
62 canvas.DrawCircle({400, 400}, 200,
67 .mask_blur_descriptor =
75 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
96 return canvas.EndRecordingAsPicture();
99 ASSERT_TRUE(OpenPlaygroundHere(
callback));
115 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
120 canvas.DrawCircle({400, 400}, 300, {.color =
Color::Green()});
127 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
143 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
153 canvas.Translate(point -
Point(400, 400));
163 return canvas.EndRecordingAsPicture();
165 ASSERT_TRUE(OpenPlaygroundHere(
callback));
170 canvas.Translate(
Point(0, -400));
180 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
196 canvas.DrawCircle(
Point::MakeXY(300.0, 300.0), 200.0, clear);
198 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
205 ImGuiWindowFlags_AlwaysAutoResize)) {
206 ImGui::SliderFloat(
"Sigma", &sigma, 0, 50);
210 canvas.Scale(GetContentScale());
211 canvas.DrawPaint({});
214 .mask_blur_descriptor =
217 .sigma =
Sigma(sigma),
221 return canvas.EndRecordingAsPicture();
224 ASSERT_TRUE(OpenPlaygroundHere(
callback));
229 canvas.Scale(GetContentScale());
235 paint.stroke_width = 5;
245 for (
int x = 0;
x < 5; ++
x) {
246 for (
int y = 0;
y < 5; ++
y) {
254 std::shared_ptr<Texture>
texture =
265 Paint{.color_source = image_source});
270 Paint{.color_source = image_source, .image_filter = blur_filter});
271 paint_lines(0, 300,
Paint{.color_source = image_source});
272 paint_lines(300, 300,
273 Paint{.color_source = image_source, .image_filter = blur_filter});
274 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
282 .mask_blur_descriptor =
289 canvas.DrawCircle({300, 300}, 200,
paint);
292 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
308 canvas.Scale(
Vector2{0.8f, 0.8f});
317 paint.mask_blur_descriptor->style = config.
style;
324 const Scalar radius = 20.0f;
325 const Scalar y_spacing = 100.0f;
330 radius, 60.0f - radius),
335 canvas.DrawCircle({
x + 25,
y + 25}, radius,
paint);
340 radius, 60.0f - radius),
352 {radius, 5.0f},
paint);
375 return canvas.EndRecordingAsPicture();
380 {
"NormalTranslucentZeroSigma",
385 {
"NormalTranslucent",
398 {
"SolidTranslucentWithFilters",
406 .invert_colors =
true}},
408 {
"SolidTranslucentExclusionBlend",
419 {
"InnerTranslucentWithBlurImageFilter",
433 {
"OuterOpaqueWithBlurImageFilter",
442#define MASK_BLUR_VARIANT_TEST(config) \
443 TEST_P(AiksTest, MaskBlurVariantTest##config) { \
444 ASSERT_TRUE(OpenPlaygroundHere( \
445 MaskBlurVariantTest(*this, kPaintVariations.at(#config)))); \
459#undef MASK_BLUR_VARIANT_TEST
464 canvas.Scale(GetContentScale());
476 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
482 canvas.Scale(GetContentScale());
483 std::shared_ptr<Texture> boston = CreateTextureForFixture(
"boston.jpg");
484 canvas.DrawImageRect(
485 std::make_shared<Image>(boston),
486 Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height),
496 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
499#define FLT_FORWARD(mock, real, method) \
500 EXPECT_CALL(*mock, method()) \
501 .WillRepeatedly(::testing::Return(real->method()));
506 "This backend doesn't yet support setting device capabilities.");
508 if (!WillRenderSomething()) {
512 GTEST_SKIP_(
"This test requires playgrounds.");
515 std::shared_ptr<const Capabilities> old_capabilities =
517 auto mock_capabilities = std::make_shared<MockCapabilities>();
518 EXPECT_CALL(*mock_capabilities, SupportsDecalSamplerAddressMode())
519 .Times(::testing::AtLeast(1))
520 .WillRepeatedly(::testing::Return(
false));
521 FLT_FORWARD(mock_capabilities, old_capabilities, GetDefaultColorFormat);
522 FLT_FORWARD(mock_capabilities, old_capabilities, GetDefaultStencilFormat);
524 GetDefaultDepthStencilFormat);
525 FLT_FORWARD(mock_capabilities, old_capabilities, SupportsOffscreenMSAA);
527 SupportsImplicitResolvingMSAA);
528 FLT_FORWARD(mock_capabilities, old_capabilities, SupportsReadFromResolve);
529 FLT_FORWARD(mock_capabilities, old_capabilities, SupportsFramebufferFetch);
530 FLT_FORWARD(mock_capabilities, old_capabilities, SupportsSSBO);
531 FLT_FORWARD(mock_capabilities, old_capabilities, SupportsCompute);
533 SupportsTextureToTextureBlits);
534 FLT_FORWARD(mock_capabilities, old_capabilities, GetDefaultGlyphAtlasFormat);
535 ASSERT_TRUE(SetCapabilities(mock_capabilities).
ok());
537 auto texture = std::make_shared<Image>(CreateTextureForFixture(
"boston.jpg"));
539 canvas.Scale(GetContentScale() * 0.5);
548 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
554 canvas.Scale(GetContentScale());
555 canvas.Scale({0.5, 0.5, 1.0});
556 std::shared_ptr<Texture> boston = CreateTextureForFixture(
"boston.jpg");
557 canvas.DrawImage(std::make_shared<Image>(boston),
Point(100, 100),
Paint{});
563 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
572 std::shared_ptr<Texture> boston = CreateTextureForFixture(
"boston.jpg");
574 Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height);
582 canvas.Scale(GetContentScale());
585 canvas.Translate({center.x, center.y, 0});
586 canvas.Scale({0.6, 0.6, 1});
589 canvas.DrawImageRect(std::make_shared<Image>(boston),
bounds,
592 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
597 std::shared_ptr<Texture> boston = CreateTextureForFixture(
"boston.jpg");
599 Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height);
607 canvas.Scale(GetContentScale());
610 canvas.Translate({center.x, center.y, 0});
611 canvas.Scale({0.6, 0.6, 1});
613 canvas.DrawImageRect(std::make_shared<Image>(boston),
bounds,
616 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
620 std::shared_ptr<Texture> boston = CreateTextureForFixture(
"boston.jpg");
623 const char* tile_mode_names[] = {
"Clamp",
"Repeat",
"Mirror",
"Decal"};
628 static float rotation = 0;
629 static float scale = 0.6;
630 static int selected_tile_mode = 3;
633 ImGuiWindowFlags_AlwaysAutoResize)) {
634 ImGui::SliderFloat(
"Rotation (degrees)", &rotation, -180, 180);
635 ImGui::SliderFloat(
"Scale", &
scale, 0, 2.0);
636 ImGui::Combo(
"Tile mode", &selected_tile_mode, tile_mode_names,
637 sizeof(tile_mode_names) /
sizeof(
char*));
643 Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height);
648 tile_modes[selected_tile_mode])};
653 canvas.Scale(GetContentScale());
656 canvas.Translate({center.x, center.y, 0});
658 canvas.Rotate(
Degrees(rotation));
660 canvas.DrawImageRect(std::make_shared<Image>(boston),
bounds,
662 return canvas.EndRecordingAsPicture();
665 ASSERT_TRUE(OpenPlaygroundHere(
callback));
670 const char* tile_mode_names[] = {
"Clamp",
"Repeat",
"Mirror",
"Decal"};
675 static float rotation = 45;
676 static float scale = 0.6;
677 static int selected_tile_mode = 3;
680 ImGuiWindowFlags_AlwaysAutoResize)) {
681 ImGui::SliderFloat(
"Rotation (degrees)", &rotation, -180, 180);
682 ImGui::SliderFloat(
"Scale", &
scale, 0, 2.0);
683 ImGui::Combo(
"Tile mode", &selected_tile_mode, tile_mode_names,
684 sizeof(tile_mode_names) /
sizeof(
char*));
693 tile_modes[selected_tile_mode])};
695 canvas.Scale(GetContentScale());
696 canvas.Translate({center.x, center.y, 0});
698 canvas.Rotate(
Degrees(rotation));
701 return canvas.EndRecordingAsPicture();
704 ASSERT_TRUE(OpenPlaygroundHere(
callback));
711 for (int32_t
i = 1;
i < 5; ++
i) {
717 .
LineTo({100.f + fi, 100.f + fi})
725 std::shared_ptr<RenderTargetCache>
cache =
726 std::make_shared<RenderTargetCache>(
729 std::shared_ptr<Image>
image =
picture.ToImage(aiks_context, {1024, 768});
738 for (int32_t
i = 0;
i < 5; ++
i) {
754 std::shared_ptr<RenderTargetCache>
cache =
755 std::make_shared<RenderTargetCache>(
758 std::shared_ptr<Image>
image =
picture.ToImage(aiks_context, {1024, 768});
768 auto boston = std::make_shared<Image>(
769 CreateTextureForFixture(
"boston.jpg",
true));
777 ImGuiWindowFlags_AlwaysAutoResize)) {
778 ImGui::SliderFloat(
"Sigma", &sigma, 0, 200);
779 ImGui::SliderFloat(
"Frequency", &
freq, 0.01, 2.0);
780 ImGui::SliderFloat(
"Amplitude", &, 1, 100);
785 canvas.Scale(GetContentScale());
787 canvas.DrawImage(boston,
788 Point(1024 / 2 - boston->GetSize().width / 2,
789 (768 / 2 - boston->GetSize().height / 2) +
y),
802 return canvas.EndRecordingAsPicture();
804 ASSERT_TRUE(OpenPlaygroundHere(
callback));
809 canvas.Scale(GetContentScale());
811 canvas.DrawPaint({.color =
Color(0.1, 0.1, 0.1, 1.0)});
813 std::vector<Color>
colors = {
Color{0.9568, 0.2627, 0.2118, 1.0},
814 Color{0.7568, 0.2627, 0.2118, 1.0}};
815 std::vector<Scalar> stops = {0.0, 1.0};
819 {0, 0}, {200, 200}, std::move(
colors), std::move(stops),
837 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
842 canvas.Scale(GetContentScale());
844 canvas.DrawPaint({.color =
Color(0.1, 0.1, 0.1, 1.0)});
846 std::vector<Color>
colors = {
Color{0.9568, 0.2627, 0.2118, 1.0},
847 Color{0.7568, 0.2627, 0.2118, 1.0}};
848 std::vector<Scalar> stops = {0.0, 1.0};
852 {0, 0}, {200, 200}, std::move(
colors), std::move(stops),
870 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
875 canvas.Scale(GetContentScale());
877 canvas.DrawPaint({.color =
Color(0.1, 0.1, 0.1, 1.0)});
879 std::vector<Color>
colors = {
Color{0.9568, 0.2627, 0.2118, 1.0},
880 Color{0.7568, 0.2627, 0.2118, 1.0}};
881 std::vector<Scalar> stops = {0.0, 1.0};
885 {0, 0}, {200, 200}, std::move(
colors), std::move(stops),
903 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
908 canvas.Scale(GetContentScale());
910 canvas.DrawPaint({.color =
Color(0.1, 0.1, 0.1, 1.0)});
931 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
936 canvas.Scale(GetContentScale());
938 canvas.DrawPaint({.color =
Color(0.1, 0.1, 0.1, 1.0)});
959 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
964 canvas.Scale(GetContentScale());
966 canvas.DrawPaint({.color =
Color(0.1, 0.1, 0.1, 1.0)});
987 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
994 ImGuiWindowFlags_AlwaysAutoResize)) {
995 ImGui::SliderFloat(
"Sigma", &sigma, 0, 500);
999 canvas.Scale(GetContentScale());
1004 .sigma =
Sigma(sigma),
1006 std::shared_ptr<Texture> boston = CreateTextureForFixture(
"boston.jpg");
1007 canvas.DrawImage(std::make_shared<Image>(boston), {200, 200},
paint);
1011 return canvas.EndRecordingAsPicture();
1013 ASSERT_TRUE(OpenPlaygroundHere(
callback));
1038 return canvas.EndRecordingAsPicture();
1041 ASSERT_TRUE(OpenPlaygroundHere(
callback));
1047 canvas.SaveLayer({}, std::nullopt,
1054 EXPECT_EQ(4,
picture.pass->GetRequiredMipCount());
1058 size_t blur_required_mip_count =
1063 canvas.SaveLayer({}, std::nullopt,
1070 std::shared_ptr<RenderTargetCache>
cache =
1071 std::make_shared<RenderTargetCache>(
GetContext()->GetResourceAllocator());
1073 picture.ToImage(aiks_context, {100, 100});
1075 size_t max_mip_count = 0;
1076 for (
auto it =
cache->GetRenderTargetDataBegin();
1077 it !=
cache->GetRenderTargetDataEnd(); ++it) {
1078 max_mip_count =
std::max(it->config.mip_count, max_mip_count);
1080 EXPECT_EQ(max_mip_count, blur_required_mip_count);
1085 size_t blur_required_mip_count =
1092 canvas.SaveLayer({}, std::nullopt,
1099 std::shared_ptr<RenderTargetCache>
cache =
1100 std::make_shared<RenderTargetCache>(
GetContext()->GetResourceAllocator());
1102 picture.ToImage(aiks_context, {100, 100});
1104 size_t max_mip_count = 0;
1105 for (
auto it =
cache->GetRenderTargetDataBegin();
1106 it !=
cache->GetRenderTargetDataEnd(); ++it) {
1107 max_mip_count =
std::max(it->config.mip_count, max_mip_count);
1109 EXPECT_EQ(max_mip_count, blur_required_mip_count);
1123 size_t blur_required_mip_count =
1134 std::shared_ptr<RenderTargetCache>
cache =
1135 std::make_shared<RenderTargetCache>(
GetContext()->GetResourceAllocator());
1137 picture.ToImage(aiks_context, {1024, 768});
1139 size_t max_mip_count = 0;
1140 for (
auto it =
cache->GetRenderTargetDataBegin();
1141 it !=
cache->GetRenderTargetDataEnd(); ++it) {
1142 max_mip_count =
std::max(it->config.mip_count, max_mip_count);
1144 EXPECT_EQ(max_mip_count, blur_required_mip_count);
1158 size_t blur_required_mip_count =
1175 std::shared_ptr<RenderTargetCache>
cache =
1176 std::make_shared<RenderTargetCache>(
GetContext()->GetResourceAllocator());
1178 picture.ToImage(aiks_context, {1024, 768});
1180 size_t max_mip_count = 0;
1181 for (
auto it =
cache->GetRenderTargetDataBegin();
1182 it !=
cache->GetRenderTargetDataEnd(); ++it) {
1183 max_mip_count =
std::max(it->config.mip_count, max_mip_count);
1185 EXPECT_EQ(max_mip_count, blur_required_mip_count);
1202 ImGuiWindowFlags_AlwaysAutoResize)) {
1203 ImGui::SliderFloat(
"Sigma", &sigma, 0, 500);
1207 canvas.Scale(GetContentScale());
1208 canvas.DrawPaint({.color =
Color(0.1, 0.1, 0.1, 1.0)});
1210 std::shared_ptr<Texture> boston = CreateTextureForFixture(
"boston.jpg");
1217 .color_source = image_source,
1218 .mask_blur_descriptor =
1221 .sigma =
Sigma(sigma),
1225 Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height),
1228 return canvas.EndRecordingAsPicture();
1230 ASSERT_TRUE(OpenPlaygroundHere(
callback));
static bool ok(int result)
#define FLT_FORWARD(mock, real, method)
#define MASK_BLUR_VARIANT_TEST(config)
static bool ImGuiBegin(const char *name, bool *p_open, ImGuiWindowFlags flags)
static std::shared_ptr< ColorFilter > MakeBlend(BlendMode blend_mode, Color color)
static ColorSource MakeLinearGradient(Point start_point, Point end_point, std::vector< Color > colors, std::vector< Scalar > stops, Entity::TileMode tile_mode, Matrix effect_transform)
static ColorSource MakeImage(std::shared_ptr< Texture > texture, Entity::TileMode x_tile_mode, Entity::TileMode y_tile_mode, SamplerDescriptor sampler_descriptor, Matrix effect_transform)
@ kNormal
Blurred inside and outside.
@ kOuter
Nothing inside, blurred outside.
@ kInner
Blurred inside, nothing outside.
@ kSolid
Solid inside, blurred outside.
static std::string_view kNoMipsError
static std::shared_ptr< ImageFilter > MakeBlur(Sigma sigma_x, Sigma sigma_y, FilterContents::BlurStyle blur_style, Entity::TileMode tile_mode)
Path TakePath(FillType fill=FillType::kNonZero)
PathBuilder & AddArc(const Rect &oval_bounds, Radians start, Radians sweep, bool use_center=false)
PathBuilder & MoveTo(Point point, bool relative=false)
PathBuilder & AddLine(const Point &p1, const Point &p2)
Move to point p1, then insert a line from p1 to p2.
Point GetContentScale() const
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
static float max(float r, float g, float b)
static void draw_line(SkCanvas *canvas, SkImage *, const SkRect &r, sk_sp< SkImageFilter > imf)
SK_API GrDirectContext * GetContext(const SkImage *src)
Optional< SkRect > bounds
sk_sp< const SkImage > image
sk_sp< const SkPicture > picture
sk_sp< SkBlender > blender SkRect rect
PODArray< SkColor > colors
skia_private::AutoTArray< sk_sp< SkImageFilter > > filters TypedMatrix matrix TypedMatrix matrix SkScalar dx
SK_API sk_sp< SkShader > Color(SkColor)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace Enable an endless trace buffer The default is a ring buffer This is useful when very old events need to viewed For during application launch Memory usage will continue to grow indefinitely however Start app with an specific route defined on the framework flutter assets Path to the Flutter assets directory enable service port Allow the VM service to fallback to automatic port selection if binding to a specified port fails trace Trace early application lifecycle Automatically switches to an endless trace buffer trace skia Filters out all Skia trace event categories except those that are specified in this comma separated list dump skp on shader Automatically dump the skp that triggers new shader compilations This is useful for writing custom ShaderWarmUp to reduce jank By this is not enabled to reduce the overhead purge persistent cache
static const std::map< std::string, MaskBlurTestConfig > kPaintVariations
static Picture MaskBlurVariantTest(const AiksTest &test_context, const MaskBlurTestConfig &config)
TEST_P(AiksTest, CanRenderAdvancedBlendColorFilterWithSaveLayer)
Point DrawPlaygroundPoint(PlaygroundPoint &point)
std::tuple< Point, Point > DrawPlaygroundLine(PlaygroundPoint &point_a, PlaygroundPoint &point_b)
void MoveTo(PathBuilder *builder, Scalar x, Scalar y)
void LineTo(PathBuilder *builder, Scalar x, Scalar y)
void Close(PathBuilder *builder)
static constexpr Color Crimson()
static constexpr Color Grey()
static constexpr Color LimeGreen()
static constexpr Color GreenYellow()
static constexpr Color Chartreuse()
static constexpr Color Black()
static constexpr Color CornflowerBlue()
static constexpr Color White()
static constexpr Color Magenta()
constexpr Color WithAlpha(Scalar new_alpha) const
static constexpr Color Maroon()
static constexpr Color OrangeRed()
static constexpr Color DarkGreen()
static constexpr Color Orange()
static constexpr Color Purple()
static constexpr Color Wheat()
static constexpr Color Red()
static constexpr Color AntiqueWhite()
static constexpr Color DarkMagenta()
static constexpr Color Yellow()
static constexpr Color Blue()
static constexpr Color Green()
static constexpr Matrix MakeTranslation(const Vector3 &t)
static constexpr Matrix MakeScale(const Vector3 &s)
FilterContents::BlurStyle style
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...
static constexpr TPoint< Type > MakeXY(Type x, Type y)
static constexpr TRect MakeXYWH(Type x, Type y, Type width, Type height)
constexpr TRect< T > Expand(T left, T top, T right, T bottom) const
Returns a rectangle with expanded edges. Negative expansion results in shrinking.
static constexpr TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
std::shared_ptr< ImageFilter > image_filter
FilterContents::BlurStyle style
#define EXPECT_TRUE(handle)