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/testing/display_list_testing.h"
6
7#include <iomanip>
8
9#include "flutter/display_list/display_list.h"
10
11namespace flutter {
12namespace testing {
13
14// clang-format off
15bool DisplayListsEQ_Verbose(const DisplayList* a, const DisplayList* b) {
16 if (a->Equals(other: b)) {
17 return true;
18 }
19 FML_LOG(ERROR) << std::endl
20 << std::endl
21 << *a << std::endl
22 << "not identical to ..." << std::endl
23 << std::endl
24 << *b;
25 return false;
26}
27
28bool DisplayListsNE_Verbose(const DisplayList* a, const DisplayList* b) {
29 if (a->Equals(other: b)) {
30 FML_LOG(ERROR) << std::endl
31 << "DisplayLists are both the same:" << std::endl
32 << *a;
33 return false;
34 }
35 return true;
36}
37
38std::ostream& operator<<(std::ostream& os,
39 const DisplayList& display_list) {
40 DisplayListStreamDispatcher dispatcher(os);
41 os << std::boolalpha;
42 os << std::setprecision(std::numeric_limits<long double>::digits10 + 1);
43 os << "DisplayList {" << std::endl;
44 display_list.Dispatch(ctx&: dispatcher);
45 os << "}" << std::endl;
46 return os;
47}
48
49std::ostream& operator<<(std::ostream& os, const DlPaint& paint) {
50 os << "DlPaint("
51 << "isaa: " << paint.isAntiAlias() << ", "
52 << paint.getColor() << ", "
53 << paint.getBlendMode() << ", "
54 << paint.getDrawStyle();
55 if (paint.getDrawStyle() != DlDrawStyle::kFill) {
56 os << ", width: " << paint.getStrokeWidth()
57 << ", miter: " << paint.getStrokeMiter()
58 << ", " << paint.getStrokeCap()
59 << ", " << paint.getStrokeJoin();
60 }
61 if (paint.getColorSource()) {
62 os << ", " << paint.getColorSource();
63 }
64 if (paint.getColorFilter()) {
65 os << ", " << paint.getColorFilter();
66 }
67 if (paint.getImageFilter()) {
68 os << ", " << paint.getImageFilter();
69 }
70 if (paint.getMaskFilter()) {
71 os << ", " << paint.getMaskFilter();
72 }
73 if (paint.isDither()) {
74 os << ", dither: " << paint.isDither();
75 }
76 if (paint.isInvertColors()) {
77 os << ", invertColors: " << paint.isInvertColors();
78 }
79 return os << ")";
80}
81
82std::ostream& operator<<(std::ostream& os, const DlBlendMode& mode) {
83 switch (mode) {
84 case DlBlendMode::kClear: return os << "BlendMode::kClear";
85 case DlBlendMode::kSrc: return os << "BlendMode::kSrc";
86 case DlBlendMode::kDst: return os << "BlendMode::kDst";
87 case DlBlendMode::kSrcOver: return os << "BlendMode::kSrcOver";
88 case DlBlendMode::kDstOver: return os << "BlendMode::kDstOver";
89 case DlBlendMode::kSrcIn: return os << "BlendMode::kSrcIn";
90 case DlBlendMode::kDstIn: return os << "BlendMode::kDstIn";
91 case DlBlendMode::kSrcOut: return os << "BlendMode::kSrcOut";
92 case DlBlendMode::kDstOut: return os << "BlendMode::kDstOut";
93 case DlBlendMode::kSrcATop: return os << "BlendMode::kSrcATop";
94 case DlBlendMode::kDstATop: return os << "BlendMode::kDstATop";
95 case DlBlendMode::kXor: return os << "BlendMode::kXor";
96 case DlBlendMode::kPlus: return os << "BlendMode::kPlus";
97 case DlBlendMode::kModulate: return os << "BlendMode::kModulate";
98 case DlBlendMode::kScreen: return os << "BlendMode::kScreen";
99
100 case DlBlendMode::kOverlay: return os << "BlendMode::kOverlay";
101 case DlBlendMode::kDarken: return os << "BlendMode::kDarken";
102 case DlBlendMode::kLighten: return os << "BlendMode::kLighten";
103 case DlBlendMode::kColorDodge: return os << "BlendMode::kColorDodge";
104 case DlBlendMode::kColorBurn: return os << "BlendMode::kColorBurn";
105 case DlBlendMode::kHardLight: return os << "BlendMode::kHardLight";
106 case DlBlendMode::kSoftLight: return os << "BlendMode::kSoftLight";
107 case DlBlendMode::kDifference: return os << "BlendMode::kDifference";
108 case DlBlendMode::kExclusion: return os << "BlendMode::kExclusion";
109 case DlBlendMode::kMultiply: return os << "BlendMode::kMultiply";
110
111 case DlBlendMode::kHue: return os << "BlendMode::kHue";
112 case DlBlendMode::kSaturation: return os << "BlendMode::kSaturation";
113 case DlBlendMode::kColor: return os << "BlendMode::kColor";
114 case DlBlendMode::kLuminosity: return os << "BlendMode::kLuminosity";
115
116 default: return os << "BlendMode::????";
117 }
118}
119
120std::ostream& operator<<(std::ostream& os, const SaveLayerOptions& options) {
121 return os << "SaveLayerOptions("
122 << "can_distribute_opacity: " << options.can_distribute_opacity()
123 << ", "
124 << "renders_with_attributes: " << options.renders_with_attributes()
125 << ")";
126}
127
128static std::ostream& operator<<(std::ostream& os, const SkPoint& point) {
129 return os << "SkPoint(" << point.fX << ", " << point.fY << ")";
130}
131
132static std::ostream& operator<<(std::ostream& os, const SkIRect& rect) {
133 return os << "SkIRect("
134 << "left: " << rect.fLeft << ", "
135 << "top: " << rect.fTop << ", "
136 << "right: " << rect.fRight << ", "
137 << "bottom: " << rect.fBottom
138 << ")";
139}
140
141static std::ostream& operator<<(std::ostream& os, const SkRect& rect) {
142 return os << "SkRect("
143 << "left: " << rect.fLeft << ", "
144 << "top: " << rect.fTop << ", "
145 << "right: " << rect.fRight << ", "
146 << "bottom: " << rect.fBottom
147 << ")";
148}
149
150static std::ostream& operator<<(std::ostream& os, const SkRect* rect) {
151 return rect ? (os << "&" << *rect) : os << "no rect";
152}
153
154static std::ostream& operator<<(std::ostream& os, const SkRRect& rrect) {
155 return os << "SkRRect("
156 << rrect.rect() << ", "
157 << "ul: (" << rrect.radii(corner: SkRRect::kUpperLeft_Corner).fX << ", "
158 << rrect.radii(corner: SkRRect::kUpperLeft_Corner).fY << "), "
159 << "ur: (" << rrect.radii(corner: SkRRect::kUpperRight_Corner).fX << ", "
160 << rrect.radii(corner: SkRRect::kUpperRight_Corner).fY << "), "
161 << "lr: (" << rrect.radii(corner: SkRRect::kLowerRight_Corner).fX << ", "
162 << rrect.radii(corner: SkRRect::kLowerRight_Corner).fY << "), "
163 << "ll: (" << rrect.radii(corner: SkRRect::kLowerLeft_Corner).fX << ", "
164 << rrect.radii(corner: SkRRect::kLowerLeft_Corner).fY << ")"
165 << ")";
166}
167
168static std::ostream& operator<<(std::ostream& os, const SkPath& path) {
169 return os << "SkPath("
170 << "bounds: " << path.getBounds()
171 // should iterate over verbs and coordinates...
172 << ")";
173}
174
175static std::ostream& operator<<(std::ostream& os, const SkMatrix& matrix) {
176 return os << "SkMatrix("
177 << "[" << matrix[0] << ", " << matrix[1] << ", " << matrix[2] << "], "
178 << "[" << matrix[3] << ", " << matrix[4] << ", " << matrix[5] << "], "
179 << "[" << matrix[6] << ", " << matrix[7] << ", " << matrix[8] << "]"
180 << ")";
181}
182
183static std::ostream& operator<<(std::ostream& os, const SkMatrix* matrix) {
184 if (matrix) return os << "&" << *matrix;
185 return os << "no matrix";
186}
187
188static std::ostream& operator<<(std::ostream& os, const SkRSXform& xform) {
189 return os << "SkRSXform("
190 << "scos: " << xform.fSCos << ", "
191 << "ssin: " << xform.fSSin << ", "
192 << "tx: " << xform.fTx << ", "
193 << "ty: " << xform.fTy << ")";
194}
195
196std::ostream& operator<<(std::ostream& os, const DlCanvas::ClipOp& op) {
197 switch (op) {
198 case DlCanvas::ClipOp::kDifference: return os << "ClipOp::kDifference";
199 case DlCanvas::ClipOp::kIntersect: return os << "ClipOp::kIntersect";
200 }
201}
202
203std::ostream& operator<<(std::ostream& os, const DlCanvas::SrcRectConstraint& constraint) {
204 switch (constraint) {
205 case DlCanvas::SrcRectConstraint::kFast:
206 return os << "SrcRectConstraint::kFast";
207 case DlCanvas::SrcRectConstraint::kStrict:
208 return os << "SrcRectConstraint::kStrict";
209 }
210}
211
212std::ostream& operator<<(std::ostream& os, const DlStrokeCap& cap) {
213 switch (cap) {
214 case DlStrokeCap::kButt: return os << "Cap::kButt";
215 case DlStrokeCap::kRound: return os << "Cap::kRound";
216 case DlStrokeCap::kSquare: return os << "Cap::kSquare";
217 }
218}
219
220std::ostream& operator<<(std::ostream& os, const DlStrokeJoin& join) {
221 switch (join) {
222 case DlStrokeJoin::kMiter: return os << "Join::kMiter";
223 case DlStrokeJoin::kRound: return os << "Join::kRound";
224 case DlStrokeJoin::kBevel: return os << "Join::kBevel";
225 }
226}
227
228std::ostream& operator<<(std::ostream& os, const DlDrawStyle& style) {
229 switch (style) {
230 case DlDrawStyle::kFill: return os << "Style::kFill";
231 case DlDrawStyle::kStroke: return os << "Style::kStroke";
232 case DlDrawStyle::kStrokeAndFill: return os << "Style::kStrokeAnFill";
233 }
234}
235
236std::ostream& operator<<(std::ostream& os, const DlBlurStyle& style) {
237 switch (style) {
238 case DlBlurStyle::kNormal: return os << "BlurStyle::kNormal";
239 case DlBlurStyle::kSolid: return os << "BlurStyle::kSolid";
240 case DlBlurStyle::kOuter: return os << "BlurStyle::kOuter";
241 case DlBlurStyle::kInner: return os << "BlurStyle::kInner";
242 }
243}
244
245std::ostream& operator<<(std::ostream& os, const DlCanvas::PointMode& mode) {
246 switch (mode) {
247 case DlCanvas::PointMode::kPoints: return os << "PointMode::kPoints";
248 case DlCanvas::PointMode::kLines: return os << "PointMode::kLines";
249 case DlCanvas::PointMode::kPolygon: return os << "PointMode::kPolygon";
250 }
251}
252
253std::ostream& operator<<(std::ostream& os, const DlFilterMode& mode) {
254 switch (mode) {
255 case DlFilterMode::kNearest: return os << "FilterMode::kNearest";
256 case DlFilterMode::kLinear: return os << "FilterMode::kLinear";
257
258 default: return os << "FilterMode::????";
259 }
260}
261
262std::ostream& operator<<(std::ostream& os, const DlColor& color) {
263 return os << "DlColor(" << std::hex << color.argb << std::dec << ")";
264}
265
266std::ostream& operator<<(std::ostream& os, DlImageSampling sampling) {
267 switch (sampling) {
268 case DlImageSampling::kNearestNeighbor: {
269 return os << "NearestSampling";
270 }
271 case DlImageSampling::kLinear: {
272 return os << "LinearSampling";
273 }
274 case DlImageSampling::kMipmapLinear: {
275 return os << "MipmapSampling";
276 }
277 case DlImageSampling::kCubic: {
278 return os << "CubicSampling";
279 }
280 }
281}
282
283static std::ostream& operator<<(std::ostream& os, const SkTextBlob* blob) {
284 if (blob == nullptr) {
285 return os << "no text";
286 }
287 return os << "&SkTextBlob(ID: " << blob->uniqueID() << ", " << blob->bounds() << ")";
288}
289
290std::ostream& operator<<(std::ostream& os, const DlVertexMode& mode) {
291 switch (mode) {
292 case DlVertexMode::kTriangles: return os << "VertexMode::kTriangles";
293 case DlVertexMode::kTriangleStrip: return os << "VertexMode::kTriangleStrip";
294 case DlVertexMode::kTriangleFan: return os << "VertexMode::kTriangleFan";
295
296 default: return os << "VertexMode::????";
297 }
298}
299
300std::ostream& operator<<(std::ostream& os, const DlTileMode& mode) {
301 switch (mode) {
302 case DlTileMode::kClamp: return os << "TileMode::kClamp";
303 case DlTileMode::kRepeat: return os << "TileMode::kRepeat";
304 case DlTileMode::kMirror: return os << "TileMode::kMirror";
305 case DlTileMode::kDecal: return os << "TileMode::kDecal";
306
307 default: return os << "TileMode::????";
308 }
309}
310
311std::ostream& operator<<(std::ostream& os, const DlImage* image) {
312 if (image == nullptr) {
313 return os << "null image";
314 }
315 os << "&DlImage(" << image->width() << " x " << image->height() << ", ";
316 if (image->skia_image()) {
317 os << "skia(" << image->skia_image().get() << "), ";
318 }
319 if (image->impeller_texture()) {
320 os << "impeller(" << image->impeller_texture().get() << "), ";
321 }
322 return os << "isTextureBacked: " << image->isTextureBacked() << ")";
323}
324
325std::ostream& DisplayListStreamDispatcher::startl() {
326 for (int i = 0; i < cur_indent_; i++) {
327 os_ << " ";
328 }
329 return os_;
330}
331
332template <class T>
333std::ostream& DisplayListStreamDispatcher::out_array(std::string name, // NOLINT(performance-unnecessary-value-param)
334 int count,
335 const T array[]) {
336 if (array == nullptr || count < 0) {
337 return os_ << "no " << name;
338 }
339 os_ << name << "[" << count << "] = [" << std::endl;
340 indent();
341 indent();
342 for (int i = 0; i < count; i++) {
343 startl() << array[i] << "," << std::endl;
344 }
345 outdent();
346 startl() << "]";
347 outdent();
348 return os_;
349}
350
351void DisplayListStreamDispatcher::setAntiAlias(bool aa) {
352 startl() << "setAntiAlias(" << aa << ");" << std::endl;
353}
354void DisplayListStreamDispatcher::setDither(bool dither) {
355 startl() << "setDither(" << dither << ");" << std::endl;
356}
357void DisplayListStreamDispatcher::setDrawStyle(DlDrawStyle style) {
358 startl() << "setStyle(" << style << ");" << std::endl;
359}
360void DisplayListStreamDispatcher::setColor(DlColor color) {
361 startl() << "setColor(" << color << ");" << std::endl;
362}
363void DisplayListStreamDispatcher::setStrokeWidth(SkScalar width) {
364 startl() << "setStrokeWidth(" << width << ");" << std::endl;
365}
366void DisplayListStreamDispatcher::setStrokeMiter(SkScalar limit) {
367 startl() << "setStrokeMiter(" << limit << ");" << std::endl;
368}
369void DisplayListStreamDispatcher::setStrokeCap(DlStrokeCap cap) {
370 startl() << "setStrokeCap(" << cap << ");" << std::endl;
371}
372void DisplayListStreamDispatcher::setStrokeJoin(DlStrokeJoin join) {
373 startl() << "setStrokeJoin(" << join << ");" << std::endl;
374}
375void DisplayListStreamDispatcher::setColorSource(const DlColorSource* source) {
376 if (source == nullptr) {
377 startl() << "setColorSource(no ColorSource);" << std::endl;
378 return;
379 }
380 startl() << "setColorSource(";
381 switch (source->type()) {
382 case DlColorSourceType::kColor: {
383 const DlColorColorSource* color_src = source->asColor();
384 FML_DCHECK(color_src);
385 os_ << "DlColorColorSource(" << color_src->color() << ")";
386 break;
387 }
388 case DlColorSourceType::kImage: {
389 const DlImageColorSource* image_src = source->asImage();
390 FML_DCHECK(image_src);
391 os_ << "DlImageColorSource(image: " << image_src->image()
392 << ", hMode: " << image_src->horizontal_tile_mode()
393 << ", vMode: " << image_src->vertical_tile_mode()
394 << ", " << image_src->sampling()
395 << ", " << image_src->matrix_ptr()
396 << ")";
397 break;
398 }
399 case DlColorSourceType::kLinearGradient: {
400 const DlLinearGradientColorSource* linear_src = source->asLinearGradient();
401 FML_DCHECK(linear_src);
402 os_ << "DlLinearGradientSource("
403 << "start: " << linear_src->start_point()
404 << ", end: " << linear_src->end_point() << ", ";
405 out_array(name: "colors", count: linear_src->stop_count(), array: linear_src->colors()) << ", ";
406 out_array(name: "stops", count: linear_src->stop_count(), array: linear_src->stops()) << ", "
407 << linear_src->tile_mode() << ", " << linear_src->matrix_ptr() << ")";
408 break;
409 }
410 case DlColorSourceType::kRadialGradient: {
411 const DlRadialGradientColorSource* radial_src = source->asRadialGradient();
412 FML_DCHECK(radial_src);
413 os_ << "DlRadialGradientSource("
414 << "center: " << radial_src->center()
415 << ", radius: " << radial_src->radius() << ", ";
416 out_array(name: "colors", count: radial_src->stop_count(), array: radial_src->colors()) << ", ";
417 out_array(name: "stops", count: radial_src->stop_count(), array: radial_src->stops()) << ", "
418 << radial_src->tile_mode() << ", " << radial_src->matrix_ptr() << ")";
419 break;
420 }
421 case DlColorSourceType::kConicalGradient: {
422 const DlConicalGradientColorSource* conical_src = source->asConicalGradient();
423 FML_DCHECK(conical_src);
424 os_ << "DlConicalGradientColorSource("
425 << "start center: " << conical_src->start_center()
426 << ", start radius: " << conical_src->start_radius()
427 << ", end center: " << conical_src->end_center()
428 << ", end radius: " << conical_src->end_radius() << ", ";
429 out_array(name: "colors", count: conical_src->stop_count(), array: conical_src->colors()) << ", ";
430 out_array(name: "stops", count: conical_src->stop_count(), array: conical_src->stops()) << ", "
431 << conical_src->tile_mode() << ", " << conical_src->matrix_ptr() << ")";
432 break;
433 }
434 case DlColorSourceType::kSweepGradient: {
435 const DlSweepGradientColorSource* sweep_src = source->asSweepGradient();
436 FML_DCHECK(sweep_src);
437 os_ << "DlSweepGradientColorSource("
438 << "center: " << sweep_src->center()
439 << ", start: " << sweep_src->start() << ", "
440 << ", end: " << sweep_src->end() << ", ";
441 out_array(name: "colors", count: sweep_src->stop_count(), array: sweep_src->colors()) << ", ";
442 out_array(name: "stops", count: sweep_src->stop_count(), array: sweep_src->stops()) << ", "
443 << sweep_src->tile_mode() << ", " << sweep_src->matrix_ptr() << ")";
444 break;
445 }
446 default:
447 os_ << "?DlUnknownColorSource?()";
448 break;
449 }
450 os_ << ");" << std::endl;
451}
452void DisplayListStreamDispatcher::out(const DlColorFilter& filter) {
453 switch (filter.type()) {
454 case DlColorFilterType::kBlend: {
455 const DlBlendColorFilter* blend = filter.asBlend();
456 FML_DCHECK(blend);
457 os_ << "DlBlendColorFilter(" << blend->color() << ", "
458 << static_cast<int>(blend->mode()) << ")";
459 break;
460 }
461 case DlColorFilterType::kMatrix: {
462 const DlMatrixColorFilter* matrix = filter.asMatrix();
463 FML_DCHECK(matrix);
464 float values[20];
465 matrix->get_matrix(matrix: values);
466 os_ << "DlMatrixColorFilter(matrix[20] = [" << std::endl;
467 indent();
468 for (int i = 0; i < 20; i += 5) {
469 startl() << values[i] << ", "
470 << values[i+1] << ", "
471 << values[i+2] << ", "
472 << values[i+3] << ", "
473 << values[i+4] << ","
474 << std::endl;
475 }
476 outdent();
477 startl() << "]";
478 break;
479 }
480 case DlColorFilterType::kSrgbToLinearGamma: {
481 os_ << "DlSrgbToLinearGammaColorFilter()";
482 break;
483 }
484 case DlColorFilterType::kLinearToSrgbGamma: {
485 os_ << "DlLinearToSrgbGammaColorFilter()";
486 break;
487 }
488 default:
489 os_ << "?DlUnknownColorFilter?()";
490 break;
491 }
492}
493void DisplayListStreamDispatcher::out(const DlColorFilter* filter) {
494 if (filter == nullptr) {
495 os_ << "no ColorFilter";
496 } else {
497 os_ << "&";
498 out(filter: *filter);
499 }
500}
501void DisplayListStreamDispatcher::setColorFilter(const DlColorFilter* filter) {
502 startl() << "setColorFilter(";
503 out(filter);
504 os_ << ");" << std::endl;
505}
506void DisplayListStreamDispatcher::setInvertColors(bool invert) {
507 startl() << "setInvertColors(" << invert << ");" << std::endl;
508}
509void DisplayListStreamDispatcher::setBlendMode(DlBlendMode mode) {
510 startl() << "setBlendMode(" << mode << ");" << std::endl;
511}
512void DisplayListStreamDispatcher::setPathEffect(const DlPathEffect* effect) {
513 startl() << "setPathEffect(" << effect << ");" << std::endl;
514}
515void DisplayListStreamDispatcher::setMaskFilter(const DlMaskFilter* filter) {
516 if (filter == nullptr) {
517 startl() << "setMaskFilter(no MaskFilter);" << std::endl;
518 return;
519 }
520 startl() << "setMaskFilter(";
521 switch (filter->type()) {
522 case DlMaskFilterType::kBlur: {
523 const DlBlurMaskFilter* blur = filter->asBlur();
524 FML_DCHECK(blur);
525 os_ << "DlMaskFilter(" << blur->style() << ", " << blur->sigma() << ")";
526 break;
527 }
528 default:
529 os_ << "?DlUnknownMaskFilter?()";
530 break;
531 }
532 os_ << ");" << std::endl;
533}
534void DisplayListStreamDispatcher::out(const DlImageFilter& filter) {
535 switch (filter.type()) {
536 case DlImageFilterType::kBlur: {
537 const DlBlurImageFilter* blur = filter.asBlur();
538 FML_DCHECK(blur);
539 os_ << "DlBlurImageFilter(" << blur->sigma_x() << ", "
540 << blur->sigma_y() << ", "
541 << blur->tile_mode() << ")";
542 break;
543 }
544 case DlImageFilterType::kDilate: {
545 const DlDilateImageFilter* dilate = filter.asDilate();
546 FML_DCHECK(dilate);
547 os_ << "DlDilateImageFilter(" << dilate->radius_x() << ", " << dilate->radius_y() << ")";
548 break;
549 }
550 case DlImageFilterType::kErode: {
551 const DlErodeImageFilter* erode = filter.asErode();
552 FML_DCHECK(erode);
553 os_ << "DlDilateImageFilter(" << erode->radius_x() << ", " << erode->radius_y() << ")";
554 break;
555 }
556 case DlImageFilterType::kMatrix: {
557 const DlMatrixImageFilter* matrix = filter.asMatrix();
558 FML_DCHECK(matrix);
559 os_ << "DlMatrixImageFilter(" << matrix->matrix() << ", " << matrix->sampling() << ")";
560 break;
561 }
562 case DlImageFilterType::kCompose: {
563 const DlComposeImageFilter* compose = filter.asCompose();
564 FML_DCHECK(compose);
565 os_ << "DlComposeImageFilter(" << std::endl;
566 indent();
567 startl() << "outer: ";
568 indent(spaces: 7);
569 out(filter: compose->outer().get());
570 os_ << "," << std::endl;
571 outdent(spaces: 7);
572 startl() << "inner: ";
573 indent(spaces: 7);
574 out(filter: compose->inner().get());
575 os_ << std::endl;
576 outdent(spaces: 7);
577 outdent();
578 startl() << ")";
579 break;
580 }
581 case DlImageFilterType::kColorFilter: {
582 const DlColorFilterImageFilter* color_filter = filter.asColorFilter();
583 FML_DCHECK(color_filter);
584 os_ << "DlColorFilterImageFilter(";
585 out(filter: *color_filter->color_filter());
586 os_ << ")";
587 break;
588 }
589 case DlImageFilterType::kLocalMatrix: {
590 const DlLocalMatrixImageFilter* local_matrix = filter.asLocalMatrix();
591 FML_DCHECK(local_matrix);
592 os_ << "DlLocalMatrixImageFilter(" << local_matrix->matrix();
593 os_ << "," << std::endl;
594 indent(spaces: 25);
595 startl() << "filter: ";
596 out(filter: local_matrix->image_filter().get());
597 os_ << std::endl;
598 outdent(spaces: 25);
599 startl() << ")";
600 break;
601 }
602 }
603}
604void DisplayListStreamDispatcher::out(const DlImageFilter* filter) {
605 if (filter == nullptr) {
606 os_ << "no ImageFilter";
607 } else {
608 os_ << "&";
609 indent(spaces: 1);
610 out(filter: *filter);
611 outdent(spaces: 1);
612 }
613}
614void DisplayListStreamDispatcher::setImageFilter(const DlImageFilter* filter) {
615 startl() << "setImageFilter(";
616 indent(spaces: 15);
617 out(filter);
618 outdent(spaces: 15);
619 os_ << ");" << std::endl;
620}
621void DisplayListStreamDispatcher::save() {
622 startl() << "save();" << std::endl;
623 startl() << "{" << std::endl;
624 indent();
625}
626void DisplayListStreamDispatcher::saveLayer(const SkRect* bounds,
627 const SaveLayerOptions options,
628 const DlImageFilter* backdrop) {
629 startl() << "saveLayer(" << bounds << ", " << options;
630 if (backdrop) {
631 os_ << "," << std::endl;
632 indent(spaces: 10);
633 startl() << "backdrop: ";
634 out(filter: backdrop);
635 outdent(spaces: 10);
636 } else {
637 os_ << ", no backdrop";
638 }
639 os_ << ");" << std::endl;
640 startl() << "{" << std::endl;
641 indent();
642}
643void DisplayListStreamDispatcher::restore() {
644 outdent();
645 startl() << "}" << std::endl;
646 startl() << "restore();" << std::endl;
647}
648
649void DisplayListStreamDispatcher::translate(SkScalar tx, SkScalar ty) {
650 startl() << "translate(" << tx << ", " << ty << ");" << std::endl;
651}
652void DisplayListStreamDispatcher::scale(SkScalar sx, SkScalar sy) {
653 startl() << "scale(" << sx << ", " << sy << ");" << std::endl;
654}
655void DisplayListStreamDispatcher::rotate(SkScalar degrees) {
656 startl() << "rotate(" << degrees << ");" << std::endl;
657}
658void DisplayListStreamDispatcher::skew(SkScalar sx, SkScalar sy) {
659 startl() << "skew(" << sx << ", " << sy << ");" << std::endl;
660}
661void DisplayListStreamDispatcher::transform2DAffine(
662 SkScalar mxx, SkScalar mxy, SkScalar mxt,
663 SkScalar myx, SkScalar myy, SkScalar myt) {
664 startl() << "transform2DAffine(" << std::endl;
665 indent();
666 {
667 startl()
668 << "[" << mxx << ", " << mxy << ", " << mxt << "], "
669 << std::endl;
670 startl()
671 << "[" << myx << ", " << myy << ", " << myt << "], "
672 << std::endl;
673 }
674 outdent();
675 startl() << ");" << std::endl;
676}
677void DisplayListStreamDispatcher::transformFullPerspective(
678 SkScalar mxx, SkScalar mxy, SkScalar mxz, SkScalar mxt,
679 SkScalar myx, SkScalar myy, SkScalar myz, SkScalar myt,
680 SkScalar mzx, SkScalar mzy, SkScalar mzz, SkScalar mzt,
681 SkScalar mwx, SkScalar mwy, SkScalar mwz, SkScalar mwt) {
682 startl() << "transformFullPerspective(" << std::endl;
683 indent();
684 {
685 startl()
686 << "[" << mxx << ", " << mxy << ", " << mxz << ", " << mxt << "], "
687 << std::endl;
688 startl()
689 << "[" << myx << ", " << myy << ", " << myz << ", " << myt << "], "
690 << std::endl;
691 startl()
692 << "[" << mzx << ", " << mzy << ", " << mzz << ", " << mzt << "], "
693 << std::endl;
694 startl()
695 << "[" << mwx << ", " << mwy << ", " << mwz << ", " << mwt << "]"
696 << std::endl;
697 }
698 outdent();
699 startl() << ");" << std::endl;
700}
701void DisplayListStreamDispatcher::transformReset() {
702 startl() << "transformReset();" << std::endl;
703}
704
705void DisplayListStreamDispatcher::clipRect(const SkRect& rect, ClipOp clip_op,
706 bool is_aa) {
707 startl() << "clipRect("
708 << rect << ", "
709 << clip_op << ", "
710 << "isaa: " << is_aa
711 << ");" << std::endl;
712}
713void DisplayListStreamDispatcher::clipRRect(const SkRRect& rrect,
714 ClipOp clip_op,
715 bool is_aa) {
716 startl() << "clipRRect("
717 << rrect << ", "
718 << clip_op << ", "
719 << "isaa: " << is_aa
720 << ");" << std::endl;
721}
722void DisplayListStreamDispatcher::clipPath(const SkPath& path, ClipOp clip_op,
723 bool is_aa) {
724 startl() << "clipPath("
725 << path << ", "
726 << clip_op << ", "
727 << "isaa: " << is_aa
728 << ");" << std::endl;
729}
730
731void DisplayListStreamDispatcher::drawColor(DlColor color, DlBlendMode mode) {
732 startl() << "drawColor("
733 << color << ", "
734 << mode
735 << ");" << std::endl;
736}
737void DisplayListStreamDispatcher::drawPaint() {
738 startl() << "drawPaint();" << std::endl;
739}
740void DisplayListStreamDispatcher::drawLine(const SkPoint& p0,
741 const SkPoint& p1) {
742 startl() << "drawLine(" << p0 << ", " << p1 << ");" << std::endl;
743}
744void DisplayListStreamDispatcher::drawRect(const SkRect& rect) {
745 startl() << "drawRect(" << rect << ");" << std::endl;
746}
747void DisplayListStreamDispatcher::drawOval(const SkRect& bounds) {
748 startl() << "drawOval(" << bounds << ");" << std::endl;
749}
750void DisplayListStreamDispatcher::drawCircle(const SkPoint& center,
751 SkScalar radius) {
752 startl() << "drawCircle(" << center << ", " << radius << ");" << std::endl;
753}
754void DisplayListStreamDispatcher::drawRRect(const SkRRect& rrect) {
755 startl() << "drawRRect(" << rrect << ");" << std::endl;
756}
757void DisplayListStreamDispatcher::drawDRRect(const SkRRect& outer,
758 const SkRRect& inner) {
759 startl() << "drawDRRect(outer: " << outer << ", " << std::endl;
760 startl() << " inner: " << inner << ");" << std::endl;
761}
762void DisplayListStreamDispatcher::drawPath(const SkPath& path) {
763 startl() << "drawPath(" << path << ");" << std::endl;
764}
765void DisplayListStreamDispatcher::drawArc(const SkRect& oval_bounds,
766 SkScalar start_degrees,
767 SkScalar sweep_degrees,
768 bool use_center) {
769 startl() << "drawArc("
770 << oval_bounds << ", "
771 << start_degrees << ", "
772 << sweep_degrees << ", "
773 << "use_center: " << use_center
774 << ");" << std::endl;
775}
776void DisplayListStreamDispatcher::drawPoints(PointMode mode,
777 uint32_t count,
778 const SkPoint points[]) {
779 startl() << "drawPoints(" << mode << ", ";
780 out_array(name: "points", count, array: points)
781 << ");" << std::endl;
782}
783void DisplayListStreamDispatcher::drawVertices(const DlVertices* vertices,
784 DlBlendMode mode) {
785 startl() << "drawVertices("
786 << "DlVertices("
787 << vertices->mode() << ", ";
788 out_array(name: "vertices", count: vertices->vertex_count(), array: vertices->vertices()) << ", ";
789 out_array(name: "texture_coords", count: vertices->vertex_count(), array: vertices->texture_coordinates()) << ", ";
790 out_array(name: "colors", count: vertices->vertex_count(), array: vertices->colors()) << ", ";
791 out_array(name: "indices", count: vertices->index_count(), array: vertices->indices())
792 << "), " << mode << ");" << std::endl;
793}
794void DisplayListStreamDispatcher::drawImage(const sk_sp<DlImage> image,
795 const SkPoint point,
796 DlImageSampling sampling,
797 bool render_with_attributes) {
798 startl() << "drawImage(" << image.get() << "," << std::endl;
799 startl() << " " << point << ", "
800 << sampling << ", "
801 << "with attributes: " << render_with_attributes
802 << ");" << std::endl;
803}
804void DisplayListStreamDispatcher::drawImageRect(const sk_sp<DlImage> image,
805 const SkRect& src,
806 const SkRect& dst,
807 DlImageSampling sampling,
808 bool render_with_attributes,
809 SrcRectConstraint constraint) {
810 startl() << "drawImageRect(" << image.get() << "," << std::endl;
811 startl() << " src: " << src << "," << std::endl;
812 startl() << " dst: " << dst << "," << std::endl;
813 startl() << " " << sampling << ", "
814 << "with attributes: " << render_with_attributes << ", "
815 << constraint
816 << ");" << std::endl;
817}
818void DisplayListStreamDispatcher::drawImageNine(const sk_sp<DlImage> image,
819 const SkIRect& center,
820 const SkRect& dst,
821 DlFilterMode filter,
822 bool render_with_attributes) {
823 startl() << "drawImageNine(" << image.get() << "," << std::endl;
824 startl() << " center: " << center << "," << std::endl;
825 startl() << " dst: " << dst << "," << std::endl;
826 startl() << " " << filter << ", "
827 << "with attributes: " << render_with_attributes
828 << ");" << std::endl;
829}
830void DisplayListStreamDispatcher::drawAtlas(const sk_sp<DlImage> atlas,
831 const SkRSXform xform[],
832 const SkRect tex[],
833 const DlColor colors[],
834 int count,
835 DlBlendMode mode,
836 DlImageSampling sampling,
837 const SkRect* cull_rect,
838 bool render_with_attributes) {
839 startl() << "drawAtlas(" << atlas.get() << ", ";
840 out_array(name: "xforms", count, array: xform) << ", ";
841 out_array(name: "tex_coords", count, array: tex) << ", ";
842 out_array(name: "colors", count, array: colors) << ", "
843 << mode << ", " << sampling << ", cull: " << cull_rect << ", "
844 << "with attributes: " << render_with_attributes
845 << ");" << std::endl;
846}
847void DisplayListStreamDispatcher::drawDisplayList(
848 const sk_sp<DisplayList> display_list, SkScalar opacity) {
849 startl() << "drawDisplayList("
850 << "ID: " << display_list->unique_id() << ", "
851 << "bounds: " << display_list->bounds() << ", "
852 << "opacity: " << opacity
853 << ");" << std::endl;
854}
855void DisplayListStreamDispatcher::drawTextBlob(const sk_sp<SkTextBlob> blob,
856 SkScalar x,
857 SkScalar y) {
858 startl() << "drawTextBlob("
859 << blob.get() << ", "
860 << x << ", " << y << ");" << std::endl;
861}
862void DisplayListStreamDispatcher::drawShadow(const SkPath& path,
863 const DlColor color,
864 const SkScalar elevation,
865 bool transparent_occluder,
866 SkScalar dpr) {
867 startl() << "drawShadow("
868 << path << ", "
869 << color << ", "
870 << elevation << ", "
871 << transparent_occluder << ", "
872 << dpr
873 << ");" << std::endl;
874}
875// clang-format on
876
877} // namespace testing
878} // namespace flutter
879

source code of flutter_engine/flutter/testing/display_list_testing.cc