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 =
41 return absl::InternalError(
"Runtime stage not found for backend.");
43 if (!runtime_stage->IsDirty()) {
44 return absl::InternalError(
"Runtime stage is not dirty.");
49 return DlColorSource::MakeRuntimeEffect(dl_runtime_effect, samplers,
59 } frag_uniforms = {.iResolution =
Vector2(400, 400), .iTime = 100.0};
60 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
61 uniform_data->resize(
sizeof(FragUniforms));
62 memcpy(uniform_data->data(), &frag_uniforms,
sizeof(FragUniforms));
66 MakeRuntimeEffect(
this,
"runtime_stage_example.frag.iplr", uniform_data);
67 ABSL_ASSERT_OK(effect);
68 paint.setColorSource(effect.value());
70 DisplayListBuilder builder;
72 builder.ClipRoundRect(
73 DlRoundRect::MakeRectXY(DlRect::MakeXYWH(0, 0, 400, 400), 10.0, 10.0),
74 DlClipOp::kIntersect);
75 builder.DrawRect(DlRect::MakeXYWH(0, 0, 400, 400), paint);
78 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
85 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
86 uniform_data->resize(
sizeof(FragUniforms));
87 memcpy(uniform_data->data(), &frag_uniforms,
sizeof(FragUniforms));
90 auto effect = MakeRuntimeEffect(
this,
"gradient.frag.iplr", uniform_data);
91 ABSL_ASSERT_OK(effect);
92 paint.setColorSource(effect.value());
94 DisplayListBuilder builder;
96 builder.Scale(GetContentScale().
x, GetContentScale().y);
97 builder.DrawPaint(paint);
100 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
104 auto runtime_stages_result =
105 OpenAssetAsRuntimeStage(
"runtime_stage_filter_example.frag.iplr");
106 ABSL_ASSERT_OK(runtime_stages_result);
107 std::shared_ptr<RuntimeStage> runtime_stage =
108 runtime_stages_result
110 ASSERT_TRUE(runtime_stage);
111 ASSERT_TRUE(runtime_stage->IsDirty());
113 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
116 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
117 uniform_data->resize(
sizeof(
Vector2));
120 paint.setColor(DlColor::kAqua());
121 paint.setImageFilter(DlImageFilter::MakeRuntimeEffect(
125 DisplayListBuilder builder;
126 builder.DrawRect(DlRect::MakeXYWH(0, 0, 400, 400), paint);
128 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
135 std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
136 flutter::DlColor::kRed()};
137 const float stops[2] = {0.0, 1.0};
138 auto linear = flutter::DlColorSource::MakeLinear({0.0, 0.0}, {300.0, 300.0},
139 2, colors.data(), stops,
140 flutter::DlTileMode::kClamp);
141 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
145 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
146 uniform_data->resize(
sizeof(
Vector2));
150 MakeRuntimeEffect(
this,
"runtime_stage_filter_example.frag.iplr",
151 uniform_data, sampler_inputs);
152 ABSL_ASSERT_OK(effect);
153 paint.setColorSource(effect.value());
155 DisplayListBuilder builder;
156 builder.DrawPaint(paint);
158 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
162 DisplayListBuilder builder;
164 background.setColor(DlColor(1.0, 0.1, 0.1, 0.1, DlColorSpace::kSRGB));
165 builder.DrawPaint(background);
168 paint.setColor(DlColor::kGreen());
175 std::shared_ptr<DlImageFilter> color_filter =
176 DlImageFilter::MakeColorFilter(DlColorFilter::MakeMatrix(matrix));
178 auto runtime_stages_result =
179 OpenAssetAsRuntimeStage(
"runtime_stage_filter_warp.frag.iplr");
180 ABSL_ASSERT_OK(runtime_stages_result);
181 std::shared_ptr<RuntimeStage> runtime_stage =
182 runtime_stages_result
184 ASSERT_TRUE(runtime_stage);
185 ASSERT_TRUE(runtime_stage->IsDirty());
187 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
190 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
191 uniform_data->resize(
sizeof(
Vector2));
193 auto runtime_filter = DlImageFilter::MakeRuntimeEffect(
197 builder.Translate(50, 50);
198 builder.Scale(0.7, 0.7);
200 paint.setImageFilter(
201 DlImageFilter::MakeCompose(runtime_filter, color_filter));
203 builder.DrawImage(image,
DlPoint(100.0, 100.0),
204 DlImageSampling::kNearestNeighbor, &paint);
207 green.setColor(DlColor::kGreen());
208 builder.DrawLine({100, 100}, {200, 100}, green);
209 builder.DrawLine({100, 100}, {100, 200}, green);
211 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
215 auto runtime_stages_result =
216 OpenAssetAsRuntimeStage(
"runtime_stage_filter_warp.frag.iplr");
217 ABSL_ASSERT_OK(runtime_stages_result);
218 std::shared_ptr<RuntimeStage> runtime_stage =
219 runtime_stages_result
221 ASSERT_TRUE(runtime_stage);
222 ASSERT_TRUE(runtime_stage->IsDirty());
227 bool compare =
false;
229 auto callback = [&]() -> sk_sp<DisplayList> {
231 ImGuiWindowFlags_AlwaysAutoResize)) {
232 ImGui::SliderFloat(
"xoffset", &xoffset, -50, 50);
233 ImGui::SliderFloat(
"yoffset", &yoffset, -50, 50);
234 ImGui::SliderFloat(
"xscale", &xscale, 0, 1);
235 ImGui::SliderFloat(
"yscale", &yscale, 0, 1);
236 ImGui::Checkbox(
"compare", &compare);
239 DisplayListBuilder builder;
241 background.setColor(DlColor(1.0, 0.1, 0.1, 0.1, DlColorSpace::kSRGB));
242 builder.DrawPaint(background);
245 paint.setColor(DlColor::kGreen());
252 std::shared_ptr<DlImageFilter> color_filter =
253 DlImageFilter::MakeColorFilter(DlColorFilter::MakeMatrix(matrix));
255 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
258 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
259 uniform_data->resize(
sizeof(
Vector2));
261 auto runtime_filter = DlImageFilter::MakeRuntimeEffect(
265 builder.Translate(xoffset, yoffset);
266 builder.Scale(xscale, yscale);
268 paint.setImageFilter(
269 DlImageFilter::MakeCompose(color_filter, runtime_filter));
271 builder.DrawImage(image,
DlPoint(100.0, 100.0),
272 DlImageSampling::kNearestNeighbor, &paint);
275 paint.setImageFilter(
276 DlImageFilter::MakeCompose(runtime_filter, color_filter));
277 builder.DrawImage(image,
DlPoint(800.0, 100.0),
278 DlImageSampling::kNearestNeighbor, &paint);
280 paint.setImageFilter(runtime_filter);
281 builder.DrawImage(image,
DlPoint(100.0, 800.0),
282 DlImageSampling::kNearestNeighbor, &paint);
286 green.setColor(DlColor::kGreen());
287 builder.DrawLine({100, 100}, {200, 100}, green);
288 builder.DrawLine({100, 100}, {100, 200}, green);
290 builder.DrawLine({800, 100}, {900, 100}, green);
291 builder.DrawLine({800, 100}, {800, 200}, green);
292 builder.DrawLine({100, 800}, {200, 800}, green);
293 builder.DrawLine({100, 800}, {100, 900}, green);
296 return builder.Build();
299 ASSERT_TRUE(OpenPlaygroundHere(callback));
303 auto runtime_stages_result =
304 OpenAssetAsRuntimeStage(
"runtime_stage_filter_circle.frag.iplr");
305 ABSL_ASSERT_OK(runtime_stages_result);
306 std::shared_ptr<RuntimeStage> runtime_stage =
307 runtime_stages_result
309 ASSERT_TRUE(runtime_stage);
310 ASSERT_TRUE(runtime_stage->IsDirty());
313 auto callback = [&]() -> sk_sp<DisplayList> {
315 ImGuiWindowFlags_AlwaysAutoResize)) {
316 ImGui::SliderFloat(
"sigma", &sigma, 0, 20);
319 DisplayListBuilder builder;
321 background.setColor(DlColor(1.0, 0.1, 0.1, 0.1, DlColorSpace::kSRGB));
322 builder.DrawPaint(background);
325 DlImageFilter::MakeBlur(sigma, sigma, DlTileMode::kClamp);
327 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
331 struct FragUniforms {
334 } frag_uniforms = {.size =
Vector2(1, 1), .origin =
Vector2(30.f, 30.f)};
335 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
336 uniform_data->resize(
sizeof(FragUniforms));
337 memcpy(uniform_data->data(), &frag_uniforms,
sizeof(FragUniforms));
339 auto runtime_filter = DlImageFilter::MakeRuntimeEffect(
343 auto backdrop_filter = DlImageFilter::MakeCompose(runtime_filter,
348 builder.DrawImage(image,
DlPoint(100.0, 100.0),
349 DlImageSampling::kNearestNeighbor, &paint);
352 save_paint.setBlendMode(DlBlendMode::kSrc);
353 builder.SaveLayer(std::nullopt, &save_paint, backdrop_filter.get());
357 green.setColor(DlColor::kGreen());
358 builder.DrawLine({100, 100}, {200, 100}, green);
359 builder.DrawLine({100, 100}, {100, 200}, green);
361 return builder.Build();
364 ASSERT_TRUE(OpenPlaygroundHere(callback));
368 auto runtime_stages_result =
369 OpenAssetAsRuntimeStage(
"runtime_stage_filter_circle.frag.iplr");
370 ABSL_ASSERT_OK(runtime_stages_result);
371 std::shared_ptr<RuntimeStage> runtime_stage =
372 runtime_stages_result
374 ASSERT_TRUE(runtime_stage);
375 ASSERT_TRUE(runtime_stage->IsDirty());
378 auto callback = [&]() -> sk_sp<DisplayList> {
380 ImGuiWindowFlags_AlwaysAutoResize)) {
381 ImGui::SliderFloat(
"sigma", &sigma, 0, 20);
384 DisplayListBuilder builder;
386 background.setColor(DlColor(1.0, 0.1, 0.1, 0.1, DlColorSpace::kSRGB));
387 builder.DrawPaint(background);
390 DlImageFilter::MakeBlur(sigma, sigma, DlTileMode::kClamp);
392 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
395 struct FragUniforms {
398 } frag_uniforms = {.size =
Vector2(1, 1), .origin =
Vector2(30.f, 30.f)};
399 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
400 uniform_data->resize(
sizeof(FragUniforms));
401 memcpy(uniform_data->data(), &frag_uniforms,
sizeof(FragUniforms));
403 auto runtime_filter = DlImageFilter::MakeRuntimeEffect(
407 auto backdrop_filter = DlImageFilter::MakeCompose(runtime_filter,
412 builder.DrawImage(image,
DlPoint(100.0, 100.0),
413 DlImageSampling::kNearestNeighbor, &paint);
416 save_paint.setBlendMode(DlBlendMode::kSrc);
417 builder.SaveLayer(std::nullopt, &save_paint, backdrop_filter.get());
421 green.setColor(DlColor::kGreen());
422 builder.DrawLine({100, 100}, {200, 100}, green);
423 builder.DrawLine({100, 100}, {100, 200}, green);
425 return builder.Build();
428 ASSERT_TRUE(OpenPlaygroundHere(callback));
432 auto runtime_stages_result =
433 OpenAssetAsRuntimeStage(
"runtime_stage_filter_circle.frag.iplr");
434 ABSL_ASSERT_OK(runtime_stages_result);
435 std::shared_ptr<RuntimeStage> runtime_stage =
436 runtime_stages_result
438 ASSERT_TRUE(runtime_stage);
439 ASSERT_TRUE(runtime_stage->IsDirty());
445 auto callback = [&]() -> sk_sp<DisplayList> {
447 ImGuiWindowFlags_AlwaysAutoResize)) {
448 ImGui::SliderFloat(
"sigma", &sigma, 0, 20);
449 ImGui::SliderFloat(
"clip_x", &clip_origin.
x, 0, 2048.f);
450 ImGui::SliderFloat(
"clip_y", &clip_origin.
y, 0, 1536.f);
451 ImGui::SliderFloat(
"clip_width", &clip_size.
x, 0, 2048.f);
452 ImGui::SliderFloat(
"clip_height", &clip_size.
y, 0, 1536.f);
453 ImGui::SliderFloat(
"circle_x", &circle_origin.
x, 0.f, 2048.f);
454 ImGui::SliderFloat(
"circle_y", &circle_origin.
y, 0.f, 1536.f);
457 DisplayListBuilder builder;
459 background.setColor(DlColor(1.0, 0.1, 0.1, 0.1, DlColorSpace::kSRGB));
460 builder.DrawPaint(background);
463 DlImageFilter::MakeBlur(sigma, sigma, DlTileMode::kClamp);
465 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
468 struct FragUniforms {
471 } frag_uniforms = {.size =
Vector2(1, 1), .origin = circle_origin};
472 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
473 uniform_data->resize(
sizeof(FragUniforms));
474 memcpy(uniform_data->data(), &frag_uniforms,
sizeof(FragUniforms));
476 auto runtime_filter = DlImageFilter::MakeRuntimeEffect(
480 auto backdrop_filter = DlImageFilter::MakeCompose(runtime_filter,
483 builder.ClipRect(DlRect::MakeXYWH(clip_origin.
x, clip_origin.
y, clip_size.
x,
488 builder.DrawImage(image,
DlPoint(100.0, 100.0),
489 DlImageSampling::kNearestNeighbor, &paint);
492 save_paint.setBlendMode(DlBlendMode::kSrc);
493 builder.SaveLayer(std::nullopt, &save_paint, backdrop_filter.get());
497 green.setColor(DlColor::kGreen());
498 builder.DrawLine({100, 100}, {200, 100}, green);
499 builder.DrawLine({100, 100}, {100, 200}, green);
501 return builder.Build();
504 ASSERT_TRUE(OpenPlaygroundHere(callback));
508 struct FragUniforms {
510 } frag_uniforms = {.uSize =
Vector2(400, 400)};
511 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
512 uniform_data->resize(
sizeof(FragUniforms));
513 memcpy(uniform_data->data(), &frag_uniforms,
sizeof(FragUniforms));
515 auto runtime_stages_result =
516 OpenAssetAsRuntimeStage(
"runtime_stage_border.frag.iplr");
517 ABSL_ASSERT_OK(runtime_stages_result);
518 std::shared_ptr<RuntimeStage> runtime_stage =
519 runtime_stages_result
521 ASSERT_TRUE(runtime_stage);
522 ASSERT_TRUE(runtime_stage->IsDirty());
524 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
528 auto runtime_filter = DlImageFilter::MakeRuntimeEffect(
532 DisplayListBuilder builder;
535 DlPaint background_paint;
536 background_paint.setColor(DlColor::kWhite());
537 builder.DrawPaint(background_paint);
540 DlPaint pattern_paint;
541 pattern_paint.setColor(DlColor::kRed());
542 builder.DrawRect(DlRect::MakeXYWH(0, 0, 200, 200), pattern_paint);
543 pattern_paint.setColor(DlColor::kBlue());
544 builder.DrawRect(DlRect::MakeXYWH(200, 200, 200, 200), pattern_paint);
550 builder.ClipRect(DlRect::MakeXYWH(66, 66, 268, 268));
555 builder.SaveLayer(std::nullopt, &save_paint, runtime_filter.get());
563 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
568 auto size = image->GetBounds().GetSize();
570 struct FragUniforms {
572 } frag_uniforms = {.size =
Size(size.width, size.height)};
573 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
574 uniform_data->resize(
sizeof(FragUniforms));
575 memcpy(uniform_data->data(), &frag_uniforms,
sizeof(FragUniforms));
577 auto runtime_stages_result = OpenAssetAsRuntimeStage(
"gradient.frag.iplr");
578 ABSL_ASSERT_OK(runtime_stages_result);
579 std::shared_ptr<RuntimeStage> runtime_stage =
580 runtime_stages_result
582 ASSERT_TRUE(runtime_stage);
583 ASSERT_TRUE(runtime_stage->IsDirty());
585 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
589 auto runtime_filter = DlImageFilter::MakeRuntimeEffect(
595 auto callback = [&]() -> sk_sp<DisplayList> {
597 ImGuiWindowFlags_AlwaysAutoResize)) {
598 ImGui::SliderFloat(
"rotation", &rotation, 0, 360);
601 DisplayListBuilder builder;
602 builder.Translate(size.width * 0.5, size.height * 0.5);
603 builder.Rotate(rotation);
604 builder.Translate(-size.width * 0.5, -size.height * 0.5);
607 paint.setImageFilter(runtime_filter);
608 builder.DrawImage(image,
DlPoint(0.0, 0.0),
609 DlImageSampling::kNearestNeighbor, &paint);
611 return builder.Build();
614 ASSERT_TRUE(OpenPlaygroundHere(callback));
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)
TEST_P(AiksTest, DrawAtlasNoColor)
constexpr RuntimeStageBackend PlaygroundBackendToRuntimeStageBackend(PlaygroundBackend backend)
static constexpr TSize MakeWH(Type width, Type height)