16 #include "flutter/testing/testing.h"
22 #include "impeller/aiks/testing/context_spy.h"
42 #include "third_party/imgui/imgui.h"
43 #include "third_party/skia/include/core/SkFontMgr.h"
44 #include "txt/platform.h"
63 ASSERT_EQ(canvas.
Restore(),
false);
90 auto image = std::make_shared<Image>(CreateTextureForFixture(
"kalimba.jpg"));
99 auto image = std::make_shared<Image>(CreateTextureForFixture(
"kalimba.jpg"));
142 Color(0, 1, 0, 0.5)),
156 bool GenerateMipmap(
const std::shared_ptr<Context>& context,
157 std::shared_ptr<Texture> texture,
159 auto buffer = context->CreateCommandBuffer();
163 auto pass = buffer->CreateBlitPass();
167 pass->GenerateMipmap(std::move(texture), std::move(label));
169 pass->EncodeCommands(context->GetResourceAllocator());
170 return context->GetCommandQueue()->Submit({buffer}).ok();
173 void CanRenderTiledTexture(
AiksTest* aiks_test,
175 Matrix local_matrix = {}) {
176 auto context = aiks_test->GetContext();
177 ASSERT_TRUE(context);
178 auto texture = aiks_test->CreateTextureForFixture(
"table_mountain_nx.png",
180 GenerateMipmap(context, texture,
"table_mountain_nx");
182 canvas.Scale(aiks_test->GetContentScale());
183 canvas.Translate({100.0f, 100.0f, 0});
187 paint.color = Color(1, 1, 1, 1);
203 PathBuilder path_builder;
204 path_builder.AddCircle({150, 150}, 150);
205 path_builder.AddRoundedRect(
Rect::MakeLTRB(300, 300, 600, 600), 10);
207 canvas.DrawPath(path_builder.TakePath(), paint);
212 PathBuilder path_builder;
213 path_builder.AddCircle({150, 450}, 150);
216 canvas.DrawPath(path_builder.TakePath(), paint);
219 ASSERT_TRUE(aiks_test->OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
247 auto image = std::make_shared<Image>(CreateTextureForFixture(
"kalimba.jpg"));
248 Size image_half_size =
Size(image->GetSize()) * 0.5;
252 source_rect = source_rect.Shift(
Point(image_half_size));
261 canvas.
Scale(GetContentScale());
306 std::vector<Color> gradient_colors = {
307 Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
308 Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
309 Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
310 Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
311 Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
312 Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
313 Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
314 std::vector<Scalar> stops = {
323 auto texture = CreateTextureForFixture(
"airplane.jpg",
327 {500, 600}, 75, std::move(gradient_colors), std::move(stops),
380 .HorizontalLineTo(-200)
382 .CubicCurveTo({0, -40}, {0, -80}, {200, -80})
420 for (
int i = 0; i < 15; i++) {
423 paint.
color = colors[i % colors.size()];
452 std::vector<Color> colors = {
Color{0.9568, 0.2627, 0.2118, 1.0},
453 Color{0.1294, 0.5882, 0.9529, 1.0}};
454 std::vector<Scalar> stops = {
460 {0, 0}, {100, 100}, std::move(colors), std::move(stops),
478 paint.
color =
Color{0.9568, 0.2627, 0.2118, 1.0};
480 paint.
color =
Color{0.1294, 0.5882, 0.9529, 1.0};
488 auto image = picture.
ToImage(renderer,
ISize{1000, 1000});
510 auto image = picture.
ToImage(renderer,
ISize{1000, 1000});
576 std::make_shared<Image>(CreateTextureForFixture(
"kalimba.jpg"));
660 CanPerformSaveLayerWithBoundsAndLargerIntermediateIsNotAllocated) {
716 const std::string& text,
717 const std::string_view& font_fixture,
721 Rect::MakeXYWH(options.position.x - 50, options.position.y, 900, 10),
722 Paint{.color = Color::Aqua().WithAlpha(0.25)});
726 Paint{.color = Color::Red().WithAlpha(0.25)});
729 auto c_font_fixture = std::string(font_fixture);
730 auto mapping = flutter::testing::OpenFixtureAsSkData(c_font_fixture.c_str());
734 sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
735 SkFont sk_font(font_mgr->makeFromData(mapping), options.font_size);
736 auto blob = SkTextBlob::MakeFromString(text.c_str(), sk_font);
745 text_paint.color = options.color;
746 text_paint.mask_blur_descriptor = options.mask_blur_descriptor;
753 const std::string& text,
754 const std::string& font_fixture,
758 Rect::MakeXYWH(options.position.x - 50, options.position.y, 900, 10),
759 Paint{.color = Color::Aqua().WithAlpha(0.25)});
763 Paint{.color = Color::Red().WithAlpha(0.25)});
766 auto mapping = flutter::testing::OpenFixtureAsMapping(font_fixture.c_str());
770 auto typeface_stb = std::make_shared<TypefaceSTB>(std::move(mapping));
773 typeface_stb, Font::Metrics{.point_size = options.font_size}, text);
776 text_paint.color = options.color;
785 GetContext(), canvas,
"the quick brown fox jumped over the lazy dog!.?",
786 "Roboto-Regular.ttf"));
794 GetContext(), canvas,
"the quick brown fox jumped over the lazy dog!.?",
795 "Roboto-Regular.ttf"));
803 std::array<Scalar, 20> phase_offsets = {
804 7.82637e-06, 0.131538, 0.755605, 0.45865, 0.532767,
805 0.218959, 0.0470446, 0.678865, 0.679296, 0.934693,
806 0.383502, 0.519416, 0.830965, 0.0345721, 0.0534616,
807 0.5297, 0.671149, 0.00769819, 0.383416, 0.0668422};
808 auto callback = [&](
AiksContext& renderer) -> std::optional<Picture> {
809 static float font_size = 20;
810 static float phase_variation = 0.2;
811 static float speed = 0.5;
812 static float magnitude = 100;
814 ImGuiWindowFlags_AlwaysAutoResize)) {
815 ImGui::SliderFloat(
"Font size", &font_size, 5, 50);
816 ImGui::SliderFloat(
"Phase variation", &phase_variation, 0, 1);
817 ImGui::SliderFloat(
"Oscillation speed", &speed, 0, 2);
818 ImGui::SliderFloat(
"Oscillation magnitude", &magnitude, 0, 300);
823 canvas.
Scale(GetContentScale());
825 for (
size_t i = 0; i < phase_offsets.size(); i++) {
827 Point(200 + magnitude *
828 std::sin((-phase_offsets[i] *
k2Pi * phase_variation +
829 GetSecondsElapsed() * speed)),
830 200 + i * font_size * 1.1
833 GetContext(), canvas,
834 "the quick brown fox jumped over "
836 "Roboto-Regular.ttf",
837 {.font_size = font_size, .position = position})) {
844 ASSERT_TRUE(OpenPlaygroundHere(callback));
852 GetContext(), canvas,
"the quick brown fox jumped over the lazy dog!.?",
853 "HomemadeApple.ttf"));
859 "Apple Color Emoji.ttc";
861 "NotoColorEmoji.ttf";
869 GetContext(), canvas,
"😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊",
kFontFixture));
878 GetContext(), canvas,
"😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊",
kFontFixture,
882 .sigma =
Sigma(4)}}));
891 GetContext(), canvas,
"😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊",
kFontFixture,
906 GetContext(), canvas,
"the quick brown fox jumped over the lazy dog!.?",
907 "Roboto-Regular.ttf"));
912 GetContext(), canvas,
"the quick brown fox jumped over the lazy dog!.?",
913 "Roboto-Regular.ttf"));
923 auto mapping = flutter::testing::OpenFixtureAsSkData(
"wtf.otf");
924 ASSERT_NE(mapping,
nullptr);
927 sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
928 SkFont sk_font(font_mgr->makeFromData(mapping), font_size);
936 } text[] = {{
Point(0, 0),
"0F0F0F0"},
937 {
Point(1, 2),
"789"},
938 {
Point(1, 3),
"456"},
939 {
Point(1, 4),
"123"},
940 {
Point(0, 6),
"0F0F0F0"}};
941 for (
auto& t : text) {
943 canvas.
Translate(t.position *
Point(font_size * 2, font_size * 1.1));
945 auto blob = SkTextBlob::MakeFromString(t.text, sk_font);
946 ASSERT_NE(blob,
nullptr);
958 canvas.
Scale(GetContentScale());
966 GetContext(), canvas,
"the quick brown fox jumped over the lazy dog!.?",
967 "Roboto-Regular.ttf"));
983 canvas.
DrawPaint({.color = Color::Color::OrangeRed().WithAlpha(0.5)});
991 canvas.
DrawPaint({.color = Color::Color::OrangeRed().WithAlpha(0.5),
999 .mask_blur_descriptor =
1008 canvas.
DrawCircle({300, 300}, 200, filtered);
1014 std::vector<Color> colors = {
Color{0.9568, 0.2627, 0.2118, 1.0},
1015 Color{0.1294, 0.5882, 0.9529, 1.0}};
1016 std::vector<Scalar> stops = {0.0, 1.0};
1020 {0, 0}, {100, 100}, std::move(colors), std::move(stops),
1033 #define BLEND_MODE_TUPLE(blend_mode) {#blend_mode, BlendMode::k##blend_mode},
1041 std::vector<const char*> blend_mode_names;
1042 std::vector<BlendMode> blend_mode_values;
1044 const std::vector<std::tuple<const char*, BlendMode>> blends = {
1046 assert(blends.size() ==
1048 for (
const auto& [name, mode] : blends) {
1049 blend_mode_names.push_back(name);
1050 blend_mode_values.push_back(mode);
1054 return {blend_mode_names, blend_mode_values};
1060 auto callback = [&](
AiksContext& renderer) -> std::optional<Picture> {
1062 static Color foreground = Color::Color::OrangeRed().
WithAlpha(0.5);
1063 static int current_blend_index = 3;
1066 ImGuiWindowFlags_AlwaysAutoResize)) {
1067 ImGui::ColorEdit4(
"Background",
reinterpret_cast<float*
>(&background));
1068 ImGui::ColorEdit4(
"Foreground",
reinterpret_cast<float*
>(&foreground));
1069 ImGui::ListBox(
"Blend mode", ¤t_blend_index,
1070 modes.blend_mode_names.data(),
1071 modes.blend_mode_names.size());
1077 canvas.
DrawPaint({.color = background});
1079 {.color = foreground,
1080 .blend_mode =
static_cast<BlendMode>(current_blend_index)});
1083 ASSERT_TRUE(OpenPlaygroundHere(callback));
1110 auto draw_color_wheel = [](
Canvas& canvas) {
1113 auto color_wheel_sampler = [](
Radians r) {
1117 auto color_cycle = [](
Scalar x) {
1118 Scalar cycle = std::fmod(x, 6.0f);
1119 return std::max(0.0f, std::min(1.0f, 2 - std::abs(2 - cycle)));
1121 return Color(color_cycle(6 * x + 1),
1122 color_cycle(6 * x - 1),
1123 color_cycle(6 * x - 3),
1132 const int max_dist = 900;
1133 for (
int i = 0; i <= 900; i++) {
1136 Scalar normalized_distance =
static_cast<Scalar>(i) / max_dist;
1139 color_wheel_sampler(r).
WithAlpha(1.0f - normalized_distance);
1143 canvas.
DrawCircle(position, 9 + normalized_distance * 3, paint);
1147 std::shared_ptr<Image> color_wheel_image;
1148 Matrix color_wheel_transform;
1150 auto callback = [&](
AiksContext& renderer) -> std::optional<Picture> {
1152 static bool cache_the_wheel =
true;
1153 static int current_blend_index = 3;
1154 static float dst_alpha = 1;
1155 static float src_alpha = 1;
1161 ImGuiWindowFlags_AlwaysAutoResize)) {
1162 ImGui::Checkbox(
"Cache the wheel", &cache_the_wheel);
1163 ImGui::ListBox(
"Blending mode", ¤t_blend_index,
1166 ImGui::SliderFloat(
"Source alpha", &src_alpha, 0, 1);
1167 ImGui::ColorEdit4(
"Color A",
reinterpret_cast<float*
>(&color0));
1168 ImGui::ColorEdit4(
"Color B",
reinterpret_cast<float*
>(&color1));
1169 ImGui::ColorEdit4(
"Color C",
reinterpret_cast<float*
>(&color2));
1170 ImGui::SliderFloat(
"Destination alpha", &dst_alpha, 0, 1);
1174 static Point content_scale;
1175 Point new_content_scale = GetContentScale();
1177 if (!cache_the_wheel || new_content_scale != content_scale) {
1178 content_scale = new_content_scale;
1183 canvas.
Scale(content_scale);
1188 draw_color_wheel(canvas);
1190 auto snapshot = color_wheel_picture.
Snapshot(renderer);
1191 if (!snapshot.has_value() || !snapshot->texture) {
1192 return std::nullopt;
1194 color_wheel_image = std::make_shared<Image>(snapshot->texture);
1195 color_wheel_transform = snapshot->transform;
1207 canvas.
Transform(color_wheel_transform);
1213 canvas.
Scale(content_scale);
1226 paint.
color = color0;
1228 paint.
color = color1;
1230 paint.
color = color2;
1238 ASSERT_TRUE(OpenPlaygroundHere(callback));
1282 canvas.
Scale(GetContentScale());
1284 const int color_count = 3;
1285 Color colors[color_count] = {
1296 while (radius > 0) {
1297 paint.
color = colors[(c_index++) % color_count];
1306 std::vector<Color> gradient_colors = {
1307 Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
1308 Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
1309 Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
1310 Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
1311 Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
1312 Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
1313 Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
1314 std::vector<Scalar> stops = {
1323 auto texture = CreateTextureForFixture(
"airplane.jpg",
1327 {500, 600}, 75, std::move(gradient_colors), std::move(stops),
1341 canvas.
Scale(GetContentScale());
1343 const int color_count = 3;
1344 Color colors[color_count] = {
1355 auto draw = [&paint, &colors, &c_index](
Canvas& canvas,
Point center,
1357 for (
int i = 0; i < n; i++) {
1358 paint.
color = colors[(c_index++) % color_count];
1359 canvas.DrawCircle(center, r, paint);
1366 draw(canvas, {10, 10}, 2, 2, 14);
1368 draw(canvas, {10, 10}, 35, 10, 56);
1370 std::vector<Color> gradient_colors = {
1371 Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
1372 Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
1373 Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
1374 Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
1375 Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
1376 Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
1377 Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
1378 std::vector<Scalar> stops = {
1387 auto texture = CreateTextureForFixture(
"airplane.jpg",
1391 {500, 600}, 75, std::move(gradient_colors), std::move(stops),
1393 draw(canvas, {500, 600}, 5, 10, 10);
1398 draw(canvas, {800, 300}, 5, 10, 10);
1400 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1405 canvas.
Scale(GetContentScale());
1407 const int color_count = 3;
1408 Color colors[color_count] = {
1418 int long_radius = 600;
1419 int short_radius = 600;
1420 while (long_radius > 0 && short_radius > 0) {
1421 paint.
color = colors[(c_index++) % color_count];
1423 long_radius * 2, short_radius * 2),
1426 short_radius * 2, long_radius * 2),
1428 if (short_radius > 30) {
1437 std::vector<Color> gradient_colors = {
1438 Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
1439 Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
1440 Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
1441 Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
1442 Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
1443 Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
1444 Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
1445 std::vector<Scalar> stops = {
1454 auto texture = CreateTextureForFixture(
"airplane.jpg",
1460 {300, 650}, 75, std::move(gradient_colors), std::move(stops),
1476 canvas.
Scale(GetContentScale());
1478 const int color_count = 3;
1479 Color colors[color_count] = {
1489 for (
int i = 0; i < 4; i++) {
1490 for (
int j = 0; j < 4; j++) {
1491 paint.
color = colors[(c_index++) % color_count];
1493 Size(i * 5 + 10, j * 5 + 10), paint);
1496 paint.
color = colors[(c_index++) % color_count];
1498 paint.
color = colors[(c_index++) % color_count];
1501 std::vector<Color> gradient_colors = {
1502 Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
1503 Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
1504 Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
1505 Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
1506 Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
1507 Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
1508 Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
1509 std::vector<Scalar> stops = {
1518 auto texture = CreateTextureForFixture(
"airplane.jpg",
1524 for (
int i = 1; i <= 10; i++) {
1527 550 + i * 20, 550 + j * 20),
1528 Size(i * 10, j * 10), paint);
1532 {200, 650}, 75, std::move(gradient_colors), std::move(stops),
1541 for (
int i = 1; i <= 10; i++) {
1544 720 + i * 20, 220 + j * 20),
1545 Size(i * 10, j * 10), paint);
1559 canvas.
Scale(GetContentScale());
1570 for (
int i = 0; i < 5; i++) {
1571 Scalar x = (i + 1) * 100;
1572 Scalar radius = x / 10.0f;
1574 radius, 60.0f - radius),
1580 for (
int i = 0; i < 5; i++) {
1581 Scalar x = (i + 1) * 100;
1582 Scalar radius = x / 10.0f;
1583 canvas.
DrawCircle({x + 25, y + 25}, radius, paint);
1588 for (
int i = 0; i < 5; i++) {
1589 Scalar x = (i + 1) * 100;
1590 Scalar radius = x / 10.0f;
1592 radius, 60.0f - radius),
1598 for (
int i = 0; i < 5; i++) {
1599 Scalar x = (i + 1) * 100;
1600 Scalar radius = x / 20.0f;
1608 for (
int i = 0; i < 5; i++) {
1609 Scalar x = (i + 1) * 100;
1610 Scalar radius = x / 20.0f;
1612 {radius, 5.0f}, paint);
1620 canvas.
Scale(GetContentScale());
1622 const int color_count = 3;
1623 Color colors[color_count] = {
1632 auto draw_rrect_as_path = [&canvas](
const Rect& rect,
const Size& radii,
1633 const Paint& paint) {
1640 for (
int i = 0; i < 4; i++) {
1641 for (
int j = 0; j < 4; j++) {
1642 paint.
color = colors[(c_index++) % color_count];
1643 draw_rrect_as_path(
Rect::MakeXYWH(i * 100 + 10, j * 100 + 20, 80, 80),
1644 Size(i * 5 + 10, j * 5 + 10), paint);
1647 paint.
color = colors[(c_index++) % color_count];
1649 paint.
color = colors[(c_index++) % color_count];
1652 std::vector<Color> gradient_colors = {
1653 Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
1654 Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
1655 Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
1656 Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
1657 Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
1658 Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
1659 Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
1660 std::vector<Scalar> stops = {
1669 auto texture = CreateTextureForFixture(
"airplane.jpg",
1675 for (
int i = 1; i <= 10; i++) {
1678 550 + i * 20, 550 + j * 20),
1679 Size(i * 10, j * 10), paint);
1683 {200, 650}, 75, std::move(gradient_colors), std::move(stops),
1692 for (
int i = 1; i <= 10; i++) {
1695 720 + i * 20, 220 + j * 20),
1696 Size(i * 10, j * 10), paint);
1709 auto callback = [&](
AiksContext& renderer) -> std::optional<Picture> {
1711 canvas.
Scale(GetContentScale());
1716 auto current =
Point{25, 25};
1718 const auto size =
Size(100, 100);
1726 .stroke_width = 5.0f,
1743 ASSERT_TRUE(OpenPlaygroundHere(callback));
1829 canvas.
Scale(GetContentScale());
1832 auto texture = std::make_shared<Image>(CreateTextureForFixture(
"boston.jpg"));
1833 auto draw_image_layer = [&canvas, &texture](
const Paint& paint) {
1844 draw_image_layer(effect_paint);
1848 draw_image_layer(effect_paint);
1853 #if IMPELLER_ENABLE_3D
1857 flutter::testing::OpenFixtureAsMapping(
"flutter_logo_baked.glb.ipscene");
1858 ASSERT_NE(mapping,
nullptr);
1861 *mapping, *GetContext()->GetResourceAllocator());
1862 ASSERT_NE(gltf_scene,
nullptr);
1864 auto callback = [&](
AiksContext& renderer) -> std::optional<Picture> {
1871 ImGuiWindowFlags_AlwaysAutoResize)) {
1872 ImGui::SliderFloat(
"Distance", &
distance, 0, 4);
1873 ImGui::SliderFloat(
"Y", &y_pos, -3, 3);
1874 ImGui::SliderFloat(
"FOV", &fov, 1, 180);
1878 Scalar angle = GetSecondsElapsed();
1879 auto camera_position =
1889 canvas.Scale(GetContentScale());
1890 canvas.DrawPaint(paint);
1891 return canvas.EndRecordingAsPicture();
1894 ASSERT_TRUE(OpenPlaygroundHere(callback));
1896 #endif // IMPELLER_ENABLE_3D
1926 auto entity_pass = std::make_shared<EntityPass>();
1934 auto delegate = std::make_shared<OpacityPeepholePassDelegate>(paint);
1935 ASSERT_FALSE(delegate->CanCollapseIntoParentPass(entity_pass.get()));
1943 delegate = std::make_shared<OpacityPeepholePassDelegate>(paint);
1944 ASSERT_FALSE(delegate->CanCollapseIntoParentPass(entity_pass.get()));
1950 delegate = std::make_shared<OpacityPeepholePassDelegate>(paint);
1951 ASSERT_FALSE(delegate->CanCollapseIntoParentPass(entity_pass.get()));
1957 entity_pass->AddEntity(std::move(entity));
1960 delegate = std::make_shared<OpacityPeepholePassDelegate>(paint);
1961 ASSERT_TRUE(delegate->CanCollapseIntoParentPass(entity_pass.get()));
1973 ASSERT_EQ(picture.
pass->GetClearColor(), expected);
1975 std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
1976 std::shared_ptr<Context> real_context = GetContext();
1977 std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
1979 std::shared_ptr<Image> image = picture.
ToImage(renderer, {300, 300});
1981 ASSERT_EQ(spy->render_passes_.size(), 1llu);
1982 std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
1983 ASSERT_EQ(render_pass->GetCommands().size(), 0llu);
1989 ParentSaveLayerCreatesRenderPassWhenChildBackdropFilterIsPresent) {
1999 std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
2000 std::shared_ptr<Context> real_context = GetContext();
2001 std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
2003 std::shared_ptr<Image> image = picture.
ToImage(renderer, {300, 300});
2005 ASSERT_EQ(spy->render_passes_.size(),
2007 std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
2008 ASSERT_EQ(render_pass->GetCommands().size(), 0llu);
2019 std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
2021 std::shared_ptr<Context> real_context = GetContext();
2022 std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
2024 std::shared_ptr<Image> image = picture.
ToImage(renderer, {300, 300});
2026 ASSERT_EQ(spy->render_passes_.size(), 1llu);
2027 std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
2028 ASSERT_EQ(render_pass->GetCommands().size(), 0llu);
2039 std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
2041 std::shared_ptr<Context> real_context = GetContext();
2042 std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
2044 std::shared_ptr<Image> image = picture.
ToImage(renderer, {300, 300});
2046 ASSERT_EQ(spy->render_passes_.size(), 1llu);
2047 std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
2048 ASSERT_EQ(render_pass->GetCommands().size(), 2llu);
2059 std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
2061 std::shared_ptr<Context> real_context = GetContext();
2062 std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
2064 std::shared_ptr<Image> image = picture.
ToImage(renderer, {300, 300});
2066 ASSERT_EQ(spy->render_passes_.size(), 1llu);
2067 std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
2068 ASSERT_EQ(render_pass->GetCommands().size(), 1llu);
2079 std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
2081 std::shared_ptr<Context> real_context = GetContext();
2082 std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
2084 std::shared_ptr<Image> image = picture.
ToImage(renderer, {301, 301});
2086 ASSERT_EQ(spy->render_passes_.size(), 1llu);
2087 std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
2088 ASSERT_EQ(render_pass->GetCommands().size(), 2llu);
2102 ASSERT_EQ(picture.
pass->GetClearColor(), expected);
2104 std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
2105 std::shared_ptr<Context> real_context = GetContext();
2106 std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
2108 std::shared_ptr<Image> image = picture.
ToImage(renderer, {300, 300});
2110 ASSERT_EQ(spy->render_passes_.size(), 1llu);
2111 std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
2112 ASSERT_EQ(render_pass->GetCommands().size(), 0llu);
2128 std::optional<Color> actual_color;
2129 bool found_subpass =
false;
2131 if (
auto subpass = std::get_if<std::unique_ptr<EntityPass>>(&element)) {
2132 actual_color = subpass->get()->GetClearColor();
2133 found_subpass =
true;
2139 EXPECT_TRUE(found_subpass);
2140 EXPECT_FALSE(actual_color.has_value());
2194 1.0, 1.0, 1.0, 1.0, 0
2235 const std::shared_ptr<Image>& src_image,
2236 const std::shared_ptr<Image>& dst_image) {
2253 for (
const auto& color : source_colors) {
2260 canvas.SaveLayer({});
2262 canvas.DrawPaint({.color = destination_color});
2265 canvas.SaveLayer({.blend_mode = blend_mode});
2267 canvas.DrawRect(
Rect::MakeXYWH(25, 25, 100, 100), {.color = color});
2274 canvas.Translate(
Vector2(100, 0));
2276 canvas.RestoreToCount(0);
2283 canvas.Translate({0, 100});
2286 canvas.SaveLayer({});
2287 for (
const auto& color : source_colors) {
2290 {.color = destination_color.
Blend(color, blend_mode),
2292 canvas.Translate(
Vector2(100, 0));
2304 canvas.Translate({0, 250});
2310 for (
int y = 0; y < 400 / 8; y++) {
2311 for (
int x = 0; x < 800 / 16; x++) {
2312 canvas.DrawRect(
Rect::MakeXYWH(x * 16 + (y % 2) * 8, y * 8, 8, 8),
2322 canvas.DrawImage(src_image, {0, 0}, {.blend_mode = blend_mode});
2331 canvas.DrawImage(dst_image, {400, 0},
2333 canvas.SaveLayer({.blend_mode = blend_mode});
2335 canvas.DrawImage(src_image, {400, 0},
2343 return canvas.EndRecordingAsPicture();
2346 #define BLEND_MODE_TEST(blend_mode) \
2347 TEST_P(AiksTest, BlendMode##blend_mode) { \
2348 auto src_image = std::make_shared<Image>( \
2349 CreateTextureForFixture("blend_mode_src.png")); \
2350 auto dst_image = std::make_shared<Image>( \
2351 CreateTextureForFixture("blend_mode_dst.png")); \
2352 OpenPlaygroundHere(BlendModeTest( \
2353 GetContentScale(), BlendMode::k##blend_mode, src_image, dst_image)); \
2421 canvas.
Scale(GetContentScale());
2423 auto test = [&canvas](
const std::shared_ptr<ImageFilter>& filter) {
2424 auto DrawLine = [&canvas](
const Point& p0,
const Point& p1,
2440 canvas.
SaveLayer({.image_filter = filter},
2467 auto rotate_filter =
2472 test(rotate_filter);
2483 test(rgb_swap_filter);
2510 canvas.
Scale(GetContentScale());
2516 canvas.
SaveLayer({.image_filter = blur_filter}, std::nullopt);
2533 auto image = std::make_shared<Image>(CreateTextureForFixture(
"airplane.jpg"));
2534 canvas.
DrawImage(image, {100, 100}, {});
2537 canvas.
DrawImage(image, {100, 500}, {});
2546 auto image = std::make_shared<Image>(CreateTextureForFixture(
"airplane.jpg"));
2547 canvas.
DrawImage(image, {100, 100}, {});
2559 canvas.
DrawImage(image, {100, 500}, {});
2568 auto image = std::make_shared<Image>(CreateTextureForFixture(
"airplane.jpg"));
2569 canvas.
DrawImage(image, {100, 100}, {});
2582 canvas.
DrawImage(image, {100, 500}, {});
2589 TranslucentSaveLayerWithColorFilterAndImageFilterDrawsCorrectly) {
2592 auto image = std::make_shared<Image>(CreateTextureForFixture(
"airplane.jpg"));
2593 canvas.
DrawImage(image, {100, 100}, {});
2608 canvas.
DrawImage(image, {100, 500}, {});
2682 std::vector<Entity> entity;
2683 std::shared_ptr<SolidColorContents> contents;
2684 picture.
pass->IterateAllEntities([e = &entity, &contents](
Entity& entity) {
2687 std::static_pointer_cast<SolidColorContents>(entity.
GetContents());
2688 e->emplace_back(entity.
Clone());
2694 ASSERT_TRUE(entity.size() >= 1);
2695 ASSERT_TRUE(contents->IsOpaque());
2715 auto runtime_stages =
2716 OpenAssetAsRuntimeStage(
"runtime_stage_example.frag.iplr");
2718 auto runtime_stage =
2720 ASSERT_TRUE(runtime_stage);
2721 ASSERT_TRUE(runtime_stage->IsDirty());
2723 struct FragUniforms {
2726 } frag_uniforms = {.iResolution =
Vector2(400, 400), .iTime = 100.0};
2727 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
2728 uniform_data->resize(
sizeof(FragUniforms));
2729 memcpy(uniform_data->data(), &frag_uniforms,
sizeof(FragUniforms));
2731 std::vector<RuntimeEffectContents::TextureInput> texture_inputs;
2735 runtime_stage, uniform_data, texture_inputs);
2748 auto runtime_stages = OpenAssetAsRuntimeStage(
"gradient.frag.iplr");
2749 auto runtime_stage =
2751 ASSERT_TRUE(runtime_stage);
2752 ASSERT_TRUE(runtime_stage->IsDirty());
2754 struct FragUniforms {
2757 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
2758 uniform_data->resize(
sizeof(FragUniforms));
2759 memcpy(uniform_data->data(), &frag_uniforms,
sizeof(FragUniforms));
2761 std::vector<RuntimeEffectContents::TextureInput> texture_inputs;
2765 runtime_stage, uniform_data, texture_inputs);
2769 canvas.
Scale(GetContentScale());
2777 std::vector<Point> points = {
2786 std::vector<PointStyle> caps = {
2809 auto atlas = CreateTextureForFixture(
"bay_bridge.jpg");
2810 auto size = atlas->GetSize();
2811 auto image = std::make_shared<Image>(atlas);
2813 Scalar half_width = size.width / 2;
2814 Scalar half_height = size.height / 2;
2815 std::vector<Rect> texture_coordinates = {
2819 Rect::MakeLTRB(half_width, half_height, size.width, size.height)};
2821 std::vector<Matrix> transforms = {
2832 canvas.
Scale({0.25, 0.25, 1.0});
2833 canvas.
DrawAtlas(image, transforms, texture_coordinates, colors,
2842 auto atlas = CreateTextureForFixture(
"bay_bridge.jpg");
2843 auto size = atlas->GetSize();
2844 auto image = std::make_shared<Image>(atlas);
2846 Scalar half_width = size.width / 2;
2847 Scalar half_height = size.height / 2;
2848 std::vector<Rect> texture_coordinates = {
2852 Rect::MakeLTRB(half_width, half_height, size.width, size.height)};
2854 std::vector<Matrix> transforms = {
2863 canvas.
Scale({0.25, 0.25, 1.0});
2864 canvas.
DrawAtlas(image, transforms, texture_coordinates, {},
2871 auto texture = CreateTextureForFixture(
"table_mountain_nx.png",
2874 std::vector<Point> points = {
2883 std::vector<PointStyle> caps = {
2894 canvas.Translate({150, 0});
2897 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2904 auto mapping = flutter::testing::OpenFixtureAsSkData(
"Roboto-Regular.ttf");
2905 ASSERT_NE(mapping,
nullptr);
2908 sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
2909 SkFont sk_font(font_mgr->makeFromData(mapping), font_size);
2914 std::vector<Color> colors = {
Color{0.9568, 0.2627, 0.2118, 1.0},
2915 Color{0.1294, 0.5882, 0.9529, 1.0}};
2916 std::vector<Scalar> stops = {
2921 {0, 0}, {100, 100}, std::move(colors), std::move(stops),
2928 auto blob = SkTextBlob::MakeFromString(
"Hello", sk_font);
2929 ASSERT_NE(blob,
nullptr);
2931 canvas.DrawTextFrame(frame,
Point(), text_paint);
2933 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2990 auto result = contents.ApplyColorFilter([](
const Color& color) {
2993 ASSERT_TRUE(result);
2995 Color(0.424452, 0.828743, 0.79105, 0.9375));
3002 0.0, 0.0, 1.0, 0.01,
3003 0.0, 0.0, 0.0, 1.0) *
3007 "Roboto-Regular.ttf"));
3018 0.0, 0.0, 1.0, 0.01,
3019 0.0, 0.0, 0.0, 1.0) *
3023 "Roboto-Regular.ttf"));
3053 auto callback = [&](
AiksContext& renderer) -> std::optional<Picture> {
3056 capture_context.Rewind();
3057 auto document = capture_context.GetDocument(
"TestDocument");
3063 ImGuiWindowFlags_AlwaysAutoResize)) {
3064 document.GetElement()->properties.Iterate([](
CaptureProperty& property) {
3065 property.Invoke({.color = [](CaptureColorProperty& p) {
3066 ImGui::ColorEdit4(p.label.c_str(),
3067 reinterpret_cast<float*
>(&p.value));
3075 OpenPlaygroundHere(callback);
3079 ASSERT_FALSE(GetContext()->capture.IsActive());
3084 auto context = MakeContext();
3085 std::weak_ptr<Texture> weak_texture;
3088 auto texture = CreateTextureForFixture(
"table_mountain_nx.png");
3091 canvas.
Scale(GetContentScale());
3107 context->Shutdown();
3110 ASSERT_TRUE(weak_texture.expired()) <<
"When the texture is no longer in use "
3111 "by the backend, it should be "
3119 auto texture = CreateTextureForFixture(
"table_mountain_nx.png");
3124 auto vertices = {
Point(0, 0),
Point(texture->GetSize().width, 0),
3125 Point(0, texture->GetSize().height)};
3126 std::vector<uint16_t> indices = {0u, 1u, 2u};
3127 std::vector<Point> texture_coordinates = {};
3128 std::vector<Color> vertex_colors = {};
3129 auto geometry = std::make_shared<VerticesGeometry>(
3130 vertices, indices, texture_coordinates, vertex_colors,
3141 auto texture = CreateTextureForFixture(
"table_mountain_nx.png");
3147 auto vertices = {
Point(0, 0),
Point(texture->GetSize().width, 0),
3148 Point(0, texture->GetSize().height)};
3149 std::vector<uint16_t> indices = {0u, 1u, 2u};
3150 std::vector<Point> texture_coordinates = {};
3151 std::vector<Color> vertex_colors = {};
3152 auto geometry = std::make_shared<VerticesGeometry>(
3153 vertices, indices, texture_coordinates, vertex_colors,
3174 canvas.
Scale(GetContentScale());
3175 auto image = std::make_shared<Image>(CreateTextureForFixture(
"airplane.jpg"));
3178 .image_filter = std::make_shared<MatrixImageFilter>(
3191 canvas.
Scale(GetContentScale());
3196 .image_filter = std::make_shared<MatrixImageFilter>(
3207 MatrixImageFilterDoesntCullWhenScaledAndTranslatedFromOffscreen) {
3209 canvas.
Scale(GetContentScale());
3214 .image_filter = std::make_shared<MatrixImageFilter>(
3226 SetWindowSize({400, 400});
3228 canvas.
Scale(GetContentScale());
3231 .image_filter = std::make_shared<MatrixImageFilter>(
3241 ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3246 canvas.
Scale(GetContentScale());
3256 canvas.
Scale(GetContentScale());
3257 auto image = std::make_shared<Image>(CreateTextureForFixture(
"airplane.jpg"));
3291 auto texture = CreateTextureForFixture(
"monkey.png");
3351 std::vector<uint32_t> expected = {
3363 std::vector<uint32_t> actual;
3366 if (
auto* subpass = std::get_if<std::unique_ptr<EntityPass>>(&element)) {
3367 actual.push_back(subpass->get()->GetNewClipDepth());
3369 if (
Entity* entity = std::get_if<Entity>(&element)) {
3370 actual.push_back(entity->GetNewClipDepth());
3375 ASSERT_EQ(actual.size(), expected.size());
3376 for (
size_t i = 0; i < expected.size(); i++) {
3377 EXPECT_EQ(expected[i], actual[i]) <<
"Index: " << i;
3384 auto callback = [&](
AiksContext& renderer) -> std::optional<Picture> {
3410 Matrix(1.0, 0.0, 0.0, 0.0,
3412 0.0, 0.0, 1.0, 0.003,
3413 0.0, 0.0, 0.0, 1.0) *
3416 std::make_shared<Image>(CreateTextureForFixture(
"airplane.jpg"));
3428 ASSERT_TRUE(OpenPlaygroundHere(callback));
3435 canvas.
Scale(GetContentScale());
3438 std::vector<Color> colors = {
Color{0.9568, 0.2627, 0.2118, 1.0},
3439 Color{0.1294, 0.5882, 0.9529, 1.0}};
3440 std::vector<Scalar> stops = {
3445 {0, 0}, {100, 100}, std::move(colors), std::move(stops),