Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
dl_test_snippets.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 "flutter/display_list/testing/dl_test_snippets.h"
6#include "flutter/display_list/dl_builder.h"
7#include "flutter/display_list/dl_op_receiver.h"
10#include "txt/platform.h"
11
12namespace flutter {
13namespace testing {
14
16 DisplayListBuilder builder(SkRect::MakeWH(150, 100));
17 builder.DrawRect(SkRect::MakeXYWH(10, 10, 80, 80), DlPaint(DlColor::kRed()));
18 return builder.Build();
19}
20
22 DisplayListBuilder builder(SkRect::MakeWH(150, 100));
24 for (int y = 10; y <= 60; y += 10) {
25 for (int x = 10; x <= 60; x += 10) {
26 paint.setColor(((x + y) % 20) == 10 ? DlColor(SK_ColorRED)
28 builder.DrawRect(SkRect::MakeXYWH(x, y, 80, 80), paint);
29 }
30 }
31 DisplayListBuilder outer_builder(SkRect::MakeWH(150, 100));
32 outer_builder.DrawDisplayList(builder.Build());
33 return outer_builder.Build();
34}
35
37 DisplayListBuilder builder(SkRect::MakeWH(150, 100));
38 for (int i = 0; i < ops; i++) {
39 builder.DrawColor(DlColor::kRed(), DlBlendMode::kSrc);
40 }
41 return builder.Build();
42}
43
44// ---------------
45// Test Suite data
46// ---------------
47
48std::vector<DisplayListInvocationGroup> CreateAllAttributesOps() {
49 return {
50 {"SetAntiAlias",
51 {
52 {0, 8, 0, [](DlOpReceiver& r) { r.setAntiAlias(true); }},
53 {0, 0, 0, [](DlOpReceiver& r) { r.setAntiAlias(false); }},
54 }},
55 {"SetInvertColors",
56 {
57 {0, 8, 0, [](DlOpReceiver& r) { r.setInvertColors(true); }},
58 {0, 0, 0, [](DlOpReceiver& r) { r.setInvertColors(false); }},
59 }},
60 {"SetStrokeCap",
61 {
62 {0, 8, 0,
63 [](DlOpReceiver& r) { r.setStrokeCap(DlStrokeCap::kRound); }},
64 {0, 8, 0,
65 [](DlOpReceiver& r) { r.setStrokeCap(DlStrokeCap::kSquare); }},
66 {0, 0, 0,
67 [](DlOpReceiver& r) { r.setStrokeCap(DlStrokeCap::kButt); }},
68 }},
69 {"SetStrokeJoin",
70 {
71 {0, 8, 0,
72 [](DlOpReceiver& r) { r.setStrokeJoin(DlStrokeJoin::kBevel); }},
73 {0, 8, 0,
74 [](DlOpReceiver& r) { r.setStrokeJoin(DlStrokeJoin::kRound); }},
75 {0, 0, 0,
76 [](DlOpReceiver& r) { r.setStrokeJoin(DlStrokeJoin::kMiter); }},
77 }},
78 {"SetStyle",
79 {
80 {0, 8, 0,
81 [](DlOpReceiver& r) { r.setDrawStyle(DlDrawStyle::kStroke); }},
82 {0, 8, 0,
83 [](DlOpReceiver& r) {
84 r.setDrawStyle(DlDrawStyle::kStrokeAndFill);
85 }},
86 {0, 0, 0,
87 [](DlOpReceiver& r) { r.setDrawStyle(DlDrawStyle::kFill); }},
88 }},
89 {"SetStrokeWidth",
90 {
91 {0, 8, 0, [](DlOpReceiver& r) { r.setStrokeWidth(1.0); }},
92 {0, 8, 0, [](DlOpReceiver& r) { r.setStrokeWidth(5.0); }},
93 {0, 0, 0, [](DlOpReceiver& r) { r.setStrokeWidth(0.0); }},
94 }},
95 {"SetStrokeMiter",
96 {
97 {0, 8, 0, [](DlOpReceiver& r) { r.setStrokeMiter(0.0); }},
98 {0, 8, 0, [](DlOpReceiver& r) { r.setStrokeMiter(5.0); }},
99 {0, 0, 0, [](DlOpReceiver& r) { r.setStrokeMiter(4.0); }},
100 }},
101 {"SetColor",
102 {
103 {0, 8, 0,
104 [](DlOpReceiver& r) { r.setColor(DlColor(SK_ColorGREEN)); }},
105 {0, 8, 0,
106 [](DlOpReceiver& r) { r.setColor(DlColor(SK_ColorBLUE)); }},
107 {0, 0, 0,
108 [](DlOpReceiver& r) { r.setColor(DlColor(SK_ColorBLACK)); }},
109 }},
110 {"SetBlendMode",
111 {
112 {0, 8, 0,
113 [](DlOpReceiver& r) { r.setBlendMode(DlBlendMode::kSrcIn); }},
114 {0, 8, 0,
115 [](DlOpReceiver& r) { r.setBlendMode(DlBlendMode::kDstIn); }},
116 {0, 0, 0,
117 [](DlOpReceiver& r) { r.setBlendMode(DlBlendMode::kSrcOver); }},
118 }},
119 {"SetColorSource",
120 {
121 {0, 96, 0, [](DlOpReceiver& r) { r.setColorSource(&kTestSource1); }},
122 // stop_count * (sizeof(float) + sizeof(uint32_t)) = 80
123 {0, 80 + 6 * 4, 0,
124 [](DlOpReceiver& r) { r.setColorSource(kTestSource2.get()); }},
125 {0, 80 + 6 * 4, 0,
126 [](DlOpReceiver& r) { r.setColorSource(kTestSource3.get()); }},
127 {0, 88 + 6 * 4, 0,
128 [](DlOpReceiver& r) { r.setColorSource(kTestSource4.get()); }},
129 {0, 80 + 6 * 4, 0,
130 [](DlOpReceiver& r) { r.setColorSource(kTestSource5.get()); }},
131 {0, 0, 0, [](DlOpReceiver& r) { r.setColorSource(nullptr); }},
132 }},
133 {"SetImageFilter",
134 {
135 {0, 32, 0,
136 [](DlOpReceiver& r) { r.setImageFilter(&kTestBlurImageFilter1); }},
137 {0, 32, 0,
138 [](DlOpReceiver& r) { r.setImageFilter(&kTestBlurImageFilter2); }},
139 {0, 32, 0,
140 [](DlOpReceiver& r) { r.setImageFilter(&kTestBlurImageFilter3); }},
141 {0, 32, 0,
142 [](DlOpReceiver& r) { r.setImageFilter(&kTestBlurImageFilter4); }},
143 {0, 24, 0,
144 [](DlOpReceiver& r) {
145 r.setImageFilter(&kTestDilateImageFilter1);
146 }},
147 {0, 24, 0,
148 [](DlOpReceiver& r) {
149 r.setImageFilter(&kTestDilateImageFilter2);
150 }},
151 {0, 24, 0,
152 [](DlOpReceiver& r) {
153 r.setImageFilter(&kTestDilateImageFilter3);
154 }},
155 {0, 24, 0,
156 [](DlOpReceiver& r) { r.setImageFilter(&kTestErodeImageFilter1); }},
157 {0, 24, 0,
158 [](DlOpReceiver& r) { r.setImageFilter(&kTestErodeImageFilter2); }},
159 {0, 24, 0,
160 [](DlOpReceiver& r) { r.setImageFilter(&kTestErodeImageFilter3); }},
161 {0, 64, 0,
162 [](DlOpReceiver& r) {
163 r.setImageFilter(&kTestMatrixImageFilter1);
164 }},
165 {0, 64, 0,
166 [](DlOpReceiver& r) {
167 r.setImageFilter(&kTestMatrixImageFilter2);
168 }},
169 {0, 64, 0,
170 [](DlOpReceiver& r) {
171 r.setImageFilter(&kTestMatrixImageFilter3);
172 }},
173 {0, 24, 0,
174 [](DlOpReceiver& r) {
175 r.setImageFilter(&kTestComposeImageFilter1);
176 }},
177 {0, 24, 0,
178 [](DlOpReceiver& r) {
179 r.setImageFilter(&kTestComposeImageFilter2);
180 }},
181 {0, 24, 0,
182 [](DlOpReceiver& r) {
183 r.setImageFilter(&kTestComposeImageFilter3);
184 }},
185 {0, 24, 0,
186 [](DlOpReceiver& r) { r.setImageFilter(&kTestCFImageFilter1); }},
187 {0, 24, 0,
188 [](DlOpReceiver& r) { r.setImageFilter(&kTestCFImageFilter2); }},
189 {0, 0, 0, [](DlOpReceiver& r) { r.setImageFilter(nullptr); }},
190 {0, 24, 0,
191 [](DlOpReceiver& r) {
192 r.setImageFilter(
194 .makeWithLocalMatrix(SkMatrix::Translate(2, 2))
195 .get());
196 }},
197 }},
198 {"SetColorFilter",
199 {
200 {0, 24, 0,
201 [](DlOpReceiver& r) { r.setColorFilter(&kTestBlendColorFilter1); }},
202 {0, 24, 0,
203 [](DlOpReceiver& r) { r.setColorFilter(&kTestBlendColorFilter2); }},
204 {0, 24, 0,
205 [](DlOpReceiver& r) { r.setColorFilter(&kTestBlendColorFilter3); }},
206 {0, 96, 0,
207 [](DlOpReceiver& r) {
208 r.setColorFilter(&kTestMatrixColorFilter1);
209 }},
210 {0, 96, 0,
211 [](DlOpReceiver& r) {
212 r.setColorFilter(&kTestMatrixColorFilter2);
213 }},
214 {0, 16, 0,
215 [](DlOpReceiver& r) {
216 r.setColorFilter(DlSrgbToLinearGammaColorFilter::kInstance.get());
217 }},
218 {0, 16, 0,
219 [](DlOpReceiver& r) {
220 r.setColorFilter(DlLinearToSrgbGammaColorFilter::kInstance.get());
221 }},
222 {0, 0, 0, [](DlOpReceiver& r) { r.setColorFilter(nullptr); }},
223 }},
224 {"SetPathEffect",
225 {
226 // sizeof(DlDashPathEffect) + 2 * sizeof(SkScalar)
227 {0, 32, 0,
228 [](DlOpReceiver& r) { r.setPathEffect(kTestPathEffect1.get()); }},
229 {0, 32, 0,
230 [](DlOpReceiver& r) { r.setPathEffect(kTestPathEffect2.get()); }},
231 {0, 0, 0, [](DlOpReceiver& r) { r.setPathEffect(nullptr); }},
232 }},
233 {"SetMaskFilter",
234 {
235 {0, 32, 0,
236 [](DlOpReceiver& r) { r.setMaskFilter(&kTestMaskFilter1); }, 0u,
237 2u},
238 {0, 32, 0,
239 [](DlOpReceiver& r) { r.setMaskFilter(&kTestMaskFilter2); }, 0u,
240 2u},
241 {0, 32, 0,
242 [](DlOpReceiver& r) { r.setMaskFilter(&kTestMaskFilter3); }, 0u,
243 2u},
244 {0, 32, 0,
245 [](DlOpReceiver& r) { r.setMaskFilter(&kTestMaskFilter4); }, 0u,
246 2u},
247 {0, 32, 0,
248 [](DlOpReceiver& r) { r.setMaskFilter(&kTestMaskFilter5); }, 0u,
249 2u},
250 {0, 0, 0, [](DlOpReceiver& r) { r.setMaskFilter(nullptr); }, 0u, 1u},
251 }},
252 };
253}
254
255std::vector<DisplayListInvocationGroup> CreateAllSaveRestoreOps() {
256 return {
257 {"Save(Layer)+Restore",
258 {
259 // There are many reasons that save and restore can elide content,
260 // including whether or not there are any draw operations between
261 // them, whether or not there are any state changes to restore, and
262 // whether group rendering (opacity) optimizations can allow
263 // attributes to be distributed to the children. To prevent those
264 // cases we include at least one clip operation and 2 overlapping
265 // rendering primitives between each save/restore pair.
266 {5, 96, 2,
267 [](DlOpReceiver& r) {
268 r.save();
269 r.clipRect({0, 0, 25, 25}, DlCanvas::ClipOp::kIntersect, true);
270 r.drawRect({5, 5, 15, 15});
271 r.drawRect({10, 10, 20, 20});
272 r.restore();
273 }},
274 {5, 112, 3,
275 [](DlOpReceiver& r) {
276 r.saveLayer(nullptr, SaveLayerOptions::kNoAttributes);
277 r.clipRect({0, 0, 25, 25}, DlCanvas::ClipOp::kIntersect, true);
278 r.drawRect({5, 5, 15, 15});
279 r.drawRect({10, 10, 20, 20});
280 r.restore();
281 }},
282 {5, 112, 3,
283 [](DlOpReceiver& r) {
284 r.saveLayer(nullptr, SaveLayerOptions::kWithAttributes);
285 r.clipRect({0, 0, 25, 25}, DlCanvas::ClipOp::kIntersect, true);
286 r.drawRect({5, 5, 15, 15});
287 r.drawRect({10, 10, 20, 20});
288 r.restore();
289 }},
290 {5, 112, 3,
291 [](DlOpReceiver& r) {
293 r.clipRect({0, 0, 25, 25}, DlCanvas::ClipOp::kIntersect, true);
294 r.drawRect({5, 5, 15, 15});
295 r.drawRect({10, 10, 20, 20});
296 r.restore();
297 }},
298 {5, 112, 3,
299 [](DlOpReceiver& r) {
301 r.clipRect({0, 0, 25, 25}, DlCanvas::ClipOp::kIntersect, true);
302 r.drawRect({5, 5, 15, 15});
303 r.drawRect({10, 10, 20, 20});
304 r.restore();
305 }},
306 {5, 128, 3,
307 [](DlOpReceiver& r) {
308 r.saveLayer(nullptr, SaveLayerOptions::kNoAttributes,
310 r.clipRect({0, 0, 25, 25}, DlCanvas::ClipOp::kIntersect, true);
311 r.drawRect({5, 5, 15, 15});
312 r.drawRect({10, 10, 20, 20});
313 r.restore();
314 }},
315 {5, 128, 3,
316 [](DlOpReceiver& r) {
317 r.saveLayer(nullptr, SaveLayerOptions::kWithAttributes,
319 r.clipRect({0, 0, 25, 25}, DlCanvas::ClipOp::kIntersect, true);
320 r.drawRect({5, 5, 15, 15});
321 r.drawRect({10, 10, 20, 20});
322 r.restore();
323 }},
324 {5, 128, 3,
325 [](DlOpReceiver& r) {
328 r.clipRect({0, 0, 25, 25}, DlCanvas::ClipOp::kIntersect, true);
329 r.drawRect({5, 5, 15, 15});
330 r.drawRect({10, 10, 20, 20});
331 r.restore();
332 }},
333 {5, 128, 3,
334 [](DlOpReceiver& r) {
337 r.clipRect({0, 0, 25, 25}, DlCanvas::ClipOp::kIntersect, true);
338 r.drawRect({5, 5, 15, 15});
339 r.drawRect({10, 10, 20, 20});
340 r.restore();
341 }},
342 }},
343 };
344}
345
346std::vector<DisplayListInvocationGroup> CreateAllTransformOps() {
347 return {
348 {"Translate",
349 {
350 {1, 16, 0, [](DlOpReceiver& r) { r.translate(10, 10); }},
351 {1, 16, 0, [](DlOpReceiver& r) { r.translate(10, 15); }},
352 {1, 16, 0, [](DlOpReceiver& r) { r.translate(15, 10); }},
353 {0, 0, 0, [](DlOpReceiver& r) { r.translate(0, 0); }},
354 }},
355 {"Scale",
356 {
357 {1, 16, 0, [](DlOpReceiver& r) { r.scale(2, 2); }},
358 {1, 16, 0, [](DlOpReceiver& r) { r.scale(2, 3); }},
359 {1, 16, 0, [](DlOpReceiver& r) { r.scale(3, 2); }},
360 {0, 0, 0, [](DlOpReceiver& r) { r.scale(1, 1); }},
361 }},
362 {"Rotate",
363 {
364 {1, 8, 0, [](DlOpReceiver& r) { r.rotate(30); }},
365 {1, 8, 0, [](DlOpReceiver& r) { r.rotate(45); }},
366 {0, 0, 0, [](DlOpReceiver& r) { r.rotate(0); }},
367 {0, 0, 0, [](DlOpReceiver& r) { r.rotate(360); }},
368 }},
369 {"Skew",
370 {
371 {1, 16, 0, [](DlOpReceiver& r) { r.skew(0.1, 0.1); }},
372 {1, 16, 0, [](DlOpReceiver& r) { r.skew(0.1, 0.2); }},
373 {1, 16, 0, [](DlOpReceiver& r) { r.skew(0.2, 0.1); }},
374 {0, 0, 0, [](DlOpReceiver& r) { r.skew(0, 0); }},
375 }},
376 {"Transform2DAffine",
377 {
378 {1, 32, 0,
379 [](DlOpReceiver& r) { r.transform2DAffine(0, 1, 12, 1, 0, 33); }},
380 // r.transform(identity) is ignored
381 {0, 0, 0,
382 [](DlOpReceiver& r) { r.transform2DAffine(1, 0, 0, 0, 1, 0); }},
383 }},
384 {"TransformFullPerspective",
385 {
386 {1, 72, 0,
387 [](DlOpReceiver& r) {
388 r.transformFullPerspective(0, 1, 0, 12, 1, 0, 0, 33, 3, 2, 5, 29,
389 0, 0, 0, 12);
390 }},
391 // r.transform(2D affine) is reduced to 2x3
392 {1, 32, 0,
393 [](DlOpReceiver& r) {
394 r.transformFullPerspective(2, 1, 0, 4, 1, 3, 0, 5, 0, 0, 1, 0, 0,
395 0, 0, 1);
396 }},
397 // r.transform(identity) is ignored
398 {0, 0, 0,
399 [](DlOpReceiver& r) {
400 r.transformFullPerspective(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0,
401 0, 0, 1);
402 }},
403 }},
404 };
405}
406
407std::vector<DisplayListInvocationGroup> CreateAllClipOps() {
408 return {
409 {"ClipRect",
410 {
411 {1, 24, 0,
412 [](DlOpReceiver& r) {
413 r.clipRect(kTestBounds, DlCanvas::ClipOp::kIntersect, true);
414 }},
415 {1, 24, 0,
416 [](DlOpReceiver& r) {
417 r.clipRect(kTestBounds.makeOffset(1, 1),
419 }},
420 {1, 24, 0,
421 [](DlOpReceiver& r) {
422 r.clipRect(kTestBounds, DlCanvas::ClipOp::kIntersect, false);
423 }},
424 {1, 24, 0,
425 [](DlOpReceiver& r) {
427 }},
428 {1, 24, 0,
429 [](DlOpReceiver& r) {
430 r.clipRect(kTestBounds, DlCanvas::ClipOp::kDifference, false);
431 }},
432 }},
433 {"ClipRRect",
434 {
435 {1, 64, 0,
436 [](DlOpReceiver& r) {
437 r.clipRRect(kTestRRect, DlCanvas::ClipOp::kIntersect, true);
438 }},
439 {1, 64, 0,
440 [](DlOpReceiver& r) {
441 r.clipRRect(kTestRRect.makeOffset(1, 1),
443 }},
444 {1, 64, 0,
445 [](DlOpReceiver& r) {
446 r.clipRRect(kTestRRect, DlCanvas::ClipOp::kIntersect, false);
447 }},
448 {1, 64, 0,
449 [](DlOpReceiver& r) {
450 r.clipRRect(kTestRRect, DlCanvas::ClipOp::kDifference, true);
451 }},
452 {1, 64, 0,
453 [](DlOpReceiver& r) {
454 r.clipRRect(kTestRRect, DlCanvas::ClipOp::kDifference, false);
455 }},
456 }},
457 {"ClipPath",
458 {
459 {1, 40, 0,
460 [](DlOpReceiver& r) {
461 r.clipPath(kTestPath1, DlCanvas::ClipOp::kIntersect, true);
462 }},
463 {1, 40, 0,
464 [](DlOpReceiver& r) {
465 r.clipPath(kTestPath2, DlCanvas::ClipOp::kIntersect, true);
466 }},
467 {1, 40, 0,
468 [](DlOpReceiver& r) {
469 r.clipPath(kTestPath3, DlCanvas::ClipOp::kIntersect, true);
470 }},
471 {1, 40, 0,
472 [](DlOpReceiver& r) {
473 r.clipPath(kTestPath1, DlCanvas::ClipOp::kIntersect, false);
474 }},
475 {1, 40, 0,
476 [](DlOpReceiver& r) {
477 r.clipPath(kTestPath1, DlCanvas::ClipOp::kDifference, true);
478 }},
479 {1, 40, 0,
480 [](DlOpReceiver& r) {
481 r.clipPath(kTestPath1, DlCanvas::ClipOp::kDifference, false);
482 }},
483 // clipPath(rect) becomes clipRect
484 {1, 24, 0,
485 [](DlOpReceiver& r) {
487 }},
488 // clipPath(oval) becomes clipRRect
489 {1, 64, 0,
490 [](DlOpReceiver& r) {
492 }},
493 }},
494 };
495}
496
497std::vector<DisplayListInvocationGroup> CreateAllRenderingOps() {
498 return {
499 {"DrawPaint",
500 {
501 {1, 8, 1, [](DlOpReceiver& r) { r.drawPaint(); }},
502 }},
503 {"DrawColor",
504 {
505 {1, 16, 1,
506 [](DlOpReceiver& r) {
508 }},
509 {1, 16, 1,
510 [](DlOpReceiver& r) {
512 }},
513 {1, 16, 1,
514 [](DlOpReceiver& r) {
516 }},
517 }},
518 {"DrawLine",
519 {
520 {1, 24, 1,
521 [](DlOpReceiver& r) {
522 r.drawLine({0, 0}, {10, 10});
523 }},
524 {1, 24, 1,
525 [](DlOpReceiver& r) {
526 r.drawLine({0, 1}, {10, 10});
527 }},
528 {1, 24, 1,
529 [](DlOpReceiver& r) {
530 r.drawLine({0, 0}, {20, 10});
531 }},
532 {1, 24, 1,
533 [](DlOpReceiver& r) {
534 r.drawLine({0, 0}, {10, 20});
535 }},
536 }},
537 {"DrawRect",
538 {
539 {1, 24, 1,
540 [](DlOpReceiver& r) {
541 r.drawRect({0, 0, 10, 10});
542 }},
543 {1, 24, 1,
544 [](DlOpReceiver& r) {
545 r.drawRect({0, 1, 10, 10});
546 }},
547 {1, 24, 1,
548 [](DlOpReceiver& r) {
549 r.drawRect({0, 0, 20, 10});
550 }},
551 {1, 24, 1,
552 [](DlOpReceiver& r) {
553 r.drawRect({0, 0, 10, 20});
554 }},
555 }},
556 {"DrawOval",
557 {
558 {1, 24, 1,
559 [](DlOpReceiver& r) {
560 r.drawOval({0, 0, 10, 10});
561 }},
562 {1, 24, 1,
563 [](DlOpReceiver& r) {
564 r.drawOval({0, 1, 10, 10});
565 }},
566 {1, 24, 1,
567 [](DlOpReceiver& r) {
568 r.drawOval({0, 0, 20, 10});
569 }},
570 {1, 24, 1,
571 [](DlOpReceiver& r) {
572 r.drawOval({0, 0, 10, 20});
573 }},
574 }},
575 {"DrawCircle",
576 {
577 {1, 16, 1,
578 [](DlOpReceiver& r) {
579 r.drawCircle({0, 0}, 10);
580 }},
581 {1, 16, 1,
582 [](DlOpReceiver& r) {
583 r.drawCircle({0, 5}, 10);
584 }},
585 {1, 16, 1,
586 [](DlOpReceiver& r) {
587 r.drawCircle({0, 0}, 20);
588 }},
589 }},
590 {"DrawRRect",
591 {
592 {1, 56, 1, [](DlOpReceiver& r) { r.drawRRect(kTestRRect); }},
593 {1, 56, 1,
594 [](DlOpReceiver& r) { r.drawRRect(kTestRRect.makeOffset(5, 5)); }},
595 }},
596 {"DrawDRRect",
597 {
598 {1, 112, 1,
599 [](DlOpReceiver& r) { r.drawDRRect(kTestRRect, kTestInnerRRect); }},
600 {1, 112, 1,
601 [](DlOpReceiver& r) {
602 r.drawDRRect(kTestRRect.makeOffset(5, 5),
604 }},
605 }},
606 {"DrawPath",
607 {
608 {1, 40, 1, [](DlOpReceiver& r) { r.drawPath(kTestPath1); }},
609 {1, 40, 1, [](DlOpReceiver& r) { r.drawPath(kTestPath2); }},
610 {1, 40, 1, [](DlOpReceiver& r) { r.drawPath(kTestPath3); }},
611 {1, 40, 1, [](DlOpReceiver& r) { r.drawPath(kTestPathRect); }},
612 {1, 40, 1, [](DlOpReceiver& r) { r.drawPath(kTestPathOval); }},
613 }},
614 {"DrawArc",
615 {
616 {1, 32, 1,
617 [](DlOpReceiver& r) { r.drawArc(kTestBounds, 45, 270, false); }},
618 {1, 32, 1,
619 [](DlOpReceiver& r) {
620 r.drawArc(kTestBounds.makeOffset(1, 1), 45, 270, false);
621 }},
622 {1, 32, 1,
623 [](DlOpReceiver& r) { r.drawArc(kTestBounds, 30, 270, false); }},
624 {1, 32, 1,
625 [](DlOpReceiver& r) { r.drawArc(kTestBounds, 45, 260, false); }},
626 {1, 32, 1,
627 [](DlOpReceiver& r) { r.drawArc(kTestBounds, 45, 270, true); }},
628 }},
629 {"DrawPoints",
630 {
631 {1, 8 + TestPointCount * 8, 1,
632 [](DlOpReceiver& r) {
635 }},
636 {1, 8 + (TestPointCount - 1) * 8, 1,
637 [](DlOpReceiver& r) {
640 }},
641 {1, 8 + TestPointCount * 8, 1,
642 [](DlOpReceiver& r) {
645 }},
646 {1, 8 + TestPointCount * 8, 1,
647 [](DlOpReceiver& r) {
650 }},
651 }},
652 {"DrawVertices",
653 {
654 {1, 112, 1,
655 [](DlOpReceiver& r) {
656 r.drawVertices(TestVertices1.get(), DlBlendMode::kSrcIn);
657 }},
658 {1, 112, 1,
659 [](DlOpReceiver& r) {
660 r.drawVertices(TestVertices1.get(), DlBlendMode::kDstIn);
661 }},
662 {1, 112, 1,
663 [](DlOpReceiver& r) {
664 r.drawVertices(TestVertices2.get(), DlBlendMode::kSrcIn);
665 }},
666 }},
667 {"DrawImage",
668 {
669 {1, 24, 1,
670 [](DlOpReceiver& r) {
671 r.drawImage(TestImage1, {10, 10}, kNearestSampling, false);
672 }},
673 {1, 24, 1,
674 [](DlOpReceiver& r) {
675 r.drawImage(TestImage1, {10, 10}, kNearestSampling, true);
676 }},
677 {1, 24, 1,
678 [](DlOpReceiver& r) {
679 r.drawImage(TestImage1, {20, 10}, kNearestSampling, false);
680 }},
681 {1, 24, 1,
682 [](DlOpReceiver& r) {
683 r.drawImage(TestImage1, {10, 20}, kNearestSampling, false);
684 }},
685 {1, 24, 1,
686 [](DlOpReceiver& r) {
687 r.drawImage(TestImage1, {10, 10}, kLinearSampling, false);
688 }},
689 {1, 24, 1,
690 [](DlOpReceiver& r) {
691 r.drawImage(TestImage2, {10, 10}, kNearestSampling, false);
692 }},
693 {1, 24, 1,
694 [](DlOpReceiver& r) {
695 auto dl_image = DlImage::Make(TestSkImage);
696 r.drawImage(dl_image, {10, 10}, kNearestSampling, false);
697 }},
698 }},
699 {"DrawImageRect",
700 {
701 {1, 56, 1,
702 [](DlOpReceiver& r) {
703 r.drawImageRect(TestImage1, {10, 10, 20, 20}, {10, 10, 80, 80},
704 kNearestSampling, false,
706 }},
707 {1, 56, 1,
708 [](DlOpReceiver& r) {
709 r.drawImageRect(TestImage1, {10, 10, 20, 20}, {10, 10, 80, 80},
710 kNearestSampling, true,
712 }},
713 {1, 56, 1,
714 [](DlOpReceiver& r) {
715 r.drawImageRect(TestImage1, {10, 10, 20, 20}, {10, 10, 80, 80},
716 kNearestSampling, false,
718 }},
719 {1, 56, 1,
720 [](DlOpReceiver& r) {
721 r.drawImageRect(TestImage1, {10, 10, 25, 20}, {10, 10, 80, 80},
722 kNearestSampling, false,
724 }},
725 {1, 56, 1,
726 [](DlOpReceiver& r) {
727 r.drawImageRect(TestImage1, {10, 10, 20, 20}, {10, 10, 85, 80},
728 kNearestSampling, false,
730 }},
731 {1, 56, 1,
732 [](DlOpReceiver& r) {
733 r.drawImageRect(TestImage1, {10, 10, 20, 20}, {10, 10, 80, 80},
734 kLinearSampling, false,
736 }},
737 {1, 56, 1,
738 [](DlOpReceiver& r) {
739 r.drawImageRect(TestImage2, {10, 10, 15, 15}, {10, 10, 80, 80},
740 kNearestSampling, false,
742 }},
743 {1, 56, 1,
744 [](DlOpReceiver& r) {
745 auto dl_image = DlImage::Make(TestSkImage);
746 r.drawImageRect(dl_image, {10, 10, 15, 15}, {10, 10, 80, 80},
747 kNearestSampling, false,
749 }},
750 }},
751 {"DrawImageNine",
752 {
753 {1, 48, 1,
754 [](DlOpReceiver& r) {
755 r.drawImageNine(TestImage1, {10, 10, 20, 20}, {10, 10, 80, 80},
757 }},
758 {1, 48, 1,
759 [](DlOpReceiver& r) {
760 r.drawImageNine(TestImage1, {10, 10, 20, 20}, {10, 10, 80, 80},
762 }},
763 {1, 48, 1,
764 [](DlOpReceiver& r) {
765 r.drawImageNine(TestImage1, {10, 10, 25, 20}, {10, 10, 80, 80},
767 }},
768 {1, 48, 1,
769 [](DlOpReceiver& r) {
770 r.drawImageNine(TestImage1, {10, 10, 20, 20}, {10, 10, 85, 80},
772 }},
773 {1, 48, 1,
774 [](DlOpReceiver& r) {
775 r.drawImageNine(TestImage1, {10, 10, 20, 20}, {10, 10, 80, 80},
776 DlFilterMode::kLinear, false);
777 }},
778 {1, 48, 1,
779 [](DlOpReceiver& r) {
780 r.drawImageNine(TestImage2, {10, 10, 15, 15}, {10, 10, 80, 80},
782 }},
783 {1, 48, 1,
784 [](DlOpReceiver& r) {
785 auto dl_image = DlImage::Make(TestSkImage);
786 r.drawImageNine(dl_image, {10, 10, 15, 15}, {10, 10, 80, 80},
788 }},
789 }},
790 {"DrawAtlas",
791 {
792 {1, 48 + 32 + 8, 1,
793 [](DlOpReceiver& r) {
794 static SkRSXform xforms[] = {{1, 0, 0, 0}, {0, 1, 0, 0}};
795 static SkRect texs[] = {{10, 10, 20, 20}, {20, 20, 30, 30}};
796 r.drawAtlas(TestImage1, xforms, texs, nullptr, 2,
798 false);
799 }},
800 {1, 48 + 32 + 8, 1,
801 [](DlOpReceiver& r) {
802 static SkRSXform xforms[] = {{1, 0, 0, 0}, {0, 1, 0, 0}};
803 static SkRect texs[] = {{10, 10, 20, 20}, {20, 20, 30, 30}};
804 r.drawAtlas(TestImage1, xforms, texs, nullptr, 2,
805 DlBlendMode::kSrcIn, kNearestSampling, nullptr, true);
806 }},
807 {1, 48 + 32 + 8, 1,
808 [](DlOpReceiver& r) {
809 static SkRSXform xforms[] = {{0, 1, 0, 0}, {0, 1, 0, 0}};
810 static SkRect texs[] = {{10, 10, 20, 20}, {20, 20, 30, 30}};
811 r.drawAtlas(TestImage1, xforms, texs, nullptr, 2,
813 false);
814 }},
815 {1, 48 + 32 + 8, 1,
816 [](DlOpReceiver& r) {
817 static SkRSXform xforms[] = {{1, 0, 0, 0}, {0, 1, 0, 0}};
818 static SkRect texs[] = {{10, 10, 20, 20}, {20, 25, 30, 30}};
819 r.drawAtlas(TestImage1, xforms, texs, nullptr, 2,
821 false);
822 }},
823 {1, 48 + 32 + 8, 1,
824 [](DlOpReceiver& r) {
825 static SkRSXform xforms[] = {{1, 0, 0, 0}, {0, 1, 0, 0}};
826 static SkRect texs[] = {{10, 10, 20, 20}, {20, 20, 30, 30}};
827 r.drawAtlas(TestImage1, xforms, texs, nullptr, 2,
828 DlBlendMode::kSrcIn, kLinearSampling, nullptr, false);
829 }},
830 {1, 48 + 32 + 8, 1,
831 [](DlOpReceiver& r) {
832 static SkRSXform xforms[] = {{1, 0, 0, 0}, {0, 1, 0, 0}};
833 static SkRect texs[] = {{10, 10, 20, 20}, {20, 20, 30, 30}};
834 r.drawAtlas(TestImage1, xforms, texs, nullptr, 2,
836 false);
837 }},
838 {1, 64 + 32 + 8, 1,
839 [](DlOpReceiver& r) {
840 static SkRSXform xforms[] = {{1, 0, 0, 0}, {0, 1, 0, 0}};
841 static SkRect texs[] = {{10, 10, 20, 20}, {20, 20, 30, 30}};
842 static SkRect cull_rect = {0, 0, 200, 200};
843 r.drawAtlas(TestImage2, xforms, texs, nullptr, 2,
845 false);
846 }},
847 {1, 48 + 32 + 8 + 8, 1,
848 [](DlOpReceiver& r) {
849 static SkRSXform xforms[] = {{1, 0, 0, 0}, {0, 1, 0, 0}};
850 static SkRect texs[] = {{10, 10, 20, 20}, {20, 20, 30, 30}};
851 static DlColor colors[] = {DlColor::kBlue(), DlColor::kGreen()};
852 r.drawAtlas(TestImage1, xforms, texs, colors, 2,
854 false);
855 }},
856 {1, 64 + 32 + 8 + 8, 1,
857 [](DlOpReceiver& r) {
858 static SkRSXform xforms[] = {{1, 0, 0, 0}, {0, 1, 0, 0}};
859 static SkRect texs[] = {{10, 10, 20, 20}, {20, 20, 30, 30}};
860 static DlColor colors[] = {DlColor::kBlue(), DlColor::kGreen()};
861 static SkRect cull_rect = {0, 0, 200, 200};
862 r.drawAtlas(TestImage1, xforms, texs, colors, 2,
864 false);
865 }},
866 {1, 48 + 32 + 8, 1,
867 [](DlOpReceiver& r) {
868 auto dl_image = DlImage::Make(TestSkImage);
869 static SkRSXform xforms[] = {{1, 0, 0, 0}, {0, 1, 0, 0}};
870 static SkRect texs[] = {{10, 10, 20, 20}, {20, 20, 30, 30}};
871 r.drawAtlas(dl_image, xforms, texs, nullptr, 2,
873 false);
874 }},
875 }},
876 {"DrawDisplayList",
877 {
878 {1, 16, 1,
879 [](DlOpReceiver& r) { r.drawDisplayList(TestDisplayList1, 1.0); },
880 1u},
881 {1, 16, 1,
882 [](DlOpReceiver& r) { r.drawDisplayList(TestDisplayList1, 0.5); },
883 1u},
884 {1, 16, 1,
885 [](DlOpReceiver& r) { r.drawDisplayList(TestDisplayList2, 1.0); },
886 1u},
887 {1, 16, 1,
888 [](DlOpReceiver& r) {
889 r.drawDisplayList(MakeTestDisplayList(10, 10, SK_ColorRED), 1.0);
890 },
891 1u},
892 }},
893 {"DrawTextBlob",
894 {
895 {1, 24, 1,
896 [](DlOpReceiver& r) {
897 r.drawTextBlob(GetTestTextBlob(1), 10, 10);
898 }},
899 {1, 24, 1,
900 [](DlOpReceiver& r) {
901 r.drawTextBlob(GetTestTextBlob(1), 20, 10);
902 }},
903 {1, 24, 1,
904 [](DlOpReceiver& r) {
905 r.drawTextBlob(GetTestTextBlob(1), 10, 20);
906 }},
907 {1, 24, 1,
908 [](DlOpReceiver& r) {
909 r.drawTextBlob(GetTestTextBlob(2), 10, 10);
910 }},
911 }},
912 {"DrawShadow",
913 {
914 {1, 48, 1,
915 [](DlOpReceiver& r) {
916 r.drawShadow(kTestPath1, DlColor(SK_ColorGREEN), 1.0, false, 1.0);
917 }},
918 {1, 48, 1,
919 [](DlOpReceiver& r) {
920 r.drawShadow(kTestPath2, DlColor(SK_ColorGREEN), 1.0, false, 1.0);
921 }},
922 {1, 48, 1,
923 [](DlOpReceiver& r) {
924 r.drawShadow(kTestPath1, DlColor(SK_ColorBLUE), 1.0, false, 1.0);
925 }},
926 {1, 48, 1,
927 [](DlOpReceiver& r) {
928 r.drawShadow(kTestPath1, DlColor(SK_ColorGREEN), 2.0, false, 1.0);
929 }},
930 {1, 48, 1,
931 [](DlOpReceiver& r) {
932 r.drawShadow(kTestPath1, DlColor(SK_ColorGREEN), 1.0, true, 1.0);
933 }},
934 {1, 48, 1,
935 [](DlOpReceiver& r) {
936 r.drawShadow(kTestPath1, DlColor(SK_ColorGREEN), 1.0, false, 2.5);
937 }},
938 }},
939 };
940}
941
942std::vector<DisplayListInvocationGroup> CreateAllGroups() {
943 std::vector<DisplayListInvocationGroup> result;
944 auto all_attribute_ops = CreateAllAttributesOps();
945 std::move(all_attribute_ops.begin(), all_attribute_ops.end(),
946 std::back_inserter(result));
947 auto all_save_restore_ops = CreateAllSaveRestoreOps();
948 std::move(all_save_restore_ops.begin(), all_save_restore_ops.end(),
949 std::back_inserter(result));
950 auto all_transform_ops = CreateAllTransformOps();
951 std::move(all_transform_ops.begin(), all_transform_ops.end(),
952 std::back_inserter(result));
953 auto all_clip_ops = CreateAllClipOps();
954 std::move(all_clip_ops.begin(), all_clip_ops.end(),
955 std::back_inserter(result));
956 auto all_rendering_ops = CreateAllRenderingOps();
957 std::move(all_rendering_ops.begin(), all_rendering_ops.end(),
958 std::back_inserter(result));
959 return result;
960}
961
963 static constexpr const char* kTestFontFixture = "Roboto-Regular.ttf";
964 auto mapping = flutter::testing::OpenFixtureAsSkData(kTestFontFixture);
965 FML_CHECK(mapping);
966 return SkFont{txt::GetDefaultFontManager()->makeFromData(mapping), scalar};
967}
968
970 static std::map<int, sk_sp<SkTextBlob>> text_blobs;
971 auto it = text_blobs.find(index);
972 if (it != text_blobs.end()) {
973 return it->second;
974 }
975 std::string text = "TestBlob" + std::to_string(index);
976 sk_sp<SkTextBlob> blob =
977 SkTextBlob::MakeFromText(text.c_str(), text.size(),
979 text_blobs.insert(std::make_pair(index, blob));
980 return blob;
981}
982
983} // namespace testing
984} // namespace flutter
SkPathOp ops[]
constexpr SkColor SK_ColorCYAN
Definition SkColor.h:143
constexpr SkColor SK_ColorBLUE
Definition SkColor.h:135
constexpr SkColor SK_ColorRED
Definition SkColor.h:126
constexpr SkColor SK_ColorBLACK
Definition SkColor.h:103
constexpr SkColor SK_ColorGREEN
Definition SkColor.h:131
@ kUTF8
uses bytes to represent UTF-8 or ASCII
sk_sp< SkTypeface > makeFromData(sk_sp< SkData >, int ttcIndex=0) const
static SkMatrix Translate(SkScalar dx, SkScalar dy)
Definition SkMatrix.h:91
SkRRect makeOffset(SkScalar dx, SkScalar dy) const
Definition SkRRect.h:397
static sk_sp< SkTextBlob > MakeFromText(const void *text, size_t byteLength, const SkFont &font, SkTextEncoding encoding=SkTextEncoding::kUTF8)
sk_sp< DisplayList > Build()
Definition dl_builder.cc:67
void DrawDisplayList(const sk_sp< DisplayList > display_list, SkScalar opacity=SK_Scalar1) override
@ kLines
draw each separate pair of points as a line segment
@ kPolygon
draw each pair of overlapping points as a line segment
@ kPoints
draw each point separately
static sk_sp< DlImage > Make(const SkImage *image)
Definition dl_image.cc:11
static const std::shared_ptr< DlLinearToSrgbGammaColorFilter > kInstance
Internal API for rendering recorded display lists to backends.
virtual void drawPoints(PointMode mode, uint32_t count, const SkPoint points[])=0
static const std::shared_ptr< DlSrgbToLinearGammaColorFilter > kInstance
static const SaveLayerOptions kNoAttributes
static const SaveLayerOptions kWithAttributes
const Paint & paint
#define TestPointCount
float SkScalar
Definition extension.cpp:12
GAsyncResult * result
#define FML_CHECK(condition)
Definition logging.h:85
std::u16string text
double y
double x
static const DlComposeImageFilter kTestComposeImageFilter2(kTestBlurImageFilter2, kTestMatrixImageFilter1)
std::vector< DisplayListInvocationGroup > CreateAllClipOps()
static const DlDilateImageFilter kTestDilateImageFilter2(6.0, 5.0)
std::vector< DisplayListInvocationGroup > CreateAllTransformOps()
static const std::shared_ptr< DlColorSource > kTestSource3
constexpr SkRect kTestBounds
static auto TestSkImage
static const DlMatrixImageFilter kTestMatrixImageFilter1(SkMatrix::RotateDeg(45), kNearestSampling)
SkFont CreateTestFontOfSize(SkScalar scalar)
static const DlBlurMaskFilter kTestMaskFilter1(DlBlurStyle::kNormal, 3.0)
static const std::shared_ptr< DlPathEffect > kTestPathEffect2
std::vector< DisplayListInvocationGroup > CreateAllSaveRestoreOps()
static const std::shared_ptr< DlColorSource > kTestSource4
static const SkRRect kTestInnerRRect
static const DlBlurMaskFilter kTestMaskFilter4(DlBlurStyle::kInner, 3.0)
static const SkPath kTestPath1
static const DlComposeImageFilter kTestComposeImageFilter1(kTestBlurImageFilter1, kTestMatrixImageFilter1)
static std::shared_ptr< const DlVertices > TestVertices2
static const DlColorFilterImageFilter kTestCFImageFilter2(kTestBlendColorFilter2)
static const DlErodeImageFilter kTestErodeImageFilter2(4.0, 3.0)
static const DlMatrixColorFilter kTestMatrixColorFilter2(kInvertColorMatrix)
sk_sp< SkData > OpenFixtureAsSkData(const std::string &fixture_name)
Opens a fixture of the given file name and returns a Skia SkData holding its contents.
Definition testing.cc:64
static const DlBlurMaskFilter kTestMaskFilter3(DlBlurStyle::kSolid, 3.0)
static const DlImageColorSource kTestSource1(TestImage1, DlTileMode::kClamp, DlTileMode::kMirror, kLinearSampling)
static const DlBlurImageFilter kTestBlurImageFilter4(5.0, 5.0, DlTileMode::kDecal)
static const DlErodeImageFilter kTestErodeImageFilter3(3.0, 4.0)
static const DlMatrixImageFilter kTestMatrixImageFilter3(SkMatrix::RotateDeg(45), kLinearSampling)
static const DlColorFilterImageFilter kTestCFImageFilter1(kTestBlendColorFilter1)
static constexpr SkPoint kTestPoints[2]
static const std::shared_ptr< DlColorSource > kTestSource5
std::vector< DisplayListInvocationGroup > CreateAllAttributesOps()
static const DlErodeImageFilter kTestErodeImageFilter1(4.0, 4.0)
static const SkRRect kTestRRect
sk_sp< DisplayList > GetSampleDisplayList()
static const std::shared_ptr< DlColorSource > kTestSource2
static const DlBlurMaskFilter kTestMaskFilter2(DlBlurStyle::kNormal, 5.0)
static const DlBlurImageFilter kTestBlurImageFilter2(6.0, 5.0, DlTileMode::kClamp)
static const DlBlendColorFilter kTestBlendColorFilter2(DlColor::kBlue(), DlBlendMode::kDstATop)
static const DlBlendColorFilter kTestBlendColorFilter1(DlColor::kRed(), DlBlendMode::kDstATop)
static auto TestImage1
static const std::shared_ptr< DlPathEffect > kTestPathEffect1
static const DlMatrixColorFilter kTestMatrixColorFilter1(kRotateColorMatrix)
static const DlBlendColorFilter kTestBlendColorFilter3(DlColor::kRed(), DlBlendMode::kDstIn)
static DlImageSampling kLinearSampling
static sk_sp< DisplayList > TestDisplayList2
static const DlMatrixImageFilter kTestMatrixImageFilter2(SkMatrix::RotateDeg(85), kNearestSampling)
static std::shared_ptr< const DlVertices > TestVertices1
static const SkPath kTestPath2
static const DlBlurImageFilter kTestBlurImageFilter3(5.0, 6.0, DlTileMode::kClamp)
std::vector< DisplayListInvocationGroup > CreateAllRenderingOps()
static const SkPath kTestPathRect
static const DlDilateImageFilter kTestDilateImageFilter1(5.0, 5.0)
sk_sp< DisplayList > GetSampleNestedDisplayList()
static DlImageSampling kNearestSampling
static const DlBlurMaskFilter kTestMaskFilter5(DlBlurStyle::kOuter, 3.0)
sk_sp< SkTextBlob > GetTestTextBlob(int index)
static const DlDilateImageFilter kTestDilateImageFilter3(5.0, 6.0)
static sk_sp< DisplayList > MakeTestDisplayList(int w, int h, SkColor color)
static const DlBlurImageFilter kTestBlurImageFilter1(5.0, 5.0, DlTileMode::kClamp)
static auto TestImage2
static const SkPath kTestPathOval
std::vector< DisplayListInvocationGroup > CreateAllGroups()
static const DlComposeImageFilter kTestComposeImageFilter3(kTestBlurImageFilter1, kTestMatrixImageFilter2)
static const SkPath kTestPath3
static sk_sp< DisplayList > TestDisplayList1
@ kMiter
extends to miter limit
@ kBevel
connects outside edges
@ kRound
adds circle
@ kButt
no stroke extension
@ kSquare
adds square
@ kStrokeAndFill
both strokes and fills shapes
@ kStroke
strokes boundary of shapes
@ kFill
fills interior of shapes
@ kSrcOver
r = s + (1-sa)*d
@ kDstOut
r = d * (1-sa)
sk_sp< SkFontMgr > GetDefaultFontManager(uint32_t font_initialization_data)
Definition platform.cc:17
constexpr SkRect makeOffset(float dx, float dy) const
Definition SkRect.h:965
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition SkRect.h:659
static constexpr SkRect MakeWH(float w, float h)
Definition SkRect.h:609
static constexpr DlColor kBlue()
Definition dl_color.h:26
static constexpr DlColor kRed()
Definition dl_color.h:24
static constexpr DlColor kGreen()
Definition dl_color.h:25