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.value()[test->GetRuntimeStageBackend()];
39 if (!runtime_stage) {
40 return absl::InternalError("Runtime stage not found for backend.");
41 }
42 if (!runtime_stage->IsDirty()) {
43 return absl::InternalError("Runtime stage is not dirty.");
44 }
45
46 auto dl_runtime_effect = DlRuntimeEffectImpeller::Make(runtime_stage);
47
48 return DlColorSource::MakeRuntimeEffect(dl_runtime_effect, samplers,
49 uniform_data);
50}
51} // namespace
52
53// Regression test for https://github.com/flutter/flutter/issues/126701 .
54TEST_P(AiksTest, CanRenderClippedRuntimeEffects) {
55 // This test used to be excluded on Vulkan for impeller_golden_tests
56 // but has been running fine so far with the playground-based golden
57 // mechanism, so we will let it run as the underlying problem may
58 // have been fixed since the exclusion was added.
59 // https://github.com/flutter/flutter/blame/ad80825c24d770a19e33f67800fc0338a3b89ec7/engine/src/flutter/impeller/golden_tests/golden_playground_test_mac.cc#L109
60
61 struct FragUniforms {
62 Vector2 iResolution;
63 Scalar iTime;
64 } frag_uniforms = {.iResolution = Vector2(400, 400), .iTime = 100.0};
65 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
66 uniform_data->resize(sizeof(FragUniforms));
67 memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
68
69 DlPaint paint;
70 auto effect =
71 MakeRuntimeEffect(this, "runtime_stage_example.frag.iplr", uniform_data);
72 ABSL_ASSERT_OK(effect);
73 paint.setColorSource(effect.value());
74
75 DisplayListBuilder builder;
76 builder.Save();
77 builder.ClipRoundRect(
78 DlRoundRect::MakeRectXY(DlRect::MakeXYWH(0, 0, 400, 400), 10.0, 10.0),
79 DlClipOp::kIntersect);
80 builder.DrawRect(DlRect::MakeXYWH(0, 0, 400, 400), paint);
81 builder.Restore();
82
83 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
84}
85
86TEST_P(AiksTest, DrawPaintTransformsBounds) {
87 struct FragUniforms {
88 Size size;
89 } frag_uniforms = {.size = Size::MakeWH(400, 400)};
90 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
91 uniform_data->resize(sizeof(FragUniforms));
92 memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
93
94 DlPaint paint;
95 auto effect = MakeRuntimeEffect(this, "gradient.frag.iplr", uniform_data);
96 ABSL_ASSERT_OK(effect);
97 paint.setColorSource(effect.value());
98
99 DisplayListBuilder builder;
100 builder.Save();
101 builder.Scale(GetContentScale().x, GetContentScale().y);
102 builder.DrawPaint(paint);
103 builder.Restore();
104
105 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
106}
107
108TEST_P(AiksTest, CanRenderRuntimeEffectFilter) {
109 auto runtime_stages_result =
110 OpenAssetAsRuntimeStage("runtime_stage_filter_example.frag.iplr");
111 ABSL_ASSERT_OK(runtime_stages_result);
112 std::shared_ptr<RuntimeStage> runtime_stage =
113 runtime_stages_result.value()[GetRuntimeStageBackend()];
114 ASSERT_TRUE(runtime_stage);
115 ASSERT_TRUE(runtime_stage->IsDirty());
116
117 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
118 nullptr,
119 };
120 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
121 uniform_data->resize(sizeof(Vector2));
122
123 DlPaint paint;
124 paint.setColor(DlColor::kAqua());
126 DlRuntimeEffectImpeller::Make(runtime_stage), sampler_inputs,
127 uniform_data));
128
129 DisplayListBuilder builder;
130 builder.DrawRect(DlRect::MakeXYWH(0, 0, 400, 400), paint);
131
132 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
133}
134
135TEST_P(AiksTest, RuntimeEffectWithInvalidSamplerDoesNotCrash) {
136 ScopedValidationDisable disable_validation;
137
138 // Create a sampler that is not usable as an input to the runtime effect.
139 std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
141 const float stops[2] = {0.0, 1.0};
142 auto linear = flutter::DlColorSource::MakeLinear({0.0, 0.0}, {300.0, 300.0},
143 2, colors.data(), stops,
145 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
146 linear,
147 };
148
149 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
150 uniform_data->resize(sizeof(Vector2));
151
152 DlPaint paint;
153 auto effect =
154 MakeRuntimeEffect(this, "runtime_stage_filter_example.frag.iplr",
155 uniform_data, sampler_inputs);
156 ABSL_ASSERT_OK(effect);
157 paint.setColorSource(effect.value());
158
159 DisplayListBuilder builder;
160 builder.DrawPaint(paint);
161
162 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
163}
164
165TEST_P(AiksTest, ComposePaintRuntimeOuter) {
166 DisplayListBuilder builder;
167 DlPaint background;
168 background.setColor(DlColor(1.0, 0.1, 0.1, 0.1, DlColorSpace::kSRGB));
169 builder.DrawPaint(background);
170
171 DlPaint paint;
172 paint.setColor(DlColor::kGreen());
173 float matrix[] = {
174 0, 1, 0, 0, 0, //
175 1, 0, 0, 0, 0, //
176 0, 0, 1, 0, 0, //
177 0, 0, 0, 1, 0 //
178 };
179 std::shared_ptr<DlImageFilter> color_filter =
181
182 auto runtime_stages_result =
183 OpenAssetAsRuntimeStage("runtime_stage_filter_warp.frag.iplr");
184 ABSL_ASSERT_OK(runtime_stages_result);
185 std::shared_ptr<RuntimeStage> runtime_stage =
186 runtime_stages_result.value()[GetRuntimeStageBackend()];
187 ASSERT_TRUE(runtime_stage);
188 ASSERT_TRUE(runtime_stage->IsDirty());
189
190 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
191 nullptr,
192 };
193 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
194 uniform_data->resize(sizeof(Vector2));
195
196 auto runtime_filter = DlImageFilter::MakeRuntimeEffect(
197 DlRuntimeEffectImpeller::Make(runtime_stage), sampler_inputs,
198 uniform_data);
199
200 builder.Translate(50, 50);
201 builder.Scale(0.7, 0.7);
202
203 paint.setImageFilter(
204 DlImageFilter::MakeCompose(runtime_filter, color_filter));
205 auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
206 builder.DrawImage(image, DlPoint(100.0, 100.0),
207 DlImageSampling::kNearestNeighbor, &paint);
208
209 DlPaint green;
210 green.setColor(DlColor::kGreen());
211 builder.DrawLine({100, 100}, {200, 100}, green);
212 builder.DrawLine({100, 100}, {100, 200}, green);
213
214 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
215}
216
217TEST_P(AiksTest, ComposePaintRuntimeInner) {
218 auto runtime_stages_result =
219 OpenAssetAsRuntimeStage("runtime_stage_filter_warp.frag.iplr");
220 ABSL_ASSERT_OK(runtime_stages_result);
221 std::shared_ptr<RuntimeStage> runtime_stage =
222 runtime_stages_result.value()[GetRuntimeStageBackend()];
223 ASSERT_TRUE(runtime_stage);
224 ASSERT_TRUE(runtime_stage->IsDirty());
225 Scalar xoffset = 50;
226 Scalar yoffset = 50;
227 Scalar xscale = 0.7;
228 Scalar yscale = 0.7;
229 bool compare = false;
230
231 auto callback = [&]() -> sk_sp<DisplayList> {
232 if (IsPlaygroundEnabled()) {
233 ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
234 ImGui::SliderFloat("xoffset", &xoffset, -50, 50);
235 ImGui::SliderFloat("yoffset", &yoffset, -50, 50);
236 ImGui::SliderFloat("xscale", &xscale, 0, 1);
237 ImGui::SliderFloat("yscale", &yscale, 0, 1);
238 ImGui::Checkbox("compare", &compare);
239 ImGui::End();
240 }
241 DisplayListBuilder builder;
242 DlPaint background;
243 background.setColor(DlColor(1.0, 0.1, 0.1, 0.1, DlColorSpace::kSRGB));
244 builder.DrawPaint(background);
245
246 DlPaint paint;
247 paint.setColor(DlColor::kGreen());
248 float matrix[] = {
249 0, 1, 0, 0, 0, //
250 1, 0, 0, 0, 0, //
251 0, 0, 1, 0, 0, //
252 0, 0, 0, 1, 0 //
253 };
254 std::shared_ptr<DlImageFilter> color_filter =
256
257 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
258 nullptr,
259 };
260 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
261 uniform_data->resize(sizeof(Vector2));
262
263 auto runtime_filter = DlImageFilter::MakeRuntimeEffect(
264 DlRuntimeEffectImpeller::Make(runtime_stage), sampler_inputs,
265 uniform_data);
266
267 builder.Translate(xoffset, yoffset);
268 builder.Scale(xscale, yscale);
269
270 paint.setImageFilter(
271 DlImageFilter::MakeCompose(color_filter, runtime_filter));
272 auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
273 builder.DrawImage(image, DlPoint(100.0, 100.0),
274 DlImageSampling::kNearestNeighbor, &paint);
275
276 if (compare) {
277 paint.setImageFilter(
278 DlImageFilter::MakeCompose(runtime_filter, color_filter));
279 builder.DrawImage(image, DlPoint(800.0, 100.0),
280 DlImageSampling::kNearestNeighbor, &paint);
281
282 paint.setImageFilter(runtime_filter);
283 builder.DrawImage(image, DlPoint(100.0, 800.0),
284 DlImageSampling::kNearestNeighbor, &paint);
285 }
286
287 DlPaint green;
288 green.setColor(DlColor::kGreen());
289 builder.DrawLine({100, 100}, {200, 100}, green);
290 builder.DrawLine({100, 100}, {100, 200}, green);
291 if (compare) {
292 builder.DrawLine({800, 100}, {900, 100}, green);
293 builder.DrawLine({800, 100}, {800, 200}, green);
294 builder.DrawLine({100, 800}, {200, 800}, green);
295 builder.DrawLine({100, 800}, {100, 900}, green);
296 }
297
298 return builder.Build();
299 };
300
301 ASSERT_TRUE(OpenPlaygroundHere(callback));
302}
303
304TEST_P(AiksTest, ComposeBackdropRuntimeOuterBlurInner) {
305 auto runtime_stages_result =
306 OpenAssetAsRuntimeStage("runtime_stage_filter_circle.frag.iplr");
307 ABSL_ASSERT_OK(runtime_stages_result);
308 std::shared_ptr<RuntimeStage> runtime_stage =
309 runtime_stages_result.value()[GetRuntimeStageBackend()];
310 ASSERT_TRUE(runtime_stage);
311 ASSERT_TRUE(runtime_stage->IsDirty());
312 Scalar sigma = 20.0;
313
314 auto callback = [&]() -> sk_sp<DisplayList> {
315 if (IsPlaygroundEnabled()) {
316 ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
317 ImGui::SliderFloat("sigma", &sigma, 0, 20);
318 ImGui::End();
319 }
320 DisplayListBuilder builder;
321 DlPaint background;
322 background.setColor(DlColor(1.0, 0.1, 0.1, 0.1, DlColorSpace::kSRGB));
323 builder.DrawPaint(background);
324
325 auto blur_filter =
326 DlImageFilter::MakeBlur(sigma, sigma, DlTileMode::kClamp);
327
328 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
329 nullptr,
330 };
331
332 struct FragUniforms {
334 Vector2 origin;
335 } frag_uniforms = {.size = Vector2(1, 1), .origin = Vector2(30.f, 30.f)};
336 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
337 uniform_data->resize(sizeof(FragUniforms));
338 memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
339
340 auto runtime_filter = DlImageFilter::MakeRuntimeEffect(
341 DlRuntimeEffectImpeller::Make(runtime_stage), sampler_inputs,
342 uniform_data);
343
344 auto backdrop_filter = DlImageFilter::MakeCompose(/*outer=*/runtime_filter,
345 /*inner=*/blur_filter);
346
347 DlPaint paint;
348 auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
349 builder.DrawImage(image, DlPoint(100.0, 100.0),
350 DlImageSampling::kNearestNeighbor, &paint);
351
352 DlPaint save_paint;
353 save_paint.setBlendMode(DlBlendMode::kSrc);
354 builder.SaveLayer(std::nullopt, &save_paint, backdrop_filter.get());
355 builder.Restore();
356
357 DlPaint green;
358 green.setColor(DlColor::kGreen());
359 builder.DrawLine({100, 100}, {200, 100}, green);
360 builder.DrawLine({100, 100}, {100, 200}, green);
361
362 return builder.Build();
363 };
364
365 ASSERT_TRUE(OpenPlaygroundHere(callback));
366}
367
368TEST_P(AiksTest, ComposeBackdropRuntimeOuterBlurInnerSmallSigma) {
369 auto runtime_stages_result =
370 OpenAssetAsRuntimeStage("runtime_stage_filter_circle.frag.iplr");
371 ABSL_ASSERT_OK(runtime_stages_result);
372 std::shared_ptr<RuntimeStage> runtime_stage =
373 runtime_stages_result.value()[GetRuntimeStageBackend()];
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 (IsPlaygroundEnabled()) {
380 ImGui::Begin("Controls", nullptr, 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.value()[GetRuntimeStageBackend()];
437 ASSERT_TRUE(runtime_stage);
438 ASSERT_TRUE(runtime_stage->IsDirty());
439 Scalar sigma = 5.0;
440 Vector2 clip_origin = Vector2(20.f, 20.f);
441 Vector2 clip_size = Vector2(300, 300);
442 Vector2 circle_origin = Vector2(30.f, 30.f);
443
444 auto callback = [&]() -> sk_sp<DisplayList> {
445 if (IsPlaygroundEnabled()) {
446 ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
447 ImGui::SliderFloat("sigma", &sigma, 0, 20);
448 ImGui::SliderFloat("clip_x", &clip_origin.x, 0, 2048.f);
449 ImGui::SliderFloat("clip_y", &clip_origin.y, 0, 1536.f);
450 ImGui::SliderFloat("clip_width", &clip_size.x, 0, 2048.f);
451 ImGui::SliderFloat("clip_height", &clip_size.y, 0, 1536.f);
452 ImGui::SliderFloat("circle_x", &circle_origin.x, 0.f, 2048.f);
453 ImGui::SliderFloat("circle_y", &circle_origin.y, 0.f, 1536.f);
454 ImGui::End();
455 }
456 DisplayListBuilder builder;
457 DlPaint background;
458 background.setColor(DlColor(1.0, 0.1, 0.1, 0.1, DlColorSpace::kSRGB));
459 builder.DrawPaint(background);
460
461 auto blur_filter =
462 DlImageFilter::MakeBlur(sigma, sigma, DlTileMode::kClamp);
463
464 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
465 nullptr,
466 };
467 struct FragUniforms {
469 Vector2 origin;
470 } frag_uniforms = {.size = Vector2(1, 1), .origin = circle_origin};
471 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
472 uniform_data->resize(sizeof(FragUniforms));
473 memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
474
475 auto runtime_filter = DlImageFilter::MakeRuntimeEffect(
476 DlRuntimeEffectImpeller::Make(runtime_stage), sampler_inputs,
477 uniform_data);
478
479 auto backdrop_filter = DlImageFilter::MakeCompose(/*outer=*/runtime_filter,
480 /*inner=*/blur_filter);
481
482 builder.ClipRect(DlRect::MakeXYWH(clip_origin.x, clip_origin.y, clip_size.x,
483 clip_size.y));
484
485 DlPaint paint;
486 auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
487 builder.DrawImage(image, DlPoint(100.0, 100.0),
488 DlImageSampling::kNearestNeighbor, &paint);
489
490 DlPaint save_paint;
491 save_paint.setBlendMode(DlBlendMode::kSrc);
492 builder.SaveLayer(std::nullopt, &save_paint, backdrop_filter.get());
493 builder.Restore();
494
495 DlPaint green;
496 green.setColor(DlColor::kGreen());
497 builder.DrawLine({100, 100}, {200, 100}, green);
498 builder.DrawLine({100, 100}, {100, 200}, green);
499
500 return builder.Build();
501 };
502
503 ASSERT_TRUE(OpenPlaygroundHere(callback));
504}
505
506TEST_P(AiksTest, ClippedBackdropFilterWithShader) {
507 struct FragUniforms {
508 Vector2 uSize;
509 } frag_uniforms = {.uSize = Vector2(400, 400)};
510 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
511 uniform_data->resize(sizeof(FragUniforms));
512 memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
513
514 auto runtime_stages_result =
515 OpenAssetAsRuntimeStage("runtime_stage_border.frag.iplr");
516 ABSL_ASSERT_OK(runtime_stages_result);
517 std::shared_ptr<RuntimeStage> runtime_stage =
518 runtime_stages_result.value()[GetRuntimeStageBackend()];
519 ASSERT_TRUE(runtime_stage);
520 ASSERT_TRUE(runtime_stage->IsDirty());
521
522 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
523 nullptr,
524 };
525
526 auto runtime_filter = DlImageFilter::MakeRuntimeEffect(
527 DlRuntimeEffectImpeller::Make(runtime_stage), sampler_inputs,
528 uniform_data);
529
530 DisplayListBuilder builder;
531
532 // Draw a background so the backdrop filter has something to affect
533 DlPaint background_paint;
534 background_paint.setColor(DlColor::kWhite());
535 builder.DrawPaint(background_paint);
536
537 // Draw some pattern to verify the filter effect
538 DlPaint pattern_paint;
539 pattern_paint.setColor(DlColor::kRed());
540 builder.DrawRect(DlRect::MakeXYWH(0, 0, 200, 200), pattern_paint);
541 pattern_paint.setColor(DlColor::kBlue());
542 builder.DrawRect(DlRect::MakeXYWH(200, 200, 200, 200), pattern_paint);
543
544 builder.Save();
545
546 // Replicate the clip rect (inset by 66)
547 // Assuming a 400x400 screen, inset 66 gives roughly 66, 66, 268, 268
548 builder.ClipRect(DlRect::MakeXYWH(66, 66, 268, 268));
549
550 DlPaint save_paint;
551 // The Flutter code uses a backdrop filter layer.
552 // In DisplayList, this corresponds to SaveLayer with a backdrop filter.
553 builder.SaveLayer(std::nullopt, &save_paint, runtime_filter.get());
554
555 // The child was empty in the Flutter example, so we don't draw anything
556 // inside the SaveLayer
557
558 builder.Restore(); // Restore SaveLayer
559 builder.Restore(); // Restore Save (Clip)
560
561 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
562}
563
564TEST_P(AiksTest, RuntimeEffectImageFilterRotated) {
565 auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
566 auto size = image->GetBounds().GetSize();
567
568 struct FragUniforms {
569 Size size;
570 } frag_uniforms = {.size = Size(size.width, size.height)};
571 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
572 uniform_data->resize(sizeof(FragUniforms));
573 memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
574
575 auto runtime_stages_result = OpenAssetAsRuntimeStage("gradient.frag.iplr");
576 ABSL_ASSERT_OK(runtime_stages_result);
577 std::shared_ptr<RuntimeStage> runtime_stage =
578 runtime_stages_result.value()[GetRuntimeStageBackend()];
579 ASSERT_TRUE(runtime_stage);
580 ASSERT_TRUE(runtime_stage->IsDirty());
581
582 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
583 nullptr,
584 };
585
586 auto runtime_filter = DlImageFilter::MakeRuntimeEffect(
587 DlRuntimeEffectImpeller::Make(runtime_stage), sampler_inputs,
588 uniform_data);
589
590 Scalar rotation = 45;
591
592 auto callback = [&]() -> sk_sp<DisplayList> {
593 if (IsPlaygroundEnabled()) {
594 ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
595 ImGui::SliderFloat("rotation", &rotation, 0, 360);
596 ImGui::End();
597 }
598 DisplayListBuilder builder;
599 builder.Translate(size.width * 0.5, size.height * 0.5);
600 builder.Rotate(rotation);
601 builder.Translate(-size.width * 0.5, -size.height * 0.5);
602
603 DlPaint paint;
604 paint.setImageFilter(runtime_filter);
605 builder.DrawImage(image, DlPoint(0.0, 0.0),
606 DlImageSampling::kNearestNeighbor, &paint);
607
608 return builder.Build();
609 };
610
611 ASSERT_TRUE(OpenPlaygroundHere(callback));
612}
613
614TEST_P(AiksTest, RuntimeEffectVectorArray) {
615 constexpr float kDimension = 400.0f;
616 struct FragUniforms {
617 Vector2 iResolution;
618 Vector4 iValues;
619 } frag_uniforms = {.iResolution = Vector2(kDimension, kDimension),
620 .iValues = Vector4(0.25, 0.50, 0.75, 1.0)};
621 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
622 uniform_data->resize(sizeof(FragUniforms));
623 memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
624
625 DlPaint paint;
626 auto effect = MakeRuntimeEffect(this, "runtime_stage_vector_array.frag.iplr",
627 uniform_data);
628 ABSL_ASSERT_OK(effect);
629 paint.setColorSource(effect.value());
630
631 DisplayListBuilder builder;
632 builder.DrawRect(DlRect::MakeXYWH(0, 0, kDimension, kDimension), paint);
633
634 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
635}
636
637} // namespace testing
638} // 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()
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 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
TEST_P(AiksTest, DrawAtlasNoColor)
AiksPlaygroundWithGoldens AiksTest
Point Vector2
Definition point.h:430
float Scalar
Definition scalar.h:19
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