| Flutter Impeller |

aiks_dl_vertices_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 "display_list/dl_sampling_options.h"
6 #include "display_list/dl_tile_mode.h"
7 #include "display_list/dl_vertices.h"
8 #include "flutter/impeller/aiks/aiks_unittests.h"
9
10 #include "flutter/display_list/dl_blend_mode.h"
11 #include "flutter/display_list/dl_builder.h"
12 #include "flutter/display_list/dl_color.h"
13 #include "flutter/display_list/dl_paint.h"
14 #include "flutter/testing/testing.h"
15 #include "impeller/display_list/dl_image_impeller.h"
16
17 namespace impeller {
18 namespace testing {
19
20 using namespace flutter;
21
22 namespace {
23 std::shared_ptr<DlVertices> MakeVertices(
24 DlVertexMode mode,
25 std::vector<SkPoint> vertices,
26 std::vector<uint16_t> indices,
27 std::vector<SkPoint> texture_coordinates,
28 std::vector<DlColor> colors) {
29 DlVertices::Builder::Flags flags(
30 {{texture_coordinates.size() > 0, colors.size() > 0}});
31 DlVertices::Builder builder(mode, vertices.size(), flags, indices.size());
32 if (colors.size() > 0) {
33 builder.store_colors(colors.data());
34 }
35 if (texture_coordinates.size() > 0) {
36 builder.store_texture_coordinates(texture_coordinates.data());
37 }
38 if (indices.size() > 0) {
39 builder.store_indices(indices.data());
40 }
41 builder.store_vertices(vertices.data());
42 return builder.build();
43 }
44 }; // namespace
45
46 // Regression test for https://github.com/flutter/flutter/issues/135441 .
47 TEST_P(AiksTest, VerticesGeometryUVPositionData) {
48 DisplayListBuilder builder;
49 DlPaint paint;
50 auto image =
51 DlImageImpeller::Make(CreateTextureForFixture("table_mountain_nx.png"));
52 auto size = image->impeller_texture()->GetSize();
53
54 paint.setColorSource(std::make_shared<DlImageColorSource>(
55 image, DlTileMode::kClamp, DlTileMode::kClamp));
56
57 std::vector<SkPoint> vertex_coordinates = {SkPoint::Make(0, 0),
58 SkPoint::Make(size.width, 0),
59 SkPoint::Make(0, size.height)};
60 auto vertices = MakeVertices(DlVertexMode::kTriangleStrip, vertex_coordinates,
61 {0, 1, 2}, {}, {});
62
63 builder.DrawVertices(vertices, DlBlendMode::kSrcOver, paint);
64 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
65 }
66
67 // Regression test for https://github.com/flutter/flutter/issues/135441 .
68 TEST_P(AiksTest, VerticesGeometryUVPositionDataWithTranslate) {
69 DisplayListBuilder builder;
70 DlPaint paint;
71 auto image =
72 DlImageImpeller::Make(CreateTextureForFixture("table_mountain_nx.png"));
73 auto size = image->impeller_texture()->GetSize();
74
75 SkMatrix matrix;
76 matrix.setTranslateX(100);
77 matrix.setTranslateY(100);
78 paint.setColorSource(std::make_shared<DlImageColorSource>(
79 image, DlTileMode::kClamp, DlTileMode::kClamp, DlImageSampling::kLinear,
80 &matrix));
81
82 std::vector<SkPoint> positions = {SkPoint::Make(0, 0),
83 SkPoint::Make(size.width, 0),
84 SkPoint::Make(0, size.height)};
85 auto vertices =
86 MakeVertices(DlVertexMode::kTriangleStrip, positions, {0, 1, 2}, {}, {});
87
88 builder.DrawVertices(vertices, DlBlendMode::kSrcOver, paint);
89 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
90 }
91
92 // Regression test for https://github.com/flutter/flutter/issues/145707
93 TEST_P(AiksTest, VerticesGeometryColorUVPositionData) {
94 DisplayListBuilder builder;
95 DlPaint paint;
96 auto image =
97 DlImageImpeller::Make(CreateTextureForFixture("table_mountain_nx.png"));
98 auto size = image->impeller_texture()->GetSize();
99
100 paint.setColorSource(std::make_shared<DlImageColorSource>(
101 image, DlTileMode::kClamp, DlTileMode::kClamp));
102
103 std::vector<SkPoint> positions = {
104 SkPoint::Make(0, 0), SkPoint::Make(size.width, 0),
105 SkPoint::Make(0, size.height), SkPoint::Make(size.width, 0),
106 SkPoint::Make(0, 0), SkPoint::Make(size.width, size.height),
107 };
108 std::vector<DlColor> colors = {
109 DlColor::kRed().withAlpha(128), DlColor::kBlue().withAlpha(128),
110 DlColor::kGreen().withAlpha(128), DlColor::kRed().withAlpha(128),
111 DlColor::kBlue().withAlpha(128), DlColor::kGreen().withAlpha(128),
112 };
113
114 auto vertices =
115 MakeVertices(DlVertexMode::kTriangles, positions, {}, {}, colors);
116
117 builder.DrawVertices(vertices, DlBlendMode::kDstOver, paint);
118 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
119 }
120
121 TEST_P(AiksTest, VerticesGeometryColorUVPositionDataAdvancedBlend) {
122 DisplayListBuilder builder;
123 DlPaint paint;
124 auto image =
125 DlImageImpeller::Make(CreateTextureForFixture("table_mountain_nx.png"));
126 auto size = image->impeller_texture()->GetSize();
127
128 paint.setColorSource(std::make_shared<DlImageColorSource>(
129 image, DlTileMode::kClamp, DlTileMode::kClamp));
130
131 std::vector<SkPoint> positions = {
132 SkPoint::Make(0, 0), SkPoint::Make(size.width, 0),
133 SkPoint::Make(0, size.height), SkPoint::Make(size.width, 0),
134 SkPoint::Make(0, 0), SkPoint::Make(size.width, size.height),
135 };
136 std::vector<DlColor> colors = {
137 DlColor::kRed().modulateOpacity(0.5),
138 DlColor::kBlue().modulateOpacity(0.5),
139 DlColor::kGreen().modulateOpacity(0.5),
140 DlColor::kRed().modulateOpacity(0.5),
141 DlColor::kBlue().modulateOpacity(0.5),
142 DlColor::kGreen().modulateOpacity(0.5),
143 };
144
145 auto vertices =
146 MakeVertices(DlVertexMode::kTriangles, positions, {}, {}, colors);
147
148 builder.DrawVertices(vertices, DlBlendMode::kColorBurn, paint);
149 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
150 }
151
152 // Draw a hexagon using triangle fan
153 TEST_P(AiksTest, CanConvertTriangleFanToTriangles) {
154 constexpr Scalar hexagon_radius = 125;
155 auto hex_start = Point(200.0, -hexagon_radius + 200.0);
156 auto center_to_flat = 1.73 / 2 * hexagon_radius;
157
158 // clang-format off
159 std::vector<SkPoint> vertices = {
160 SkPoint::Make(hex_start.x, hex_start.y),
161 SkPoint::Make(hex_start.x + center_to_flat, hex_start.y + 0.5 * hexagon_radius),
162 SkPoint::Make(hex_start.x + center_to_flat, hex_start.y + 1.5 * hexagon_radius),
163 SkPoint::Make(hex_start.x + center_to_flat, hex_start.y + 1.5 * hexagon_radius),
164 SkPoint::Make(hex_start.x, hex_start.y + 2 * hexagon_radius),
165 SkPoint::Make(hex_start.x, hex_start.y + 2 * hexagon_radius),
166 SkPoint::Make(hex_start.x - center_to_flat, hex_start.y + 1.5 * hexagon_radius),
167 SkPoint::Make(hex_start.x - center_to_flat, hex_start.y + 1.5 * hexagon_radius),
168 SkPoint::Make(hex_start.x - center_to_flat, hex_start.y + 0.5 * hexagon_radius)
169 };
170 // clang-format on
171 auto paint = flutter::DlPaint(flutter::DlColor::kDarkGrey());
172 auto dl_vertices = flutter::DlVertices::Make(
173 flutter::DlVertexMode::kTriangleFan, vertices.size(), vertices.data(),
174 nullptr, nullptr);
175 flutter::DisplayListBuilder builder;
176 builder.DrawVertices(dl_vertices, flutter::DlBlendMode::kSrcOver, paint);
177 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
178 }
179
180 TEST_P(AiksTest, DrawVerticesSolidColorTrianglesWithoutIndices) {
181 // Use negative coordinates and then scale the transform by -1, -1 to make
182 // sure coverage is taking the transform into account.
183 std::vector<SkPoint> positions = {SkPoint::Make(-100, -300),
184 SkPoint::Make(-200, -100),
185 SkPoint::Make(-300, -300)};
186 std::vector<flutter::DlColor> colors = {flutter::DlColor::kWhite(),
187 flutter::DlColor::kGreen(),
188 flutter::DlColor::kWhite()};
189
190 auto vertices = flutter::DlVertices::Make(
191 flutter::DlVertexMode::kTriangles, 3, positions.data(),
192 /*texture_coordinates=*/nullptr, colors.data());
193
194 flutter::DisplayListBuilder builder;
195 flutter::DlPaint paint;
196
197 paint.setColor(flutter::DlColor::kRed().modulateOpacity(0.5));
198 builder.Scale(-1, -1);
199 builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
200
201 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
202 }
203
204 TEST_P(AiksTest, DrawVerticesLinearGradientWithoutIndices) {
205 std::vector<SkPoint> positions = {SkPoint::Make(100, 300),
206 SkPoint::Make(200, 100),
207 SkPoint::Make(300, 300)};
208
209 auto vertices = flutter::DlVertices::Make(
210 flutter::DlVertexMode::kTriangles, 3, positions.data(),
211 /*texture_coordinates=*/nullptr, /*colors=*/nullptr);
212
213 std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
214 flutter::DlColor::kRed()};
215 const float stops[2] = {0.0, 1.0};
216
217 auto linear = flutter::DlColorSource::MakeLinear(
218 {100.0, 100.0}, {300.0, 300.0}, 2, colors.data(), stops,
219 flutter::DlTileMode::kRepeat);
220
221 flutter::DisplayListBuilder builder;
222 flutter::DlPaint paint;
223
224 paint.setColorSource(linear);
225 builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
226
227 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
228 }
229
230 TEST_P(AiksTest, DrawVerticesLinearGradientWithTextureCoordinates) {
231 std::vector<SkPoint> positions = {SkPoint::Make(100, 300),
232 SkPoint::Make(200, 100),
233 SkPoint::Make(300, 300)};
234 std::vector<SkPoint> texture_coordinates = {SkPoint::Make(300, 100),
235 SkPoint::Make(100, 200),
236 SkPoint::Make(300, 300)};
237
238 auto vertices = flutter::DlVertices::Make(
239 flutter::DlVertexMode::kTriangles, 3, positions.data(),
240 texture_coordinates.data(), /*colors=*/nullptr);
241
242 std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
243 flutter::DlColor::kRed()};
244 const float stops[2] = {0.0, 1.0};
245
246 auto linear = flutter::DlColorSource::MakeLinear(
247 {100.0, 100.0}, {300.0, 300.0}, 2, colors.data(), stops,
248 flutter::DlTileMode::kRepeat);
249
250 flutter::DisplayListBuilder builder;
251 flutter::DlPaint paint;
252
253 paint.setColorSource(linear);
254 builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
255
256 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
257 }
258
259 TEST_P(AiksTest, DrawVerticesImageSourceWithTextureCoordinates) {
260 auto texture = CreateTextureForFixture("embarcadero.jpg");
261 auto dl_image = DlImageImpeller::Make(texture);
262 std::vector<SkPoint> positions = {SkPoint::Make(100, 300),
263 SkPoint::Make(200, 100),
264 SkPoint::Make(300, 300)};
265 std::vector<SkPoint> texture_coordinates = {
266 SkPoint::Make(0, 0), SkPoint::Make(100, 200), SkPoint::Make(200, 100)};
267
268 auto vertices = flutter::DlVertices::Make(
269 flutter::DlVertexMode::kTriangles, 3, positions.data(),
270 texture_coordinates.data(), /*colors=*/nullptr);
271
272 flutter::DisplayListBuilder builder;
273 flutter::DlPaint paint;
274
275 auto image_source = flutter::DlImageColorSource(
276 dl_image, flutter::DlTileMode::kRepeat, flutter::DlTileMode::kRepeat);
277
278 paint.setColorSource(&image_source);
279 builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
280
281 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
282 }
283
284 TEST_P(AiksTest,
285 DrawVerticesImageSourceWithTextureCoordinatesAndColorBlending) {
286 auto texture = CreateTextureForFixture("embarcadero.jpg");
287 auto dl_image = DlImageImpeller::Make(texture);
288 std::vector<SkPoint> positions = {SkPoint::Make(100, 300),
289 SkPoint::Make(200, 100),
290 SkPoint::Make(300, 300)};
291 std::vector<flutter::DlColor> colors = {flutter::DlColor::kWhite(),
292 flutter::DlColor::kGreen(),
293 flutter::DlColor::kWhite()};
294 std::vector<SkPoint> texture_coordinates = {
295 SkPoint::Make(0, 0), SkPoint::Make(100, 200), SkPoint::Make(200, 100)};
296
297 auto vertices = flutter::DlVertices::Make(
298 flutter::DlVertexMode::kTriangles, 3, positions.data(),
299 texture_coordinates.data(), colors.data());
300
301 flutter::DisplayListBuilder builder;
302 flutter::DlPaint paint;
303
304 auto image_source = flutter::DlImageColorSource(
305 dl_image, flutter::DlTileMode::kRepeat, flutter::DlTileMode::kRepeat);
306
307 paint.setColorSource(&image_source);
308 builder.DrawVertices(vertices, flutter::DlBlendMode::kModulate, paint);
309
310 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
311 }
312
313 TEST_P(AiksTest, DrawVerticesSolidColorTrianglesWithIndices) {
314 std::vector<SkPoint> positions = {
315 SkPoint::Make(100, 300), SkPoint::Make(200, 100), SkPoint::Make(300, 300),
316 SkPoint::Make(200, 500)};
317 std::vector<uint16_t> indices = {0, 1, 2, 0, 2, 3};
318
319 auto vertices = flutter::DlVertices::Make(
320 flutter::DlVertexMode::kTriangles, positions.size(), positions.data(),
321 /*texture_coordinates=*/nullptr, /*colors=*/nullptr, indices.size(),
322 indices.data());
323
324 flutter::DisplayListBuilder builder;
325 flutter::DlPaint paint;
326
327 paint.setColor(flutter::DlColor::kRed());
328 builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
329
330 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
331 }
332
333 TEST_P(AiksTest, DrawVerticesPremultipliesColors) {
334 std::vector<SkPoint> positions = {
335 SkPoint::Make(100, 300), SkPoint::Make(200, 100), SkPoint::Make(300, 300),
336 SkPoint::Make(200, 500)};
337 auto color = flutter::DlColor::kBlue().withAlpha(0x99);
338 std::vector<uint16_t> indices = {0, 1, 2, 0, 2, 3};
339 std::vector<flutter::DlColor> colors = {color, color, color, color};
340
341 auto vertices = flutter::DlVertices::Make(
342 flutter::DlVertexMode::kTriangles, positions.size(), positions.data(),
343 /*texture_coordinates=*/nullptr, colors.data(), indices.size(),
344 indices.data());
345
346 flutter::DisplayListBuilder builder;
347 flutter::DlPaint paint;
348 paint.setBlendMode(flutter::DlBlendMode::kSrcOver);
349 paint.setColor(flutter::DlColor::kRed());
350
351 builder.DrawRect(SkRect::MakeLTRB(0, 0, 400, 400), paint);
352 builder.DrawVertices(vertices, flutter::DlBlendMode::kDst, paint);
353
354 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
355 }
356
357 // All four vertices should form a solid red rectangle with no gaps.
358 // The blur rectangle drawn under them should not be visible.
359 TEST_P(AiksTest, DrawVerticesTextureCoordinatesWithFragmentShader) {
360 std::vector<SkPoint> positions_lt = {
361 SkPoint::Make(0, 0), //
362 SkPoint::Make(50, 0), //
363 SkPoint::Make(0, 50), //
364 SkPoint::Make(50, 50), //
365 };
366
367 auto vertices_lt = flutter::DlVertices::Make(
368 flutter::DlVertexMode::kTriangleStrip, positions_lt.size(),
369 positions_lt.data(),
370 /*texture_coordinates=*/positions_lt.data(), /*colors=*/nullptr,
371 /*index_count=*/0,
372 /*indices=*/nullptr);
373
374 std::vector<SkPoint> positions_rt = {
375 SkPoint::Make(50, 0), //
376 SkPoint::Make(100, 0), //
377 SkPoint::Make(50, 50), //
378 SkPoint::Make(100, 50), //
379 };
380
381 auto vertices_rt = flutter::DlVertices::Make(
382 flutter::DlVertexMode::kTriangleStrip, positions_rt.size(),
383 positions_rt.data(),
384 /*texture_coordinates=*/positions_rt.data(), /*colors=*/nullptr,
385 /*index_count=*/0,
386 /*indices=*/nullptr);
387
388 std::vector<SkPoint> positions_lb = {
389 SkPoint::Make(0, 50), //
390 SkPoint::Make(50, 50), //
391 SkPoint::Make(0, 100), //
392 SkPoint::Make(50, 100), //
393 };
394
395 auto vertices_lb = flutter::DlVertices::Make(
396 flutter::DlVertexMode::kTriangleStrip, positions_lb.size(),
397 positions_lb.data(),
398 /*texture_coordinates=*/positions_lb.data(), /*colors=*/nullptr,
399 /*index_count=*/0,
400 /*indices=*/nullptr);
401
402 std::vector<SkPoint> positions_rb = {
403 SkPoint::Make(50, 50), //
404 SkPoint::Make(100, 50), //
405 SkPoint::Make(50, 100), //
406 SkPoint::Make(100, 100), //
407 };
408
409 auto vertices_rb = flutter::DlVertices::Make(
410 flutter::DlVertexMode::kTriangleStrip, positions_rb.size(),
411 positions_rb.data(),
412 /*texture_coordinates=*/positions_rb.data(), /*colors=*/nullptr,
413 /*index_count=*/0,
414 /*indices=*/nullptr);
415
416 flutter::DisplayListBuilder builder;
417 flutter::DlPaint paint;
418 flutter::DlPaint rect_paint;
419 rect_paint.setColor(DlColor::kBlue());
420
421 auto runtime_stages =
422 OpenAssetAsRuntimeStage("runtime_stage_simple.frag.iplr");
423
424 auto runtime_stage =
425 runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
426 ASSERT_TRUE(runtime_stage);
427
428 auto runtime_effect = DlRuntimeEffect::MakeImpeller(runtime_stage);
429 auto uniform_data = std::make_shared<std::vector<uint8_t>>();
430 auto color_source = flutter::DlColorSource::MakeRuntimeEffect(
431 runtime_effect, {}, uniform_data);
432
433 paint.setColorSource(color_source);
434
435 builder.Scale(GetContentScale().x, GetContentScale().y);
436 builder.Save();
437 builder.DrawRect(SkRect::MakeLTRB(0, 0, 100, 100), rect_paint);
438 builder.DrawVertices(vertices_lt, flutter::DlBlendMode::kSrcOver, paint);
439 builder.DrawVertices(vertices_rt, flutter::DlBlendMode::kSrcOver, paint);
440 builder.DrawVertices(vertices_lb, flutter::DlBlendMode::kSrcOver, paint);
441 builder.DrawVertices(vertices_rb, flutter::DlBlendMode::kSrcOver, paint);
442 builder.Restore();
443
444 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
445 }
446
447 } // namespace testing
448 } // namespace impeller
impeller::AiksPlayground
Definition: aiks_playground.h:17
impeller::Scalar
float Scalar
Definition: scalar.h:18
aiks_unittests.h
impeller::PlaygroundBackendToRuntimeStageBackend
constexpr RuntimeStageBackend PlaygroundBackendToRuntimeStageBackend(PlaygroundBackend backend)
Definition: playground.h:33
impeller::DlImageImpeller::Make
static sk_sp< DlImageImpeller > Make(std::shared_ptr< Texture > texture, OwningContext owning_context=OwningContext::kIO)
Definition: dl_image_impeller.cc:12
impeller::testing::TEST_P
TEST_P(AiksTest, CanRenderAdvancedBlendColorFilterWithSaveLayer)
Definition: aiks_blend_unittests.cc:21
impeller::Point
TPoint< Scalar > Point
Definition: point.h:322
flutter
Definition: dl_golden_blur_unittests.cc:14
paint
const Paint & paint
Definition: color_source.cc:38
color
DlColor color
Definition: dl_golden_blur_unittests.cc:23
impeller
Definition: aiks_blend_unittests.cc:18
impeller::MakeVertices
std::shared_ptr< impeller::VerticesGeometry > MakeVertices(const std::shared_ptr< const flutter::DlVertices > &vertices)
Definition: dl_vertices_geometry.cc:31
dl_image_impeller.h