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 struct FragUniforms {
56 Vector2 iResolution;
57 Scalar iTime;
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));
62
63 DlPaint paint;
64 auto effect =
65 MakeRuntimeEffect(this, "runtime_stage_example.frag.iplr", uniform_data);
66 ABSL_ASSERT_OK(effect);
67 paint.setColorSource(effect.value());
68
69 DisplayListBuilder builder;
70 builder.Save();
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);
75 builder.Restore();
76
77 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
78}
79
80TEST_P(AiksTest, DrawPaintTransformsBounds) {
81 struct FragUniforms {
82 Size size;
83 } frag_uniforms = {.size = Size::MakeWH(400, 400)};
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));
87
88 DlPaint paint;
89 auto effect = MakeRuntimeEffect(this, "gradient.frag.iplr", uniform_data);
90 ABSL_ASSERT_OK(effect);
91 paint.setColorSource(effect.value());
92
93 DisplayListBuilder builder;
94 builder.Save();
95 builder.Scale(GetContentScale().x, GetContentScale().y);
96 builder.DrawPaint(paint);
97 builder.Restore();
98
99 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
100}
101
102TEST_P(AiksTest, CanRenderRuntimeEffectFilter) {
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 =
107 runtime_stages_result.value()[GetRuntimeStageBackend()];
108 ASSERT_TRUE(runtime_stage);
109 ASSERT_TRUE(runtime_stage->IsDirty());
110
111 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
112 nullptr,
113 };
114 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
115 uniform_data->resize(sizeof(Vector2));
116
117 DlPaint paint;
118 paint.setColor(DlColor::kAqua());
120 DlRuntimeEffectImpeller::Make(runtime_stage), sampler_inputs,
121 uniform_data));
122
123 DisplayListBuilder builder;
124 builder.DrawRect(DlRect::MakeXYWH(0, 0, 400, 400), paint);
125
126 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
127}
128
129TEST_P(AiksTest, RuntimeEffectWithInvalidSamplerDoesNotCrash) {
130 ScopedValidationDisable disable_validation;
131
132 // Create a sampler that is not usable as an input to the runtime effect.
133 std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
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,
139 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
140 linear,
141 };
142
143 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
144 uniform_data->resize(sizeof(Vector2));
145
146 DlPaint paint;
147 auto effect =
148 MakeRuntimeEffect(this, "runtime_stage_filter_example.frag.iplr",
149 uniform_data, sampler_inputs);
150 ABSL_ASSERT_OK(effect);
151 paint.setColorSource(effect.value());
152
153 DisplayListBuilder builder;
154 builder.DrawPaint(paint);
155
156 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
157}
158
159TEST_P(AiksTest, ComposePaintRuntimeOuter) {
160 DisplayListBuilder builder;
161 DlPaint background;
162 background.setColor(DlColor(1.0, 0.1, 0.1, 0.1, DlColorSpace::kSRGB));
163 builder.DrawPaint(background);
164
165 DlPaint paint;
166 paint.setColor(DlColor::kGreen());
167 float matrix[] = {
168 0, 1, 0, 0, 0, //
169 1, 0, 0, 0, 0, //
170 0, 0, 1, 0, 0, //
171 0, 0, 0, 1, 0 //
172 };
173 std::shared_ptr<DlImageFilter> color_filter =
175
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 =
180 runtime_stages_result.value()[GetRuntimeStageBackend()];
181 ASSERT_TRUE(runtime_stage);
182 ASSERT_TRUE(runtime_stage->IsDirty());
183
184 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
185 nullptr,
186 };
187 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
188 uniform_data->resize(sizeof(Vector2));
189
190 auto runtime_filter = DlImageFilter::MakeRuntimeEffect(
191 DlRuntimeEffectImpeller::Make(runtime_stage), sampler_inputs,
192 uniform_data);
193
194 builder.Translate(50, 50);
195 builder.Scale(0.7, 0.7);
196
197 paint.setImageFilter(
198 DlImageFilter::MakeCompose(runtime_filter, color_filter));
199 auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
200 builder.DrawImage(image, DlPoint(100.0, 100.0),
201 DlImageSampling::kNearestNeighbor, &paint);
202
203 DlPaint green;
204 green.setColor(DlColor::kGreen());
205 builder.DrawLine({100, 100}, {200, 100}, green);
206 builder.DrawLine({100, 100}, {100, 200}, green);
207
208 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
209}
210
211TEST_P(AiksTest, ComposePaintRuntimeInner) {
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 =
216 runtime_stages_result.value()[GetRuntimeStageBackend()];
217 ASSERT_TRUE(runtime_stage);
218 ASSERT_TRUE(runtime_stage->IsDirty());
219 Scalar xoffset = 50;
220 Scalar yoffset = 50;
221 Scalar xscale = 0.7;
222 Scalar yscale = 0.7;
223 bool compare = false;
224
225 auto callback = [&]() -> sk_sp<DisplayList> {
226 if (AiksTest::ImGuiBegin("Controls", nullptr,
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);
233 ImGui::End();
234 }
235 DisplayListBuilder builder;
236 DlPaint background;
237 background.setColor(DlColor(1.0, 0.1, 0.1, 0.1, DlColorSpace::kSRGB));
238 builder.DrawPaint(background);
239
240 DlPaint paint;
241 paint.setColor(DlColor::kGreen());
242 float matrix[] = {
243 0, 1, 0, 0, 0, //
244 1, 0, 0, 0, 0, //
245 0, 0, 1, 0, 0, //
246 0, 0, 0, 1, 0 //
247 };
248 std::shared_ptr<DlImageFilter> color_filter =
250
251 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
252 nullptr,
253 };
254 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
255 uniform_data->resize(sizeof(Vector2));
256
257 auto runtime_filter = DlImageFilter::MakeRuntimeEffect(
258 DlRuntimeEffectImpeller::Make(runtime_stage), sampler_inputs,
259 uniform_data);
260
261 builder.Translate(xoffset, yoffset);
262 builder.Scale(xscale, yscale);
263
264 paint.setImageFilter(
265 DlImageFilter::MakeCompose(color_filter, runtime_filter));
266 auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
267 builder.DrawImage(image, DlPoint(100.0, 100.0),
268 DlImageSampling::kNearestNeighbor, &paint);
269
270 if (compare) {
271 paint.setImageFilter(
272 DlImageFilter::MakeCompose(runtime_filter, color_filter));
273 builder.DrawImage(image, DlPoint(800.0, 100.0),
274 DlImageSampling::kNearestNeighbor, &paint);
275
276 paint.setImageFilter(runtime_filter);
277 builder.DrawImage(image, DlPoint(100.0, 800.0),
278 DlImageSampling::kNearestNeighbor, &paint);
279 }
280
281 DlPaint green;
282 green.setColor(DlColor::kGreen());
283 builder.DrawLine({100, 100}, {200, 100}, green);
284 builder.DrawLine({100, 100}, {100, 200}, green);
285 if (compare) {
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);
290 }
291
292 return builder.Build();
293 };
294
295 ASSERT_TRUE(OpenPlaygroundHere(callback));
296}
297
298TEST_P(AiksTest, ComposeBackdropRuntimeOuterBlurInner) {
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 =
303 runtime_stages_result.value()[GetRuntimeStageBackend()];
304 ASSERT_TRUE(runtime_stage);
305 ASSERT_TRUE(runtime_stage->IsDirty());
306 Scalar sigma = 20.0;
307
308 auto callback = [&]() -> sk_sp<DisplayList> {
309 if (AiksTest::ImGuiBegin("Controls", nullptr,
310 ImGuiWindowFlags_AlwaysAutoResize)) {
311 ImGui::SliderFloat("sigma", &sigma, 0, 20);
312 ImGui::End();
313 }
314 DisplayListBuilder builder;
315 DlPaint background;
316 background.setColor(DlColor(1.0, 0.1, 0.1, 0.1, DlColorSpace::kSRGB));
317 builder.DrawPaint(background);
318
319 auto blur_filter =
320 DlImageFilter::MakeBlur(sigma, sigma, DlTileMode::kClamp);
321
322 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
323 nullptr,
324 };
325
326 struct FragUniforms {
328 Vector2 origin;
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));
333
334 auto runtime_filter = DlImageFilter::MakeRuntimeEffect(
335 DlRuntimeEffectImpeller::Make(runtime_stage), sampler_inputs,
336 uniform_data);
337
338 auto backdrop_filter = DlImageFilter::MakeCompose(/*outer=*/runtime_filter,
339 /*inner=*/blur_filter);
340
341 DlPaint paint;
342 auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
343 builder.DrawImage(image, DlPoint(100.0, 100.0),
344 DlImageSampling::kNearestNeighbor, &paint);
345
346 DlPaint save_paint;
347 save_paint.setBlendMode(DlBlendMode::kSrc);
348 builder.SaveLayer(std::nullopt, &save_paint, backdrop_filter.get());
349 builder.Restore();
350
351 DlPaint green;
352 green.setColor(DlColor::kGreen());
353 builder.DrawLine({100, 100}, {200, 100}, green);
354 builder.DrawLine({100, 100}, {100, 200}, green);
355
356 return builder.Build();
357 };
358
359 ASSERT_TRUE(OpenPlaygroundHere(callback));
360}
361
362TEST_P(AiksTest, ComposeBackdropRuntimeOuterBlurInnerSmallSigma) {
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 =
367 runtime_stages_result.value()[GetRuntimeStageBackend()];
368 ASSERT_TRUE(runtime_stage);
369 ASSERT_TRUE(runtime_stage->IsDirty());
370 Scalar sigma = 5.0;
371
372 auto callback = [&]() -> sk_sp<DisplayList> {
373 if (AiksTest::ImGuiBegin("Controls", nullptr,
374 ImGuiWindowFlags_AlwaysAutoResize)) {
375 ImGui::SliderFloat("sigma", &sigma, 0, 20);
376 ImGui::End();
377 }
378 DisplayListBuilder builder;
379 DlPaint background;
380 background.setColor(DlColor(1.0, 0.1, 0.1, 0.1, DlColorSpace::kSRGB));
381 builder.DrawPaint(background);
382
383 auto blur_filter =
384 DlImageFilter::MakeBlur(sigma, sigma, DlTileMode::kClamp);
385
386 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
387 nullptr,
388 };
389 struct FragUniforms {
391 Vector2 origin;
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));
396
397 auto runtime_filter = DlImageFilter::MakeRuntimeEffect(
398 DlRuntimeEffectImpeller::Make(runtime_stage), sampler_inputs,
399 uniform_data);
400
401 auto backdrop_filter = DlImageFilter::MakeCompose(/*outer=*/runtime_filter,
402 /*inner=*/blur_filter);
403
404 DlPaint paint;
405 auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
406 builder.DrawImage(image, DlPoint(100.0, 100.0),
407 DlImageSampling::kNearestNeighbor, &paint);
408
409 DlPaint save_paint;
410 save_paint.setBlendMode(DlBlendMode::kSrc);
411 builder.SaveLayer(std::nullopt, &save_paint, backdrop_filter.get());
412 builder.Restore();
413
414 DlPaint green;
415 green.setColor(DlColor::kGreen());
416 builder.DrawLine({100, 100}, {200, 100}, green);
417 builder.DrawLine({100, 100}, {100, 200}, green);
418
419 return builder.Build();
420 };
421
422 ASSERT_TRUE(OpenPlaygroundHere(callback));
423}
424
425TEST_P(AiksTest, ClippedComposeBackdropRuntimeOuterBlurInnerSmallSigma) {
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 =
430 runtime_stages_result.value()[GetRuntimeStageBackend()];
431 ASSERT_TRUE(runtime_stage);
432 ASSERT_TRUE(runtime_stage->IsDirty());
433 Scalar sigma = 5.0;
434 Vector2 clip_origin = Vector2(20.f, 20.f);
435 Vector2 clip_size = Vector2(300, 300);
436 Vector2 circle_origin = Vector2(30.f, 30.f);
437
438 auto callback = [&]() -> sk_sp<DisplayList> {
439 if (AiksTest::ImGuiBegin("Controls", nullptr,
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);
448 ImGui::End();
449 }
450 DisplayListBuilder builder;
451 DlPaint background;
452 background.setColor(DlColor(1.0, 0.1, 0.1, 0.1, DlColorSpace::kSRGB));
453 builder.DrawPaint(background);
454
455 auto blur_filter =
456 DlImageFilter::MakeBlur(sigma, sigma, DlTileMode::kClamp);
457
458 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
459 nullptr,
460 };
461 struct FragUniforms {
463 Vector2 origin;
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));
468
469 auto runtime_filter = DlImageFilter::MakeRuntimeEffect(
470 DlRuntimeEffectImpeller::Make(runtime_stage), sampler_inputs,
471 uniform_data);
472
473 auto backdrop_filter = DlImageFilter::MakeCompose(/*outer=*/runtime_filter,
474 /*inner=*/blur_filter);
475
476 builder.ClipRect(DlRect::MakeXYWH(clip_origin.x, clip_origin.y, clip_size.x,
477 clip_size.y));
478
479 DlPaint paint;
480 auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
481 builder.DrawImage(image, DlPoint(100.0, 100.0),
482 DlImageSampling::kNearestNeighbor, &paint);
483
484 DlPaint save_paint;
485 save_paint.setBlendMode(DlBlendMode::kSrc);
486 builder.SaveLayer(std::nullopt, &save_paint, backdrop_filter.get());
487 builder.Restore();
488
489 DlPaint green;
490 green.setColor(DlColor::kGreen());
491 builder.DrawLine({100, 100}, {200, 100}, green);
492 builder.DrawLine({100, 100}, {100, 200}, green);
493
494 return builder.Build();
495 };
496
497 ASSERT_TRUE(OpenPlaygroundHere(callback));
498}
499
500TEST_P(AiksTest, ClippedBackdropFilterWithShader) {
501 struct FragUniforms {
502 Vector2 uSize;
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));
507
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 =
512 runtime_stages_result.value()[GetRuntimeStageBackend()];
513 ASSERT_TRUE(runtime_stage);
514 ASSERT_TRUE(runtime_stage->IsDirty());
515
516 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
517 nullptr,
518 };
519
520 auto runtime_filter = DlImageFilter::MakeRuntimeEffect(
521 DlRuntimeEffectImpeller::Make(runtime_stage), sampler_inputs,
522 uniform_data);
523
524 DisplayListBuilder builder;
525
526 // Draw a background so the backdrop filter has something to affect
527 DlPaint background_paint;
528 background_paint.setColor(DlColor::kWhite());
529 builder.DrawPaint(background_paint);
530
531 // Draw some pattern to verify the filter effect
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);
537
538 builder.Save();
539
540 // Replicate the clip rect (inset by 66)
541 // Assuming a 400x400 screen, inset 66 gives roughly 66, 66, 268, 268
542 builder.ClipRect(DlRect::MakeXYWH(66, 66, 268, 268));
543
544 DlPaint save_paint;
545 // The Flutter code uses a backdrop filter layer.
546 // In DisplayList, this corresponds to SaveLayer with a backdrop filter.
547 builder.SaveLayer(std::nullopt, &save_paint, runtime_filter.get());
548
549 // The child was empty in the Flutter example, so we don't draw anything
550 // inside the SaveLayer
551
552 builder.Restore(); // Restore SaveLayer
553 builder.Restore(); // Restore Save (Clip)
554
555 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
556}
557
558TEST_P(AiksTest, RuntimeEffectImageFilterRotated) {
559 auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
560 auto size = image->GetBounds().GetSize();
561
562 struct FragUniforms {
563 Size size;
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));
568
569 auto runtime_stages_result = OpenAssetAsRuntimeStage("gradient.frag.iplr");
570 ABSL_ASSERT_OK(runtime_stages_result);
571 std::shared_ptr<RuntimeStage> runtime_stage =
572 runtime_stages_result.value()[GetRuntimeStageBackend()];
573 ASSERT_TRUE(runtime_stage);
574 ASSERT_TRUE(runtime_stage->IsDirty());
575
576 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
577 nullptr,
578 };
579
580 auto runtime_filter = DlImageFilter::MakeRuntimeEffect(
581 DlRuntimeEffectImpeller::Make(runtime_stage), sampler_inputs,
582 uniform_data);
583
584 Scalar rotation = 45;
585
586 auto callback = [&]() -> sk_sp<DisplayList> {
587 if (AiksTest::ImGuiBegin("Controls", nullptr,
588 ImGuiWindowFlags_AlwaysAutoResize)) {
589 ImGui::SliderFloat("rotation", &rotation, 0, 360);
590 ImGui::End();
591 }
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);
596
597 DlPaint paint;
598 paint.setImageFilter(runtime_filter);
599 builder.DrawImage(image, DlPoint(0.0, 0.0),
600 DlImageSampling::kNearestNeighbor, &paint);
601
602 return builder.Build();
603 };
604
605 ASSERT_TRUE(OpenPlaygroundHere(callback));
606}
607
608TEST_P(AiksTest, RuntimeEffectVectorArray) {
609 constexpr float kDimension = 400.0f;
610 struct FragUniforms {
611 Vector2 iResolution;
612 Vector4 iValues;
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));
618
619 DlPaint paint;
620 auto effect = MakeRuntimeEffect(this, "runtime_stage_vector_array.frag.iplr",
621 uniform_data);
622 ABSL_ASSERT_OK(effect);
623 paint.setColorSource(effect.value());
624
625 DisplayListBuilder builder;
626 builder.DrawRect(DlRect::MakeXYWH(0, 0, kDimension, kDimension), paint);
627
628 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
629}
630
631} // namespace testing
632} // 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 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: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