| 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 | |
| 11 | namespace flutter { |
| 12 | namespace testing { |
| 13 | |
| 14 | // clang-format off |
| 15 | bool 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 | |
| 28 | bool 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 | |
| 38 | std::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 | |
| 49 | std::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 | |
| 82 | std::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 | |
| 120 | std::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 | |
| 128 | static std::ostream& operator<<(std::ostream& os, const SkPoint& point) { |
| 129 | return os << "SkPoint(" << point.fX << ", " << point.fY << ")" ; |
| 130 | } |
| 131 | |
| 132 | static 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 | |
| 141 | static 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 | |
| 150 | static std::ostream& operator<<(std::ostream& os, const SkRect* rect) { |
| 151 | return rect ? (os << "&" << *rect) : os << "no rect" ; |
| 152 | } |
| 153 | |
| 154 | static 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 | |
| 168 | static 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 | |
| 175 | static 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 | |
| 183 | static std::ostream& operator<<(std::ostream& os, const SkMatrix* matrix) { |
| 184 | if (matrix) return os << "&" << *matrix; |
| 185 | return os << "no matrix" ; |
| 186 | } |
| 187 | |
| 188 | static 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 | |
| 196 | std::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 | |
| 203 | std::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 | |
| 212 | std::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 | |
| 220 | std::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 | |
| 228 | std::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 | |
| 236 | std::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 | |
| 245 | std::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 | |
| 253 | std::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 | |
| 262 | std::ostream& operator<<(std::ostream& os, const DlColor& color) { |
| 263 | return os << "DlColor(" << std::hex << color.argb << std::dec << ")" ; |
| 264 | } |
| 265 | |
| 266 | std::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 | |
| 283 | static 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 | |
| 290 | std::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 | |
| 300 | std::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 | |
| 311 | std::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 | |
| 325 | std::ostream& DisplayListStreamDispatcher::startl() { |
| 326 | for (int i = 0; i < cur_indent_; i++) { |
| 327 | os_ << " " ; |
| 328 | } |
| 329 | return os_; |
| 330 | } |
| 331 | |
| 332 | template <class T> |
| 333 | std::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 | |
| 351 | void DisplayListStreamDispatcher::setAntiAlias(bool aa) { |
| 352 | startl() << "setAntiAlias(" << aa << ");" << std::endl; |
| 353 | } |
| 354 | void DisplayListStreamDispatcher::setDither(bool dither) { |
| 355 | startl() << "setDither(" << dither << ");" << std::endl; |
| 356 | } |
| 357 | void DisplayListStreamDispatcher::setDrawStyle(DlDrawStyle style) { |
| 358 | startl() << "setStyle(" << style << ");" << std::endl; |
| 359 | } |
| 360 | void DisplayListStreamDispatcher::setColor(DlColor color) { |
| 361 | startl() << "setColor(" << color << ");" << std::endl; |
| 362 | } |
| 363 | void DisplayListStreamDispatcher::setStrokeWidth(SkScalar width) { |
| 364 | startl() << "setStrokeWidth(" << width << ");" << std::endl; |
| 365 | } |
| 366 | void DisplayListStreamDispatcher::setStrokeMiter(SkScalar limit) { |
| 367 | startl() << "setStrokeMiter(" << limit << ");" << std::endl; |
| 368 | } |
| 369 | void DisplayListStreamDispatcher::setStrokeCap(DlStrokeCap cap) { |
| 370 | startl() << "setStrokeCap(" << cap << ");" << std::endl; |
| 371 | } |
| 372 | void DisplayListStreamDispatcher::setStrokeJoin(DlStrokeJoin join) { |
| 373 | startl() << "setStrokeJoin(" << join << ");" << std::endl; |
| 374 | } |
| 375 | void 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 | } |
| 452 | void 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 | } |
| 493 | void DisplayListStreamDispatcher::out(const DlColorFilter* filter) { |
| 494 | if (filter == nullptr) { |
| 495 | os_ << "no ColorFilter" ; |
| 496 | } else { |
| 497 | os_ << "&" ; |
| 498 | out(filter: *filter); |
| 499 | } |
| 500 | } |
| 501 | void DisplayListStreamDispatcher::setColorFilter(const DlColorFilter* filter) { |
| 502 | startl() << "setColorFilter(" ; |
| 503 | out(filter); |
| 504 | os_ << ");" << std::endl; |
| 505 | } |
| 506 | void DisplayListStreamDispatcher::setInvertColors(bool invert) { |
| 507 | startl() << "setInvertColors(" << invert << ");" << std::endl; |
| 508 | } |
| 509 | void DisplayListStreamDispatcher::setBlendMode(DlBlendMode mode) { |
| 510 | startl() << "setBlendMode(" << mode << ");" << std::endl; |
| 511 | } |
| 512 | void DisplayListStreamDispatcher::setPathEffect(const DlPathEffect* effect) { |
| 513 | startl() << "setPathEffect(" << effect << ");" << std::endl; |
| 514 | } |
| 515 | void 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 | } |
| 534 | void 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 | } |
| 604 | void 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 | } |
| 614 | void DisplayListStreamDispatcher::setImageFilter(const DlImageFilter* filter) { |
| 615 | startl() << "setImageFilter(" ; |
| 616 | indent(spaces: 15); |
| 617 | out(filter); |
| 618 | outdent(spaces: 15); |
| 619 | os_ << ");" << std::endl; |
| 620 | } |
| 621 | void DisplayListStreamDispatcher::save() { |
| 622 | startl() << "save();" << std::endl; |
| 623 | startl() << "{" << std::endl; |
| 624 | indent(); |
| 625 | } |
| 626 | void 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 | } |
| 643 | void DisplayListStreamDispatcher::restore() { |
| 644 | outdent(); |
| 645 | startl() << "}" << std::endl; |
| 646 | startl() << "restore();" << std::endl; |
| 647 | } |
| 648 | |
| 649 | void DisplayListStreamDispatcher::translate(SkScalar tx, SkScalar ty) { |
| 650 | startl() << "translate(" << tx << ", " << ty << ");" << std::endl; |
| 651 | } |
| 652 | void DisplayListStreamDispatcher::scale(SkScalar sx, SkScalar sy) { |
| 653 | startl() << "scale(" << sx << ", " << sy << ");" << std::endl; |
| 654 | } |
| 655 | void DisplayListStreamDispatcher::rotate(SkScalar degrees) { |
| 656 | startl() << "rotate(" << degrees << ");" << std::endl; |
| 657 | } |
| 658 | void DisplayListStreamDispatcher::skew(SkScalar sx, SkScalar sy) { |
| 659 | startl() << "skew(" << sx << ", " << sy << ");" << std::endl; |
| 660 | } |
| 661 | void 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 | } |
| 677 | void 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 | } |
| 701 | void DisplayListStreamDispatcher::transformReset() { |
| 702 | startl() << "transformReset();" << std::endl; |
| 703 | } |
| 704 | |
| 705 | void 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 | } |
| 713 | void 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 | } |
| 722 | void 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 | |
| 731 | void DisplayListStreamDispatcher::drawColor(DlColor color, DlBlendMode mode) { |
| 732 | startl() << "drawColor(" |
| 733 | << color << ", " |
| 734 | << mode |
| 735 | << ");" << std::endl; |
| 736 | } |
| 737 | void DisplayListStreamDispatcher::drawPaint() { |
| 738 | startl() << "drawPaint();" << std::endl; |
| 739 | } |
| 740 | void DisplayListStreamDispatcher::drawLine(const SkPoint& p0, |
| 741 | const SkPoint& p1) { |
| 742 | startl() << "drawLine(" << p0 << ", " << p1 << ");" << std::endl; |
| 743 | } |
| 744 | void DisplayListStreamDispatcher::drawRect(const SkRect& rect) { |
| 745 | startl() << "drawRect(" << rect << ");" << std::endl; |
| 746 | } |
| 747 | void DisplayListStreamDispatcher::drawOval(const SkRect& bounds) { |
| 748 | startl() << "drawOval(" << bounds << ");" << std::endl; |
| 749 | } |
| 750 | void DisplayListStreamDispatcher::drawCircle(const SkPoint& center, |
| 751 | SkScalar radius) { |
| 752 | startl() << "drawCircle(" << center << ", " << radius << ");" << std::endl; |
| 753 | } |
| 754 | void DisplayListStreamDispatcher::drawRRect(const SkRRect& rrect) { |
| 755 | startl() << "drawRRect(" << rrect << ");" << std::endl; |
| 756 | } |
| 757 | void DisplayListStreamDispatcher::drawDRRect(const SkRRect& outer, |
| 758 | const SkRRect& inner) { |
| 759 | startl() << "drawDRRect(outer: " << outer << ", " << std::endl; |
| 760 | startl() << " inner: " << inner << ");" << std::endl; |
| 761 | } |
| 762 | void DisplayListStreamDispatcher::drawPath(const SkPath& path) { |
| 763 | startl() << "drawPath(" << path << ");" << std::endl; |
| 764 | } |
| 765 | void 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 | } |
| 776 | void 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 | } |
| 783 | void 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 | } |
| 794 | void 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 | } |
| 804 | void 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 | } |
| 818 | void 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 | } |
| 830 | void 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 | } |
| 847 | void 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 | } |
| 855 | void 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 | } |
| 862 | void 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 | |