Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
mock_canvas.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/testing/mock_canvas.h"
6
7#include "flutter/fml/logging.h"
8#include "flutter/testing/display_list_testing.h"
13
14namespace flutter {
15namespace testing {
16
17constexpr SkISize kSize = SkISize::Make(64, 64);
18
20 : tracker_(SkRect::Make(kSize), SkMatrix::I()), current_layer_(0) {}
21
23 : tracker_(SkRect::MakeIWH(width, height), SkMatrix::I()),
24 current_layer_(0) {}
25
27 EXPECT_EQ(current_layer_, 0);
28}
29
31 return tracker_.base_device_cull_rect().roundOut().size();
32}
33
38
40 draw_calls_.emplace_back(
41 DrawCall{current_layer_, SaveData{current_layer_ + 1}});
42 tracker_.save();
43 current_layer_++; // Must go here; func params order of eval is undefined
44}
45
46void MockCanvas::SaveLayer(const SkRect* bounds,
47 const DlPaint* paint,
48 const DlImageFilter* backdrop) {
49 // saveLayer calls this prior to running, so we use it to track saveLayer
50 // calls
51 draw_calls_.emplace_back(DrawCall{
52 current_layer_,
53 SaveLayerData{bounds ? *bounds : SkRect(), paint ? *paint : DlPaint(),
54 backdrop ? backdrop->shared() : nullptr,
55 current_layer_ + 1}});
56 tracker_.save();
57 current_layer_++; // Must go here; func params order of eval is undefined
58}
59
61 FML_DCHECK(current_layer_ > 0);
62
63 draw_calls_.emplace_back(
64 DrawCall{current_layer_, RestoreData{current_layer_ - 1}});
65 tracker_.restore();
66 current_layer_--; // Must go here; func params order of eval is undefined
67}
68
69// clang-format off
70
71// 2x3 2D affine subset of a 4x4 transform in row major order
73 SkScalar myx, SkScalar myy, SkScalar myt) {
74 Transform(SkMatrix::MakeAll(mxx, mxy, mxt, myx, myy, myt, 0, 0, 1));
75}
76
77// full 4x4 transform in row major order
79 SkScalar mxx, SkScalar mxy, SkScalar mxz, SkScalar mxt,
80 SkScalar myx, SkScalar myy, SkScalar myz, SkScalar myt,
81 SkScalar mzx, SkScalar mzy, SkScalar mzz, SkScalar mzt,
82 SkScalar mwx, SkScalar mwy, SkScalar mwz, SkScalar mwt) {
83 Transform(SkM44(mxx, mxy, mxz, mxt,
84 myx, myy, myz, myt,
85 mzx, mzy, mzz, mzt,
86 mwx, mwy, mwz, mwt));
87}
88
89// clang-format on
90
91void MockCanvas::Transform(const SkMatrix* matrix) {
92 draw_calls_.emplace_back(
93 DrawCall{current_layer_, ConcatMatrixData{SkM44(*matrix)}});
94 tracker_.transform(*matrix);
95}
96
97void MockCanvas::Transform(const SkM44* matrix) {
98 draw_calls_.emplace_back(DrawCall{current_layer_, ConcatMatrixData{*matrix}});
99 tracker_.transform(*matrix);
100}
101
103 draw_calls_.emplace_back(
104 DrawCall{current_layer_, SetMatrixData{SkM44(*matrix)}});
105 tracker_.setTransform(*matrix);
106}
107
108void MockCanvas::SetTransform(const SkM44* matrix) {
109 draw_calls_.emplace_back(DrawCall{current_layer_, SetMatrixData{*matrix}});
110 tracker_.setTransform(*matrix);
111}
112
114 draw_calls_.emplace_back(DrawCall{current_layer_, SetMatrixData{SkM44()}});
115 tracker_.setIdentity();
116}
117
121
125
127 this->Transform(SkMatrix::RotateDeg(degrees));
128}
129
131 this->Transform(SkMatrix::Skew(sx, sy));
132}
133
135 return tracker_.matrix_4x4();
136}
137
139 return tracker_.matrix_3x3();
140}
141
143 SkScalar x,
144 SkScalar y,
145 const DlPaint& paint) {
146 // This duplicates existing logic in SkCanvas::onDrawPicture
147 // that should probably be split out so it doesn't need to be here as well.
148 // SkRect storage;
149 // if (paint.canComputeFastBounds()) {
150 // storage = text->bounds().makeOffset(x, y);
151 // SkRect tmp;
152 // if (this->quickReject(paint.computeFastBounds(storage, &tmp))) {
153 // return;
154 // }
155 // }
156
157 draw_calls_.emplace_back(DrawCall{
158 current_layer_, DrawTextData{text ? text->serialize(SkSerialProcs{})
160 paint, SkPoint::Make(x, y)}});
161}
162
164 const std::shared_ptr<impeller::TextFrame>& text_frame,
165 SkScalar x,
166 SkScalar y,
167 const DlPaint& paint) {
168 FML_DCHECK(false);
169}
170
171void MockCanvas::DrawRect(const SkRect& rect, const DlPaint& paint) {
172 draw_calls_.emplace_back(DrawCall{current_layer_, DrawRectData{rect, paint}});
173}
174
176 draw_calls_.emplace_back(DrawCall{current_layer_, DrawPathData{path, paint}});
177}
178
180 const DlColor color,
181 const SkScalar elevation,
182 bool transparent_occluder,
183 SkScalar dpr) {
184 draw_calls_.emplace_back(DrawCall{
185 current_layer_,
186 DrawShadowData{path, color, elevation, transparent_occluder, dpr}});
187}
188
190 SkPoint point,
192 const DlPaint* paint) {
193 if (paint) {
194 draw_calls_.emplace_back(
195 DrawCall{current_layer_,
196 DrawImageData{image, point.fX, point.fY, options, *paint}});
197 } else {
198 draw_calls_.emplace_back(
199 DrawCall{current_layer_,
200 DrawImageDataNoPaint{image, point.fX, point.fY, options}});
201 }
202}
203
205 SkScalar opacity) {
206 draw_calls_.emplace_back(
207 DrawCall{current_layer_, DrawDisplayListData{display_list, opacity}});
208}
209
210void MockCanvas::ClipRect(const SkRect& rect, ClipOp op, bool is_aa) {
212 draw_calls_.emplace_back(
213 DrawCall{current_layer_, ClipRectData{rect, op, style}});
214 tracker_.clipRect(rect, op, is_aa);
215}
216
217void MockCanvas::ClipRRect(const SkRRect& rrect, ClipOp op, bool is_aa) {
219 draw_calls_.emplace_back(
220 DrawCall{current_layer_, ClipRRectData{rrect, op, style}});
221 tracker_.clipRRect(rrect, op, is_aa);
222}
223
224void MockCanvas::ClipPath(const SkPath& path, ClipOp op, bool is_aa) {
226 draw_calls_.emplace_back(
227 DrawCall{current_layer_, ClipPathData{path, op, style}});
228 tracker_.clipPath(path, op, is_aa);
229}
230
234
236 return tracker_.local_cull_rect();
237}
238
239bool MockCanvas::QuickReject(const SkRect& bounds) const {
240 return tracker_.content_culled(bounds);
241}
242
243void MockCanvas::DrawDRRect(const SkRRect&, const SkRRect&, const DlPaint&) {
244 FML_DCHECK(false);
245}
246
248 draw_calls_.emplace_back(DrawCall{current_layer_, DrawPaintData{paint}});
249}
250
254
256 const SkPoint& p1,
257 const DlPaint& paint) {
258 FML_DCHECK(false);
259}
260
262 uint32_t,
263 const SkPoint[],
264 const DlPaint&) {
265 FML_DCHECK(false);
266}
267
268void MockCanvas::DrawOval(const SkRect&, const DlPaint&) {
269 FML_DCHECK(false);
270}
271
273 SkScalar radius,
274 const DlPaint& paint) {
275 FML_DCHECK(false);
276}
277
279 SkScalar,
280 SkScalar,
281 bool,
282 const DlPaint&) {
283 FML_DCHECK(false);
284}
285
287 FML_DCHECK(false);
288}
289
291 const SkRect&,
292 const SkRect&,
293 const DlImageSampling,
294 const DlPaint*,
295 SrcRectConstraint constraint) {
296 FML_DCHECK(false);
297}
298
300 const SkIRect& center,
301 const SkRect& dst,
302 DlFilterMode filter,
303 const DlPaint* paint) {
304 FML_DCHECK(false);
305}
306
308 FML_DCHECK(false);
309}
310
312 const SkRSXform[],
313 const SkRect[],
314 const DlColor[],
315 int,
317 const DlImageSampling,
318 const SkRect*,
319 const DlPaint*) {
320 FML_DCHECK(false);
321}
322
324 FML_DCHECK(false);
325}
326
327// --------------------------------------------------------
328// A few ostream operators duplicated from assertions_skia.cc
329// In the short term, there are issues trying to include that file
330// here because it appears in a skia-targeted testing source set
331// and in the long term, DlCanvas, and therefore this file will
332// eventually be cleaned of these SkObject dependencies and these
333// ostream operators will be converted to their DL equivalents.
334static std::ostream& operator<<(std::ostream& os, const SkPoint& r) {
335 return os << "XY: " << r.fX << ", " << r.fY;
336}
337
338static std::ostream& operator<<(std::ostream& os, const SkRect& r) {
339 return os << "LTRB: " << r.fLeft << ", " << r.fTop << ", " << r.fRight << ", "
340 << r.fBottom;
341}
342
343static std::ostream& operator<<(std::ostream& os, const SkRRect& r) {
344 return os << "LTRB: " << r.rect().fLeft << ", " << r.rect().fTop << ", "
345 << r.rect().fRight << ", " << r.rect().fBottom;
346}
347
348static std::ostream& operator<<(std::ostream& os, const SkPath& r) {
349 return os << "Valid: " << r.isValid()
350 << ", FillType: " << static_cast<int>(r.getFillType())
351 << ", Bounds: " << r.getBounds();
352}
353// --------------------------------------------------------
354
355static std::ostream& operator<<(std::ostream& os, const SkM44& m) {
356 os << m.rc(0, 0) << ", " << m.rc(0, 1) << ", " << m.rc(0, 2) << ", "
357 << m.rc(0, 3) << std::endl;
358 os << m.rc(1, 0) << ", " << m.rc(1, 1) << ", " << m.rc(1, 2) << ", "
359 << m.rc(1, 3) << std::endl;
360 os << m.rc(2, 0) << ", " << m.rc(2, 1) << ", " << m.rc(2, 2) << ", "
361 << m.rc(2, 3) << std::endl;
362 os << m.rc(3, 0) << ", " << m.rc(3, 1) << ", " << m.rc(3, 2) << ", "
363 << m.rc(3, 3);
364 return os;
365}
366
368 return a.save_to_layer == b.save_to_layer;
369}
370
371std::ostream& operator<<(std::ostream& os, const MockCanvas::SaveData& data) {
372 return os << data.save_to_layer;
373}
374
377 return a.save_bounds == b.save_bounds && a.restore_paint == b.restore_paint &&
378 Equals(a.backdrop_filter, b.backdrop_filter) &&
379 a.save_to_layer == b.save_to_layer;
380}
381
382std::ostream& operator<<(std::ostream& os,
384 return os << data.save_bounds << " " << data.restore_paint << " "
385 << data.backdrop_filter << " " << data.save_to_layer;
386}
387
389 const MockCanvas::RestoreData& b) {
390 return a.restore_to_layer == b.restore_to_layer;
391}
392
393std::ostream& operator<<(std::ostream& os,
395 return os << data.restore_to_layer;
396}
397
400 return a.matrix == b.matrix;
401}
402
403std::ostream& operator<<(std::ostream& os,
405 return os << data.matrix;
406}
407
410 return a.matrix == b.matrix;
411}
412
413std::ostream& operator<<(std::ostream& os,
415 return os << data.matrix;
416}
417
420 return a.rect == b.rect && a.paint == b.paint;
421}
422
423std::ostream& operator<<(std::ostream& os,
425 return os << data.rect << " " << data.paint;
426}
427
430 return a.path == b.path && a.paint == b.paint;
431}
432
433std::ostream& operator<<(std::ostream& os,
435 return os << data.path << " " << data.paint;
436}
437
440 return a.serialized_text->equals(b.serialized_text.get()) &&
441 a.paint == b.paint && a.offset == b.offset;
442}
443
444std::ostream& operator<<(std::ostream& os,
446 return os << data.serialized_text << " " << data.paint << " " << data.offset;
447}
448
451 return a.image == b.image && a.x == b.x && a.y == b.y &&
452 a.options == b.options && a.paint == b.paint;
453}
454
455std::ostream& operator<<(std::ostream& os,
457 return os << data.image << " " << data.x << " " << data.y << " "
458 << data.options << " " << data.paint;
459}
460
463 return a.image == b.image && a.x == b.x && a.y == b.y &&
464 a.options == b.options;
465}
466
467std::ostream& operator<<(std::ostream& os,
469 return os << data.image << " " << data.x << " " << data.y << " "
470 << data.options;
471}
472
475 return a.display_list->Equals(b.display_list) && a.opacity == b.opacity;
476}
477
478std::ostream& operator<<(std::ostream& os,
480 auto dl = data.display_list;
481 return os << "[" << dl->unique_id() << " " << dl->op_count() << " "
482 << dl->bytes() << "] " << data.opacity;
483}
484
487 return a.path == b.path && a.color == b.color && a.elevation == b.elevation &&
488 a.transparent_occluder == b.transparent_occluder && a.dpr == b.dpr;
489}
490
491std::ostream& operator<<(std::ostream& os,
493 return os << data.path << " " << data.color << " " << data.elevation << " "
494 << data.transparent_occluder << " " << data.dpr;
495}
496
499 return a.rect == b.rect && a.clip_op == b.clip_op && a.style == b.style;
500}
501
502static std::ostream& operator<<(std::ostream& os,
503 const MockCanvas::ClipEdgeStyle& style) {
504 return os << (style == MockCanvas::kSoftClipEdgeStyle ? "kSoftEdges"
505 : "kHardEdges");
506}
507
508std::ostream& operator<<(std::ostream& os,
510 return os << data.rect << " " << data.clip_op << " " << data.style;
511}
512
515 return a.rrect == b.rrect && a.clip_op == b.clip_op && a.style == b.style;
516}
517
518std::ostream& operator<<(std::ostream& os,
520 return os << data.rrect << " " << data.clip_op << " " << data.style;
521}
522
525 return a.path == b.path && a.clip_op == b.clip_op && a.style == b.style;
526}
527
528std::ostream& operator<<(std::ostream& os,
530 return os << data.path << " " << data.clip_op << " " << data.style;
531}
532
533std::ostream& operator<<(std::ostream& os,
535 std::visit([&os](auto& d) { os << d; }, data);
536 return os;
537}
538
540 return a.layer == b.layer && a.data == b.data;
541}
542
543std::ostream& operator<<(std::ostream& os, const MockCanvas::DrawCall& draw) {
544 return os << "[Layer: " << draw.layer << ", Data: " << draw.data << "]";
545}
546
549 return a.paint == b.paint;
550}
551
552std::ostream& operator<<(std::ostream& os,
554 return os << data.paint;
555}
556
557} // namespace testing
558} // namespace flutter
const char * options
SkColor4f color
static std::unique_ptr< SkEncoder > Make(SkWStream *dst, const SkPixmap *src, const SkYUVAPixmaps *srcYUVA, const SkColorSpace *srcYUVAColorSpace, const SkJpegEncoder::Options &options)
static SkScalar center(float pos0, float pos1)
static void draw(SkCanvas *canvas, SkRect &target, int x, int y)
Definition aaclip.cpp:27
static sk_sp< SkData > MakeUninitialized(size_t length)
Definition SkData.cpp:116
Definition SkM44.h:150
static SkM44 Translate(SkScalar x, SkScalar y, SkScalar z=0)
Definition SkM44.h:225
static SkM44 Scale(SkScalar x, SkScalar y, SkScalar z=1)
Definition SkM44.h:232
static SkMatrix RotateDeg(SkScalar deg)
Definition SkMatrix.h:104
static SkMatrix MakeAll(SkScalar scaleX, SkScalar skewX, SkScalar transX, SkScalar skewY, SkScalar scaleY, SkScalar transY, SkScalar pers0, SkScalar pers1, SkScalar pers2)
Definition SkMatrix.h:179
static SkMatrix Skew(SkScalar kx, SkScalar ky)
Definition SkMatrix.h:124
SkPathFillType getFillType() const
Definition SkPath.h:230
const SkRect & getBounds() const
Definition SkPath.cpp:420
bool isValid() const
Definition SkPath.cpp:428
const SkRect & rect() const
Definition SkRRect.h:264
void clipRect(const DlRect &rect, ClipOp op, bool is_aa)
void clipPath(const SkPath &path, ClipOp op, bool is_aa)
void clipRRect(const SkRRect &rrect, ClipOp op, bool is_aa)
bool content_culled(const SkRect &content_bounds) const
Holds all of the data (both required and optional) for a DisplayList drawVertices call.
Definition dl_vertices.h:71
SkM44 GetTransformFullPerspective() const override
void TransformFullPerspective(SkScalar mxx, SkScalar mxy, SkScalar mxz, SkScalar mxt, SkScalar myx, SkScalar myy, SkScalar myz, SkScalar myt, SkScalar mzx, SkScalar mzy, SkScalar mzz, SkScalar mzt, SkScalar mwx, SkScalar mwy, SkScalar mwz, SkScalar mwt) override
void Translate(SkScalar tx, SkScalar ty) override
void DrawShadow(const SkPath &path, const DlColor color, const SkScalar elevation, bool transparent_occluder, SkScalar dpr) override
void SetTransform(const SkMatrix *matrix) override
void DrawCircle(const SkPoint &center, SkScalar radius, const DlPaint &paint) override
SkMatrix GetTransform() const override
void Transform2DAffine(SkScalar mxx, SkScalar mxy, SkScalar mxt, SkScalar myx, SkScalar myy, SkScalar myt) override
void DrawTextBlob(const sk_sp< SkTextBlob > &blob, SkScalar x, SkScalar y, const DlPaint &paint) override
SkRect GetLocalClipBounds() const override
SkRect GetDestinationClipBounds() const override
SkISize GetBaseLayerSize() const override
void DrawImageNine(const sk_sp< DlImage > &image, const SkIRect &center, const SkRect &dst, DlFilterMode filter, const DlPaint *paint=nullptr) override
SkImageInfo GetImageInfo() const override
void ClipRRect(const SkRRect &rrect, ClipOp clip_op, bool is_aa) override
void Transform(const SkMatrix *matrix) override
void DrawPaint(const DlPaint &paint) override
void DrawLine(const SkPoint &p0, const SkPoint &p1, const DlPaint &paint) override
void DrawImage(const sk_sp< DlImage > &image, const SkPoint point, DlImageSampling sampling, const DlPaint *paint=nullptr) override
void Scale(SkScalar sx, SkScalar sy) override
void Rotate(SkScalar degrees) override
void ClipPath(const SkPath &path, ClipOp clip_op, bool is_aa) override
void ClipRect(const SkRect &rect, ClipOp clip_op, bool is_aa) override
void DrawImageRect(const sk_sp< DlImage > &image, const SkRect &src, const SkRect &dst, DlImageSampling sampling, const DlPaint *paint=nullptr, SrcRectConstraint constraint=SrcRectConstraint::kFast) override
void DrawColor(DlColor color, DlBlendMode mode) override
void DrawVertices(const DlVertices *vertices, DlBlendMode mode, const DlPaint &paint) override
std::variant< SaveData, SaveLayerData, RestoreData, ConcatMatrixData, SetMatrixData, DrawRectData, DrawPathData, DrawTextData, DrawImageDataNoPaint, DrawImageData, DrawDisplayListData, DrawShadowData, ClipRectData, ClipRRectData, ClipPathData, DrawPaintData > DrawCallData
void DrawRect(const SkRect &rect, const DlPaint &paint) override
void DrawPath(const SkPath &path, const DlPaint &paint) override
void DrawRRect(const SkRRect &rrect, const DlPaint &paint) override
void DrawPoints(PointMode mode, uint32_t count, const SkPoint pts[], const DlPaint &paint) override
void DrawDisplayList(const sk_sp< DisplayList > display_list, SkScalar opacity) override
void DrawAtlas(const sk_sp< DlImage > &atlas, const SkRSXform xform[], const SkRect tex[], const DlColor colors[], int count, DlBlendMode mode, DlImageSampling sampling, const SkRect *cullRect, const DlPaint *paint=nullptr) override
void DrawTextFrame(const std::shared_ptr< impeller::TextFrame > &text_frame, SkScalar x, SkScalar y, const DlPaint &paint) override
void SaveLayer(const SkRect *bounds, const DlPaint *paint=nullptr, const DlImageFilter *backdrop=nullptr) override
void Skew(SkScalar sx, SkScalar sy) override
void DrawDRRect(const SkRRect &outer, const SkRRect &inner, const DlPaint &paint) override
bool QuickReject(const SkRect &bounds) const override
void DrawOval(const SkRect &bounds, const DlPaint &paint) override
void DrawArc(const SkRect &bounds, SkScalar start, SkScalar sweep, bool useCenter, const DlPaint &paint) override
const Paint & paint
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition main.cc:19
sk_sp< SkImage > image
Definition examples.cpp:29
float SkScalar
Definition extension.cpp:12
static bool b
struct MyStruct a[10]
#define FML_DCHECK(condition)
Definition logging.h:103
std::u16string text
double y
double x
constexpr SkISize kSize
std::ostream & operator<<(std::ostream &os, const DisplayList &display_list)
bool operator==(const CGRect &lhs, const CGRect &rhs)
bool Equals(const T *a, const T *b)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition switches.h:57
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
Definition switches.h:41
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive mode
Definition switches.h:228
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition switches.h:259
int32_t height
int32_t width
Definition SkMD5.cpp:134
static constexpr SkISize Make(int32_t w, int32_t h)
Definition SkSize.h:20
static SkImageInfo MakeUnknown()
float fX
x-axis value
static constexpr SkPoint Make(float x, float y)
float fY
y-axis value
SkScalar fBottom
larger y-axis bounds
Definition extension.cpp:17
SkScalar fLeft
smaller x-axis bounds
Definition extension.cpp:14
SkScalar fRight
larger x-axis bounds
Definition extension.cpp:16
void roundOut(SkIRect *dst) const
Definition SkRect.h:1241
SkScalar fTop
smaller y-axis bounds
Definition extension.cpp:15