7 #include "absl/status/statusor.h"
9 #include "flutter/display_list/dl_builder.h"
10 #include "flutter/display_list/dl_paint.h"
11 #include "flutter/display_list/effects/dl_color_source.h"
12 #include "flutter/display_list/effects/dl_image_filter.h"
13 #include "flutter/display_list/effects/dl_runtime_effect.h"
20 #include "third_party/abseil-cpp/absl/status/status_matchers.h"
28 absl::StatusOr<std::shared_ptr<DlColorSource>> MakeRuntimeEffect(
30 std::string_view name,
31 const std::shared_ptr<std::vector<uint8_t>>& uniform_data = {},
32 const std::vector<std::shared_ptr<DlColorSource>>& samplers = {}) {
33 auto runtime_stages_result = test->OpenAssetAsRuntimeStage(name.data());
34 if (!runtime_stages_result.ok()) {
35 return runtime_stages_result.status();
37 std::shared_ptr<RuntimeStage> runtime_stage =
38 runtime_stages_result.value()[test->GetRuntimeStageBackend()];
40 return absl::InternalError(
"Runtime stage not found for backend.");
42 if (!runtime_stage->IsDirty()) {
43 return absl::InternalError(
"Runtime stage is not dirty.");
48 return DlColorSource::MakeRuntimeEffect(dl_runtime_effect, samplers,
58 } frag_uniforms = {.iResolution =
Vector2(400, 400), .iTime = 100.0};
59 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
60 uniform_data->resize(
sizeof(FragUniforms));
61 memcpy(uniform_data->data(), &frag_uniforms,
sizeof(FragUniforms));
65 MakeRuntimeEffect(
this,
"runtime_stage_example.frag.iplr", uniform_data);
66 ABSL_ASSERT_OK(effect);
67 paint.setColorSource(effect.value());
69 DisplayListBuilder builder;
71 builder.ClipRoundRect(
72 DlRoundRect::MakeRectXY(DlRect::MakeXYWH(0, 0, 400, 400), 10.0, 10.0),
73 DlClipOp::kIntersect);
74 builder.DrawRect(DlRect::MakeXYWH(0, 0, 400, 400), paint);
77 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
84 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
85 uniform_data->resize(
sizeof(FragUniforms));
86 memcpy(uniform_data->data(), &frag_uniforms,
sizeof(FragUniforms));
89 auto effect = MakeRuntimeEffect(
this,
"gradient.frag.iplr", uniform_data);
90 ABSL_ASSERT_OK(effect);
91 paint.setColorSource(effect.value());
93 DisplayListBuilder builder;
95 builder.Scale(GetContentScale().
x, GetContentScale().y);
96 builder.DrawPaint(paint);
99 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
103 auto runtime_stages_result =
104 OpenAssetAsRuntimeStage(
"runtime_stage_filter_example.frag.iplr");
105 ABSL_ASSERT_OK(runtime_stages_result);
106 std::shared_ptr<RuntimeStage> runtime_stage =
108 ASSERT_TRUE(runtime_stage);
109 ASSERT_TRUE(runtime_stage->IsDirty());
111 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
114 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
115 uniform_data->resize(
sizeof(
Vector2));
118 paint.setColor(DlColor::kAqua());
119 paint.setImageFilter(DlImageFilter::MakeRuntimeEffect(
123 DisplayListBuilder builder;
124 builder.DrawRect(DlRect::MakeXYWH(0, 0, 400, 400), paint);
126 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
133 std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
134 flutter::DlColor::kRed()};
135 const float stops[2] = {0.0, 1.0};
136 auto linear = flutter::DlColorSource::MakeLinear({0.0, 0.0}, {300.0, 300.0},
137 2, colors.data(), stops,
138 flutter::DlTileMode::kClamp);
139 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
143 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
144 uniform_data->resize(
sizeof(
Vector2));
148 MakeRuntimeEffect(
this,
"runtime_stage_filter_example.frag.iplr",
149 uniform_data, sampler_inputs);
150 ABSL_ASSERT_OK(effect);
151 paint.setColorSource(effect.value());
153 DisplayListBuilder builder;
154 builder.DrawPaint(paint);
156 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
160 DisplayListBuilder builder;
162 background.setColor(DlColor(1.0, 0.1, 0.1, 0.1, DlColorSpace::kSRGB));
163 builder.DrawPaint(background);
166 paint.setColor(DlColor::kGreen());
173 std::shared_ptr<DlImageFilter> color_filter =
174 DlImageFilter::MakeColorFilter(DlColorFilter::MakeMatrix(matrix));
176 auto runtime_stages_result =
177 OpenAssetAsRuntimeStage(
"runtime_stage_filter_warp.frag.iplr");
178 ABSL_ASSERT_OK(runtime_stages_result);
179 std::shared_ptr<RuntimeStage> runtime_stage =
181 ASSERT_TRUE(runtime_stage);
182 ASSERT_TRUE(runtime_stage->IsDirty());
184 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
187 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
188 uniform_data->resize(
sizeof(
Vector2));
190 auto runtime_filter = DlImageFilter::MakeRuntimeEffect(
194 builder.Translate(50, 50);
195 builder.Scale(0.7, 0.7);
197 paint.setImageFilter(
198 DlImageFilter::MakeCompose(runtime_filter, color_filter));
200 builder.DrawImage(image,
DlPoint(100.0, 100.0),
201 DlImageSampling::kNearestNeighbor, &paint);
204 green.setColor(DlColor::kGreen());
205 builder.DrawLine({100, 100}, {200, 100}, green);
206 builder.DrawLine({100, 100}, {100, 200}, green);
208 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
212 auto runtime_stages_result =
213 OpenAssetAsRuntimeStage(
"runtime_stage_filter_warp.frag.iplr");
214 ABSL_ASSERT_OK(runtime_stages_result);
215 std::shared_ptr<RuntimeStage> runtime_stage =
217 ASSERT_TRUE(runtime_stage);
218 ASSERT_TRUE(runtime_stage->IsDirty());
223 bool compare =
false;
225 auto callback = [&]() -> sk_sp<DisplayList> {
227 ImGuiWindowFlags_AlwaysAutoResize)) {
228 ImGui::SliderFloat(
"xoffset", &xoffset, -50, 50);
229 ImGui::SliderFloat(
"yoffset", &yoffset, -50, 50);
230 ImGui::SliderFloat(
"xscale", &xscale, 0, 1);
231 ImGui::SliderFloat(
"yscale", &yscale, 0, 1);
232 ImGui::Checkbox(
"compare", &compare);
235 DisplayListBuilder builder;
237 background.setColor(DlColor(1.0, 0.1, 0.1, 0.1, DlColorSpace::kSRGB));
238 builder.DrawPaint(background);
241 paint.setColor(DlColor::kGreen());
248 std::shared_ptr<DlImageFilter> color_filter =
249 DlImageFilter::MakeColorFilter(DlColorFilter::MakeMatrix(matrix));
251 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
254 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
255 uniform_data->resize(
sizeof(
Vector2));
257 auto runtime_filter = DlImageFilter::MakeRuntimeEffect(
261 builder.Translate(xoffset, yoffset);
262 builder.Scale(xscale, yscale);
264 paint.setImageFilter(
265 DlImageFilter::MakeCompose(color_filter, runtime_filter));
267 builder.DrawImage(image,
DlPoint(100.0, 100.0),
268 DlImageSampling::kNearestNeighbor, &paint);
271 paint.setImageFilter(
272 DlImageFilter::MakeCompose(runtime_filter, color_filter));
273 builder.DrawImage(image,
DlPoint(800.0, 100.0),
274 DlImageSampling::kNearestNeighbor, &paint);
276 paint.setImageFilter(runtime_filter);
277 builder.DrawImage(image,
DlPoint(100.0, 800.0),
278 DlImageSampling::kNearestNeighbor, &paint);
282 green.setColor(DlColor::kGreen());
283 builder.DrawLine({100, 100}, {200, 100}, green);
284 builder.DrawLine({100, 100}, {100, 200}, green);
286 builder.DrawLine({800, 100}, {900, 100}, green);
287 builder.DrawLine({800, 100}, {800, 200}, green);
288 builder.DrawLine({100, 800}, {200, 800}, green);
289 builder.DrawLine({100, 800}, {100, 900}, green);
292 return builder.Build();
295 ASSERT_TRUE(OpenPlaygroundHere(callback));
299 auto runtime_stages_result =
300 OpenAssetAsRuntimeStage(
"runtime_stage_filter_circle.frag.iplr");
301 ABSL_ASSERT_OK(runtime_stages_result);
302 std::shared_ptr<RuntimeStage> runtime_stage =
304 ASSERT_TRUE(runtime_stage);
305 ASSERT_TRUE(runtime_stage->IsDirty());
308 auto callback = [&]() -> sk_sp<DisplayList> {
310 ImGuiWindowFlags_AlwaysAutoResize)) {
311 ImGui::SliderFloat(
"sigma", &sigma, 0, 20);
314 DisplayListBuilder builder;
316 background.setColor(DlColor(1.0, 0.1, 0.1, 0.1, DlColorSpace::kSRGB));
317 builder.DrawPaint(background);
320 DlImageFilter::MakeBlur(sigma, sigma, DlTileMode::kClamp);
322 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
326 struct FragUniforms {
329 } frag_uniforms = {.size =
Vector2(1, 1), .origin =
Vector2(30.f, 30.f)};
330 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
331 uniform_data->resize(
sizeof(FragUniforms));
332 memcpy(uniform_data->data(), &frag_uniforms,
sizeof(FragUniforms));
334 auto runtime_filter = DlImageFilter::MakeRuntimeEffect(
338 auto backdrop_filter = DlImageFilter::MakeCompose(runtime_filter,
343 builder.DrawImage(image,
DlPoint(100.0, 100.0),
344 DlImageSampling::kNearestNeighbor, &paint);
347 save_paint.setBlendMode(DlBlendMode::kSrc);
348 builder.SaveLayer(std::nullopt, &save_paint, backdrop_filter.get());
352 green.setColor(DlColor::kGreen());
353 builder.DrawLine({100, 100}, {200, 100}, green);
354 builder.DrawLine({100, 100}, {100, 200}, green);
356 return builder.Build();
359 ASSERT_TRUE(OpenPlaygroundHere(callback));
363 auto runtime_stages_result =
364 OpenAssetAsRuntimeStage(
"runtime_stage_filter_circle.frag.iplr");
365 ABSL_ASSERT_OK(runtime_stages_result);
366 std::shared_ptr<RuntimeStage> runtime_stage =
368 ASSERT_TRUE(runtime_stage);
369 ASSERT_TRUE(runtime_stage->IsDirty());
372 auto callback = [&]() -> sk_sp<DisplayList> {
374 ImGuiWindowFlags_AlwaysAutoResize)) {
375 ImGui::SliderFloat(
"sigma", &sigma, 0, 20);
378 DisplayListBuilder builder;
380 background.setColor(DlColor(1.0, 0.1, 0.1, 0.1, DlColorSpace::kSRGB));
381 builder.DrawPaint(background);
384 DlImageFilter::MakeBlur(sigma, sigma, DlTileMode::kClamp);
386 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
389 struct FragUniforms {
392 } frag_uniforms = {.size =
Vector2(1, 1), .origin =
Vector2(30.f, 30.f)};
393 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
394 uniform_data->resize(
sizeof(FragUniforms));
395 memcpy(uniform_data->data(), &frag_uniforms,
sizeof(FragUniforms));
397 auto runtime_filter = DlImageFilter::MakeRuntimeEffect(
401 auto backdrop_filter = DlImageFilter::MakeCompose(runtime_filter,
406 builder.DrawImage(image,
DlPoint(100.0, 100.0),
407 DlImageSampling::kNearestNeighbor, &paint);
410 save_paint.setBlendMode(DlBlendMode::kSrc);
411 builder.SaveLayer(std::nullopt, &save_paint, backdrop_filter.get());
415 green.setColor(DlColor::kGreen());
416 builder.DrawLine({100, 100}, {200, 100}, green);
417 builder.DrawLine({100, 100}, {100, 200}, green);
419 return builder.Build();
422 ASSERT_TRUE(OpenPlaygroundHere(callback));
426 auto runtime_stages_result =
427 OpenAssetAsRuntimeStage(
"runtime_stage_filter_circle.frag.iplr");
428 ABSL_ASSERT_OK(runtime_stages_result);
429 std::shared_ptr<RuntimeStage> runtime_stage =
431 ASSERT_TRUE(runtime_stage);
432 ASSERT_TRUE(runtime_stage->IsDirty());
438 auto callback = [&]() -> sk_sp<DisplayList> {
440 ImGuiWindowFlags_AlwaysAutoResize)) {
441 ImGui::SliderFloat(
"sigma", &sigma, 0, 20);
442 ImGui::SliderFloat(
"clip_x", &clip_origin.
x, 0, 2048.f);
443 ImGui::SliderFloat(
"clip_y", &clip_origin.
y, 0, 1536.f);
444 ImGui::SliderFloat(
"clip_width", &clip_size.
x, 0, 2048.f);
445 ImGui::SliderFloat(
"clip_height", &clip_size.
y, 0, 1536.f);
446 ImGui::SliderFloat(
"circle_x", &circle_origin.
x, 0.f, 2048.f);
447 ImGui::SliderFloat(
"circle_y", &circle_origin.
y, 0.f, 1536.f);
450 DisplayListBuilder builder;
452 background.setColor(DlColor(1.0, 0.1, 0.1, 0.1, DlColorSpace::kSRGB));
453 builder.DrawPaint(background);
456 DlImageFilter::MakeBlur(sigma, sigma, DlTileMode::kClamp);
458 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
461 struct FragUniforms {
464 } frag_uniforms = {.size =
Vector2(1, 1), .origin = circle_origin};
465 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
466 uniform_data->resize(
sizeof(FragUniforms));
467 memcpy(uniform_data->data(), &frag_uniforms,
sizeof(FragUniforms));
469 auto runtime_filter = DlImageFilter::MakeRuntimeEffect(
473 auto backdrop_filter = DlImageFilter::MakeCompose(runtime_filter,
476 builder.ClipRect(DlRect::MakeXYWH(clip_origin.
x, clip_origin.
y, clip_size.
x,
481 builder.DrawImage(image,
DlPoint(100.0, 100.0),
482 DlImageSampling::kNearestNeighbor, &paint);
485 save_paint.setBlendMode(DlBlendMode::kSrc);
486 builder.SaveLayer(std::nullopt, &save_paint, backdrop_filter.get());
490 green.setColor(DlColor::kGreen());
491 builder.DrawLine({100, 100}, {200, 100}, green);
492 builder.DrawLine({100, 100}, {100, 200}, green);
494 return builder.Build();
497 ASSERT_TRUE(OpenPlaygroundHere(callback));
501 struct FragUniforms {
503 } frag_uniforms = {.uSize =
Vector2(400, 400)};
504 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
505 uniform_data->resize(
sizeof(FragUniforms));
506 memcpy(uniform_data->data(), &frag_uniforms,
sizeof(FragUniforms));
508 auto runtime_stages_result =
509 OpenAssetAsRuntimeStage(
"runtime_stage_border.frag.iplr");
510 ABSL_ASSERT_OK(runtime_stages_result);
511 std::shared_ptr<RuntimeStage> runtime_stage =
513 ASSERT_TRUE(runtime_stage);
514 ASSERT_TRUE(runtime_stage->IsDirty());
516 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
520 auto runtime_filter = DlImageFilter::MakeRuntimeEffect(
524 DisplayListBuilder builder;
527 DlPaint background_paint;
528 background_paint.setColor(DlColor::kWhite());
529 builder.DrawPaint(background_paint);
532 DlPaint pattern_paint;
533 pattern_paint.setColor(DlColor::kRed());
534 builder.DrawRect(DlRect::MakeXYWH(0, 0, 200, 200), pattern_paint);
535 pattern_paint.setColor(DlColor::kBlue());
536 builder.DrawRect(DlRect::MakeXYWH(200, 200, 200, 200), pattern_paint);
542 builder.ClipRect(DlRect::MakeXYWH(66, 66, 268, 268));
547 builder.SaveLayer(std::nullopt, &save_paint, runtime_filter.get());
555 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
560 auto size = image->GetBounds().GetSize();
562 struct FragUniforms {
564 } frag_uniforms = {.size =
Size(size.width, size.height)};
565 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
566 uniform_data->resize(
sizeof(FragUniforms));
567 memcpy(uniform_data->data(), &frag_uniforms,
sizeof(FragUniforms));
569 auto runtime_stages_result = OpenAssetAsRuntimeStage(
"gradient.frag.iplr");
570 ABSL_ASSERT_OK(runtime_stages_result);
571 std::shared_ptr<RuntimeStage> runtime_stage =
573 ASSERT_TRUE(runtime_stage);
574 ASSERT_TRUE(runtime_stage->IsDirty());
576 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
580 auto runtime_filter = DlImageFilter::MakeRuntimeEffect(
586 auto callback = [&]() -> sk_sp<DisplayList> {
588 ImGuiWindowFlags_AlwaysAutoResize)) {
589 ImGui::SliderFloat(
"rotation", &rotation, 0, 360);
592 DisplayListBuilder builder;
593 builder.Translate(size.width * 0.5, size.height * 0.5);
594 builder.Rotate(rotation);
595 builder.Translate(-size.width * 0.5, -size.height * 0.5);
598 paint.setImageFilter(runtime_filter);
599 builder.DrawImage(image,
DlPoint(0.0, 0.0),
600 DlImageSampling::kNearestNeighbor, &paint);
602 return builder.Build();
605 ASSERT_TRUE(OpenPlaygroundHere(callback));
609 constexpr
float kDimension = 400.0f;
610 struct FragUniforms {
613 } frag_uniforms = {.iResolution =
Vector2(kDimension, kDimension),
614 .iValues =
Vector4(0.25, 0.50, 0.75, 1.0)};
615 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
616 uniform_data->resize(
sizeof(FragUniforms));
617 memcpy(uniform_data->data(), &frag_uniforms,
sizeof(FragUniforms));
620 auto effect = MakeRuntimeEffect(
this,
"runtime_stage_vector_array.frag.iplr",
622 ABSL_ASSERT_OK(effect);
623 paint.setColorSource(effect.value());
625 DisplayListBuilder builder;
626 builder.DrawRect(DlRect::MakeXYWH(0, 0, kDimension, kDimension), paint);
628 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
static sk_sp< DlRuntimeEffect > Make(std::shared_ptr< impeller::RuntimeStage > runtime_stage)
static bool ImGuiBegin(const char *name, bool *p_open, ImGuiWindowFlags flags)
static sk_sp< DlImageImpeller > Make(std::shared_ptr< Texture > texture, OwningContext owning_context=OwningContext::kIO)
static std::optional< RuntimeStageBackend > GetRuntimeStageBackend(TargetPlatform target_platform)
TEST_P(AiksTest, DrawAtlasNoColor)
static constexpr TSize MakeWH(Type width, Type height)