12 #include "flutter/display_list/testing/dl_test_snippets.h"
13 #include "fml/logging.h"
14 #include "gtest/gtest.h"
54 #include "impeller/renderer/testing/mocks.h"
58 #include "third_party/imgui/imgui.h"
59 #include "third_party/skia/include/core/SkTextBlob.h"
92 std::shared_ptr<Texture> target,
93 const Matrix& transform)
override {
100 const Matrix& effect_transform)
const override {
105 const std::optional<Rect> coverage_;
106 const bool collapse_;
111 std::optional<Rect> bounds_hint,
113 bool collapse =
false) {
114 auto subpass = std::make_unique<EntityPass>();
118 subpass->AddEntity(std::move(entity));
119 subpass->SetDelegate(std::make_unique<TestPassDelegate>(collapse));
120 subpass->SetBoundsLimit(bounds_hint, bounds_promise);
132 auto subpass0_coverage =
134 ASSERT_TRUE(subpass0_coverage.has_value());
137 auto subpass1_coverage =
139 ASSERT_TRUE(subpass1_coverage.has_value());
147 ASSERT_TRUE(coverage.has_value());
163 auto subpass0_coverage =
165 EXPECT_TRUE(subpass0_coverage.has_value());
170 auto subpass1_coverage =
172 EXPECT_TRUE(subpass1_coverage.has_value());
182 EXPECT_TRUE(coverage.has_value());
199 auto contents = std::make_unique<SolidColorContents>();
206 ASSERT_TRUE(OpenPlaygroundHere(pass));
216 auto pass_coverage = pass->GetElementsCoverage(std::nullopt);
217 ASSERT_TRUE(pass_coverage.has_value());
226 ASSERT_FALSE(pass_coverage.has_value());
233 ASSERT_TRUE(pass_coverage.has_value());
240 auto image = CreateTextureForFixture(
"boston.jpg");
246 auto actual = filter->GetCoverage({});
249 ASSERT_TRUE(actual.has_value());
256 filter->SetCoverageHint(expected);
257 auto actual = filter->GetCoverage({});
259 ASSERT_TRUE(actual.has_value());
265 auto contents = std::make_shared<SolidColorContents>();
273 ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
277 auto contents = std::make_shared<SolidColorContents>();
289 ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
312 auto contents = std::make_unique<SolidColorContents>();
316 ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
320 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
332 auto contents = std::make_unique<TiledTextureContents>();
334 contents->SetTexture(bridge);
337 ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
373 auto contents = std::make_unique<SolidColorContents>();
378 return entity.
Render(context, pass);
380 ASSERT_TRUE(OpenPlaygroundHere(callback));
384 const Point padding(300, 250);
385 const Point margin(140, 180);
391 static Scalar miter_limit = 1.41421357;
394 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
396 ImGui::SliderFloat(
"Miter limit", &miter_limit, 0, 30);
397 ImGui::SliderFloat(
"Stroke width", &width, 0, 100);
398 if (ImGui::Button(
"Reset")) {
399 miter_limit = 1.41421357;
406 auto render_path = [width = width, &context, &pass, &world_matrix](
408 auto contents = std::make_unique<SolidColorContents>();
409 contents->SetGeometry(
418 if (coverage.has_value()) {
419 auto bounds_contents = std::make_unique<SolidColorContents>();
422 bounds_contents->SetColor(
Color::Green().WithAlpha(0.5));
424 bounds_entity.
SetContents(std::move(bounds_contents));
425 bounds_entity.
Render(context, pass);
428 entity.
Render(context, pass);
431 const Point a_def(0, 0), b_def(0, 100), c_def(150, 0), d_def(150, -100),
520 ASSERT_TRUE(OpenPlaygroundHere(callback));
527 .
MoveTo({237.164, 125.003})
528 .CubicCurveTo({236.709, 125.184}, {236.262, 125.358},
530 .CubicCurveTo({235.413, 125.68}, {234.994, 125.832},
532 .CubicCurveTo({234.592, 125.977}, {234.591, 125.977},
534 .CubicCurveTo({222.206, 130.435}, {207.708, 135.753},
536 .CubicCurveTo({162.77, 151.336}, {122.17, 156.894}, {84.1123, 160})
542 ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
547 const char* input_axis[] = {
"X",
"Y",
"Z"};
548 static int rotation_axis_index = 0;
549 static float rotation = 0;
550 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
551 ImGui::SliderFloat(
"Rotation", &rotation, -
kPi,
kPi);
552 ImGui::Combo(
"Rotation Axis", &rotation_axis_index, input_axis,
553 sizeof(input_axis) /
sizeof(
char*));
555 switch (rotation_axis_index) {
566 rotation_matrix =
Matrix{};
570 if (ImGui::Button(
"Reset")) {
574 Matrix current_transform =
578 pass.GetRenderTargetSize().height / 2.0)));
579 Matrix result_transform = current_transform * rotation_matrix;
586 return entity.
Render(context, pass);
588 ASSERT_TRUE(OpenPlaygroundHere(callback));
595 .
MoveTo({359.934, 96.6335})
596 .CubicCurveTo({358.189, 96.7055}, {356.436, 96.7908},
598 .CubicCurveTo({354.571, 96.8953}, {354.469, 96.9016},
600 .CubicCurveTo({352.672, 97.0038}, {350.969, 97.113},
602 .CubicCurveTo({349.048, 97.2506}, {348.836, 97.2678},
604 .CubicCurveTo({347.019, 97.4014}, {345.407, 97.5299},
606 .CubicCurveTo({343.428, 97.704}, {343.065, 97.7402},
608 .CubicCurveTo({341.221, 97.9086}, {339.736, 98.0505},
610 .CubicCurveTo({337.702, 98.2642}, {337.156, 98.3292},
612 .CubicCurveTo({335.284, 98.5356}, {333.956, 98.6837},
614 .CubicCurveTo({332.495, 98.8635}, {332.366, 98.8818},
616 .
LineTo({332.237, 102.601})
617 .
LineTo({321.778, 102.601})
618 .
LineTo({321.778, 100.382})
619 .CubicCurveTo({321.572, 100.413}, {321.367, 100.442},
621 .CubicCurveTo({319.22, 100.79}, {317.277, 101.123},
623 .CubicCurveTo({315.322, 101.481}, {315.311, 101.482},
625 .
LineTo({310.017, 105.94})
626 .
LineTo({309.779, 105.427})
627 .
LineTo({314.403, 101.651})
628 .CubicCurveTo({314.391, 101.653}, {314.379, 101.656},
630 .CubicCurveTo({312.528, 102.001}, {310.687, 102.366},
632 .CubicCurveTo({307.85, 102.955}, {306.855, 103.182}, {305.859, 103.4})
633 .CubicCurveTo({305.048, 103.579}, {304.236, 103.75},
635 .
LineTo({299.105, 107.578})
636 .
LineTo({298.867, 107.065})
637 .
LineTo({302.394, 104.185})
638 .
LineTo({302.412, 104.171})
639 .CubicCurveTo({301.388, 104.409}, {300.366, 104.67},
641 .CubicCurveTo({298.618, 105.1}, {297.89, 105.269}, {297.165, 105.455})
642 .CubicCurveTo({295.262, 105.94}, {293.36, 106.445},
644 .CubicCurveTo({291.132, 107.072}, {290.802, 107.163},
646 .CubicCurveTo({289.463, 107.544}, {288.455, 107.839},
648 .CubicCurveTo({286.476, 108.431}, {285.506, 108.73},
650 .CubicCurveTo({283.674, 109.304}, {282.812, 109.579},
652 .CubicCurveTo({281.177, 110.112}, {280.406, 110.377},
654 .CubicCurveTo({278.458, 111.037}, {277.256, 111.449},
656 .CubicCurveTo({276.76, 111.622}, {276.716, 111.637},
658 .CubicCurveTo({275.017, 112.239}, {273.365, 112.836},
660 .
LineTo({271.717, 113.449})
661 .CubicCurveTo({271.496, 113.496}, {271.238, 113.559},
663 .CubicCurveTo({270.893, 113.645}, {270.822, 113.663},
665 .CubicCurveTo({270.468, 113.755}, {270.169, 113.834},
667 .CubicCurveTo({269.789, 113.94}, {269.732, 113.957},
669 .CubicCurveTo({269.391, 114.053}, {269.081, 114.143},
671 .CubicCurveTo({268.628, 114.276}, {268.5, 114.314},
673 .CubicCurveTo({268.172, 114.412}, {267.959, 114.478},
675 .CubicCurveTo({263.349, 115.964}, {258.058, 117.695},
677 .CubicCurveTo({253.556, 119.255}, {253.547, 119.258},
679 .CubicCurveTo({251.844, 119.849}, {250.056, 120.474},
681 .CubicCurveTo({248, 121.197}, {247.812, 121.264}, {247.621, 121.331})
682 .CubicCurveTo({247.079, 121.522}, {246.531, 121.715},
684 .CubicCurveTo({245.554, 122.06}, {245.126, 122.212},
686 .CubicCurveTo({244.071, 122.586}, {243.437, 122.811},
688 .CubicCurveTo({242.189, 123.255}, {241.58, 123.472},
690 .CubicCurveTo({240.659, 123.801}, {240.357, 123.909},
692 .CubicCurveTo({239.12, 124.351}, {238.18, 124.687}, {237.22, 125.032})
693 .
LineTo({237.164, 125.003})
694 .CubicCurveTo({236.709, 125.184}, {236.262, 125.358},
696 .CubicCurveTo({235.413, 125.68}, {234.994, 125.832},
698 .CubicCurveTo({234.592, 125.977}, {234.591, 125.977},
700 .CubicCurveTo({222.206, 130.435}, {207.708, 135.753},
702 .CubicCurveTo({162.77, 151.336}, {122.17, 156.894}, {84.1123, 160})
707 .CubicCurveTo({359.978, 96.6317}, {359.956, 96.6326},
710 .MoveTo({337.336, 124.143})
711 .CubicCurveTo({337.274, 122.359}, {338.903, 121.511},
713 .CubicCurveTo({338.903, 121.511}, {338.96, 123.303},
716 .MoveTo({340.082, 121.849})
717 .CubicCurveTo({340.074, 121.917}, {340.062, 121.992},
719 .CubicCurveTo({340.039, 122.109}, {340.031, 122.142},
721 .CubicCurveTo({340.005, 122.26}, {339.98, 122.346},
723 .CubicCurveTo({339.941, 122.473}, {339.931, 122.507},
725 .CubicCurveTo({339.873, 122.672}, {339.819, 122.804},
727 .CubicCurveTo({339.747, 122.944}, {339.743, 122.949},
729 .CubicCurveTo({339.674, 123.08}, {339.593, 123.205},
731 .CubicCurveTo({339.473, 123.366}, {339.441, 123.401},
733 .CubicCurveTo({339.332, 123.534}, {339.243, 123.625},
735 .CubicCurveTo({339.105, 123.75}, {339.068, 123.786},
737 .CubicCurveTo({338.881, 123.937}, {338.724, 124.048},
739 .CubicCurveTo({338.532, 123.959}, {338.554, 123.79},
741 .CubicCurveTo({338.58, 123.625}, {338.58, 123.625}, {338.58, 123.625})
742 .CubicCurveTo({338.607, 123.455}, {338.65, 123.299},
744 .CubicCurveTo({338.708, 123.14}, {338.71, 123.127},
746 .CubicCurveTo({338.769, 122.971}, {338.833, 122.838},
748 .CubicCurveTo({338.911, 122.702}, {338.916, 122.69200000000001},
750 .CubicCurveTo({338.996, 122.557}, {339.072, 122.444},
752 .CubicCurveTo({339.161, 122.333}, {339.166, 122.326},
754 .CubicCurveTo({339.256, 122.215}, {339.339, 122.12},
756 .CubicCurveTo({339.428, 122.033}, {339.431, 122.03},
758 .CubicCurveTo({339.785, 121.687}, {340.106, 121.511},
760 .CubicCurveTo({340.106, 121.511}, {340.107, 121.645},
763 .MoveTo({340.678, 113.245})
764 .CubicCurveTo({340.594, 113.488}, {340.356, 113.655},
766 .CubicCurveTo({339.817, 113.948}, {339.465, 114.059},
768 .CubicCurveTo({338.251, 114.379}, {337.34, 114.516},
770 .CubicCurveTo({335.761, 114.516}, {335.072, 114.527},
772 .CubicCurveTo({334.125, 114.508}, {333.862, 114.462},
774 .CubicCurveTo({332.865, 114.318}, {332.096, 114.184},
776 .CubicCurveTo({330.979, 113.695}, {330.442, 113.34},
778 .CubicCurveTo({331.135, 111.755}, {333.219, 112.946},
780 .CubicCurveTo({334.54, 113.816}, {334.554, 113.8}, {334.569, 113.784})
781 .CubicCurveTo({333.38, 112.708}, {331.749, 110.985},
783 .CubicCurveTo({333.769, 109.82}, {334.713, 111.93},
785 .CubicCurveTo({334.915, 111.889}, {334.59, 109.636},
787 .CubicCurveTo({336.733, 109.636}, {336.408, 111.889},
789 .CubicCurveTo({336.609, 111.93}, {337.553, 109.82},
791 .CubicCurveTo({339.574, 110.984}, {337.942, 112.708},
793 .CubicCurveTo({336.768, 113.8}, {336.782, 113.816},
795 .CubicCurveTo({338.104, 112.946}, {340.187, 111.755},
797 .CubicCurveTo({340.71, 112.95}, {340.728, 113.102},
800 .MoveTo({346.357, 106.771})
801 .CubicCurveTo({346.295, 104.987}, {347.924, 104.139},
803 .CubicCurveTo({347.924, 104.139}, {347.982, 105.931},
806 .MoveTo({347.56, 106.771})
807 .CubicCurveTo({347.498, 104.987}, {349.127, 104.139},
809 .CubicCurveTo({349.127, 104.139}, {349.185, 105.931},
816 ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
824 ASSERT_EQ(path_geometry->GetStrokeCap(),
Cap::kButt);
825 ASSERT_EQ(path_geometry->GetStrokeJoin(),
Join::kMiter);
837 ASSERT_EQ(path_geometry->GetStrokeCap(),
Cap::kRound);
845 ASSERT_FLOAT_EQ(path_geometry->GetMiterLimit(), 4);
851 ASSERT_FLOAT_EQ(path_geometry->GetMiterLimit(), 8);
857 ASSERT_FLOAT_EQ(path_geometry->GetMiterLimit(), 4);
862 std::vector<const char*> blend_mode_names;
863 std::vector<BlendMode> blend_mode_values;
876 blend_mode_names.push_back(
"Clear");
879 blend_mode_names.push_back(
"Source");
882 blend_mode_names.push_back(
"Destination");
885 blend_mode_names.push_back(
"SourceOver");
888 blend_mode_names.push_back(
"DestinationOver");
891 blend_mode_names.push_back(
"SourceIn");
894 blend_mode_names.push_back(
"DestinationIn");
897 blend_mode_names.push_back(
"SourceOut");
900 blend_mode_names.push_back(
"DestinationOut");
903 blend_mode_names.push_back(
"SourceATop");
906 blend_mode_names.push_back(
"DestinationATop");
909 blend_mode_names.push_back(
"Xor");
912 blend_mode_names.push_back(
"Plus");
915 blend_mode_names.push_back(
"Modulate");
922 auto draw_rect = [&context, &pass, &world_matrix](
928 auto r = rect.GetLTRB();
939 pass.SetCommandLabel(
"Blended Rectangle");
941 options.blend_mode = blend_mode;
944 pass.SetVertexBuffer(
947 VS::FrameInfo frame_info;
948 frame_info.mvp = pass.GetOrthographicTransform() * world_matrix;
949 frame_info.color = color.Premultiply();
953 return pass.Draw().ok();
956 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
957 static Color color1(1, 0, 0, 0.5), color2(0, 1, 0, 0.5);
958 ImGui::ColorEdit4(
"Color 1",
reinterpret_cast<float*
>(&color1));
959 ImGui::ColorEdit4(
"Color 2",
reinterpret_cast<float*
>(&color2));
960 static int current_blend_index = 3;
961 ImGui::ListBox(
"Blending mode", ¤t_blend_index,
962 blend_mode_names.data(), blend_mode_names.size());
965 BlendMode selected_mode = blend_mode_values[current_blend_index];
978 pass.GetRenderTargetSize().height),
986 ASSERT_TRUE(OpenPlaygroundHere(callback));
991 static float scale = 20;
993 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
994 ImGui::SliderFloat(
"Scale", &
scale, 1, 100);
1000 .
MoveTo({97.325, 34.818})
1001 .CubicCurveTo({98.50862885295136, 34.81812293973836},
1002 {99.46822048142015, 33.85863261475589},
1003 {99.46822048142015, 32.67499810206613})
1004 .CubicCurveTo({99.46822048142015, 31.491363589376355},
1005 {98.50862885295136, 30.53187326439389},
1006 {97.32499434685802, 30.531998226542708})
1007 .CubicCurveTo({96.14153655073771, 30.532123170035373},
1008 {95.18222070648729, 31.491540299350355},
1009 {95.18222070648729, 32.67499810206613})
1010 .CubicCurveTo({95.18222070648729, 33.85845590478189},
1011 {96.14153655073771, 34.81787303409686},
1012 {97.32499434685802, 34.81799797758954})
1018 return entity.
Render(context, pass);
1020 ASSERT_TRUE(OpenPlaygroundHere(callback));
1024 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
1025 auto boston = CreateTextureForFixture(
"boston.jpg");
1026 auto kalimba = CreateTextureForFixture(
"kalimba.jpg");
1027 ASSERT_TRUE(bridge && boston && kalimba);
1045 entity.SetContents(blend1);
1046 return entity.Render(context, pass);
1048 ASSERT_TRUE(OpenPlaygroundHere(callback));
1053 CreateTextureForFixture(
"boston.jpg",
true);
1054 ASSERT_TRUE(boston);
1057 const char* input_type_names[] = {
"Texture",
"Solid Color"};
1058 const char* blur_type_names[] = {
"Image blur",
"Mask blur"};
1059 const char* pass_variation_names[] = {
"New"};
1060 const char* blur_style_names[] = {
"Normal",
"Solid",
"Outer",
"Inner"};
1061 const char* tile_mode_names[] = {
"Clamp",
"Repeat",
"Mirror",
"Decal"};
1070 static int selected_input_type = 0;
1072 static int selected_blur_type = 0;
1073 static int selected_pass_variation = 0;
1074 static bool combined_sigma =
false;
1075 static float blur_amount_coarse[2] = {0, 0};
1076 static float blur_amount_fine[2] = {10, 10};
1077 static int selected_blur_style = 0;
1078 static int selected_tile_mode = 3;
1079 static Color cover_color(1, 0, 0, 0.2);
1080 static Color bounds_color(0, 1, 0, 0.1);
1081 static float offset[2] = {500, 400};
1082 static float rotation = 0;
1083 static float scale[2] = {0.65, 0.65};
1084 static float skew[2] = {0, 0};
1085 static float path_rect[4] = {0, 0,
1086 static_cast<float>(boston->GetSize().width),
1087 static_cast<float>(boston->GetSize().height)};
1089 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1091 ImGui::Combo(
"Input type", &selected_input_type, input_type_names,
1092 sizeof(input_type_names) /
sizeof(
char*));
1093 if (selected_input_type == 0) {
1094 ImGui::SliderFloat(
"Input opacity", &input_color.
alpha, 0, 1);
1096 ImGui::ColorEdit4(
"Input color",
1097 reinterpret_cast<float*
>(&input_color));
1099 ImGui::Combo(
"Blur type", &selected_blur_type, blur_type_names,
1100 sizeof(blur_type_names) /
sizeof(
char*));
1101 if (selected_blur_type == 0) {
1102 ImGui::Combo(
"Pass variation", &selected_pass_variation,
1103 pass_variation_names,
1104 sizeof(pass_variation_names) /
sizeof(
char*));
1106 ImGui::Checkbox(
"Combined sigma", &combined_sigma);
1107 if (combined_sigma) {
1108 ImGui::SliderFloat(
"Sigma (coarse)", blur_amount_coarse, 0, 1000);
1109 ImGui::SliderFloat(
"Sigma (fine)", blur_amount_fine, 0, 10);
1110 blur_amount_coarse[1] = blur_amount_coarse[0];
1111 blur_amount_fine[1] = blur_amount_fine[0];
1113 ImGui::SliderFloat2(
"Sigma (coarse)", blur_amount_coarse, 0, 1000);
1114 ImGui::SliderFloat2(
"Sigma (fine)", blur_amount_fine, 0, 10);
1116 ImGui::Combo(
"Blur style", &selected_blur_style, blur_style_names,
1117 sizeof(blur_style_names) /
sizeof(
char*));
1118 ImGui::Combo(
"Tile mode", &selected_tile_mode, tile_mode_names,
1119 sizeof(tile_mode_names) /
sizeof(
char*));
1120 ImGui::ColorEdit4(
"Cover color",
reinterpret_cast<float*
>(&cover_color));
1121 ImGui::ColorEdit4(
"Bounds color",
1122 reinterpret_cast<float*
>(&bounds_color));
1123 ImGui::SliderFloat2(
"Translation",
offset, 0,
1124 pass.GetRenderTargetSize().width);
1125 ImGui::SliderFloat(
"Rotation", &rotation, 0,
kPi * 2);
1126 ImGui::SliderFloat2(
"Scale",
scale, 0, 3);
1127 ImGui::SliderFloat2(
"Skew", skew, -3, 3);
1128 ImGui::SliderFloat4(
"Path XYWH", path_rect, -1000, 1000);
1132 auto blur_sigma_x =
Sigma{blur_amount_coarse[0] + blur_amount_fine[0]};
1133 auto blur_sigma_y =
Sigma{blur_amount_coarse[1] + blur_amount_fine[1]};
1135 std::shared_ptr<Contents> input;
1139 Rect::MakeXYWH(path_rect[0], path_rect[1], path_rect[2], path_rect[3]);
1140 if (selected_input_type == 0) {
1141 auto texture = std::make_shared<TextureContents>();
1143 texture->SetDestinationRect(input_rect);
1144 texture->SetTexture(boston);
1145 texture->SetOpacity(input_color.
alpha);
1148 input_size = input_rect.GetSize();
1150 auto fill = std::make_shared<SolidColorContents>();
1151 fill->SetColor(input_color);
1156 input_size = input_rect.GetSize();
1159 std::shared_ptr<FilterContents> blur;
1160 switch (selected_pass_variation) {
1162 blur = std::make_shared<GaussianBlurFilterContents>(
1163 blur_sigma_x.sigma, blur_sigma_y.sigma,
1164 tile_modes[selected_tile_mode], blur_styles[selected_blur_style],
1171 tile_modes[selected_tile_mode], blur_styles[selected_blur_style]);
1178 blur_styles[selected_blur_style]);
1187 auto target_contents = selected_blur_type == 0 ? blur : mask_blur;
1193 entity.
Render(context, pass);
1202 cover_entity.
Render(context, pass);
1206 std::optional<Rect> target_contents_coverage =
1208 if (target_contents_coverage.has_value()) {
1211 .
AddRect(target_contents->GetCoverage(entity).value())
1216 bounds_entity.
Render(context, pass);
1221 ASSERT_TRUE(OpenPlaygroundHere(callback));
1225 auto boston = CreateTextureForFixture(
"boston.jpg");
1226 ASSERT_TRUE(boston);
1229 const char* morphology_type_names[] = {
"Dilate",
"Erode"};
1234 static int selected_morphology_type = 0;
1235 static float radius[2] = {20, 20};
1236 static Color cover_color(1, 0, 0, 0.2);
1237 static Color bounds_color(0, 1, 0, 0.1);
1238 static float offset[2] = {500, 400};
1239 static float rotation = 0;
1240 static float scale[2] = {0.65, 0.65};
1241 static float skew[2] = {0, 0};
1242 static float path_rect[4] = {0, 0,
1243 static_cast<float>(boston->GetSize().width),
1244 static_cast<float>(boston->GetSize().height)};
1245 static float effect_transform_scale = 1;
1247 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1249 ImGui::Combo(
"Morphology type", &selected_morphology_type,
1250 morphology_type_names,
1251 sizeof(morphology_type_names) /
sizeof(
char*));
1252 ImGui::SliderFloat2(
"Radius", radius, 0, 200);
1253 ImGui::SliderFloat(
"Input opacity", &input_color.
alpha, 0, 1);
1254 ImGui::ColorEdit4(
"Cover color",
reinterpret_cast<float*
>(&cover_color));
1255 ImGui::ColorEdit4(
"Bounds color",
1256 reinterpret_cast<float*
>(&bounds_color));
1257 ImGui::SliderFloat2(
"Translation",
offset, 0,
1258 pass.GetRenderTargetSize().width);
1259 ImGui::SliderFloat(
"Rotation", &rotation, 0,
kPi * 2);
1260 ImGui::SliderFloat2(
"Scale",
scale, 0, 3);
1261 ImGui::SliderFloat2(
"Skew", skew, -3, 3);
1262 ImGui::SliderFloat4(
"Path XYWH", path_rect, -1000, 1000);
1263 ImGui::SliderFloat(
"Effect transform scale", &effect_transform_scale, 0,
1268 std::shared_ptr<Contents> input;
1272 Rect::MakeXYWH(path_rect[0], path_rect[1], path_rect[2], path_rect[3]);
1273 auto texture = std::make_shared<TextureContents>();
1275 texture->SetDestinationRect(input_rect);
1276 texture->SetTexture(boston);
1277 texture->SetOpacity(input_color.
alpha);
1280 input_size = input_rect.GetSize();
1284 morphology_types[selected_morphology_type]);
1286 Vector2{effect_transform_scale, effect_transform_scale}));
1299 entity.
Render(context, pass);
1308 cover_entity.
Render(context, pass);
1317 bounds_entity.
Render(context, pass);
1321 ASSERT_TRUE(OpenPlaygroundHere(callback));
1333 entity.
SetContents(std::make_shared<SolidColorContents>());
1344 auto contents = std::make_unique<SolidColorContents>();
1345 contents->SetGeometry(std::move(geometry));
1350 ASSERT_TRUE(actual.has_value());
1361 auto contents = std::make_unique<SolidColorContents>();
1362 contents->SetGeometry(std::move(geometry));
1368 ASSERT_TRUE(actual.has_value());
1379 auto contents = std::make_unique<SolidColorContents>();
1380 contents->SetGeometry(std::move(geometry));
1385 ASSERT_TRUE(actual.has_value());
1391 auto fill = std::make_shared<SolidColorContents>();
1401 auto actual = border_mask_blur->GetCoverage(e);
1403 ASSERT_TRUE(actual.has_value());
1410 auto actual = border_mask_blur->GetCoverage(e);
1411 auto expected =
Rect::MakeXYWH(-287.792, -4.94975, 504.874, 504.874);
1412 ASSERT_TRUE(actual.has_value());
1419 auto atlas = CreateTextureForFixture(
"bay_bridge.jpg");
1420 auto size = atlas->GetSize();
1422 Scalar half_width = size.width / 2;
1423 Scalar half_height = size.height / 2;
1424 std::vector<Rect> texture_coordinates = {
1428 Rect::MakeLTRB(half_width, half_height, size.width, size.height)};
1430 std::vector<Matrix> transforms = {
1435 std::shared_ptr<AtlasContents> contents = std::make_shared<AtlasContents>();
1437 contents->SetTransforms(std::move(transforms));
1438 contents->SetTextureCoordinates(std::move(texture_coordinates));
1439 contents->SetTexture(atlas);
1446 ASSERT_TRUE(OpenPlaygroundHere(std::move(e)));
1451 auto atlas = CreateTextureForFixture(
"bay_bridge.jpg");
1452 auto size = atlas->GetSize();
1454 Scalar half_width = size.width / 2;
1455 Scalar half_height = size.height / 2;
1456 std::vector<Rect> texture_coordinates = {
1460 Rect::MakeLTRB(half_width, half_height, size.width, size.height)};
1462 std::vector<Matrix> transforms = {
1469 std::shared_ptr<AtlasContents> contents = std::make_shared<AtlasContents>();
1471 contents->SetTransforms(std::move(transforms));
1472 contents->SetTextureCoordinates(std::move(texture_coordinates));
1473 contents->SetTexture(atlas);
1474 contents->SetColors(colors);
1481 ASSERT_TRUE(OpenPlaygroundHere(std::move(e)));
1487 auto atlas = CreateTextureForFixture(
"bay_bridge.jpg");
1488 auto size = atlas->GetSize();
1490 Scalar half_width = size.width / 2;
1491 Scalar half_height = size.height / 2;
1492 std::vector<Rect> texture_coordinates = {
1496 Rect::MakeLTRB(half_width, half_height, size.width, size.height)};
1498 std::vector<Matrix> transforms = {
1505 std::shared_ptr<AtlasContents> contents = std::make_shared<AtlasContents>();
1507 contents->SetTransforms(std::move(transforms));
1508 contents->SetTextureCoordinates(std::move(texture_coordinates));
1509 contents->SetTexture(atlas);
1510 contents->SetColors(colors);
1517 ASSERT_TRUE(OpenPlaygroundHere(std::move(e)));
1521 auto atlas = CreateTextureForFixture(
"bay_bridge.jpg");
1522 auto size = atlas->GetSize();
1524 Scalar half_width = size.width / 2;
1525 Scalar half_height = size.height / 2;
1526 std::vector<Rect> texture_coordinates = {
1530 Rect::MakeLTRB(half_width, half_height, size.width, size.height)};
1531 std::vector<Matrix> transforms = {
1537 std::shared_ptr<AtlasContents> contents = std::make_shared<AtlasContents>();
1539 contents->SetTransforms(std::move(transforms));
1540 contents->SetTextureCoordinates(std::move(texture_coordinates));
1541 contents->SetTexture(atlas);
1549 ASSERT_EQ(contents->GetCoverage(e).value(),
1554 ASSERT_EQ(contents->GetCoverage(e).value(),
1561 auto atlas = CreateTextureForFixture(
"bay_bridge.jpg");
1562 auto size = atlas->GetSize();
1564 Scalar half_width = size.width / 2;
1565 Scalar half_height = size.height / 2;
1566 std::vector<Rect> texture_coordinates = {
1570 Rect::MakeLTRB(half_width, half_height, size.width, size.height)};
1572 std::vector<Matrix> transforms = {
1578 std::shared_ptr<AtlasContents> contents = std::make_shared<AtlasContents>();
1580 contents->SetTransforms(std::move(transforms));
1581 contents->SetTextureCoordinates(std::move(texture_coordinates));
1582 contents->SetTexture(atlas);
1584 contents->SetAlpha(0.5);
1590 ASSERT_TRUE(OpenPlaygroundHere(std::move(e)));
1594 auto atlas = CreateTextureForFixture(
"bay_bridge.jpg");
1595 auto size = atlas->GetSize();
1596 std::vector<Rect> texture_coordinates = {
1599 std::shared_ptr<AtlasContents> contents = std::make_shared<AtlasContents>();
1601 contents->SetTransforms(std::move(transforms));
1602 contents->SetTextureCoordinates(std::move(texture_coordinates));
1603 contents->SetTexture(atlas);
1610 ASSERT_TRUE(OpenPlaygroundHere(std::move(e)));
1616 auto fill = std::make_shared<SolidColorContents>();
1622 auto coverage = fill->GetCoverage({});
1623 ASSERT_TRUE(coverage.has_value());
1629 auto fill = std::make_shared<SolidColorContents>();
1640 ASSERT_TRUE(coverage.has_value());
1646 auto fill = std::make_shared<SolidColorContents>();
1651 auto coverage = fill->GetCoverage({});
1652 ASSERT_FALSE(coverage.has_value());
1659 auto fill = std::make_shared<SolidColorContents>();
1668 auto fill = std::make_shared<SolidColorContents>();
1679 auto fill = std::make_shared<SolidColorContents>();
1689 auto fill = std::make_shared<SolidColorContents>();
1707 auto clip = std::make_shared<ClipContents>();
1718 auto restore = std::make_shared<ClipRestoreContents>();
1729 auto clip = std::make_shared<ClipContents>();
1731 auto result = clip->GetClipCoverage(
Entity{},
Rect{});
1733 ASSERT_FALSE(result.coverage.has_value());
1738 auto clip = std::make_shared<ClipContents>();
1742 auto result = clip->GetClipCoverage(
Entity{},
Rect{});
1744 ASSERT_FALSE(result.coverage.has_value());
1749 auto clip = std::make_shared<ClipContents>();
1754 ASSERT_FALSE(result.coverage.has_value());
1759 auto clip = std::make_shared<ClipContents>();
1766 ASSERT_TRUE(result.coverage.has_value());
1773 auto clip = std::make_shared<ClipContents>();
1780 ASSERT_TRUE(result.coverage.has_value());
1789 static float corner_radius = 100;
1790 static float blur_radius = 100;
1791 static bool show_coverage =
false;
1794 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1795 ImGui::SliderFloat(
"Corner radius", &corner_radius, 0, 300);
1796 ImGui::SliderFloat(
"Blur radius", &blur_radius, 0, 300);
1797 ImGui::ColorEdit4(
"Color",
reinterpret_cast<Scalar*
>(&color));
1798 ImGui::Checkbox(
"Show coverage", &show_coverage);
1799 if (show_coverage) {
1800 ImGui::ColorEdit4(
"Coverage color",
1801 reinterpret_cast<Scalar*
>(&coverage_color));
1808 auto [top_left, bottom_right] =
1811 Rect::MakeLTRB(top_left.x, top_left.y, bottom_right.x, bottom_right.y);
1813 auto contents = std::make_unique<SolidRRectBlurContents>();
1814 contents->SetRRect(rect, {corner_radius, corner_radius});
1815 contents->SetColor(color);
1816 contents->SetSigma(
Radius(blur_radius));
1821 entity.
Render(context, pass);
1824 if (show_coverage && coverage.has_value()) {
1825 auto bounds_contents = std::make_unique<SolidColorContents>();
1828 bounds_contents->SetColor(coverage_color.
Premultiply());
1830 bounds_entity.
SetContents(std::move(bounds_contents));
1831 bounds_entity.
Render(context, pass);
1836 ASSERT_TRUE(OpenPlaygroundHere(callback));
1841 auto fill = std::make_shared<SolidColorContents>();
1861 auto actual = filter->GetCoverage(e);
1864 ASSERT_TRUE(actual.has_value());
1869 auto bay_bridge = CreateTextureForFixture(
"bay_bridge.jpg");
1870 ASSERT_TRUE(bay_bridge);
1880 static float offset[2] = {500, 400};
1881 static float rotation = 0;
1882 static float scale[2] = {0.65, 0.65};
1883 static float skew[2] = {0, 0};
1886 ImGui::Begin(
"Color Matrix",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1888 std::string label =
"##1";
1889 for (
int i = 0; i < 20; i += 5) {
1890 ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float,
1891 &(color_matrix.
array[i]), 5,
nullptr,
nullptr,
1896 ImGui::SliderFloat2(
"Translation", &
offset[0], 0,
1897 pass.GetRenderTargetSize().width);
1898 ImGui::SliderFloat(
"Rotation", &rotation, 0,
kPi * 2);
1899 ImGui::SliderFloat2(
"Scale", &
scale[0], 0, 3);
1900 ImGui::SliderFloat2(
"Skew", &skew[0], -3, 3);
1918 entity.
Render(context, pass);
1923 ASSERT_TRUE(OpenPlaygroundHere(callback));
1928 auto fill = std::make_shared<SolidColorContents>();
1940 auto actual = filter->GetCoverage(e);
1943 ASSERT_TRUE(actual.has_value());
1948 auto image = CreateTextureForFixture(
"kalimba.jpg");
1971 return entity_left.
Render(context, pass) &&
1972 entity_right.
Render(context, pass);
1975 ASSERT_TRUE(OpenPlaygroundHere(callback));
1980 auto fill = std::make_shared<SolidColorContents>();
1992 auto actual = filter->GetCoverage(e);
1995 ASSERT_TRUE(actual.has_value());
2000 auto image = CreateTextureForFixture(
"embarcadero.jpg");
2023 return entity_left.
Render(context, pass) &&
2024 entity_right.
Render(context, pass);
2027 ASSERT_TRUE(OpenPlaygroundHere(callback));
2031 auto boston = CreateTextureForFixture(
"boston.jpg");
2034 auto contents = std::make_shared<AtlasContents>();
2036 contents->SetTexture(boston);
2037 contents->SetColors({
2042 contents->SetTextureCoordinates({
2047 contents->SetTransforms({
2055 auto subatlas = contents->GenerateSubAtlas();
2056 ASSERT_EQ(subatlas->sub_texture_coords.size(), 1u);
2060 auto contents = std::make_shared<AtlasContents>();
2062 contents->SetTexture(boston);
2063 contents->SetColors({
2068 contents->SetTextureCoordinates({
2073 contents->SetTransforms({
2080 auto subatlas = contents->GenerateSubAtlas();
2081 ASSERT_EQ(subatlas->sub_texture_coords.size(), 3u);
2085 ASSERT_EQ(subatlas->result_texture_coords[0],
Rect::MakeXYWH(0, 0, 10, 10));
2086 ASSERT_EQ(subatlas->result_texture_coords[1],
2088 ASSERT_EQ(subatlas->result_texture_coords[2],
2095 switch (yuv_color_space) {
2097 yuv.
x = rgb.
x * 0.299 + rgb.
y * 0.587 + rgb.
z * 0.114;
2098 yuv.
y = rgb.
x * -0.169 + rgb.
y * -0.331 + rgb.
z * 0.5 + 0.5;
2099 yuv.
z = rgb.
x * 0.5 + rgb.
y * -0.419 + rgb.
z * -0.081 + 0.5;
2102 yuv.
x = rgb.
x * 0.257 + rgb.
y * 0.516 + rgb.
z * 0.100 + 0.063;
2103 yuv.
y = rgb.
x * -0.145 + rgb.
y * -0.291 + rgb.
z * 0.439 + 0.5;
2104 yuv.
z = rgb.
x * 0.429 + rgb.
y * -0.368 + rgb.
z * -0.071 + 0.5;
2113 Vector3 red = {244.0 / 255.0, 67.0 / 255.0, 54.0 / 255.0};
2114 Vector3 green = {76.0 / 255.0, 175.0 / 255.0, 80.0 / 255.0};
2115 Vector3 blue = {33.0 / 255.0, 150.0 / 255.0, 243.0 / 255.0};
2116 Vector3 white = {1.0, 1.0, 1.0};
2121 std::vector<Vector3> yuvs{red_yuv, green_yuv, blue_yuv, white_yuv};
2122 std::vector<uint8_t> y_data;
2123 std::vector<uint8_t> uv_data;
2124 for (
int i = 0; i < 4; i++) {
2126 uint8_t y = std::round(yuv.x * 255.0);
2127 uint8_t u = std::round(yuv.y * 255.0);
2128 uint8_t v = std::round(yuv.z * 255.0);
2129 for (
int j = 0; j < 16; j++) {
2130 y_data.push_back(y);
2132 for (
int j = 0; j < 8; j++) {
2133 uv_data.push_back(j % 2 == 0 ? u : v);
2139 y_texture_descriptor.
size = {8, 8};
2142 auto y_mapping = std::make_shared<fml::DataMapping>(y_data);
2143 if (!y_texture->SetContents(y_mapping)) {
2144 FML_DLOG(ERROR) <<
"Could not copy contents into Y texture.";
2150 uv_texture_descriptor.
size = {4, 4};
2153 auto uv_mapping = std::make_shared<fml::DataMapping>(uv_data);
2154 if (!uv_texture->SetContents(uv_mapping)) {
2155 FML_DLOG(ERROR) <<
"Could not copy contents into UV texture.";
2158 return {y_texture, uv_texture};
2164 GTEST_SKIP_(
"YUV to RGB filter is not supported on OpenGLES backend yet.");
2170 for (
int i = 0; i < 2; i++) {
2171 auto yuv_color_space = yuv_color_space_array[i];
2178 auto snapshot = filter_contents->RenderToSnapshot(context, filter_entity);
2182 contents->SetTexture(snapshot->texture);
2183 contents->SetSourceRect(
Rect::MakeSize(snapshot->texture->GetSize()));
2187 entity.
Render(context, pass);
2191 ASSERT_TRUE(OpenPlaygroundHere(callback));
2195 auto runtime_stages =
2196 OpenAssetAsRuntimeStage(
"runtime_stage_example.frag.iplr");
2197 auto runtime_stage =
2199 ASSERT_TRUE(runtime_stage);
2200 ASSERT_TRUE(runtime_stage->IsDirty());
2202 bool expect_dirty =
true;
2205 EXPECT_EQ(runtime_stage->IsDirty(), expect_dirty);
2207 auto contents = std::make_shared<RuntimeEffectContents>();
2209 contents->SetRuntimeStage(runtime_stage);
2211 struct FragUniforms {
2215 .iResolution =
Vector2(GetWindowSize().width, GetWindowSize().height),
2216 .iTime =
static_cast<Scalar>(GetSecondsElapsed()),
2218 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
2219 uniform_data->resize(
sizeof(FragUniforms));
2220 memcpy(uniform_data->data(), &frag_uniforms,
sizeof(FragUniforms));
2221 contents->SetUniformData(uniform_data);
2225 bool result = contents->Render(context, entity, pass);
2228 EXPECT_NE(first_pipeline, pass.GetCommands().back().pipeline.get());
2229 first_pipeline = pass.GetCommands().back().pipeline.get();
2231 EXPECT_EQ(pass.GetCommands().back().pipeline.get(), first_pipeline);
2234 expect_dirty =
false;
2239 auto content_context = GetContentContext();
2242 content_context->GetRenderTargetCache()->CreateOffscreen(
2243 *content_context->GetContext(), {1, 1}, 1u);
2245 testing::MockRenderPass mock_pass(GetContext(), target);
2246 callback(*content_context, mock_pass);
2247 callback(*content_context, mock_pass);
2250 runtime_stages = OpenAssetAsRuntimeStage(
"runtime_stage_example.frag.iplr");
2254 ASSERT_TRUE(runtime_stage->IsDirty());
2255 expect_dirty =
true;
2257 callback(*content_context, mock_pass);
2262 auto runtime_stages =
2263 OpenAssetAsRuntimeStage(
"runtime_stage_example.frag.iplr");
2264 auto runtime_stage =
2266 ASSERT_TRUE(runtime_stage);
2267 ASSERT_TRUE(runtime_stage->IsDirty());
2269 auto contents = std::make_shared<RuntimeEffectContents>();
2272 contents->SetRuntimeStage(runtime_stage);
2274 struct FragUniforms {
2278 .iResolution =
Vector2(GetWindowSize().width, GetWindowSize().height),
2279 .iTime =
static_cast<Scalar>(GetSecondsElapsed()),
2281 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
2282 uniform_data->resize(
sizeof(FragUniforms));
2283 memcpy(uniform_data->data(), &frag_uniforms,
sizeof(FragUniforms));
2284 contents->SetUniformData(uniform_data);
2292 GetContentContext()->GetRenderTargetCache()->CreateOffscreenMSAA(
2293 *GetContext(), {GetWindowSize().width, GetWindowSize().height}, 1,
2294 "RuntimeEffect Texture");
2295 testing::MockRenderPass pass(GetContext(), target);
2297 ASSERT_TRUE(contents->Render(*GetContentContext(), entity, pass));
2298 ASSERT_EQ(pass.GetCommands().size(), 1u);
2299 const auto& command = pass.GetCommands()[0];
2300 ASSERT_TRUE(command.pipeline->GetDescriptor()
2301 .GetDepthStencilAttachmentDescriptor()
2303 ASSERT_TRUE(command.pipeline->GetDescriptor()
2304 .GetFrontStencilAttachmentDescriptor()
2310 GTEST_SKIP() <<
"Test only applies to Vulkan";
2313 auto runtime_stages =
2314 OpenAssetAsRuntimeStage(
"runtime_stage_example.frag.iplr");
2315 auto runtime_stage =
2317 ASSERT_TRUE(runtime_stage);
2318 ASSERT_TRUE(runtime_stage->IsDirty());
2320 auto contents = std::make_shared<RuntimeEffectContents>();
2322 contents->SetRuntimeStage(runtime_stage);
2324 struct FragUniforms {
2328 .iResolution =
Vector2(GetWindowSize().width, GetWindowSize().height),
2329 .iTime =
static_cast<Scalar>(GetSecondsElapsed()),
2331 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
2332 uniform_data->resize(
sizeof(FragUniforms));
2333 memcpy(uniform_data->data(), &frag_uniforms,
sizeof(FragUniforms));
2334 contents->SetUniformData(uniform_data);
2339 auto context = GetContentContext();
2340 RenderTarget target = context->GetRenderTargetCache()->CreateOffscreen(
2341 *context->GetContext(), {1, 1}, 1u);
2343 testing::MockRenderPass pass(GetContext(), target);
2344 ASSERT_TRUE(contents->Render(*context, entity, pass));
2345 ASSERT_EQ(pass.GetCommands().size(), 1u);
2346 const auto& command = pass.GetCommands()[0];
2347 ASSERT_EQ(command.fragment_bindings.buffers.size(), 1u);
2352 EXPECT_EQ(command.fragment_bindings.buffers[0].view.resource.range.length,
2360 auto texture_contents = std::make_shared<TextureContents>();
2361 texture_contents->SetOpacity(0.5);
2362 ASSERT_TRUE(texture_contents->CanInheritOpacity(entity));
2364 texture_contents->SetInheritedOpacity(0.5);
2365 ASSERT_EQ(texture_contents->GetOpacity(), 0.25);
2366 texture_contents->SetInheritedOpacity(0.5);
2367 ASSERT_EQ(texture_contents->GetOpacity(), 0.25);
2371 auto solid_color = std::make_shared<SolidColorContents>();
2372 solid_color->SetGeometry(
2374 solid_color->SetColor(
Color::Blue().WithAlpha(0.5));
2376 ASSERT_TRUE(solid_color->CanInheritOpacity(entity));
2378 solid_color->SetInheritedOpacity(0.5);
2379 ASSERT_EQ(solid_color->GetColor().alpha, 0.25);
2380 solid_color->SetInheritedOpacity(0.5);
2381 ASSERT_EQ(solid_color->GetColor().alpha, 0.25);
2385 auto tiled_texture = std::make_shared<TiledTextureContents>();
2386 tiled_texture->SetGeometry(
2388 tiled_texture->SetOpacityFactor(0.5);
2390 ASSERT_TRUE(tiled_texture->CanInheritOpacity(entity));
2392 tiled_texture->SetInheritedOpacity(0.5);
2393 ASSERT_EQ(tiled_texture->GetOpacityFactor(), 0.25);
2394 tiled_texture->SetInheritedOpacity(0.5);
2395 ASSERT_EQ(tiled_texture->GetOpacityFactor(), 0.25);
2399 SkFont font = flutter::testing::CreateTestFontOfSize(30);
2400 auto blob = SkTextBlob::MakeFromString(
"A", font);
2402 auto lazy_glyph_atlas =
2404 lazy_glyph_atlas->AddTextFrame(*frame, 1.0f);
2406 auto text_contents = std::make_shared<TextContents>();
2407 text_contents->SetTextFrame(frame);
2408 text_contents->SetColor(
Color::Blue().WithAlpha(0.5));
2410 ASSERT_TRUE(text_contents->CanInheritOpacity(entity));
2412 text_contents->SetInheritedOpacity(0.5);
2413 ASSERT_EQ(text_contents->GetColor().alpha, 0.25);
2414 text_contents->SetInheritedOpacity(0.5);
2415 ASSERT_EQ(text_contents->GetColor().alpha, 0.25);
2422 auto runtime_effect = std::make_shared<RuntimeEffectContents>();
2423 ASSERT_FALSE(runtime_effect->CanInheritOpacity(entity));
2427 auto image = CreateTextureForFixture(
"boston.jpg");
2437 return entity.
Render(context, pass);
2439 ASSERT_TRUE(OpenPlaygroundHere(callback));
2443 auto image = CreateTextureForFixture(
"boston.jpg");
2453 return entity.
Render(context, pass);
2455 ASSERT_TRUE(OpenPlaygroundHere(callback));
2459 auto image = CreateTextureForFixture(
"boston.jpg");
2469 return entity.
Render(context, pass);
2471 ASSERT_TRUE(OpenPlaygroundHere(callback));
2475 auto image = CreateTextureForFixture(
"boston.jpg");
2485 return entity.
Render(context, pass);
2487 ASSERT_TRUE(OpenPlaygroundHere(callback));
2491 auto image = CreateTextureForFixture(
"boston.jpg");
2501 return entity.
Render(context, pass);
2503 ASSERT_TRUE(OpenPlaygroundHere(callback));
2517 EXPECT_LT(transform.e[0][0], 0.f);
2518 auto coverage = geometry->GetCoverage(transform);
2572 auto bay_bridge = CreateTextureForFixture(
"bay_bridge.jpg");
2600 std::vector<Point> points = {{10, 20}, {100, 200}};
2610 auto src_contents = std::make_shared<SolidColorContents>();
2611 src_contents->SetGeometry(
2615 auto dst_contents = std::make_shared<SolidColorContents>();
2616 dst_contents->SetGeometry(
2624 ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
2635 if (GetContext()->GetCapabilities()->SupportsFramebufferFetch()) {
2636 GTEST_SKIP() <<
"Backends that support framebuffer fetch dont use coverage "
2637 "for advanced blends.";
2640 auto contents = std::make_shared<SolidColorContents>();
2650 EXPECT_TRUE(coverage.has_value());
2652 auto pass = std::make_unique<EntityPass>();
2653 std::shared_ptr<RenderTargetCache> render_target_allocator =
2654 std::make_shared<RenderTargetCache>(GetContext()->GetResourceAllocator());
2660 auto rt = render_target_allocator->CreateOffscreen(
2666 pass->AddEntity(std::move(entity));
2668 EXPECT_TRUE(pass->Render(content_context, rt));
2670 auto contains_size = [&render_target_allocator](
ISize size) ->
bool {
2671 return std::find_if(render_target_allocator->GetRenderTargetDataBegin(),
2672 render_target_allocator->GetRenderTargetDataEnd(),
2673 [&size](
const auto& data) {
2674 return data.config.size == size;
2675 }) != render_target_allocator->GetRenderTargetDataEnd();
2678 EXPECT_TRUE(contains_size(
ISize(1000, 1000)))
2679 <<
"The root texture wasn't allocated";
2680 EXPECT_TRUE(contains_size(
ISize(200, 200)))
2681 <<
"The ColorBurned texture wasn't allocated (100x100 scales up 2x)";
2685 auto content_context = GetContentContext();
2687 auto default_color_burn = content_context->GetBlendColorBurnPipeline({
2689 .has_depth_stencil_attachments =
false,
2691 auto alt_color_burn = content_context->GetBlendColorBurnPipeline(
2693 .has_depth_stencil_attachments =
true});
2695 ASSERT_NE(default_color_burn, alt_color_burn);
2696 ASSERT_EQ(default_color_burn->GetDescriptor().GetSpecializationConstants(),
2697 alt_color_burn->GetDescriptor().GetSpecializationConstants());
2699 auto decal_supported =
static_cast<Scalar>(
2700 GetContext()->GetCapabilities()->SupportsDecalSamplerAddressMode());
2701 std::vector<Scalar> expected_constants = {5, decal_supported};
2702 ASSERT_EQ(default_color_burn->GetDescriptor().GetSpecializationConstants(),
2703 expected_constants);
2707 auto content_context = GetContentContext();
2708 auto default_color_burn = content_context->GetMorphologyFilterPipeline({
2712 auto decal_supported =
static_cast<Scalar>(
2713 GetContext()->GetCapabilities()->SupportsDecalSamplerAddressMode());
2714 std::vector<Scalar> expected_constants = {decal_supported};
2715 ASSERT_EQ(default_color_burn->GetDescriptor().GetSpecializationConstants(),
2716 expected_constants);
2735 EXPECT_NE(hash_a, hash_b);
2736 EXPECT_NE(hash_b, hash_c);
2737 EXPECT_NE(hash_c, hash_d);
2752 bool expected_layout =
false;
2754 FragmentShader::kDescriptorSetLayouts) {
2755 if (layout.binding == 64 &&
2757 expected_layout =
true;
2760 EXPECT_TRUE(expected_layout);
2766 testing::MockRenderPass mock_pass(GetContext(), target);
2768 auto get_result = [
this, &mock_pass](
const Path& path) {
2771 return geometry->GetPositionBuffer(*GetContentContext(), {}, mock_pass);
2804 GTEST_SKIP() <<
"Validation is only fatal on Vulkan backend.";
2809 GetContentContext()->GetBlendColorBurnPipeline({
2811 .has_depth_stencil_attachments =
false,
2827 GetContentContext()->GetRenderTargetCache()->CreateOffscreen(
2828 *GetContext(), {1, 1}, 1u);
2829 testing::MockRenderPass render_pass(GetContext(), target);
2830 auto position_result =
2831 geom->GetPositionBuffer(*GetContentContext(), entity, render_pass);
2835 *GetContentContext(), entity, render_pass);
2837 EXPECT_EQ(position_result.vertex_buffer.vertex_count, 0u);
2838 EXPECT_EQ(uv_result.vertex_buffer.vertex_count, 0u);
2850 auto contents = std::make_shared<SolidColorContents>();
2858 ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));