11 #include "flutter/display_list/testing/dl_test_snippets.h"
12 #include "fml/logging.h"
13 #include "gtest/gtest.h"
54 #include "third_party/imgui/imgui.h"
55 #include "third_party/skia/include/core/SkTextBlob.h"
88 std::shared_ptr<Texture> target,
89 const Matrix& transform)
override {
96 const Matrix& effect_transform)
const override {
101 const std::optional<Rect> coverage_;
102 const bool collapse_;
106 std::optional<Rect> bounds_hint,
107 bool collapse =
false) {
108 auto subpass = std::make_unique<EntityPass>();
112 subpass->AddEntity(std::move(entity));
113 subpass->SetDelegate(std::make_unique<TestPassDelegate>(collapse));
114 subpass->SetBoundsLimit(bounds_hint);
126 auto subpass0_coverage =
128 ASSERT_TRUE(subpass0_coverage.has_value());
131 auto subpass1_coverage =
133 ASSERT_TRUE(subpass1_coverage.has_value());
141 ASSERT_TRUE(coverage.has_value());
156 auto contents = std::make_unique<SolidColorContents>();
163 ASSERT_TRUE(OpenPlaygroundHere(pass));
173 auto pass_coverage = pass->GetElementsCoverage(std::nullopt);
174 ASSERT_TRUE(pass_coverage.has_value());
183 ASSERT_FALSE(pass_coverage.has_value());
190 ASSERT_TRUE(pass_coverage.has_value());
197 auto image = CreateTextureForFixture(
"boston.jpg");
203 auto actual = filter->GetCoverage({});
206 ASSERT_TRUE(actual.has_value());
213 filter->SetCoverageHint(expected);
214 auto actual = filter->GetCoverage({});
216 ASSERT_TRUE(actual.has_value());
222 auto contents = std::make_shared<SolidColorContents>();
230 ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
234 auto contents = std::make_shared<SolidColorContents>();
246 ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
269 auto contents = std::make_unique<SolidColorContents>();
273 ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
277 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
289 auto contents = std::make_unique<TiledTextureContents>();
291 contents->SetTexture(bridge);
294 ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
299 Point offset(100, 100);
329 auto contents = std::make_unique<SolidColorContents>();
334 return entity.
Render(context, pass);
336 ASSERT_TRUE(OpenPlaygroundHere(callback));
340 const Point padding(300, 250);
341 const Point margin(140, 180);
347 static Scalar miter_limit = 1.41421357;
350 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
352 ImGui::SliderFloat(
"Miter limit", &miter_limit, 0, 30);
353 ImGui::SliderFloat(
"Stroke width", &width, 0, 100);
354 if (ImGui::Button(
"Reset")) {
355 miter_limit = 1.41421357;
362 auto render_path = [width = width, &context, &pass, &world_matrix](
364 auto contents = std::make_unique<SolidColorContents>();
366 miter_limit, cap, join));
374 if (coverage.has_value()) {
375 auto bounds_contents = std::make_unique<SolidColorContents>();
378 bounds_contents->SetColor(
Color::Green().WithAlpha(0.5));
380 bounds_entity.
SetContents(std::move(bounds_contents));
381 bounds_entity.
Render(context, pass);
384 entity.
Render(context, pass);
387 const Point a_def(0, 0), b_def(0, 100), c_def(150, 0), d_def(150, -100),
458 ASSERT_TRUE(OpenPlaygroundHere(callback));
465 .
MoveTo({237.164, 125.003})
466 .CubicCurveTo({236.709, 125.184}, {236.262, 125.358},
468 .CubicCurveTo({235.413, 125.68}, {234.994, 125.832},
470 .CubicCurveTo({234.592, 125.977}, {234.591, 125.977},
472 .CubicCurveTo({222.206, 130.435}, {207.708, 135.753},
474 .CubicCurveTo({162.77, 151.336}, {122.17, 156.894}, {84.1123, 160})
480 ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
485 const char* input_axis[] = {
"X",
"Y",
"Z"};
486 static int rotation_axis_index = 0;
487 static float rotation = 0;
488 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
489 ImGui::SliderFloat(
"Rotation", &rotation, -
kPi,
kPi);
490 ImGui::Combo(
"Rotation Axis", &rotation_axis_index, input_axis,
491 sizeof(input_axis) /
sizeof(
char*));
493 switch (rotation_axis_index) {
504 rotation_matrix =
Matrix{};
508 if (ImGui::Button(
"Reset")) {
512 Matrix current_transform =
516 pass.GetRenderTargetSize().height / 2.0)));
517 Matrix result_transform = current_transform * rotation_matrix;
524 return entity.
Render(context, pass);
526 ASSERT_TRUE(OpenPlaygroundHere(callback));
533 .
MoveTo({359.934, 96.6335})
534 .CubicCurveTo({358.189, 96.7055}, {356.436, 96.7908},
536 .CubicCurveTo({354.571, 96.8953}, {354.469, 96.9016},
538 .CubicCurveTo({352.672, 97.0038}, {350.969, 97.113},
540 .CubicCurveTo({349.048, 97.2506}, {348.836, 97.2678},
542 .CubicCurveTo({347.019, 97.4014}, {345.407, 97.5299},
544 .CubicCurveTo({343.428, 97.704}, {343.065, 97.7402},
546 .CubicCurveTo({341.221, 97.9086}, {339.736, 98.0505},
548 .CubicCurveTo({337.702, 98.2642}, {337.156, 98.3292},
550 .CubicCurveTo({335.284, 98.5356}, {333.956, 98.6837},
552 .CubicCurveTo({332.495, 98.8635}, {332.366, 98.8818},
554 .
LineTo({332.237, 102.601})
555 .
LineTo({321.778, 102.601})
556 .
LineTo({321.778, 100.382})
557 .CubicCurveTo({321.572, 100.413}, {321.367, 100.442},
559 .CubicCurveTo({319.22, 100.79}, {317.277, 101.123},
561 .CubicCurveTo({315.322, 101.481}, {315.311, 101.482},
563 .
LineTo({310.017, 105.94})
564 .
LineTo({309.779, 105.427})
565 .
LineTo({314.403, 101.651})
566 .CubicCurveTo({314.391, 101.653}, {314.379, 101.656},
568 .CubicCurveTo({312.528, 102.001}, {310.687, 102.366},
570 .CubicCurveTo({307.85, 102.955}, {306.855, 103.182}, {305.859, 103.4})
571 .CubicCurveTo({305.048, 103.579}, {304.236, 103.75},
573 .
LineTo({299.105, 107.578})
574 .
LineTo({298.867, 107.065})
575 .
LineTo({302.394, 104.185})
576 .
LineTo({302.412, 104.171})
577 .CubicCurveTo({301.388, 104.409}, {300.366, 104.67},
579 .CubicCurveTo({298.618, 105.1}, {297.89, 105.269}, {297.165, 105.455})
580 .CubicCurveTo({295.262, 105.94}, {293.36, 106.445},
582 .CubicCurveTo({291.132, 107.072}, {290.802, 107.163},
584 .CubicCurveTo({289.463, 107.544}, {288.455, 107.839},
586 .CubicCurveTo({286.476, 108.431}, {285.506, 108.73},
588 .CubicCurveTo({283.674, 109.304}, {282.812, 109.579},
590 .CubicCurveTo({281.177, 110.112}, {280.406, 110.377},
592 .CubicCurveTo({278.458, 111.037}, {277.256, 111.449},
594 .CubicCurveTo({276.76, 111.622}, {276.716, 111.637},
596 .CubicCurveTo({275.017, 112.239}, {273.365, 112.836},
598 .
LineTo({271.717, 113.449})
599 .CubicCurveTo({271.496, 113.496}, {271.238, 113.559},
601 .CubicCurveTo({270.893, 113.645}, {270.822, 113.663},
603 .CubicCurveTo({270.468, 113.755}, {270.169, 113.834},
605 .CubicCurveTo({269.789, 113.94}, {269.732, 113.957},
607 .CubicCurveTo({269.391, 114.053}, {269.081, 114.143},
609 .CubicCurveTo({268.628, 114.276}, {268.5, 114.314},
611 .CubicCurveTo({268.172, 114.412}, {267.959, 114.478},
613 .CubicCurveTo({263.349, 115.964}, {258.058, 117.695},
615 .CubicCurveTo({253.556, 119.255}, {253.547, 119.258},
617 .CubicCurveTo({251.844, 119.849}, {250.056, 120.474},
619 .CubicCurveTo({248, 121.197}, {247.812, 121.264}, {247.621, 121.331})
620 .CubicCurveTo({247.079, 121.522}, {246.531, 121.715},
622 .CubicCurveTo({245.554, 122.06}, {245.126, 122.212},
624 .CubicCurveTo({244.071, 122.586}, {243.437, 122.811},
626 .CubicCurveTo({242.189, 123.255}, {241.58, 123.472},
628 .CubicCurveTo({240.659, 123.801}, {240.357, 123.909},
630 .CubicCurveTo({239.12, 124.351}, {238.18, 124.687}, {237.22, 125.032})
631 .
LineTo({237.164, 125.003})
632 .CubicCurveTo({236.709, 125.184}, {236.262, 125.358},
634 .CubicCurveTo({235.413, 125.68}, {234.994, 125.832},
636 .CubicCurveTo({234.592, 125.977}, {234.591, 125.977},
638 .CubicCurveTo({222.206, 130.435}, {207.708, 135.753},
640 .CubicCurveTo({162.77, 151.336}, {122.17, 156.894}, {84.1123, 160})
645 .CubicCurveTo({359.978, 96.6317}, {359.956, 96.6326},
648 .MoveTo({337.336, 124.143})
649 .CubicCurveTo({337.274, 122.359}, {338.903, 121.511},
651 .CubicCurveTo({338.903, 121.511}, {338.96, 123.303},
654 .MoveTo({340.082, 121.849})
655 .CubicCurveTo({340.074, 121.917}, {340.062, 121.992},
657 .CubicCurveTo({340.039, 122.109}, {340.031, 122.142},
659 .CubicCurveTo({340.005, 122.26}, {339.98, 122.346},
661 .CubicCurveTo({339.941, 122.473}, {339.931, 122.507},
663 .CubicCurveTo({339.873, 122.672}, {339.819, 122.804},
665 .CubicCurveTo({339.747, 122.944}, {339.743, 122.949},
667 .CubicCurveTo({339.674, 123.08}, {339.593, 123.205},
669 .CubicCurveTo({339.473, 123.366}, {339.441, 123.401},
671 .CubicCurveTo({339.332, 123.534}, {339.243, 123.625},
673 .CubicCurveTo({339.105, 123.75}, {339.068, 123.786},
675 .CubicCurveTo({338.881, 123.937}, {338.724, 124.048},
677 .CubicCurveTo({338.532, 123.959}, {338.554, 123.79},
679 .CubicCurveTo({338.58, 123.625}, {338.58, 123.625}, {338.58, 123.625})
680 .CubicCurveTo({338.607, 123.455}, {338.65, 123.299},
682 .CubicCurveTo({338.708, 123.14}, {338.71, 123.127},
684 .CubicCurveTo({338.769, 122.971}, {338.833, 122.838},
686 .CubicCurveTo({338.911, 122.702}, {338.916, 122.69200000000001},
688 .CubicCurveTo({338.996, 122.557}, {339.072, 122.444},
690 .CubicCurveTo({339.161, 122.333}, {339.166, 122.326},
692 .CubicCurveTo({339.256, 122.215}, {339.339, 122.12},
694 .CubicCurveTo({339.428, 122.033}, {339.431, 122.03},
696 .CubicCurveTo({339.785, 121.687}, {340.106, 121.511},
698 .CubicCurveTo({340.106, 121.511}, {340.107, 121.645},
701 .MoveTo({340.678, 113.245})
702 .CubicCurveTo({340.594, 113.488}, {340.356, 113.655},
704 .CubicCurveTo({339.817, 113.948}, {339.465, 114.059},
706 .CubicCurveTo({338.251, 114.379}, {337.34, 114.516},
708 .CubicCurveTo({335.761, 114.516}, {335.072, 114.527},
710 .CubicCurveTo({334.125, 114.508}, {333.862, 114.462},
712 .CubicCurveTo({332.865, 114.318}, {332.096, 114.184},
714 .CubicCurveTo({330.979, 113.695}, {330.442, 113.34},
716 .CubicCurveTo({331.135, 111.755}, {333.219, 112.946},
718 .CubicCurveTo({334.54, 113.816}, {334.554, 113.8}, {334.569, 113.784})
719 .CubicCurveTo({333.38, 112.708}, {331.749, 110.985},
721 .CubicCurveTo({333.769, 109.82}, {334.713, 111.93},
723 .CubicCurveTo({334.915, 111.889}, {334.59, 109.636},
725 .CubicCurveTo({336.733, 109.636}, {336.408, 111.889},
727 .CubicCurveTo({336.609, 111.93}, {337.553, 109.82},
729 .CubicCurveTo({339.574, 110.984}, {337.942, 112.708},
731 .CubicCurveTo({336.768, 113.8}, {336.782, 113.816},
733 .CubicCurveTo({338.104, 112.946}, {340.187, 111.755},
735 .CubicCurveTo({340.71, 112.95}, {340.728, 113.102},
738 .MoveTo({346.357, 106.771})
739 .CubicCurveTo({346.295, 104.987}, {347.924, 104.139},
741 .CubicCurveTo({347.924, 104.139}, {347.982, 105.931},
744 .MoveTo({347.56, 106.771})
745 .CubicCurveTo({347.498, 104.987}, {349.127, 104.139},
747 .CubicCurveTo({349.127, 104.139}, {349.185, 105.931},
754 ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
762 ASSERT_EQ(path_geometry->GetStrokeCap(),
Cap::kButt);
763 ASSERT_EQ(path_geometry->GetStrokeJoin(),
Join::kMiter);
775 ASSERT_EQ(path_geometry->GetStrokeCap(),
Cap::kRound);
783 ASSERT_FLOAT_EQ(path_geometry->GetMiterLimit(), 4);
789 ASSERT_FLOAT_EQ(path_geometry->GetMiterLimit(), 8);
795 ASSERT_FLOAT_EQ(path_geometry->GetMiterLimit(), 4);
800 std::vector<const char*> blend_mode_names;
801 std::vector<BlendMode> blend_mode_values;
814 blend_mode_names.push_back(
"Clear");
817 blend_mode_names.push_back(
"Source");
820 blend_mode_names.push_back(
"Destination");
823 blend_mode_names.push_back(
"SourceOver");
826 blend_mode_names.push_back(
"DestinationOver");
829 blend_mode_names.push_back(
"SourceIn");
832 blend_mode_names.push_back(
"DestinationIn");
835 blend_mode_names.push_back(
"SourceOut");
838 blend_mode_names.push_back(
"DestinationOut");
841 blend_mode_names.push_back(
"SourceATop");
844 blend_mode_names.push_back(
"DestinationATop");
847 blend_mode_names.push_back(
"Xor");
850 blend_mode_names.push_back(
"Plus");
853 blend_mode_names.push_back(
"Modulate");
860 auto draw_rect = [&context, &pass, &world_matrix](
866 auto r = rect.GetLTRB();
880 options.blend_mode = blend_mode;
886 VS::FrameInfo frame_info;
887 frame_info.mvp = pass.GetOrthographicTransform() * world_matrix;
888 frame_info.color = color.Premultiply();
889 VS::BindFrameInfo(cmd,
890 pass.GetTransientsBuffer().EmplaceUniform(frame_info));
892 return pass.AddCommand(std::move(cmd));
895 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
896 static Color color1(1, 0, 0, 0.5), color2(0, 1, 0, 0.5);
897 ImGui::ColorEdit4(
"Color 1",
reinterpret_cast<float*
>(&color1));
898 ImGui::ColorEdit4(
"Color 2",
reinterpret_cast<float*
>(&color2));
899 static int current_blend_index = 3;
900 ImGui::ListBox(
"Blending mode", ¤t_blend_index,
901 blend_mode_names.data(), blend_mode_names.size());
904 BlendMode selected_mode = blend_mode_values[current_blend_index];
915 pass.GetRenderTargetSize().height),
923 ASSERT_TRUE(OpenPlaygroundHere(callback));
928 static float scale = 20;
930 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
931 ImGui::SliderFloat(
"Scale", &scale, 1, 100);
938 .CubicCurveTo({98.50862885295136, 34.81812293973836},
939 {99.46822048142015, 33.85863261475589},
940 {99.46822048142015, 32.67499810206613})
941 .CubicCurveTo({99.46822048142015, 31.491363589376355},
942 {98.50862885295136, 30.53187326439389},
943 {97.32499434685802, 30.531998226542708})
944 .CubicCurveTo({96.14153655073771, 30.532123170035373},
945 {95.18222070648729, 31.491540299350355},
946 {95.18222070648729, 32.67499810206613})
947 .CubicCurveTo({95.18222070648729, 33.85845590478189},
948 {96.14153655073771, 34.81787303409686},
949 {97.32499434685802, 34.81799797758954})
955 return entity.
Render(context, pass);
957 ASSERT_TRUE(OpenPlaygroundHere(callback));
961 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
962 auto boston = CreateTextureForFixture(
"boston.jpg");
963 auto kalimba = CreateTextureForFixture(
"kalimba.jpg");
964 ASSERT_TRUE(bridge && boston && kalimba);
982 entity.SetContents(blend1);
983 return entity.Render(context, pass);
985 ASSERT_TRUE(OpenPlaygroundHere(callback));
989 auto boston = CreateTextureForFixture(
"boston.jpg");
993 const char* input_type_names[] = {
"Texture",
"Solid Color"};
994 const char* blur_type_names[] = {
"Image blur",
"Mask blur"};
995 const char* pass_variation_names[] = {
"New",
"2D Directional",
997 const char* blur_style_names[] = {
"Normal",
"Solid",
"Outer",
"Inner"};
998 const char* tile_mode_names[] = {
"Clamp",
"Repeat",
"Mirror",
"Decal"};
1007 static int selected_input_type = 0;
1009 static int selected_blur_type = 0;
1010 static int selected_pass_variation = 0;
1011 static bool combined_sigma =
false;
1012 static float blur_amount_coarse[2] = {0, 0};
1013 static float blur_amount_fine[2] = {10, 10};
1014 static int selected_blur_style = 0;
1015 static int selected_tile_mode = 3;
1016 static Color cover_color(1, 0, 0, 0.2);
1017 static Color bounds_color(0, 1, 0, 0.1);
1018 static float offset[2] = {500, 400};
1019 static float rotation = 0;
1020 static float scale[2] = {0.65, 0.65};
1021 static float skew[2] = {0, 0};
1022 static float path_rect[4] = {0, 0,
1023 static_cast<float>(boston->GetSize().width),
1024 static_cast<float>(boston->GetSize().height)};
1026 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1028 ImGui::Combo(
"Input type", &selected_input_type, input_type_names,
1029 sizeof(input_type_names) /
sizeof(
char*));
1030 if (selected_input_type == 0) {
1031 ImGui::SliderFloat(
"Input opacity", &input_color.
alpha, 0, 1);
1033 ImGui::ColorEdit4(
"Input color",
1034 reinterpret_cast<float*
>(&input_color));
1036 ImGui::Combo(
"Blur type", &selected_blur_type, blur_type_names,
1037 sizeof(blur_type_names) /
sizeof(
char*));
1038 if (selected_blur_type == 0) {
1039 ImGui::Combo(
"Pass variation", &selected_pass_variation,
1040 pass_variation_names,
1041 sizeof(pass_variation_names) /
sizeof(
char*));
1043 ImGui::Checkbox(
"Combined sigma", &combined_sigma);
1044 if (combined_sigma) {
1045 ImGui::SliderFloat(
"Sigma (coarse)", blur_amount_coarse, 0, 1000);
1046 ImGui::SliderFloat(
"Sigma (fine)", blur_amount_fine, 0, 10);
1047 blur_amount_coarse[1] = blur_amount_coarse[0];
1048 blur_amount_fine[1] = blur_amount_fine[0];
1050 ImGui::SliderFloat2(
"Sigma (coarse)", blur_amount_coarse, 0, 1000);
1051 ImGui::SliderFloat2(
"Sigma (fine)", blur_amount_fine, 0, 10);
1053 ImGui::Combo(
"Blur style", &selected_blur_style, blur_style_names,
1054 sizeof(blur_style_names) /
sizeof(
char*));
1055 ImGui::Combo(
"Tile mode", &selected_tile_mode, tile_mode_names,
1056 sizeof(tile_mode_names) /
sizeof(
char*));
1057 ImGui::ColorEdit4(
"Cover color",
reinterpret_cast<float*
>(&cover_color));
1058 ImGui::ColorEdit4(
"Bounds color",
1059 reinterpret_cast<float*
>(&bounds_color));
1060 ImGui::SliderFloat2(
"Translation", offset, 0,
1061 pass.GetRenderTargetSize().width);
1062 ImGui::SliderFloat(
"Rotation", &rotation, 0,
kPi * 2);
1063 ImGui::SliderFloat2(
"Scale", scale, 0, 3);
1064 ImGui::SliderFloat2(
"Skew", skew, -3, 3);
1065 ImGui::SliderFloat4(
"Path XYWH", path_rect, -1000, 1000);
1069 auto blur_sigma_x =
Sigma{blur_amount_coarse[0] + blur_amount_fine[0]};
1070 auto blur_sigma_y =
Sigma{blur_amount_coarse[1] + blur_amount_fine[1]};
1072 std::shared_ptr<Contents> input;
1076 Rect::MakeXYWH(path_rect[0], path_rect[1], path_rect[2], path_rect[3]);
1077 if (selected_input_type == 0) {
1078 auto texture = std::make_shared<TextureContents>();
1080 texture->SetDestinationRect(input_rect);
1081 texture->SetTexture(boston);
1082 texture->SetOpacity(input_color.
alpha);
1085 input_size = input_rect.GetSize();
1087 auto fill = std::make_shared<SolidColorContents>();
1088 fill->SetColor(input_color);
1093 input_size = input_rect.GetSize();
1096 std::shared_ptr<FilterContents> blur;
1097 switch (selected_pass_variation) {
1099 blur = std::make_shared<GaussianBlurFilterContents>(
1100 blur_sigma_x.sigma, blur_sigma_y.sigma,
1101 tile_modes[selected_tile_mode]);
1107 blur_styles[selected_blur_style], tile_modes[selected_tile_mode]);
1110 Vector2 blur_vector(blur_sigma_x.sigma, blur_sigma_y.sigma);
1121 blur_styles[selected_blur_style]);
1130 auto target_contents = selected_blur_type == 0 ? blur : mask_blur;
1136 entity.
Render(context, pass);
1145 cover_entity.
Render(context, pass);
1149 std::optional<Rect> target_contents_coverage =
1151 if (target_contents_coverage.has_value()) {
1154 .
AddRect(target_contents->GetCoverage(entity).value())
1159 bounds_entity.
Render(context, pass);
1164 ASSERT_TRUE(OpenPlaygroundHere(callback));
1168 auto boston = CreateTextureForFixture(
"boston.jpg");
1169 ASSERT_TRUE(boston);
1172 const char* morphology_type_names[] = {
"Dilate",
"Erode"};
1177 static int selected_morphology_type = 0;
1178 static float radius[2] = {20, 20};
1179 static Color cover_color(1, 0, 0, 0.2);
1180 static Color bounds_color(0, 1, 0, 0.1);
1181 static float offset[2] = {500, 400};
1182 static float rotation = 0;
1183 static float scale[2] = {0.65, 0.65};
1184 static float skew[2] = {0, 0};
1185 static float path_rect[4] = {0, 0,
1186 static_cast<float>(boston->GetSize().width),
1187 static_cast<float>(boston->GetSize().height)};
1188 static float effect_transform_scale = 1;
1190 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1192 ImGui::Combo(
"Morphology type", &selected_morphology_type,
1193 morphology_type_names,
1194 sizeof(morphology_type_names) /
sizeof(
char*));
1195 ImGui::SliderFloat2(
"Radius", radius, 0, 200);
1196 ImGui::SliderFloat(
"Input opacity", &input_color.
alpha, 0, 1);
1197 ImGui::ColorEdit4(
"Cover color",
reinterpret_cast<float*
>(&cover_color));
1198 ImGui::ColorEdit4(
"Bounds color",
1199 reinterpret_cast<float*
>(&bounds_color));
1200 ImGui::SliderFloat2(
"Translation", offset, 0,
1201 pass.GetRenderTargetSize().width);
1202 ImGui::SliderFloat(
"Rotation", &rotation, 0,
kPi * 2);
1203 ImGui::SliderFloat2(
"Scale", scale, 0, 3);
1204 ImGui::SliderFloat2(
"Skew", skew, -3, 3);
1205 ImGui::SliderFloat4(
"Path XYWH", path_rect, -1000, 1000);
1206 ImGui::SliderFloat(
"Effect transform scale", &effect_transform_scale, 0,
1211 std::shared_ptr<Contents> input;
1215 Rect::MakeXYWH(path_rect[0], path_rect[1], path_rect[2], path_rect[3]);
1216 auto texture = std::make_shared<TextureContents>();
1218 texture->SetDestinationRect(input_rect);
1219 texture->SetTexture(boston);
1220 texture->SetOpacity(input_color.
alpha);
1223 input_size = input_rect.GetSize();
1227 morphology_types[selected_morphology_type]);
1229 Vector2{effect_transform_scale, effect_transform_scale}));
1242 entity.
Render(context, pass);
1251 cover_entity.
Render(context, pass);
1260 bounds_entity.
Render(context, pass);
1264 ASSERT_TRUE(OpenPlaygroundHere(callback));
1276 entity.
SetContents(std::make_shared<SolidColorContents>());
1287 auto contents = std::make_unique<SolidColorContents>();
1288 contents->SetGeometry(std::move(geometry));
1293 ASSERT_TRUE(actual.has_value());
1304 auto contents = std::make_unique<SolidColorContents>();
1305 contents->SetGeometry(std::move(geometry));
1311 ASSERT_TRUE(actual.has_value());
1322 auto contents = std::make_unique<SolidColorContents>();
1323 contents->SetGeometry(std::move(geometry));
1328 ASSERT_TRUE(actual.has_value());
1334 auto fill = std::make_shared<SolidColorContents>();
1344 auto actual = border_mask_blur->GetCoverage(e);
1346 ASSERT_TRUE(actual.has_value());
1353 auto actual = border_mask_blur->GetCoverage(e);
1354 auto expected =
Rect::MakeXYWH(-287.792, -4.94975, 504.874, 504.874);
1355 ASSERT_TRUE(actual.has_value());
1362 auto atlas = CreateTextureForFixture(
"bay_bridge.jpg");
1363 auto size = atlas->GetSize();
1365 Scalar half_width = size.width / 2;
1366 Scalar half_height = size.height / 2;
1367 std::vector<Rect> texture_coordinates = {
1371 Rect::MakeLTRB(half_width, half_height, size.width, size.height)};
1373 std::vector<Matrix> transforms = {
1378 std::shared_ptr<AtlasContents> contents = std::make_shared<AtlasContents>();
1380 contents->SetTransforms(std::move(transforms));
1381 contents->SetTextureCoordinates(std::move(texture_coordinates));
1382 contents->SetTexture(atlas);
1389 ASSERT_TRUE(OpenPlaygroundHere(std::move(e)));
1394 auto atlas = CreateTextureForFixture(
"bay_bridge.jpg");
1395 auto size = atlas->GetSize();
1397 Scalar half_width = size.width / 2;
1398 Scalar half_height = size.height / 2;
1399 std::vector<Rect> texture_coordinates = {
1403 Rect::MakeLTRB(half_width, half_height, size.width, size.height)};
1405 std::vector<Matrix> transforms = {
1412 std::shared_ptr<AtlasContents> contents = std::make_shared<AtlasContents>();
1414 contents->SetTransforms(std::move(transforms));
1415 contents->SetTextureCoordinates(std::move(texture_coordinates));
1416 contents->SetTexture(atlas);
1417 contents->SetColors(colors);
1424 ASSERT_TRUE(OpenPlaygroundHere(std::move(e)));
1430 auto atlas = CreateTextureForFixture(
"bay_bridge.jpg");
1431 auto size = atlas->GetSize();
1433 Scalar half_width = size.width / 2;
1434 Scalar half_height = size.height / 2;
1435 std::vector<Rect> texture_coordinates = {
1439 Rect::MakeLTRB(half_width, half_height, size.width, size.height)};
1441 std::vector<Matrix> transforms = {
1448 std::shared_ptr<AtlasContents> contents = std::make_shared<AtlasContents>();
1450 contents->SetTransforms(std::move(transforms));
1451 contents->SetTextureCoordinates(std::move(texture_coordinates));
1452 contents->SetTexture(atlas);
1453 contents->SetColors(colors);
1460 ASSERT_TRUE(OpenPlaygroundHere(std::move(e)));
1464 auto atlas = CreateTextureForFixture(
"bay_bridge.jpg");
1465 auto size = atlas->GetSize();
1467 Scalar half_width = size.width / 2;
1468 Scalar half_height = size.height / 2;
1469 std::vector<Rect> texture_coordinates = {
1473 Rect::MakeLTRB(half_width, half_height, size.width, size.height)};
1474 std::vector<Matrix> transforms = {
1480 std::shared_ptr<AtlasContents> contents = std::make_shared<AtlasContents>();
1482 contents->SetTransforms(std::move(transforms));
1483 contents->SetTextureCoordinates(std::move(texture_coordinates));
1484 contents->SetTexture(atlas);
1492 ASSERT_EQ(contents->GetCoverage(e).value(),
1497 ASSERT_EQ(contents->GetCoverage(e).value(),
1504 auto atlas = CreateTextureForFixture(
"bay_bridge.jpg");
1505 auto size = atlas->GetSize();
1507 Scalar half_width = size.width / 2;
1508 Scalar half_height = size.height / 2;
1509 std::vector<Rect> texture_coordinates = {
1513 Rect::MakeLTRB(half_width, half_height, size.width, size.height)};
1515 std::vector<Matrix> transforms = {
1521 std::shared_ptr<AtlasContents> contents = std::make_shared<AtlasContents>();
1523 contents->SetTransforms(std::move(transforms));
1524 contents->SetTextureCoordinates(std::move(texture_coordinates));
1525 contents->SetTexture(atlas);
1527 contents->SetAlpha(0.5);
1533 ASSERT_TRUE(OpenPlaygroundHere(std::move(e)));
1537 auto atlas = CreateTextureForFixture(
"bay_bridge.jpg");
1538 auto size = atlas->GetSize();
1539 std::vector<Rect> texture_coordinates = {
1542 std::shared_ptr<AtlasContents> contents = std::make_shared<AtlasContents>();
1544 contents->SetTransforms(std::move(transforms));
1545 contents->SetTextureCoordinates(std::move(texture_coordinates));
1546 contents->SetTexture(atlas);
1553 ASSERT_TRUE(OpenPlaygroundHere(std::move(e)));
1559 auto fill = std::make_shared<SolidColorContents>();
1565 auto coverage = fill->GetCoverage({});
1566 ASSERT_TRUE(coverage.has_value());
1572 auto fill = std::make_shared<SolidColorContents>();
1583 ASSERT_TRUE(coverage.has_value());
1589 auto fill = std::make_shared<SolidColorContents>();
1594 auto coverage = fill->GetCoverage({});
1595 ASSERT_FALSE(coverage.has_value());
1602 auto fill = std::make_shared<SolidColorContents>();
1611 auto fill = std::make_shared<SolidColorContents>();
1622 auto fill = std::make_shared<SolidColorContents>();
1632 auto fill = std::make_shared<SolidColorContents>();
1650 auto clip = std::make_shared<ClipContents>();
1661 auto restore = std::make_shared<ClipRestoreContents>();
1672 auto clip = std::make_shared<ClipContents>();
1674 auto result = clip->GetClipCoverage(
Entity{},
Rect{});
1676 ASSERT_FALSE(result.coverage.has_value());
1681 auto clip = std::make_shared<ClipContents>();
1685 auto result = clip->GetClipCoverage(
Entity{},
Rect{});
1687 ASSERT_FALSE(result.coverage.has_value());
1692 auto clip = std::make_shared<ClipContents>();
1697 ASSERT_FALSE(result.coverage.has_value());
1702 auto clip = std::make_shared<ClipContents>();
1709 ASSERT_TRUE(result.coverage.has_value());
1716 auto clip = std::make_shared<ClipContents>();
1723 ASSERT_TRUE(result.coverage.has_value());
1732 static float corner_radius = 100;
1733 static float blur_radius = 100;
1734 static bool show_coverage =
false;
1737 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1738 ImGui::SliderFloat(
"Corner radius", &corner_radius, 0, 300);
1739 ImGui::SliderFloat(
"Blur radius", &blur_radius, 0, 300);
1740 ImGui::ColorEdit4(
"Color",
reinterpret_cast<Scalar*
>(&color));
1741 ImGui::Checkbox(
"Show coverage", &show_coverage);
1742 if (show_coverage) {
1743 ImGui::ColorEdit4(
"Coverage color",
1744 reinterpret_cast<Scalar*
>(&coverage_color));
1751 Rect::MakeLTRB(top_left.x, top_left.y, bottom_right.x, bottom_right.y);
1753 auto contents = std::make_unique<SolidRRectBlurContents>();
1754 contents->SetRRect(rect, {corner_radius, corner_radius});
1755 contents->SetColor(color);
1756 contents->SetSigma(
Radius(blur_radius));
1761 entity.
Render(context, pass);
1764 if (show_coverage && coverage.has_value()) {
1765 auto bounds_contents = std::make_unique<SolidColorContents>();
1768 bounds_contents->SetColor(coverage_color.
Premultiply());
1770 bounds_entity.
SetContents(std::move(bounds_contents));
1771 bounds_entity.
Render(context, pass);
1776 ASSERT_TRUE(OpenPlaygroundHere(callback));
1781 auto fill = std::make_shared<SolidColorContents>();
1801 auto actual = filter->GetCoverage(e);
1804 ASSERT_TRUE(actual.has_value());
1809 auto bay_bridge = CreateTextureForFixture(
"bay_bridge.jpg");
1810 ASSERT_TRUE(bay_bridge);
1820 static float offset[2] = {500, 400};
1821 static float rotation = 0;
1822 static float scale[2] = {0.65, 0.65};
1823 static float skew[2] = {0, 0};
1826 ImGui::Begin(
"Color Matrix",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1828 std::string label =
"##1";
1829 for (
int i = 0; i < 20; i += 5) {
1830 ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float,
1831 &(color_matrix.
array[i]), 5,
nullptr,
nullptr,
1836 ImGui::SliderFloat2(
"Translation", &offset[0], 0,
1837 pass.GetRenderTargetSize().width);
1838 ImGui::SliderFloat(
"Rotation", &rotation, 0,
kPi * 2);
1839 ImGui::SliderFloat2(
"Scale", &scale[0], 0, 3);
1840 ImGui::SliderFloat2(
"Skew", &skew[0], -3, 3);
1858 entity.
Render(context, pass);
1863 ASSERT_TRUE(OpenPlaygroundHere(callback));
1868 auto fill = std::make_shared<SolidColorContents>();
1880 auto actual = filter->GetCoverage(e);
1883 ASSERT_TRUE(actual.has_value());
1888 auto image = CreateTextureForFixture(
"kalimba.jpg");
1911 return entity_left.
Render(context, pass) &&
1912 entity_right.
Render(context, pass);
1915 ASSERT_TRUE(OpenPlaygroundHere(callback));
1920 auto fill = std::make_shared<SolidColorContents>();
1932 auto actual = filter->GetCoverage(e);
1935 ASSERT_TRUE(actual.has_value());
1940 auto image = CreateTextureForFixture(
"embarcadero.jpg");
1963 return entity_left.
Render(context, pass) &&
1964 entity_right.
Render(context, pass);
1967 ASSERT_TRUE(OpenPlaygroundHere(callback));
1971 auto boston = CreateTextureForFixture(
"boston.jpg");
1974 auto contents = std::make_shared<AtlasContents>();
1976 contents->SetTexture(boston);
1977 contents->SetColors({
1982 contents->SetTextureCoordinates({
1987 contents->SetTransforms({
1995 auto subatlas = contents->GenerateSubAtlas();
1996 ASSERT_EQ(subatlas->sub_texture_coords.size(), 1u);
2000 auto contents = std::make_shared<AtlasContents>();
2002 contents->SetTexture(boston);
2003 contents->SetColors({
2008 contents->SetTextureCoordinates({
2013 contents->SetTransforms({
2020 auto subatlas = contents->GenerateSubAtlas();
2021 ASSERT_EQ(subatlas->sub_texture_coords.size(), 3u);
2025 ASSERT_EQ(subatlas->result_texture_coords[0],
Rect::MakeXYWH(0, 0, 10, 10));
2026 ASSERT_EQ(subatlas->result_texture_coords[1],
2028 ASSERT_EQ(subatlas->result_texture_coords[2],
2035 switch (yuv_color_space) {
2037 yuv.
x = rgb.
x * 0.299 + rgb.
y * 0.587 + rgb.
z * 0.114;
2038 yuv.
y = rgb.
x * -0.169 + rgb.
y * -0.331 + rgb.
z * 0.5 + 0.5;
2039 yuv.
z = rgb.
x * 0.5 + rgb.
y * -0.419 + rgb.
z * -0.081 + 0.5;
2042 yuv.
x = rgb.
x * 0.257 + rgb.
y * 0.516 + rgb.
z * 0.100 + 0.063;
2043 yuv.
y = rgb.
x * -0.145 + rgb.
y * -0.291 + rgb.
z * 0.439 + 0.5;
2044 yuv.
z = rgb.
x * 0.429 + rgb.
y * -0.368 + rgb.
z * -0.071 + 0.5;
2053 Vector3 red = {244.0 / 255.0, 67.0 / 255.0, 54.0 / 255.0};
2054 Vector3 green = {76.0 / 255.0, 175.0 / 255.0, 80.0 / 255.0};
2055 Vector3 blue = {33.0 / 255.0, 150.0 / 255.0, 243.0 / 255.0};
2056 Vector3 white = {1.0, 1.0, 1.0};
2061 std::vector<Vector3> yuvs{red_yuv, green_yuv, blue_yuv, white_yuv};
2062 std::vector<uint8_t> y_data;
2063 std::vector<uint8_t> uv_data;
2064 for (
int i = 0; i < 4; i++) {
2066 uint8_t y = std::round(yuv.x * 255.0);
2067 uint8_t u = std::round(yuv.y * 255.0);
2068 uint8_t v = std::round(yuv.z * 255.0);
2069 for (
int j = 0; j < 16; j++) {
2070 y_data.push_back(y);
2072 for (
int j = 0; j < 8; j++) {
2073 uv_data.push_back(j % 2 == 0 ? u : v);
2079 y_texture_descriptor.
size = {8, 8};
2082 auto y_mapping = std::make_shared<fml::DataMapping>(y_data);
2083 if (!y_texture->SetContents(y_mapping)) {
2084 FML_DLOG(ERROR) <<
"Could not copy contents into Y texture.";
2090 uv_texture_descriptor.
size = {4, 4};
2093 auto uv_mapping = std::make_shared<fml::DataMapping>(uv_data);
2094 if (!uv_texture->SetContents(uv_mapping)) {
2095 FML_DLOG(ERROR) <<
"Could not copy contents into UV texture.";
2098 return {y_texture, uv_texture};
2104 GTEST_SKIP_(
"YUV to RGB filter is not supported on OpenGLES backend yet.");
2110 for (
int i = 0; i < 2; i++) {
2111 auto yuv_color_space = yuv_color_space_array[i];
2115 textures[0], textures[1], yuv_color_space);
2118 auto snapshot = filter_contents->RenderToSnapshot(context, filter_entity);
2122 contents->SetTexture(snapshot->texture);
2123 contents->SetSourceRect(
Rect::MakeSize(snapshot->texture->GetSize()));
2127 entity.
Render(context, pass);
2131 ASSERT_TRUE(OpenPlaygroundHere(callback));
2135 if (!BackendSupportsFragmentProgram()) {
2136 GTEST_SKIP_(
"This backend doesn't support runtime effects.");
2139 auto runtime_stages =
2140 OpenAssetAsRuntimeStage(
"runtime_stage_example.frag.iplr");
2141 auto runtime_stage =
2143 ASSERT_TRUE(runtime_stage);
2144 ASSERT_TRUE(runtime_stage->IsDirty());
2146 bool first_frame =
true;
2149 first_frame =
false;
2151 assert(runtime_stage->IsDirty() ==
false);
2154 auto contents = std::make_shared<RuntimeEffectContents>();
2157 contents->SetRuntimeStage(runtime_stage);
2159 struct FragUniforms {
2163 .iResolution =
Vector2(GetWindowSize().width, GetWindowSize().height),
2164 .iTime =
static_cast<Scalar>(GetSecondsElapsed()),
2166 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
2167 uniform_data->resize(
sizeof(FragUniforms));
2168 memcpy(uniform_data->data(), &frag_uniforms,
sizeof(FragUniforms));
2169 contents->SetUniformData(uniform_data);
2173 return contents->Render(context, entity, pass);
2175 ASSERT_TRUE(OpenPlaygroundHere(callback));
2182 auto texture_contents = std::make_shared<TextureContents>();
2183 texture_contents->SetOpacity(0.5);
2184 ASSERT_TRUE(texture_contents->CanInheritOpacity(entity));
2186 texture_contents->SetInheritedOpacity(0.5);
2187 ASSERT_EQ(texture_contents->GetOpacity(), 0.25);
2188 texture_contents->SetInheritedOpacity(0.5);
2189 ASSERT_EQ(texture_contents->GetOpacity(), 0.25);
2193 auto solid_color = std::make_shared<SolidColorContents>();
2194 solid_color->SetGeometry(
2196 solid_color->SetColor(
Color::Blue().WithAlpha(0.5));
2198 ASSERT_TRUE(solid_color->CanInheritOpacity(entity));
2200 solid_color->SetInheritedOpacity(0.5);
2201 ASSERT_EQ(solid_color->GetColor().alpha, 0.25);
2202 solid_color->SetInheritedOpacity(0.5);
2203 ASSERT_EQ(solid_color->GetColor().alpha, 0.25);
2207 auto tiled_texture = std::make_shared<TiledTextureContents>();
2208 tiled_texture->SetGeometry(
2210 tiled_texture->SetOpacityFactor(0.5);
2212 ASSERT_TRUE(tiled_texture->CanInheritOpacity(entity));
2214 tiled_texture->SetInheritedOpacity(0.5);
2215 ASSERT_EQ(tiled_texture->GetOpacityFactor(), 0.25);
2216 tiled_texture->SetInheritedOpacity(0.5);
2217 ASSERT_EQ(tiled_texture->GetOpacityFactor(), 0.25);
2221 SkFont font = flutter::testing::CreateTestFontOfSize(30);
2222 auto blob = SkTextBlob::MakeFromString(
"A", font);
2224 auto lazy_glyph_atlas =
2226 lazy_glyph_atlas->AddTextFrame(*frame, 1.0f);
2228 auto text_contents = std::make_shared<TextContents>();
2229 text_contents->SetTextFrame(frame);
2230 text_contents->SetColor(
Color::Blue().WithAlpha(0.5));
2232 ASSERT_TRUE(text_contents->CanInheritOpacity(entity));
2234 text_contents->SetInheritedOpacity(0.5);
2235 ASSERT_EQ(text_contents->GetColor().alpha, 0.25);
2236 text_contents->SetInheritedOpacity(0.5);
2237 ASSERT_EQ(text_contents->GetColor().alpha, 0.25);
2244 auto runtime_effect = std::make_shared<RuntimeEffectContents>();
2245 ASSERT_FALSE(runtime_effect->CanInheritOpacity(entity));
2249 auto image = CreateTextureForFixture(
"boston.jpg");
2259 return entity.
Render(context, pass);
2261 ASSERT_TRUE(OpenPlaygroundHere(callback));
2265 auto image = CreateTextureForFixture(
"boston.jpg");
2275 return entity.
Render(context, pass);
2277 ASSERT_TRUE(OpenPlaygroundHere(callback));
2281 auto image = CreateTextureForFixture(
"boston.jpg");
2291 return entity.
Render(context, pass);
2293 ASSERT_TRUE(OpenPlaygroundHere(callback));
2297 auto image = CreateTextureForFixture(
"boston.jpg");
2307 return entity.
Render(context, pass);
2309 ASSERT_TRUE(OpenPlaygroundHere(callback));
2313 auto image = CreateTextureForFixture(
"boston.jpg");
2323 return entity.
Render(context, pass);
2325 ASSERT_TRUE(OpenPlaygroundHere(callback));
2339 EXPECT_LT(transform.e[0][0], 0.f);
2340 auto coverage = geometry->GetCoverage(transform);
2394 auto bay_bridge = CreateTextureForFixture(
"bay_bridge.jpg");
2422 std::vector<Point> points = {{10, 20}, {100, 200}};
2437 auto src_contents = std::make_shared<SolidColorContents>();
2438 src_contents->SetGeometry(
2442 auto dst_contents = std::make_shared<SolidColorContents>();
2443 dst_contents->SetGeometry(
2451 ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
2470 allocated_.push_back(desc);
2481 std::vector<TextureDescriptor> allocated_;
2485 if (GetContext()->GetCapabilities()->SupportsFramebufferFetch()) {
2486 GTEST_SKIP() <<
"Backends that support framebuffer fetch dont use coverage "
2487 "for advanced blends.";
2490 auto contents = std::make_shared<SolidColorContents>();
2500 EXPECT_TRUE(coverage.has_value());
2502 auto pass = std::make_unique<EntityPass>();
2503 auto test_allocator = std::make_shared<TestRenderTargetAllocator>(
2504 GetContext()->GetResourceAllocator());
2511 *GetContext(), *test_allocator,
ISize::MakeWH(1000, 1000),
"Offscreen",
2515 pass->AddEntity(std::move(entity));
2517 EXPECT_TRUE(pass->Render(content_context, rt));
2519 if (test_allocator->GetDescriptors().size() == 6u) {
2520 EXPECT_EQ(test_allocator->GetDescriptors()[0].size,
ISize(1000, 1000));
2521 EXPECT_EQ(test_allocator->GetDescriptors()[1].size,
ISize(1000, 1000));
2523 EXPECT_EQ(test_allocator->GetDescriptors()[2].size,
ISize(200, 200));
2524 EXPECT_EQ(test_allocator->GetDescriptors()[3].size,
ISize(200, 200));
2525 EXPECT_EQ(test_allocator->GetDescriptors()[4].size,
ISize(200, 200));
2526 EXPECT_EQ(test_allocator->GetDescriptors()[5].size,
ISize(200, 200));
2527 }
else if (test_allocator->GetDescriptors().size() == 9u) {
2529 EXPECT_EQ(test_allocator->GetDescriptors()[0].size,
ISize(1000, 1000));
2530 EXPECT_EQ(test_allocator->GetDescriptors()[1].size,
ISize(1000, 1000));
2531 EXPECT_EQ(test_allocator->GetDescriptors()[2].size,
ISize(1000, 1000));
2532 EXPECT_EQ(test_allocator->GetDescriptors()[3].size,
ISize(1000, 1000));
2533 EXPECT_EQ(test_allocator->GetDescriptors()[4].size,
ISize(1000, 1000));
2535 EXPECT_EQ(test_allocator->GetDescriptors()[5].size,
ISize(200, 200));
2536 EXPECT_EQ(test_allocator->GetDescriptors()[5].size,
ISize(200, 200));
2537 EXPECT_EQ(test_allocator->GetDescriptors()[6].size,
ISize(200, 200));
2538 EXPECT_EQ(test_allocator->GetDescriptors()[7].size,
ISize(200, 200));
2545 auto content_context =
2548 auto default_color_burn = content_context.GetBlendColorBurnPipeline(
2549 {.has_stencil_attachment =
false});
2550 auto alt_color_burn = content_context.GetBlendColorBurnPipeline(
2551 {.has_stencil_attachment =
true});
2553 ASSERT_NE(default_color_burn, alt_color_burn);
2554 ASSERT_EQ(default_color_burn->GetDescriptor().GetSpecializationConstants(),
2555 alt_color_burn->GetDescriptor().GetSpecializationConstants());
2557 auto decal_supported =
static_cast<Scalar>(
2558 GetContext()->GetCapabilities()->SupportsDecalSamplerAddressMode());
2559 std::vector<Scalar> expected_constants = {5, decal_supported};
2560 ASSERT_EQ(default_color_burn->GetDescriptor().GetSpecializationConstants(),
2561 expected_constants);
2565 auto content_context =
2568 auto default_color_burn = content_context.GetMorphologyFilterPipeline({});
2570 auto decal_supported =
static_cast<Scalar>(
2571 GetContext()->GetCapabilities()->SupportsDecalSamplerAddressMode());
2572 std::vector<Scalar> expected_constants = {decal_supported};
2573 ASSERT_EQ(default_color_burn->GetDescriptor().GetSpecializationConstants(),
2574 expected_constants);
2578 auto content_context =
2580 if (!content_context.GetDeviceCapabilities().SupportsFramebufferFetch()) {
2581 GTEST_SKIP() <<
"Framebuffer fetch not supported.";
2587 content_context.GetFramebufferBlendColorBurnPipeline(options);
2589 EXPECT_TRUE(color_burn->GetDescriptor().UsesSubpassInput());
2593 auto desc_1 = std::make_shared<PipelineDescriptor>();
2594 auto desc_2 = std::make_shared<PipelineDescriptor>();
2596 EXPECT_TRUE(desc_1->IsEqual(*desc_2));
2597 EXPECT_EQ(desc_1->GetHash(), desc_2->GetHash());
2601 EXPECT_FALSE(desc_1->IsEqual(*desc_2));
2602 EXPECT_NE(desc_1->GetHash(), desc_2->GetHash());
2606 EXPECT_TRUE(desc_1->IsEqual(*desc_2));
2607 EXPECT_EQ(desc_1->GetHash(), desc_2->GetHash());
2626 EXPECT_NE(hash_a, hash_b);
2627 EXPECT_NE(hash_b, hash_c);
2628 EXPECT_NE(hash_c, hash_d);
2643 bool expected_layout =
false;
2645 FragmentShader::kDescriptorSetLayouts) {
2646 if (layout.binding == 64 &&
2648 expected_layout =
true;
2651 EXPECT_TRUE(expected_layout);