10#include "flutter/display_list/dl_blend_mode.h"
11#include "flutter/display_list/dl_builder.h"
12#include "flutter/display_list/dl_color.h"
13#include "flutter/display_list/dl_paint.h"
14#include "flutter/display_list/dl_tile_mode.h"
15#include "flutter/display_list/effects/dl_color_filter.h"
16#include "flutter/display_list/effects/dl_color_source.h"
17#include "flutter/display_list/effects/dl_image_filter.h"
18#include "flutter/display_list/effects/dl_mask_filter.h"
19#include "flutter/testing/testing.h"
20#include "gtest/gtest.h"
32#include "third_party/imgui/imgui.h"
43 Color(components[0], components[1], components[2], components[3])));
53 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
60 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
68 const float stops[2] = {0.0, 1.0};
71 2, colors.data(), stops,
79 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
89 save_paint.
setAlpha(
static_cast<uint8_t
>(255 * alpha));
90 builder.SaveLayer(
nullptr, &save_paint);
92 CreateTestFontOfSize(100)),
95 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
99 auto texture = CreateTextureForFixture(
"embarcadero.jpg");
103 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
111 paint.setStrokeWidth(30);
117 builder.Translate(100, 100);
121 paint.setStrokeMiter(4);
122 builder.DrawPath(path,
paint);
127 builder.Translate(0, 100);
130 paint.setStrokeMiter(1);
131 builder.DrawPath(path,
paint);
135 builder.Translate(150, 0);
139 builder.DrawPath(path,
paint);
142 builder.Translate(150, 0);
146 builder.DrawPath(path,
paint);
149 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
154 static float start_angle = 45;
155 static float sweep_angle = 270;
157 static bool use_center =
true;
159 static int selected_cap = 0;
160 const char* cap_names[] = {
"Butt",
"Round",
"Square"};
163 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
164 ImGui::SliderFloat(
"Start angle", &start_angle, -360, 360);
165 ImGui::SliderFloat(
"Sweep angle", &sweep_angle, -360, 360);
166 ImGui::SliderFloat(
"Stroke width", &
stroke_width, 0, 300);
167 ImGui::Combo(
"Cap", &selected_cap, cap_names,
168 sizeof(cap_names) /
sizeof(
char*));
169 ImGui::Checkbox(
"Use center", &use_center);
172 switch (selected_cap) {
197 paint.setStrokeCap(cap);
199 paint.setStrokeMiter(10);
202 paint.setStrokeWidth(2);
203 builder.DrawRect(rect,
paint);
206 builder.DrawArc(rect, start_angle, sweep_angle, use_center,
paint);
208 return builder.Build();
210 ASSERT_TRUE(OpenPlaygroundHere(
callback));
222 static int selected_stroke_type = 0;
223 static int selected_join_type = 0;
224 const char* stroke_types[] = {
"Butte",
"Round",
"Square"};
225 const char* join_type[] = {
"kMiter",
"Round",
"kBevel"};
227 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
228 ImGui::Combo(
"Cap", &selected_stroke_type, stroke_types,
229 sizeof(stroke_types) /
sizeof(
char*));
230 ImGui::Combo(
"Join", &selected_join_type, join_type,
231 sizeof(join_type) /
sizeof(
char*));
232 ImGui::SliderFloat(
"Stroke Width", &
stroke_width, 10.0f, 50.0f);
237 switch (selected_stroke_type) {
251 switch (selected_join_type) {
265 paint.setStrokeCap(cap);
266 paint.setStrokeJoin(join);
270 builder.Scale(1.5f, 1.5f);
273 builder.Translate(100, 100);
277 builder.Translate(150, 0);
282 builder.Translate(150, 0);
289 builder.Translate(150, 0);
293 path.lineTo({100, 0});
294 path.lineTo({100, 0});
295 path.lineTo({100, 100});
296 builder.DrawPath(path,
paint);
302 builder.Translate(200, 0);
311 line_path.
lineTo({50, 50});
312 line_path.
lineTo({50, 50});
313 line_path.
lineTo({100, 0});
314 line_path.
lineTo({100, 0});
315 builder.DrawPath(line_path,
paint);
317 builder.Translate(0, 100);
318 builder.DrawPath(line_path,
paint);
320 builder.Translate(0, 100);
325 builder.DrawPath(line_path2,
paint);
331 builder.Translate(150, 0);
340 builder.Translate(0, 100);
342 cubic_path2.
moveTo({0, 0});
343 cubic_path2.
cubicTo(0, 0, 0, 0, 150, 150);
344 builder.DrawPath(cubic_path2,
paint);
346 builder.Translate(0, 100);
348 cubic_path3.
moveTo({0, 0});
349 cubic_path3.
cubicTo(0, 0, 0, 0, 0, 0);
350 builder.DrawPath(cubic_path3,
paint);
356 builder.Translate(200, 0);
366 builder.Translate(0, 150);
370 quad_path2.
quadTo({0, 0}, {100, 100});
371 builder.DrawPath(quad_path2,
paint);
373 builder.Translate(0, 100);
376 quad_path3.
quadTo({0, 0}, {0, 0});
377 builder.DrawPath(quad_path3,
paint);
381 return builder.Build();
383 ASSERT_TRUE(OpenPlaygroundHere(
callback));
393 builder.Translate(300, 300);
396 path.addCircle(0, 0, 100);
397 path.addCircle(0, 0, 50);
398 builder.DrawPath(path,
paint);
400 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
412 paint.setStrokeWidth(10);
414 builder.Translate(300, 300);
422 path.lineTo(50, 100);
423 path.lineTo(100, 100);
424 path.lineTo(100, 50);
425 builder.DrawPath(path,
paint);
427 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
431 auto texture = CreateTextureForFixture(
"embarcadero.jpg");
439 paint.setMaskFilter(&filter);
449 paint.setMaskFilter(&filter);
457 paint.setMaskFilter(&filter);
458 builder.DrawTextBlob(
463 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
472 builder.DrawTextBlob(
476 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
490 paint.setColor(mat_blue);
496 builder.DrawTextBlob(text_blob, 250, 250,
paint);
500 builder.DrawTextBlob(text_blob, 250, 250,
paint);
502 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
506 auto texture = CreateTextureForFixture(
"embarcadero.jpg");
510 paint.setMaskFilter(&filter);
511 builder.SaveLayer(
nullptr, &
paint);
515 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
519 auto texture = CreateTextureForFixture(
"embarcadero.jpg");
527 paint.setColorFilter(&filter);
536 paint.setColorFilter(&filter);
541 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
545 const float invert_color_matrix[20] = {
551 auto texture = CreateTextureForFixture(
"boston.jpg");
556 std::make_shared<flutter::DlMatrixColorFilter>(invert_color_matrix);
558 std::make_shared<flutter::DlColorFilterImageFilter>(
color_filter);
560 paint.setImageFilter(image_filter.get());
564 builder.Translate(0, 700);
568 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
572 auto texture = CreateTextureForFixture(
"embarcadero.jpg");
575 static float sigma[] = {10, 10};
577 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
578 ImGui::SliderFloat2(
"Sigma", sigma, 0, 100);
586 paint.setImageFilter(&filter);
590 return builder.Build();
593 ASSERT_TRUE(OpenPlaygroundHere(
callback));
597 auto texture = CreateTextureForFixture(
"boston.jpg");
601 auto dilate = std::make_shared<flutter::DlDilateImageFilter>(10.0, 10.0);
602 auto erode = std::make_shared<flutter::DlErodeImageFilter>(10.0, 10.0);
603 auto open = std::make_shared<flutter::DlComposeImageFilter>(dilate, erode);
604 auto close = std::make_shared<flutter::DlComposeImageFilter>(erode, dilate);
606 paint.setImageFilter(open.get());
609 builder.Translate(0, 700);
610 paint.setImageFilter(close.get());
613 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
617 auto texture = CreateTextureForFixture(
"boston.jpg");
618 const float inner_color_matrix[20] = {
624 const float outer_color_matrix[20] = {
630 auto inner_color_filter =
631 std::make_shared<flutter::DlMatrixColorFilter>(inner_color_matrix);
632 auto outer_color_filter =
633 std::make_shared<flutter::DlMatrixColorFilter>(outer_color_matrix);
635 std::make_shared<flutter::DlColorFilterImageFilter>(inner_color_filter);
637 std::make_shared<flutter::DlColorFilterImageFilter>(outer_color_filter);
638 auto compose = std::make_shared<flutter::DlComposeImageFilter>(outer, inner);
642 paint.setImageFilter(compose.get());
645 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
649 auto texture = CreateTextureForFixture(
"embarcadero.jpg");
652 static float sigma[] = {10, 10};
653 static float ctm_scale = 1;
654 static bool use_bounds =
true;
655 static bool draw_circle =
true;
656 static bool add_clip =
true;
658 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
659 ImGui::SliderFloat2(
"Sigma", sigma, 0, 100);
660 ImGui::SliderFloat(
"Scale", &ctm_scale, 0, 10);
663 "If everything is working correctly, none of the options below should "
664 "impact the filter's appearance.");
665 ImGui::Checkbox(
"Use SaveLayer bounds", &use_bounds);
666 ImGui::Checkbox(
"Draw child element", &draw_circle);
667 ImGui::Checkbox(
"Add pre-clip", &add_clip);
678 std::optional<SkRect> bounds;
695 builder.SaveLayer(bounds.has_value() ? &bounds.value() :
nullptr,
nullptr,
706 paint.setStrokeWidth(10);
708 builder.DrawCircle({circle_center.x, circle_center.y}, 100,
paint);
711 return builder.Build();
714 ASSERT_TRUE(OpenPlaygroundHere(
callback));
719 auto texture = CreateTextureForFixture(
"embarcadero.jpg");
721 auto size =
texture->GetSize();
722 builder.DrawImageNine(
725 size.height * 3 / 4),
728 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
735 auto texture = CreateTextureForFixture(
"embarcadero.jpg");
737 auto size =
texture->GetSize();
738 builder.DrawImageNine(
741 size.height * 3 / 4),
744 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
751 auto texture = CreateTextureForFixture(
"embarcadero.jpg");
753 auto size =
texture->GetSize();
754 builder.DrawImageNine(
757 size.height * 3 / 4),
760 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
766 auto texture = CreateTextureForFixture(
"embarcadero.jpg");
768 auto size =
texture->GetSize();
769 builder.DrawImageNine(
772 size.height * 3 / 4),
775 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
781 auto texture = CreateTextureForFixture(
"embarcadero.jpg");
783 auto size =
texture->GetSize();
784 builder.DrawImageNine(
787 size.height * 3 / 4),
790 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
796 auto texture = CreateTextureForFixture(
"nine_patch_corners.png");
802 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
816 std::vector<flutter::DlStrokeCap> caps = {
825 builder.Translate(50, 50);
826 for (
auto cap : caps) {
827 paint.setStrokeCap(cap);
830 builder.Translate(150, 0);
832 builder.Translate(150, 0);
836 builder.Translate(0, 150);
838 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
843 std::vector<flutter::DlStrokeCap> caps = {
855 for (
auto cap : caps) {
856 paint.setStrokeCap(cap);
857 builder.DrawLine({50, 50}, {50, 50},
paint);
858 builder.DrawPath(path,
paint);
859 builder.Translate(0, 150);
861 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
868 auto content_scale = GetContentScale() * 0.8;
869 builder.Scale(content_scale.x, content_scale.y);
871 constexpr size_t star_spikes = 5;
872 constexpr SkScalar half_spike_rotation =
kPi / star_spikes;
875 constexpr SkScalar outer_radius = radius + spike_size;
876 constexpr SkScalar inner_radius = radius - spike_size;
877 std::array<SkPoint, star_spikes * 2> star;
878 for (
size_t i = 0; i < star_spikes; i++) {
879 const SkScalar rotation = half_spike_rotation * i * 2;
880 star[i * 2] =
SkPoint::Make(50 + std::sin(rotation) * outer_radius,
881 50 - std::cos(rotation) * outer_radius);
883 50 + std::sin(rotation + half_spike_rotation) * inner_radius,
884 50 - std::cos(rotation + half_spike_rotation) * inner_radius);
887 std::array<SkPath, 4> paths = {
895 builder.DrawPaint(
paint);
897 builder.Translate(100, 50);
898 for (
size_t x = 0;
x < paths.size();
x++) {
900 for (
size_t y = 0;
y < 6;
y++) {
903 builder.DrawPath(paths[
x],
paint);
904 builder.Translate(0, 150);
907 builder.Translate(250, 0);
910 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
914 DispatcherDoesNotCullPerspectiveTransformedChildDisplayLists) {
919 auto display_list = sub_builder.
Build();
922 dispatcher.
scale(2.0, 2.0);
926 0.8, -0.2, -0.1, -0.0,
929 63.2, 65.3, 48.6, 1.1
937 picture.pass->IterateAllEntities([&found](
Entity& entity) {
938 if (std::static_pointer_cast<SolidColorContents>(entity.
GetContents())
952 dispatcher.
scale(1.618, 1.618);
959 std::shared_ptr<SolidRRectBlurContents> rrect_blur;
960 picture.pass->IterateAllEntities([&rrect_blur](
Entity& entity) {
962 rrect_blur = std::static_pointer_cast<SolidRRectBlurContents>(
963 entity.GetContents());
969 ASSERT_NE(rrect_blur,
nullptr);
970 ASSERT_EQ(rrect_blur->GetColor().red, 0);
971 ASSERT_EQ(rrect_blur->GetColor().green, 0);
972 ASSERT_EQ(rrect_blur->GetColor().blue, 0);
973 ASSERT_EQ(rrect_blur->GetColor().alpha, 0);
978 constexpr Scalar hexagon_radius = 125;
979 auto hex_start =
Point(200.0, -hexagon_radius + 200.0);
980 auto center_to_flat = 1.73 / 2 * hexagon_radius;
983 std::vector<SkPoint> vertices = {
985 SkPoint::Make(hex_start.x + center_to_flat, hex_start.y + 0.5 * hexagon_radius),
986 SkPoint::Make(hex_start.x + center_to_flat, hex_start.y + 1.5 * hexagon_radius),
987 SkPoint::Make(hex_start.x + center_to_flat, hex_start.y + 1.5 * hexagon_radius),
988 SkPoint::Make(hex_start.x, hex_start.y + 2 * hexagon_radius),
989 SkPoint::Make(hex_start.x, hex_start.y + 2 * hexagon_radius),
990 SkPoint::Make(hex_start.x - center_to_flat, hex_start.y + 1.5 * hexagon_radius),
991 SkPoint::Make(hex_start.x - center_to_flat, hex_start.y + 1.5 * hexagon_radius),
992 SkPoint::Make(hex_start.x - center_to_flat, hex_start.y + 0.5 * hexagon_radius)
1001 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1006 std::vector<flutter::DlStrokeCap> caps = {
1023 for (
auto cap : caps) {
1024 paint.setStrokeCap(cap);
1025 builder.DrawLine({50, 50}, {60, 50},
paint);
1026 builder.DrawRect({45, 45, 65, 55}, outline_paint);
1027 builder.DrawLine({100, 50}, {100, 50},
paint);
1029 builder.DrawRect({95, 45, 105, 55}, outline_paint);
1031 builder.DrawPath(path,
paint);
1032 builder.DrawRect(path.getBounds().makeOutset(5, 5), outline_paint);
1033 builder.Translate(0, 150);
1035 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1039 auto boston = CreateTextureForFixture(
"boston.jpg");
1042 static int selected_matrix_type = 0;
1043 const char* matrix_type_names[] = {
"Matrix",
"Local Matrix"};
1045 static float ctm_translation[2] = {200, 200};
1046 static float ctm_scale[2] = {0.65, 0.65};
1047 static float ctm_skew[2] = {0, 0};
1049 static bool enable =
true;
1050 static float translation[2] = {100, 100};
1051 static float scale[2] = {0.8, 0.8};
1052 static float skew[2] = {0.2, 0.2};
1054 static bool enable_savelayer =
true;
1056 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1058 ImGui::Combo(
"Filter type", &selected_matrix_type, matrix_type_names,
1059 sizeof(matrix_type_names) /
sizeof(
char*));
1061 ImGui::TextWrapped(
"Current Transform");
1062 ImGui::SliderFloat2(
"CTM Translation", ctm_translation, 0, 1000);
1063 ImGui::SliderFloat2(
"CTM Scale", ctm_scale, 0, 3);
1064 ImGui::SliderFloat2(
"CTM Skew", ctm_skew, -3, 3);
1067 "MatrixFilter and LocalMatrixFilter modify the CTM in the same way. "
1068 "The only difference is that MatrixFilter doesn't affect the effect "
1069 "transform, whereas LocalMatrixFilter does.");
1072 ImGui::Checkbox(
"Enable", &enable);
1073 ImGui::SliderFloat2(
"Filter Translation", translation, 0, 1000);
1074 ImGui::SliderFloat2(
"Filter Scale",
scale, 0, 3);
1075 ImGui::SliderFloat2(
"Filter Skew", skew, -3, 3);
1078 "Rendering the filtered image within a layer can expose bounds "
1079 "issues. If the rendered image gets cut off when this setting is "
1080 "enabled, there's a coverage bug in the filter.");
1081 ImGui::Checkbox(
"Render in layer", &enable_savelayer);
1088 if (enable_savelayer) {
1089 builder.SaveLayer(
nullptr,
nullptr);
1092 auto content_scale = GetContentScale();
1093 builder.Scale(content_scale.x, content_scale.y);
1098 ctm_skew[1], ctm_scale[1], ctm_translation[1],
1100 builder.Transform(ctm_matrix);
1103 auto filter_matrix =
1105 skew[1],
scale[1], translation[1],
1109 switch (selected_matrix_type) {
1113 paint.setImageFilter(&filter);
1117 auto internal_filter =
1122 paint.setImageFilter(&filter);
1131 if (enable_savelayer) {
1135 return builder.Build();
1138 ASSERT_TRUE(OpenPlaygroundHere(
callback));
1143 static float translation[2] = {0, 0};
1144 static bool enable_save_layer =
true;
1146 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1147 ImGui::SliderFloat2(
"Translation", translation, -130, 130);
1148 ImGui::Checkbox(
"Enable save layer", &enable_save_layer);
1153 builder.Scale(2.0, 2.0);
1157 paint.setStrokeWidth(1.0);
1167 if (enable_save_layer) {
1171 builder.SaveLayer(&bounds, &save_paint);
1174 builder.Transform(translate_matrix);
1186 builder.SaveLayer(&bounds, &save_paint);
1189 builder.DrawRect(bounds, paint2);
1192 return builder.Build();
1195 ASSERT_TRUE(OpenPlaygroundHere(
callback));
1202 paint.setColorFilter(
1205 builder.Translate(0, 200);
1207 paint.setColorFilter(
1211 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1219 const float stops[2] = {0.0, 1.0};
1224 builder.Translate(100, 100);
1230 builder.DrawPaint(
paint);
1234 builder.Translate(500, 100);
1238 paint.setColorSource(radial);
1239 builder.DrawPaint(
paint);
1243 builder.Translate(100, 500);
1248 paint.setColorSource(sweep);
1249 builder.DrawPaint(
paint);
1253 builder.Translate(500, 500);
1255 auto texture = CreateTextureForFixture(
"table_mountain_nx.png");
1256 auto image = std::make_shared<flutter::DlImageColorSource>(
1260 builder.DrawPaint(
paint);
1263 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1270 builder.SaveLayer(
nullptr,
nullptr);
1271 builder.Translate(100, 100);
1281 builder.SaveLayer(
nullptr,
nullptr);
1282 builder.Translate(300, 100);
1292 builder.SaveLayer(
nullptr,
nullptr);
1293 builder.Translate(100, 300);
1303 builder.SaveLayer(
nullptr,
nullptr);
1304 builder.Translate(300, 300);
1314 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1319 const float green_color_matrix[20] = {
1325 const float blue_color_matrix[20] = {
1331 auto green_color_filter =
1332 std::make_shared<flutter::DlMatrixColorFilter>(green_color_matrix);
1333 auto blue_color_filter =
1334 std::make_shared<flutter::DlMatrixColorFilter>(blue_color_matrix);
1335 auto blue_image_filter =
1336 std::make_shared<flutter::DlColorFilterImageFilter>(blue_color_filter);
1340 paint.setColorFilter(green_color_filter);
1341 paint.setImageFilter(blue_image_filter);
1343 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1347 auto blur_filter = std::make_shared<flutter::DlBlurMaskFilter>(
1354 std::array<float, 2> stops = {0, 1};
1355 std::array<std::shared_ptr<flutter::DlColorSource>, 2> color_sources = {
1362 for (
const auto& color_source : color_sources) {
1364 paint.setColorSource(color_source);
1365 paint.setMaskFilter(blur_filter);
1372 paint.setStrokeWidth(10);
1380 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1386 std::vector<SkPoint> positions = {
SkPoint::Make(-100, -300),
1395 nullptr, colors.data());
1401 builder.Scale(-1, -1);
1404 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1418 const float stops[2] = {0.0, 1.0};
1421 {100.0, 100.0}, {300.0, 300.0}, 2, colors.data(), stops,
1430 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1437 std::vector<SkPoint> texture_coordinates = {
SkPoint::Make(300, 100),
1443 texture_coordinates.data(),
nullptr);
1447 const float stops[2] = {0.0, 1.0};
1450 {100.0, 100.0}, {300.0, 300.0}, 2, colors.data(), stops,
1459 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1463 auto texture = CreateTextureForFixture(
"embarcadero.jpg");
1468 std::vector<SkPoint> texture_coordinates = {
1473 texture_coordinates.data(),
nullptr);
1481 paint.setColorSource(&image_source);
1484 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1488 DrawVerticesImageSourceWithTextureCoordinatesAndColorBlending) {
1489 auto texture = CreateTextureForFixture(
"embarcadero.jpg");
1497 std::vector<SkPoint> texture_coordinates = {
1502 texture_coordinates.data(), colors.data());
1510 paint.setColorSource(&image_source);
1513 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1517 std::vector<SkPoint> positions = {
1520 std::vector<uint16_t> indices = {0, 1, 2, 0, 2, 3};
1524 nullptr,
nullptr, indices.size(),
1533 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1537 std::vector<SkPoint> positions = {
1541 std::vector<uint16_t> indices = {0, 1, 2, 0, 2, 3};
1546 nullptr, colors.data(), indices.size(),
1557 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1562 std::vector<flutter::DlStrokeJoin> joins = {
1579 builder.Translate(300, 50);
1580 builder.Scale(0.8, 0.8);
1581 for (
auto join : joins) {
1582 paint.setStrokeJoin(join);
1591 builder.DrawCircle({350, 50}, 50,
paint);
1592 builder.DrawCircle({350, 200}, 50, stroke_paint);
1593 builder.Translate(0, 300);
1595 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1648 builder.DrawPaint(clip_fill_paint);
1654 builder.DrawPaint(clip_fill_paint);
1657 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1661 std::vector<const char*> blend_mode_names;
1662 std::vector<flutter::DlBlendMode> blend_mode_values;
1664 const std::vector<std::tuple<const char*, flutter::DlBlendMode>> blends = {
1697 assert(blends.size() ==
1699 for (
const auto& [
name, mode] : blends) {
1700 blend_mode_names.push_back(
name);
1701 blend_mode_values.push_back(mode);
1706 static int current_blend_index = 3;
1707 static float dst_alpha = 1;
1708 static float src_alpha = 1;
1709 static float color0[4] = {1.0f, 0.0f, 0.0f, 1.0f};
1710 static float color1[4] = {0.0f, 1.0f, 0.0f, 1.0f};
1711 static float color2[4] = {0.0f, 0.0f, 1.0f, 1.0f};
1712 static float src_color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
1714 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1716 ImGui::ListBox(
"Blending mode", ¤t_blend_index,
1717 blend_mode_names.data(), blend_mode_names.size());
1718 ImGui::SliderFloat(
"Source alpha", &src_alpha, 0, 1);
1719 ImGui::ColorEdit4(
"Color A", color0);
1720 ImGui::ColorEdit4(
"Color B", color1);
1721 ImGui::ColorEdit4(
"Color C", color2);
1722 ImGui::ColorEdit4(
"Source Color", src_color);
1723 ImGui::SliderFloat(
"Destination alpha", &dst_alpha, 0, 1);
1730 std::vector<flutter::DlColor> colors = {
1737 nullptr, colors.data());
1742 paint.setColor(
toColor(src_color).modulateOpacity(src_alpha));
1743 builder.DrawVertices(vertices, blend_mode_values[current_blend_index],
1745 return builder.Build();
1748 ASSERT_TRUE(OpenPlaygroundHere(
callback));
1751template <
typename Contents>
1753 std::optional<Rect> coverage;
1754 picture.pass->IterateAllEntities([&coverage](
Entity& entity) {
1755 if (std::static_pointer_cast<Contents>(entity.
GetContents())) {
1756 auto contents = std::static_pointer_cast<Contents>(entity.GetContents());
1758 coverage = contents->GetCoverage(entity);
1773 builder.DrawPath(path,
paint);
1774 auto display_list = builder.Build();
1777 display_list->Dispatch(dispatcher);
1780 std::optional<Rect> coverage =
1781 GetCoverageOfFirstEntity<SolidColorContents>(picture);
1784 ASSERT_TRUE(coverage.has_value());
1795 builder.DrawPath(path,
paint);
1796 auto display_list = builder.Build();
1799 display_list->Dispatch(dispatcher);
1802 std::optional<Rect> coverage =
1803 GetCoverageOfFirstEntity<SolidColorContents>(picture);
1805 ASSERT_TRUE(coverage.has_value());
1810#ifdef IMPELLER_ENABLE_3D
1815 ASSERT_NE(mapping,
nullptr);
1817 std::shared_ptr<scene::Node> gltf_scene =
1819 *mapping, *GetContext()->GetResourceAllocator());
1820 ASSERT_NE(gltf_scene,
nullptr);
1824 auto color_source = std::make_shared<flutter::DlSceneColorSource>(
1833 ASSERT_TRUE(OpenPlaygroundHere(
builder.Build()));
1842 builder.DrawCircle({300, 300}, 200,
1847 const float stops[2] = {0.0, 1.0};
1849 {100.0, 100.0}, {300.0, 300.0}, 2, colors.data(), stops,
1855 builder.DrawPaint(blend_paint);
1857 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1868 builder.Translate(1.0f, 1.0f);
1876 for (
int x = 1;
x <= 4;
x++) {
1877 for (
int y = 1;
y <= 4;
y++) {
1885 builder.Translate(500.0f, 0.0f);
1886 auto normal_filter =
1896 for (
int x = 1;
x <= 4;
x++) {
1897 for (
int y = 1;
y <= 4;
y++) {
1904 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
#define TEST(S, s, D, expected)
static const int points[]
static sk_sp< SkImage > color_filter(const SkImage *image, SkColorFilter *colorFilter)
SkMatrix & postTranslate(SkScalar dx, SkScalar dy)
static SkMatrix RotateDeg(SkScalar deg)
SkMatrix & postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
static SkMatrix Translate(SkScalar dx, SkScalar dy)
static SkMatrix MakeAll(SkScalar scaleX, SkScalar skewX, SkScalar transX, SkScalar skewY, SkScalar scaleY, SkScalar transY, SkScalar pers0, SkScalar pers1, SkScalar pers2)
static const SkMatrix & I()
SkPathBuilder & lineTo(SkPoint pt)
SkPathBuilder & moveTo(SkPoint pt)
SkPath & addCircle(SkScalar x, SkScalar y, SkScalar radius, SkPathDirection dir=SkPathDirection::kCW)
SkPath & moveTo(SkScalar x, SkScalar y)
SkPath & addPoly(const SkPoint pts[], int count, bool close)
SkPath & lineTo(SkScalar x, SkScalar y)
SkPath & addRRect(const SkRRect &rrect, SkPathDirection dir=SkPathDirection::kCW)
SkPath & quadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2)
SkPath & cubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, SkScalar x3, SkScalar y3)
SkPath & addRect(const SkRect &rect, SkPathDirection dir, unsigned start)
static SkRRect MakeRectXY(const SkRect &rect, SkScalar xRad, SkScalar yRad)
static sk_sp< SkTextBlob > MakeFromString(const char *string, const SkFont &font, SkTextEncoding encoding=SkTextEncoding::kUTF8)
void DrawRect(const SkRect &rect, const DlPaint &paint) override
sk_sp< DisplayList > Build()
std::shared_ptr< DlImageFilter > shared() const override
static std::shared_ptr< DlMaskFilter > Make(DlBlurStyle style, SkScalar sigma, bool respect_ctm=true)
@ kLines
draw each separate pair of points as a line segment
@ kPolygon
draw each pair of overlapping points as a line segment
@ kPoints
draw each point separately
static std::shared_ptr< DlLinearGradientColorSource > MakeLinear(const SkPoint start_point, const SkPoint end_point, uint32_t stop_count, const DlColor *colors, const float *stops, DlTileMode tile_mode, const SkMatrix *matrix=nullptr)
static std::shared_ptr< DlSweepGradientColorSource > MakeSweep(SkPoint center, SkScalar start, SkScalar end, uint32_t stop_count, const DlColor *colors, const float *stops, DlTileMode tile_mode, const SkMatrix *matrix=nullptr)
static std::shared_ptr< DlRadialGradientColorSource > MakeRadial(SkPoint center, SkScalar radius, uint32_t stop_count, const DlColor *colors, const float *stops, DlTileMode tile_mode, const SkMatrix *matrix=nullptr)
static const std::shared_ptr< DlLinearToSrgbGammaColorFilter > kInstance
static std::shared_ptr< DlImageFilter > Make(const SkMatrix &matrix, DlImageSampling sampling)
DlPaint & setColor(DlColor color)
DlPaint & setMaskFilter(const std::shared_ptr< DlMaskFilter > &filter)
DlPaint & setStrokeCap(DlStrokeCap cap)
DlPaint & setStrokeWidth(float width)
DlPaint & setAlpha(uint8_t alpha)
DlPaint & setBlendMode(DlBlendMode mode)
DlPaint & setImageFilter(const std::shared_ptr< const DlImageFilter > &filter)
DlPaint & setDrawStyle(DlDrawStyle style)
DlPaint & setStrokeJoin(DlStrokeJoin join)
DlPaint & setColorSource(std::shared_ptr< const DlColorSource > source)
static const std::shared_ptr< DlSrgbToLinearGammaColorFilter > kInstance
static std::shared_ptr< DlVertices > Make(DlVertexMode mode, int vertex_count, const SkPoint vertices[], const SkPoint texture_coordinates[], const DlColor colors[], int index_count=0, const uint16_t indices[]=nullptr)
Constructs a DlVector with compact inline storage for all of its required and optional lists of data.
void transformFullPerspective(SkScalar mxx, SkScalar mxy, SkScalar mxz, SkScalar mxt, SkScalar myx, SkScalar myy, SkScalar myz, SkScalar myt, SkScalar mzx, SkScalar mzy, SkScalar mzz, SkScalar mzt, SkScalar mwx, SkScalar mwy, SkScalar mwz, SkScalar mwt) override
Picture EndRecordingAsPicture()
void translate(SkScalar tx, SkScalar ty) override
void drawShadow(const SkPath &path, const flutter::DlColor color, const SkScalar elevation, bool transparent_occluder, SkScalar dpr) override
void scale(SkScalar sx, SkScalar sy) override
void drawDisplayList(const sk_sp< flutter::DisplayList > display_list, SkScalar opacity) override
static sk_sp< DlImageImpeller > Make(std::shared_ptr< Texture > texture, OwningContext owning_context=OwningContext::kIO)
const std::shared_ptr< Contents > & GetContents() const
const Matrix & GetTransform() const
Get the global transform matrix for this Entity.
static std::shared_ptr< Node > MakeFromFlatbuffer(const fml::Mapping &ipscene_mapping, Allocator &allocator)
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
std::unique_ptr< fml::Mapping > OpenFixtureAsMapping(const std::string &fixture_name)
Opens a fixture of the given file name and returns a mapping to its contents.
@ kMiter
extends to miter limit
@ kBevel
connects outside edges
@ kButt
no stroke extension
@ kTriangles
The vertices are taken 3 at a time to form a triangle.
@ kStroke
strokes boundary of shapes
@ kFill
fills interior of shapes
@ kNormal
fuzzy inside and outside
@ kOuter
nothing inside, fuzzy outside
@ kSolid
solid inside, fuzzy outside
@ kExclusion
rc = s + d - two(s*d), ra = kSrcOver
@ kSaturation
saturation of source with hue and luminosity of destination
@ kColorBurn
darken destination to reflect source
@ kLighten
rc = s + d - min(s*da, d*sa), ra = kSrcOver
@ kHue
hue of source with saturation and luminosity of destination
@ kMultiply
r = s*(1-da) + d*(1-sa) + s*d
@ kColorDodge
brighten destination to reflect source
@ kSrcOver
r = s + (1-sa)*d
@ kXor
r = s*(1-da) + d*(1-sa)
@ kLuminosity
luminosity of source with hue and saturation of destination
@ kSoftLight
lighten or darken, depending on source
@ kDifference
rc = s + d - 2*(min(s*da, d*sa)), ra = kSrcOver
@ kOverlay
multiply or screen, depending on destination
@ kSrcATop
r = s*da + d*(1-sa)
@ kDstATop
r = d*sa + s*(1-da)
@ kDstOver
r = d + (1-da)*s
@ kLastMode
last valid value
@ kColor
hue and saturation of source with luminosity of destination
@ kHardLight
multiply or screen, depending on source
@ kDarken
rc = s + d - max(s*da, d*sa), ra = kSrcOver
DlPlayground DisplayListTest
flutter::DlColor toColor(const float *components)
TEST_P(AiksTest, CanRenderAdvancedBlendColorFilterWithSaveLayer)
static std::optional< Rect > GetCoverageOfFirstEntity(const Picture &picture)
Point DrawPlaygroundPoint(PlaygroundPoint &point)
std::tuple< Point, Point > DrawPlaygroundLine(PlaygroundPoint &point_a, PlaygroundPoint &point_b)
constexpr bool ScalarNearlyEqual(Scalar x, Scalar y, Scalar tolerance=kEhCloseEnough)
#define INSTANTIATE_PLAYGROUND_SUITE(playground)
const Scalar stroke_width
static constexpr SkIRect MakeLTRB(int32_t l, int32_t t, int32_t r, int32_t b)
static constexpr SkIRect MakeXYWH(int32_t x, int32_t y, int32_t w, int32_t h)
static constexpr SkPoint Make(float x, float y)
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
static constexpr SkRect MakeSize(const SkSize &size)
static constexpr SkRect MakeWH(float w, float h)
static constexpr SkRect MakeLTRB(float l, float t, float r, float b)
constexpr DlColor modulateOpacity(float opacity) const
static constexpr DlColor kWhite()
static constexpr DlColor kBlue()
static constexpr DlColor kBlack()
static constexpr DlColor kYellow()
constexpr DlColor withAlpha(uint8_t alpha) const
static constexpr DlColor kMidGrey()
static constexpr DlColor kTransparent()
static constexpr DlColor kRed()
static constexpr DlColor kGreen()
static constexpr DlColor kDarkGrey()
static constexpr DlColor kCyan()
static constexpr uint32_t ToIColor(Color color)
Convert this color to a 32-bit representation.
static constexpr Color White()
static constexpr Color Red()
static constexpr Matrix MakePerspective(Radians fov_y, Scalar aspect_ratio, Scalar z_near, Scalar z_far)
constexpr Vector3 GetScale() const
static constexpr Matrix MakeLookAt(Vector3 position, Vector3 target, Vector3 up)
static constexpr TRect MakeMaximum()
static constexpr TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
#define EXPECT_TRUE(handle)
static sk_sp< SkShader > linear(sk_sp< SkShader > shader)