Flutter Engine
 
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
15
16namespace impeller {
17namespace testing {
18
19using namespace flutter;
20
21namespace {
22std::shared_ptr<DlColorSource> MakeRuntimeEffect(
23 AiksTest* test,
24 std::string_view name,
25 const std::shared_ptr<std::vector<uint8_t>>& uniform_data = {},
26 const std::vector<std::shared_ptr<DlColorSource>>& samplers = {}) {
27 auto runtime_stages = test->OpenAssetAsRuntimeStage(name.data());
28 auto runtime_stage = runtime_stages[PlaygroundBackendToRuntimeStageBackend(
29 test->GetBackend())];
30 FML_CHECK(runtime_stage);
31 FML_CHECK(runtime_stage->IsDirty());
32
33 auto dl_runtime_effect = DlRuntimeEffectImpeller::Make(runtime_stage);
34
35 return DlColorSource::MakeRuntimeEffect(dl_runtime_effect, samplers,
36 uniform_data);
37}
38} // namespace
39
40// Regression test for https://github.com/flutter/flutter/issues/126701 .
41TEST_P(AiksTest, CanRenderClippedRuntimeEffects) {
42 struct FragUniforms {
43 Vector2 iResolution;
44 Scalar iTime;
45 } frag_uniforms = {.iResolution = Vector2(400, 400), .iTime = 100.0};
46 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
47 uniform_data->resize(sizeof(FragUniforms));
48 memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
49
50 DlPaint paint;
51 paint.setColorSource(
52 MakeRuntimeEffect(this, "runtime_stage_example.frag.iplr", uniform_data));
53
54 DisplayListBuilder builder;
55 builder.Save();
56 builder.ClipRoundRect(
57 DlRoundRect::MakeRectXY(DlRect::MakeXYWH(0, 0, 400, 400), 10.0, 10.0),
58 DlClipOp::kIntersect);
59 builder.DrawRect(DlRect::MakeXYWH(0, 0, 400, 400), paint);
60 builder.Restore();
61
62 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
63}
64
65TEST_P(AiksTest, DrawPaintTransformsBounds) {
66 struct FragUniforms {
67 Size size;
68 } frag_uniforms = {.size = Size::MakeWH(400, 400)};
69 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
70 uniform_data->resize(sizeof(FragUniforms));
71 memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
72
73 DlPaint paint;
74 paint.setColorSource(
75 MakeRuntimeEffect(this, "gradient.frag.iplr", uniform_data));
76
77 DisplayListBuilder builder;
78 builder.Save();
79 builder.Scale(GetContentScale().x, GetContentScale().y);
80 builder.DrawPaint(paint);
81 builder.Restore();
82
83 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
84}
85
86TEST_P(AiksTest, CanRenderRuntimeEffectFilter) {
87 auto runtime_stages =
88 OpenAssetAsRuntimeStage("runtime_stage_filter_example.frag.iplr");
89
90 std::shared_ptr<RuntimeStage> runtime_stage =
91 runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
92 ASSERT_TRUE(runtime_stage);
93 ASSERT_TRUE(runtime_stage->IsDirty());
94
95 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
96 nullptr,
97 };
98 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
99 uniform_data->resize(sizeof(Vector2));
100
101 DlPaint paint;
102 paint.setColor(DlColor::kAqua());
104 DlRuntimeEffectImpeller::Make(runtime_stage), sampler_inputs,
105 uniform_data));
106
107 DisplayListBuilder builder;
108 builder.DrawRect(DlRect::MakeXYWH(0, 0, 400, 400), paint);
109
110 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
111}
112
113TEST_P(AiksTest, RuntimeEffectWithInvalidSamplerDoesNotCrash) {
114 ScopedValidationDisable disable_validation;
115
116 // Create a sampler that is not usable as an input to the runtime effect.
117 std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
119 const float stops[2] = {0.0, 1.0};
120 auto linear = flutter::DlColorSource::MakeLinear({0.0, 0.0}, {300.0, 300.0},
121 2, colors.data(), stops,
123 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
124 linear,
125 };
126
127 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
128 uniform_data->resize(sizeof(Vector2));
129
130 DlPaint paint;
131 paint.setColorSource(
132 MakeRuntimeEffect(this, "runtime_stage_filter_example.frag.iplr",
133 uniform_data, sampler_inputs));
134
135 DisplayListBuilder builder;
136 builder.DrawPaint(paint);
137
138 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
139}
140
141TEST_P(AiksTest, ComposePaintRuntimeOuter) {
142 DisplayListBuilder builder;
143 DlPaint background;
144 background.setColor(DlColor(1.0, 0.1, 0.1, 0.1, DlColorSpace::kSRGB));
145 builder.DrawPaint(background);
146
147 DlPaint paint;
148 paint.setColor(DlColor::kGreen());
149 float matrix[] = {
150 0, 1, 0, 0, 0, //
151 1, 0, 0, 0, 0, //
152 0, 0, 1, 0, 0, //
153 0, 0, 0, 1, 0 //
154 };
155 std::shared_ptr<DlImageFilter> color_filter =
157
158 auto runtime_stages =
159 OpenAssetAsRuntimeStage("runtime_stage_filter_warp.frag.iplr");
160
161 std::shared_ptr<RuntimeStage> runtime_stage =
162 runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
163 ASSERT_TRUE(runtime_stage);
164 ASSERT_TRUE(runtime_stage->IsDirty());
165
166 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
167 nullptr,
168 };
169 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
170 uniform_data->resize(sizeof(Vector2));
171
172 auto runtime_filter = DlImageFilter::MakeRuntimeEffect(
173 DlRuntimeEffectImpeller::Make(runtime_stage), sampler_inputs,
174 uniform_data);
175
176 builder.Translate(50, 50);
177 builder.Scale(0.7, 0.7);
178
179 paint.setImageFilter(
180 DlImageFilter::MakeCompose(runtime_filter, color_filter));
181 auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
182 builder.DrawImage(image, DlPoint(100.0, 100.0),
183 DlImageSampling::kNearestNeighbor, &paint);
184
185 DlPaint green;
186 green.setColor(DlColor::kGreen());
187 builder.DrawLine({100, 100}, {200, 100}, green);
188 builder.DrawLine({100, 100}, {100, 200}, green);
189
190 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
191}
192
193TEST_P(AiksTest, ComposePaintRuntimeInner) {
194 auto runtime_stages =
195 OpenAssetAsRuntimeStage("runtime_stage_filter_warp.frag.iplr");
196
197 std::shared_ptr<RuntimeStage> runtime_stage =
198 runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
199 ASSERT_TRUE(runtime_stage);
200 ASSERT_TRUE(runtime_stage->IsDirty());
201 Scalar xoffset = 50;
202 Scalar yoffset = 50;
203 Scalar xscale = 0.7;
204 Scalar yscale = 0.7;
205 bool compare = false;
206
207 auto callback = [&]() -> sk_sp<DisplayList> {
208 if (AiksTest::ImGuiBegin("Controls", nullptr,
209 ImGuiWindowFlags_AlwaysAutoResize)) {
210 ImGui::SliderFloat("xoffset", &xoffset, -50, 50);
211 ImGui::SliderFloat("yoffset", &yoffset, -50, 50);
212 ImGui::SliderFloat("xscale", &xscale, 0, 1);
213 ImGui::SliderFloat("yscale", &yscale, 0, 1);
214 ImGui::Checkbox("compare", &compare);
215 ImGui::End();
216 }
217 DisplayListBuilder builder;
218 DlPaint background;
219 background.setColor(DlColor(1.0, 0.1, 0.1, 0.1, DlColorSpace::kSRGB));
220 builder.DrawPaint(background);
221
222 DlPaint paint;
223 paint.setColor(DlColor::kGreen());
224 float matrix[] = {
225 0, 1, 0, 0, 0, //
226 1, 0, 0, 0, 0, //
227 0, 0, 1, 0, 0, //
228 0, 0, 0, 1, 0 //
229 };
230 std::shared_ptr<DlImageFilter> color_filter =
232
233 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
234 nullptr,
235 };
236 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
237 uniform_data->resize(sizeof(Vector2));
238
239 auto runtime_filter = DlImageFilter::MakeRuntimeEffect(
240 DlRuntimeEffectImpeller::Make(runtime_stage), sampler_inputs,
241 uniform_data);
242
243 builder.Translate(xoffset, yoffset);
244 builder.Scale(xscale, yscale);
245
246 paint.setImageFilter(
247 DlImageFilter::MakeCompose(color_filter, runtime_filter));
248 auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
249 builder.DrawImage(image, DlPoint(100.0, 100.0),
250 DlImageSampling::kNearestNeighbor, &paint);
251
252 if (compare) {
253 paint.setImageFilter(
254 DlImageFilter::MakeCompose(runtime_filter, color_filter));
255 builder.DrawImage(image, DlPoint(800.0, 100.0),
256 DlImageSampling::kNearestNeighbor, &paint);
257
258 paint.setImageFilter(runtime_filter);
259 builder.DrawImage(image, DlPoint(100.0, 800.0),
260 DlImageSampling::kNearestNeighbor, &paint);
261 }
262
263 DlPaint green;
264 green.setColor(DlColor::kGreen());
265 builder.DrawLine({100, 100}, {200, 100}, green);
266 builder.DrawLine({100, 100}, {100, 200}, green);
267 if (compare) {
268 builder.DrawLine({800, 100}, {900, 100}, green);
269 builder.DrawLine({800, 100}, {800, 200}, green);
270 builder.DrawLine({100, 800}, {200, 800}, green);
271 builder.DrawLine({100, 800}, {100, 900}, green);
272 }
273
274 return builder.Build();
275 };
276
277 ASSERT_TRUE(OpenPlaygroundHere(callback));
278}
279
280TEST_P(AiksTest, ComposeBackdropRuntimeOuterBlurInner) {
281 auto runtime_stages =
282 OpenAssetAsRuntimeStage("runtime_stage_filter_circle.frag.iplr");
283
284 std::shared_ptr<RuntimeStage> runtime_stage =
285 runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
286 ASSERT_TRUE(runtime_stage);
287 ASSERT_TRUE(runtime_stage->IsDirty());
288 Scalar sigma = 20.0;
289
290 auto callback = [&]() -> sk_sp<DisplayList> {
291 if (AiksTest::ImGuiBegin("Controls", nullptr,
292 ImGuiWindowFlags_AlwaysAutoResize)) {
293 ImGui::SliderFloat("sigma", &sigma, 0, 20);
294 ImGui::End();
295 }
296 DisplayListBuilder builder;
297 DlPaint background;
298 background.setColor(DlColor(1.0, 0.1, 0.1, 0.1, DlColorSpace::kSRGB));
299 builder.DrawPaint(background);
300
301 auto blur_filter =
302 DlImageFilter::MakeBlur(sigma, sigma, DlTileMode::kClamp);
303
304 std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
305 nullptr,
306 };
307 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
308 uniform_data->resize(sizeof(Vector2));
309
310 auto runtime_filter = DlImageFilter::MakeRuntimeEffect(
311 DlRuntimeEffectImpeller::Make(runtime_stage), sampler_inputs,
312 uniform_data);
313
314 auto backdrop_filter = DlImageFilter::MakeCompose(/*outer=*/runtime_filter,
315 /*inner=*/blur_filter);
316
317 DlPaint paint;
318 auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
319 builder.DrawImage(image, DlPoint(100.0, 100.0),
320 DlImageSampling::kNearestNeighbor, &paint);
321
322 DlPaint save_paint;
323 save_paint.setBlendMode(DlBlendMode::kSrc);
324 builder.SaveLayer(std::nullopt, &save_paint, backdrop_filter.get());
325 builder.Restore();
326
327 DlPaint green;
328 green.setColor(DlColor::kGreen());
329 builder.DrawLine({100, 100}, {200, 100}, green);
330 builder.DrawLine({100, 100}, {100, 200}, green);
331
332 return builder.Build();
333 };
334
335 ASSERT_TRUE(OpenPlaygroundHere(callback));
336}
337
338} // namespace testing
339} // namespace impeller
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 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
#define FML_CHECK(condition)
Definition logging.h:104
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:331
float Scalar
Definition scalar.h:19
constexpr RuntimeStageBackend PlaygroundBackendToRuntimeStageBackend(PlaygroundBackend backend)
Definition playground.h:33
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