Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
aiks_dl_runtime_effect_unittests.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <memory>
6
7#include "absl/status/statusor.h"
8
17#include "imgui.h"
20#include "third_party/abseil-cpp/absl/status/status_matchers.h"
21
22namespace impeller {
23namespace testing {
24
25using namespace flutter;
26
27namespace {
28absl::StatusOr<std::shared_ptr<DlColorSource>> MakeRuntimeEffect(
29 AiksTest* test,
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();
36 }
37 std::shared_ptr<RuntimeStage> runtime_stage =
38 runtime_stages_result
39 .value()[PlaygroundBackendToRuntimeStageBackend(test->GetBackend())];
40 if (!runtime_stage) {
41 return absl::InternalError("Runtime stage not found for backend.");
42 }
43 if (!runtime_stage->IsDirty()) {
44 return absl::InternalError("Runtime stage is not dirty.");
45 }
46
47 auto dl_runtime_effect = DlRuntimeEffectImpeller::Make(runtime_stage);
48
49 return DlColorSource::MakeRuntimeEffect(dl_runtime_effect, samplers,
50 uniform_data);
51}
52} // namespace
53
54// Regression test for https://github.com/flutter/flutter/issues/126701 .
55TEST_P(AiksTest, CanRenderClippedRuntimeEffects) {
56 struct FragUniforms {
57 Vector2 iResolution;
58 Scalar iTime;
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));
63
64 DlPaint paint;
65 auto effect =
66 MakeRuntimeEffect(this, "runtime_stage_example.frag.iplr", uniform_data);
67 ABSL_ASSERT_OK(effect);
68 paint.setColorSource(effect.value());
69
70 DisplayListBuilder builder;
71 builder.Save();
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);
76 builder.Restore();
77
78 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
79}
80
81TEST_P(AiksTest, DrawPaintTransformsBounds) {
82 struct FragUniforms {
83 Size size;
84 } frag_uniforms = {.size = Size::MakeWH(400, 400)};
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));
88
89 DlPaint paint;
90 auto effect = MakeRuntimeEffect(this, "gradient.frag.iplr", uniform_data);
91 ABSL_ASSERT_OK(effect);
92 paint.setColorSource(effect.value());
93
94 DisplayListBuilder builder;
95 builder.Save();
96 builder.Scale(GetContentScale().x, GetContentScale().y);
97 builder.DrawPaint(paint);
98 builder.Restore();
99
100 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
101}
102
103TEST_P(AiksTest, CanRenderRuntimeEffectFilter) {
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
109 .value()[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
110 ASSERT_TRUE(runtime_stage);
111 ASSERT_TRUE(runtime_stage->IsDirty());
112
113 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
114 nullptr,
115 };
116 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
117 uniform_data->resize(sizeof(Vector2));
118
119 DlPaint paint;
120 paint.setColor(DlColor::kAqua());
122 DlRuntimeEffectImpeller::Make(runtime_stage), sampler_inputs,
123 uniform_data));
124
125 DisplayListBuilder builder;
126 builder.DrawRect(DlRect::MakeXYWH(0, 0, 400, 400), paint);
127
128 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
129}
130
131TEST_P(AiksTest, RuntimeEffectWithInvalidSamplerDoesNotCrash) {
132 ScopedValidationDisable disable_validation;
133
134 // Create a sampler that is not usable as an input to the runtime effect.
135 std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
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,
141 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
142 linear,
143 };
144
145 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
146 uniform_data->resize(sizeof(Vector2));
147
148 DlPaint paint;
149 auto effect =
150 MakeRuntimeEffect(this, "runtime_stage_filter_example.frag.iplr",
151 uniform_data, sampler_inputs);
152 ABSL_ASSERT_OK(effect);
153 paint.setColorSource(effect.value());
154
155 DisplayListBuilder builder;
156 builder.DrawPaint(paint);
157
158 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
159}
160
161TEST_P(AiksTest, ComposePaintRuntimeOuter) {
162 DisplayListBuilder builder;
163 DlPaint background;
164 background.setColor(DlColor(1.0, 0.1, 0.1, 0.1, DlColorSpace::kSRGB));
165 builder.DrawPaint(background);
166
167 DlPaint paint;
168 paint.setColor(DlColor::kGreen());
169 float matrix[] = {
170 0, 1, 0, 0, 0, //
171 1, 0, 0, 0, 0, //
172 0, 0, 1, 0, 0, //
173 0, 0, 0, 1, 0 //
174 };
175 std::shared_ptr<DlImageFilter> color_filter =
177
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
183 .value()[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
184 ASSERT_TRUE(runtime_stage);
185 ASSERT_TRUE(runtime_stage->IsDirty());
186
187 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
188 nullptr,
189 };
190 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
191 uniform_data->resize(sizeof(Vector2));
192
193 auto runtime_filter = DlImageFilter::MakeRuntimeEffect(
194 DlRuntimeEffectImpeller::Make(runtime_stage), sampler_inputs,
195 uniform_data);
196
197 builder.Translate(50, 50);
198 builder.Scale(0.7, 0.7);
199
200 paint.setImageFilter(
201 DlImageFilter::MakeCompose(runtime_filter, color_filter));
202 auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
203 builder.DrawImage(image, DlPoint(100.0, 100.0),
204 DlImageSampling::kNearestNeighbor, &paint);
205
206 DlPaint green;
207 green.setColor(DlColor::kGreen());
208 builder.DrawLine({100, 100}, {200, 100}, green);
209 builder.DrawLine({100, 100}, {100, 200}, green);
210
211 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
212}
213
214TEST_P(AiksTest, ComposePaintRuntimeInner) {
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
220 .value()[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
221 ASSERT_TRUE(runtime_stage);
222 ASSERT_TRUE(runtime_stage->IsDirty());
223 Scalar xoffset = 50;
224 Scalar yoffset = 50;
225 Scalar xscale = 0.7;
226 Scalar yscale = 0.7;
227 bool compare = false;
228
229 auto callback = [&]() -> sk_sp<DisplayList> {
230 if (AiksTest::ImGuiBegin("Controls", nullptr,
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);
237 ImGui::End();
238 }
239 DisplayListBuilder builder;
240 DlPaint background;
241 background.setColor(DlColor(1.0, 0.1, 0.1, 0.1, DlColorSpace::kSRGB));
242 builder.DrawPaint(background);
243
244 DlPaint paint;
245 paint.setColor(DlColor::kGreen());
246 float matrix[] = {
247 0, 1, 0, 0, 0, //
248 1, 0, 0, 0, 0, //
249 0, 0, 1, 0, 0, //
250 0, 0, 0, 1, 0 //
251 };
252 std::shared_ptr<DlImageFilter> color_filter =
254
255 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
256 nullptr,
257 };
258 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
259 uniform_data->resize(sizeof(Vector2));
260
261 auto runtime_filter = DlImageFilter::MakeRuntimeEffect(
262 DlRuntimeEffectImpeller::Make(runtime_stage), sampler_inputs,
263 uniform_data);
264
265 builder.Translate(xoffset, yoffset);
266 builder.Scale(xscale, yscale);
267
268 paint.setImageFilter(
269 DlImageFilter::MakeCompose(color_filter, runtime_filter));
270 auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
271 builder.DrawImage(image, DlPoint(100.0, 100.0),
272 DlImageSampling::kNearestNeighbor, &paint);
273
274 if (compare) {
275 paint.setImageFilter(
276 DlImageFilter::MakeCompose(runtime_filter, color_filter));
277 builder.DrawImage(image, DlPoint(800.0, 100.0),
278 DlImageSampling::kNearestNeighbor, &paint);
279
280 paint.setImageFilter(runtime_filter);
281 builder.DrawImage(image, DlPoint(100.0, 800.0),
282 DlImageSampling::kNearestNeighbor, &paint);
283 }
284
285 DlPaint green;
286 green.setColor(DlColor::kGreen());
287 builder.DrawLine({100, 100}, {200, 100}, green);
288 builder.DrawLine({100, 100}, {100, 200}, green);
289 if (compare) {
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);
294 }
295
296 return builder.Build();
297 };
298
299 ASSERT_TRUE(OpenPlaygroundHere(callback));
300}
301
302TEST_P(AiksTest, ComposeBackdropRuntimeOuterBlurInner) {
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
308 .value()[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
309 ASSERT_TRUE(runtime_stage);
310 ASSERT_TRUE(runtime_stage->IsDirty());
311 Scalar sigma = 20.0;
312
313 auto callback = [&]() -> sk_sp<DisplayList> {
314 if (AiksTest::ImGuiBegin("Controls", nullptr,
315 ImGuiWindowFlags_AlwaysAutoResize)) {
316 ImGui::SliderFloat("sigma", &sigma, 0, 20);
317 ImGui::End();
318 }
319 DisplayListBuilder builder;
320 DlPaint background;
321 background.setColor(DlColor(1.0, 0.1, 0.1, 0.1, DlColorSpace::kSRGB));
322 builder.DrawPaint(background);
323
324 auto blur_filter =
325 DlImageFilter::MakeBlur(sigma, sigma, DlTileMode::kClamp);
326
327 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
328 nullptr,
329 };
330
331 struct FragUniforms {
333 Vector2 origin;
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));
338
339 auto runtime_filter = DlImageFilter::MakeRuntimeEffect(
340 DlRuntimeEffectImpeller::Make(runtime_stage), sampler_inputs,
341 uniform_data);
342
343 auto backdrop_filter = DlImageFilter::MakeCompose(/*outer=*/runtime_filter,
344 /*inner=*/blur_filter);
345
346 DlPaint paint;
347 auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
348 builder.DrawImage(image, DlPoint(100.0, 100.0),
349 DlImageSampling::kNearestNeighbor, &paint);
350
351 DlPaint save_paint;
352 save_paint.setBlendMode(DlBlendMode::kSrc);
353 builder.SaveLayer(std::nullopt, &save_paint, backdrop_filter.get());
354 builder.Restore();
355
356 DlPaint green;
357 green.setColor(DlColor::kGreen());
358 builder.DrawLine({100, 100}, {200, 100}, green);
359 builder.DrawLine({100, 100}, {100, 200}, green);
360
361 return builder.Build();
362 };
363
364 ASSERT_TRUE(OpenPlaygroundHere(callback));
365}
366
367TEST_P(AiksTest, ComposeBackdropRuntimeOuterBlurInnerSmallSigma) {
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
373 .value()[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
374 ASSERT_TRUE(runtime_stage);
375 ASSERT_TRUE(runtime_stage->IsDirty());
376 Scalar sigma = 5.0;
377
378 auto callback = [&]() -> sk_sp<DisplayList> {
379 if (AiksTest::ImGuiBegin("Controls", nullptr,
380 ImGuiWindowFlags_AlwaysAutoResize)) {
381 ImGui::SliderFloat("sigma", &sigma, 0, 20);
382 ImGui::End();
383 }
384 DisplayListBuilder builder;
385 DlPaint background;
386 background.setColor(DlColor(1.0, 0.1, 0.1, 0.1, DlColorSpace::kSRGB));
387 builder.DrawPaint(background);
388
389 auto blur_filter =
390 DlImageFilter::MakeBlur(sigma, sigma, DlTileMode::kClamp);
391
392 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
393 nullptr,
394 };
395 struct FragUniforms {
397 Vector2 origin;
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));
402
403 auto runtime_filter = DlImageFilter::MakeRuntimeEffect(
404 DlRuntimeEffectImpeller::Make(runtime_stage), sampler_inputs,
405 uniform_data);
406
407 auto backdrop_filter = DlImageFilter::MakeCompose(/*outer=*/runtime_filter,
408 /*inner=*/blur_filter);
409
410 DlPaint paint;
411 auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
412 builder.DrawImage(image, DlPoint(100.0, 100.0),
413 DlImageSampling::kNearestNeighbor, &paint);
414
415 DlPaint save_paint;
416 save_paint.setBlendMode(DlBlendMode::kSrc);
417 builder.SaveLayer(std::nullopt, &save_paint, backdrop_filter.get());
418 builder.Restore();
419
420 DlPaint green;
421 green.setColor(DlColor::kGreen());
422 builder.DrawLine({100, 100}, {200, 100}, green);
423 builder.DrawLine({100, 100}, {100, 200}, green);
424
425 return builder.Build();
426 };
427
428 ASSERT_TRUE(OpenPlaygroundHere(callback));
429}
430
431TEST_P(AiksTest, ClippedComposeBackdropRuntimeOuterBlurInnerSmallSigma) {
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
437 .value()[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
438 ASSERT_TRUE(runtime_stage);
439 ASSERT_TRUE(runtime_stage->IsDirty());
440 Scalar sigma = 5.0;
441 Vector2 clip_origin = Vector2(20.f, 20.f);
442 Vector2 clip_size = Vector2(300, 300);
443 Vector2 circle_origin = Vector2(30.f, 30.f);
444
445 auto callback = [&]() -> sk_sp<DisplayList> {
446 if (AiksTest::ImGuiBegin("Controls", nullptr,
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);
455 ImGui::End();
456 }
457 DisplayListBuilder builder;
458 DlPaint background;
459 background.setColor(DlColor(1.0, 0.1, 0.1, 0.1, DlColorSpace::kSRGB));
460 builder.DrawPaint(background);
461
462 auto blur_filter =
463 DlImageFilter::MakeBlur(sigma, sigma, DlTileMode::kClamp);
464
465 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
466 nullptr,
467 };
468 struct FragUniforms {
470 Vector2 origin;
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));
475
476 auto runtime_filter = DlImageFilter::MakeRuntimeEffect(
477 DlRuntimeEffectImpeller::Make(runtime_stage), sampler_inputs,
478 uniform_data);
479
480 auto backdrop_filter = DlImageFilter::MakeCompose(/*outer=*/runtime_filter,
481 /*inner=*/blur_filter);
482
483 builder.ClipRect(DlRect::MakeXYWH(clip_origin.x, clip_origin.y, clip_size.x,
484 clip_size.y));
485
486 DlPaint paint;
487 auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
488 builder.DrawImage(image, DlPoint(100.0, 100.0),
489 DlImageSampling::kNearestNeighbor, &paint);
490
491 DlPaint save_paint;
492 save_paint.setBlendMode(DlBlendMode::kSrc);
493 builder.SaveLayer(std::nullopt, &save_paint, backdrop_filter.get());
494 builder.Restore();
495
496 DlPaint green;
497 green.setColor(DlColor::kGreen());
498 builder.DrawLine({100, 100}, {200, 100}, green);
499 builder.DrawLine({100, 100}, {100, 200}, green);
500
501 return builder.Build();
502 };
503
504 ASSERT_TRUE(OpenPlaygroundHere(callback));
505}
506
507TEST_P(AiksTest, ClippedBackdropFilterWithShader) {
508 struct FragUniforms {
509 Vector2 uSize;
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));
514
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
520 .value()[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
521 ASSERT_TRUE(runtime_stage);
522 ASSERT_TRUE(runtime_stage->IsDirty());
523
524 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
525 nullptr,
526 };
527
528 auto runtime_filter = DlImageFilter::MakeRuntimeEffect(
529 DlRuntimeEffectImpeller::Make(runtime_stage), sampler_inputs,
530 uniform_data);
531
532 DisplayListBuilder builder;
533
534 // Draw a background so the backdrop filter has something to affect
535 DlPaint background_paint;
536 background_paint.setColor(DlColor::kWhite());
537 builder.DrawPaint(background_paint);
538
539 // Draw some pattern to verify the filter effect
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);
545
546 builder.Save();
547
548 // Replicate the clip rect (inset by 66)
549 // Assuming a 400x400 screen, inset 66 gives roughly 66, 66, 268, 268
550 builder.ClipRect(DlRect::MakeXYWH(66, 66, 268, 268));
551
552 DlPaint save_paint;
553 // The Flutter code uses a backdrop filter layer.
554 // In DisplayList, this corresponds to SaveLayer with a backdrop filter.
555 builder.SaveLayer(std::nullopt, &save_paint, runtime_filter.get());
556
557 // The child was empty in the Flutter example, so we don't draw anything
558 // inside the SaveLayer
559
560 builder.Restore(); // Restore SaveLayer
561 builder.Restore(); // Restore Save (Clip)
562
563 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
564}
565
566TEST_P(AiksTest, RuntimeEffectImageFilterRotated) {
567 auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
568 auto size = image->GetBounds().GetSize();
569
570 struct FragUniforms {
571 Size size;
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));
576
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
581 .value()[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
582 ASSERT_TRUE(runtime_stage);
583 ASSERT_TRUE(runtime_stage->IsDirty());
584
585 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
586 nullptr,
587 };
588
589 auto runtime_filter = DlImageFilter::MakeRuntimeEffect(
590 DlRuntimeEffectImpeller::Make(runtime_stage), sampler_inputs,
591 uniform_data);
592
593 Scalar rotation = 45;
594
595 auto callback = [&]() -> sk_sp<DisplayList> {
596 if (AiksTest::ImGuiBegin("Controls", nullptr,
597 ImGuiWindowFlags_AlwaysAutoResize)) {
598 ImGui::SliderFloat("rotation", &rotation, 0, 360);
599 ImGui::End();
600 }
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);
605
606 DlPaint paint;
607 paint.setImageFilter(runtime_filter);
608 builder.DrawImage(image, DlPoint(0.0, 0.0),
609 DlImageSampling::kNearestNeighbor, &paint);
610
611 return builder.Build();
612 };
613
614 ASSERT_TRUE(OpenPlaygroundHere(callback));
615}
616
617TEST_P(AiksTest, RuntimeEffectVectorArray) {
618 constexpr float kDimension = 400.0f;
619 struct FragUniforms {
620 Vector2 iResolution;
621 Vector4 iValues;
622 } frag_uniforms = {.iResolution = Vector2(kDimension, kDimension),
623 .iValues = Vector4(0.25, 0.50, 0.75, 1.0)};
624 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
625 uniform_data->resize(sizeof(FragUniforms));
626 memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
627
628 DlPaint paint;
629 auto effect = MakeRuntimeEffect(this, "runtime_stage_vector_array.frag.iplr",
630 uniform_data);
631 ABSL_ASSERT_OK(effect);
632 paint.setColorSource(effect.value());
633
634 DisplayListBuilder builder;
635 builder.DrawRect(DlRect::MakeXYWH(0, 0, kDimension, kDimension), paint);
636
637 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
638}
639
640} // namespace testing
641} // namespace impeller
void ClipRect(const DlRect &rect, DlClipOp clip_op=DlClipOp::kIntersect, bool is_aa=false) override
void DrawImage(const sk_sp< DlImage > &image, const DlPoint &point, DlImageSampling sampling, const DlPaint *paint=nullptr) override
void SaveLayer(const std::optional< DlRect > &bounds, const DlPaint *paint=nullptr, const DlImageFilter *backdrop=nullptr, std::optional< int64_t > backdrop_id=std::nullopt) override
void DrawLine(const DlPoint &p0, const DlPoint &p1, const DlPaint &paint) override
void ClipRoundRect(const DlRoundRect &rrect, DlClipOp clip_op=DlClipOp::kIntersect, bool is_aa=false) override
void Rotate(DlScalar degrees) override
void Scale(DlScalar sx, DlScalar sy) override
void Translate(DlScalar tx, DlScalar ty) override
void DrawPaint(const DlPaint &paint) override
sk_sp< DisplayList > Build()
Definition dl_builder.cc:66
void DrawRect(const DlRect &rect, const DlPaint &paint) override
static std::shared_ptr< const DlColorFilter > MakeMatrix(const float matrix[20])
static std::shared_ptr< DlColorSource > MakeLinear(const DlPoint start_point, const DlPoint end_point, uint32_t stop_count, const DlColor *colors, const float *stops, DlTileMode tile_mode, const DlMatrix *matrix=nullptr)
static std::shared_ptr< DlColorSource > MakeRuntimeEffect(sk_sp< DlRuntimeEffect > runtime_effect, std::vector< std::shared_ptr< DlColorSource > > samplers, std::shared_ptr< std::vector< uint8_t > > uniform_data)
static std::shared_ptr< DlImageFilter > MakeBlur(DlScalar sigma_x, DlScalar sigma_y, DlTileMode tile_mode)
static std::shared_ptr< DlImageFilter > MakeRuntimeEffect(sk_sp< DlRuntimeEffect > runtime_effect, std::vector< std::shared_ptr< DlColorSource > > samplers, std::shared_ptr< std::vector< uint8_t > > uniform_data)
static std::shared_ptr< DlImageFilter > MakeColorFilter(const std::shared_ptr< const DlColorFilter > &filter)
static std::shared_ptr< DlImageFilter > MakeCompose(const std::shared_ptr< DlImageFilter > &outer, const std::shared_ptr< DlImageFilter > &inner)
DlPaint & setColor(DlColor color)
Definition dl_paint.h:70
DlPaint & setBlendMode(DlBlendMode mode)
Definition dl_paint.h:85
DlPaint & setImageFilter(std::nullptr_t filter)
Definition dl_paint.h:167
DlPaint & setColorSource(std::nullptr_t source)
Definition dl_paint.h:131
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)
int32_t x
FlutterVulkanImage * image
FlutterDesktopBinaryReply callback
double y
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
DEF_SWITCHES_START aot vmservice shared library name
Definition switch_defs.h:27
impeller::Point DlPoint
AiksPlayground AiksTest
TEST_P(AiksTest, DrawAtlasNoColor)
Point Vector2
Definition point.h:429
float Scalar
Definition scalar.h:19
constexpr RuntimeStageBackend PlaygroundBackendToRuntimeStageBackend(PlaygroundBackend backend)
Definition playground.h:33
static constexpr DlColor kWhite()
Definition dl_color.h:70
static constexpr DlColor kBlue()
Definition dl_color.h:73
static constexpr DlColor kAqua()
Definition dl_color.h:86
static constexpr DlColor kRed()
Definition dl_color.h:71
static constexpr DlColor kGreen()
Definition dl_color.h:72
static RoundRect MakeRectXY(const Rect &rect, Scalar x_radius, Scalar y_radius)
Definition round_rect.h:31
static constexpr TRect MakeXYWH(Type x, Type y, Type width, Type height)
Definition rect.h:136
static constexpr TSize MakeWH(Type width, Type height)
Definition size.h:43