Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
DebugCanvas.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2012 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
9
12#include "include/core/SkData.h"
15#include "include/core/SkPath.h"
29#include "src/core/SkRectPriv.h"
34
35#include <cstring>
36#include <string>
37#include <utility>
38
39class SkDrawable;
40class SkImage;
41class SkRRect;
42class SkRegion;
43class UrlDataManager;
44struct SkDrawShadowRec;
45
46#if defined(SK_GANESH)
52#endif
53
54using namespace skia_private;
55
56#define SKDEBUGCANVAS_VERSION 1
57#define SKDEBUGCANVAS_ATTRIBUTE_VERSION "version"
58#define SKDEBUGCANVAS_ATTRIBUTE_COMMANDS "commands"
59#define SKDEBUGCANVAS_ATTRIBUTE_AUDITTRAIL "auditTrail"
60
61namespace {
62 // Constants used in Annotations by Android for keeping track of layers
63 static constexpr char kOffscreenLayerDraw[] = "OffscreenLayerDraw";
64 static constexpr char kSurfaceID[] = "SurfaceID";
65 static constexpr char kAndroidClip[] = "AndroidDeviceClipRestriction";
66
67 static SkPath arrowHead = SkPath::Polygon({
68 { 0, 0},
69 { 6, -15},
70 { 0, -12},
71 {-6, -15},
72 }, true);
73
74 void drawArrow(SkCanvas* canvas, const SkPoint& a, const SkPoint& b, const SkPaint& paint) {
75 canvas->translate(0.5, 0.5);
76 canvas->drawLine(a, b, paint);
77 canvas->save();
78 canvas->translate(b.fX, b.fY);
79 SkScalar angle = SkScalarATan2((b.fY - a.fY), b.fX - a.fX);
80 canvas->rotate(angle * 180 / SK_ScalarPI - 90);
81 // arrow head
82 canvas->drawPath(arrowHead, paint);
83 canvas->restore();
84 canvas->restore();
85 }
86} // namespace
87
89public:
91
92protected:
93 bool onFilter(SkPaint& paint) const override {
94 paint.setColor(SK_ColorRED);
95 paint.setAlpha(0x08);
96 paint.setBlendMode(SkBlendMode::kSrcOver);
97 return true;
98 }
99
100 void onDrawPicture(const SkPicture* picture,
101 const SkMatrix* matrix,
102 const SkPaint* paint) override {
103 // We need to replay the picture onto this canvas in order to filter its internal paints.
104 this->SkCanvas::onDrawPicture(picture, matrix, paint);
105 }
106
107private:
108
109 using INHERITED = SkPaintFilterCanvas;
110};
111
114 , fOverdrawViz(false)
115 , fClipVizColor(SK_ColorTRANSPARENT)
116 , fDrawGpuOpBounds(false)
117 , fShowAndroidClip(false)
118 , fShowOrigin(false)
119 , fnextDrawPictureLayerId(-1)
120 , fnextDrawImageRectLayerId(-1)
121 , fAndroidClip(SkRect::MakeEmpty()) {
122 // SkPicturePlayback uses the base-class' quickReject calls to cull clipped
123 // operations. This can lead to problems in the debugger which expects all
124 // the operations in the captured skp to appear in the debug canvas. To
125 // circumvent this we create a wide open clip here (an empty clip rect
126 // is not sufficient).
127 // Internally, the SkRect passed to clipRect is converted to an SkIRect and
128 // rounded out. The following code creates a nearly maximal rect that will
129 // not get collapsed by the coming conversions (Due to precision loss the
130 // inset has to be surprisingly large).
131 SkIRect largeIRect = SkRectPriv::MakeILarge();
132 largeIRect.inset(1024, 1024);
133 SkRect large = SkRect::Make(largeIRect);
134#ifdef SK_DEBUG
135 SkASSERT(!large.roundOut().isEmpty());
136#endif
137 // call the base class' version to avoid adding a draw command
139}
140
142 : DebugCanvas(bounds.width(), bounds.height()) {}
143
145 for (DrawCommand* p : fCommandVector) {
146 delete p;
147 }
148 fCommandVector.reset();
149}
150
151void DebugCanvas::addDrawCommand(DrawCommand* command) { fCommandVector.push_back(command); }
152
154 if (!fCommandVector.empty()) {
155 this->drawTo(canvas, fCommandVector.size() - 1);
156 }
157}
158
159void DebugCanvas::drawTo(SkCanvas* originalCanvas, int index, int m) {
160 SkASSERT(!fCommandVector.empty());
161 SkASSERT(index < fCommandVector.size());
162
163 int saveCount = originalCanvas->save();
164
165 originalCanvas->resetMatrix();
166 SkCanvasPriv::ResetClip(originalCanvas);
167
168 DebugPaintFilterCanvas filterCanvas(originalCanvas);
169 SkCanvas* finalCanvas = fOverdrawViz ? &filterCanvas : originalCanvas;
170
171#if defined(SK_GANESH)
172 auto dContext = GrAsDirectContext(finalCanvas->recordingContext());
173
174 // If we have a GPU backend we can also visualize the op information
175 GrAuditTrail* at = nullptr;
176 if (fDrawGpuOpBounds || m != -1) {
177 // The audit trail must be obtained from the original canvas.
178 at = this->getAuditTrail(originalCanvas);
179 }
180#endif
181
182 for (int i = 0; i <= index; i++) {
183#if defined(SK_GANESH)
184 GrAuditTrail::AutoCollectOps* acb = nullptr;
185 if (at) {
186 // We need to flush any pending operations, or they might combine with commands below.
187 // Previous operations were not registered with the audit trail when they were
188 // created, so if we allow them to combine, the audit trail will fail to find them.
189 if (dContext) {
190 dContext->flush();
191 }
192 acb = new GrAuditTrail::AutoCollectOps(at, i);
193 }
194#endif
195 if (fCommandVector[i]->isVisible()) {
196 fCommandVector[i]->execute(finalCanvas);
197 }
198#if defined(SK_GANESH)
199 if (at && acb) {
200 delete acb;
201 }
202#endif
203 }
204
205 if (SkColorGetA(fClipVizColor) != 0) {
206 finalCanvas->save();
207 SkPaint clipPaint;
208 clipPaint.setColor(fClipVizColor);
209 finalCanvas->drawPaint(clipPaint);
210 finalCanvas->restore();
211 }
212
213 fMatrix = finalCanvas->getLocalToDevice();
214 fClip = finalCanvas->getDeviceClipBounds();
215 if (fShowOrigin) {
216 const SkPaint originXPaint = SkPaint({1.0, 0, 0, 1.0});
217 const SkPaint originYPaint = SkPaint({0, 1.0, 0, 1.0});
218 // Draw an origin cross at the origin before restoring to assist in visualizing the
219 // current matrix.
220 drawArrow(finalCanvas, {-50, 0}, {50, 0}, originXPaint);
221 drawArrow(finalCanvas, {0, -50}, {0, 50}, originYPaint);
222 }
223 finalCanvas->restoreToCount(saveCount);
224
225 if (fShowAndroidClip) {
226 // Draw visualization of android device clip restriction
227 SkPaint androidClipPaint;
228 androidClipPaint.setARGB(80, 255, 100, 0);
229 finalCanvas->drawRect(fAndroidClip, androidClipPaint);
230 }
231
232#if defined(SK_GANESH)
233 // draw any ops if required and issue a full reset onto GrAuditTrail
234 if (at) {
235 // just in case there is global reordering, we flush the canvas before querying
236 // GrAuditTrail
238 if (dContext) {
239 dContext->flush();
240 }
241
242 // we pick three colorblind-safe colors, 75% alpha
243 static const SkColor kTotalBounds = SkColorSetARGB(0xC0, 0x6A, 0x3D, 0x9A);
244 static const SkColor kCommandOpBounds = SkColorSetARGB(0xC0, 0xE3, 0x1A, 0x1C);
245 static const SkColor kOtherOpBounds = SkColorSetARGB(0xC0, 0xFF, 0x7F, 0x00);
246
247 // get the render target of the top device (from the original canvas) so we can ignore ops
248 // drawn offscreen
250 GrSurfaceProxy::UniqueID proxyID = rtp->uniqueID();
251
252 // get the bounding boxes to draw
253 TArray<GrAuditTrail::OpInfo> childrenBounds;
254 if (m == -1) {
255 at->getBoundsByClientID(&childrenBounds, index);
256 } else {
257 // the client wants us to draw the mth op
258 at->getBoundsByOpsTaskID(&childrenBounds.push_back(), m);
259 }
260 // Shift the rects half a pixel, so they appear as exactly 1px thick lines.
261 finalCanvas->save();
262 finalCanvas->translate(0.5, -0.5);
265 paint.setStrokeWidth(1);
266 for (int i = 0; i < childrenBounds.size(); i++) {
267 if (childrenBounds[i].fProxyUniqueID != proxyID) {
268 // offscreen draw, ignore for now
269 continue;
270 }
271 paint.setColor(kTotalBounds);
272 finalCanvas->drawRect(childrenBounds[i].fBounds, paint);
273 for (int j = 0; j < childrenBounds[i].fOps.size(); j++) {
274 const GrAuditTrail::OpInfo::Op& op = childrenBounds[i].fOps[j];
275 if (op.fClientID != index) {
276 paint.setColor(kOtherOpBounds);
277 } else {
278 paint.setColor(kCommandOpBounds);
279 }
280 finalCanvas->drawRect(op.fBounds, paint);
281 }
282 }
283 finalCanvas->restore();
284 this->cleanupAuditTrail(at);
285 }
286#endif
287}
288
290 SkASSERT(index < fCommandVector.size());
291 delete fCommandVector[index];
292 fCommandVector.remove(index);
293}
294
296 SkASSERT(index < fCommandVector.size());
297 return fCommandVector[index];
298}
299
300#if defined(SK_GANESH)
301GrAuditTrail* DebugCanvas::getAuditTrail(SkCanvas* canvas) {
302 GrAuditTrail* at = nullptr;
303 auto ctx = canvas->recordingContext();
304 if (ctx) {
305 at = ctx->priv().auditTrail();
306 }
307 return at;
308}
309
310void DebugCanvas::drawAndCollectOps(SkCanvas* canvas) {
311 GrAuditTrail* at = this->getAuditTrail(canvas);
312 if (at) {
313 // loop over all of the commands and draw them, this is to collect reordering
314 // information
315 for (int i = 0; i < this->getSize(); i++) {
316 GrAuditTrail::AutoCollectOps enable(at, i);
317 fCommandVector[i]->execute(canvas);
318 }
319
320 // in case there is some kind of global reordering
321 {
323
324 auto dContext = GrAsDirectContext(canvas->recordingContext());
325 if (dContext) {
326 dContext->flush();
327 }
328 }
329 }
330}
331
332void DebugCanvas::cleanupAuditTrail(GrAuditTrail* at) {
333 if (at) {
335 at->fullReset();
336 }
337}
338#endif // defined(SK_GANESH)
339
341 UrlDataManager& urlDataManager,
342 SkCanvas* canvas) {
343#if defined(SK_GANESH)
344 this->drawAndCollectOps(canvas);
345
346 // now collect json
347 GrAuditTrail* at = this->getAuditTrail(canvas);
348#endif
351
352 for (int i = 0; i < this->getSize(); i++) {
353 writer.beginObject(); // command
354 this->getDrawCommandAt(i)->toJSON(writer, urlDataManager);
355
356#if defined(SK_GANESH)
357 if (at && at->isEnabled()) {
359 at->toJson(writer, i);
360 }
361#endif
362 writer.endObject(); // command
363 }
364
365 writer.endArray(); // commands
366#if defined(SK_GANESH)
367 this->cleanupAuditTrail(at);
368#endif
369}
370
372#if defined(SK_GANESH)
373 this->drawAndCollectOps(canvas);
374
375 GrAuditTrail* at = this->getAuditTrail(canvas);
376 if (at) {
378 at->toJson(writer);
379 this->cleanupAuditTrail(at);
380 return;
381 }
382#endif
383
384 writer.beginObject();
385 writer.endObject();
386}
387
388void DebugCanvas::setOverdrawViz(bool overdrawViz) { fOverdrawViz = overdrawViz; }
389
390void DebugCanvas::onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle edgeStyle) {
391 this->addDrawCommand(new ClipPathCommand(path, op, kSoft_ClipEdgeStyle == edgeStyle));
392}
393
394void DebugCanvas::onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle edgeStyle) {
395 this->addDrawCommand(new ClipRectCommand(rect, op, kSoft_ClipEdgeStyle == edgeStyle));
396}
397
398void DebugCanvas::onClipRRect(const SkRRect& rrect, SkClipOp op, ClipEdgeStyle edgeStyle) {
399 this->addDrawCommand(new ClipRRectCommand(rrect, op, kSoft_ClipEdgeStyle == edgeStyle));
400}
401
403 this->addDrawCommand(new ClipRegionCommand(region, op));
404}
405
407 this->addDrawCommand(new ClipShaderCommand(std::move(cs), op));
408}
409
411 this->addDrawCommand(new ResetClipCommand());
412}
413
415 this->addDrawCommand(new Concat44Command(m));
416 this->INHERITED::didConcat44(m);
417}
418
422
426
427void DebugCanvas::onDrawAnnotation(const SkRect& rect, const char key[], SkData* value) {
428 // Parse layer-releated annotations added in SkiaPipeline.cpp and RenderNodeDrawable.cpp
429 // the format of the annotations is <Indicator|RenderNodeId>
430 TArray<SkString> tokens;
431 SkStrSplit(key, "|", kStrict_SkStrSplitMode, &tokens);
432 if (tokens.size() == 2) {
433 if (tokens[0].equals(kOffscreenLayerDraw)) {
434 // Indicates that the next drawPicture command contains the SkPicture to render the
435 // node at this id in an offscreen buffer.
436 fnextDrawPictureLayerId = std::stoi(tokens[1].c_str());
437 fnextDrawPictureDirtyRect = rect.roundOut();
438 return; // don't record it
439 } else if (tokens[0].equals(kSurfaceID)) {
440 // Indicates that the following drawImageRect should draw the offscreen buffer.
441 fnextDrawImageRectLayerId = std::stoi(tokens[1].c_str());
442 return; // don't record it
443 }
444 }
445 if (strcmp(kAndroidClip, key) == 0) {
446 // Store this frame's android device clip restriction for visualization later.
447 // This annotation stands in place of the androidFramework_setDeviceClipRestriction
448 // which is unrecordable.
449 fAndroidClip = rect;
450 }
451 this->addDrawCommand(new DrawAnnotationCommand(rect, key, sk_ref_sp(value)));
452}
453
456 SkScalar top,
457 const SkSamplingOptions& sampling,
458 const SkPaint* paint) {
459 this->addDrawCommand(new DrawImageCommand(image, left, top, sampling, paint));
460}
461
463 const Lattice& lattice,
464 const SkRect& dst,
465 SkFilterMode filter, // todo
466 const SkPaint* paint) {
467 this->addDrawCommand(new DrawImageLatticeCommand(image, lattice, dst, filter, paint));
468}
469
471 const SkRect& src,
472 const SkRect& dst,
473 const SkSamplingOptions& sampling,
474 const SkPaint* paint,
475 SrcRectConstraint constraint) {
476 if (fnextDrawImageRectLayerId != -1 && fLayerManager) {
477 // This drawImageRect command would have drawn the offscreen buffer for a layer.
478 // On Android, we recorded an SkPicture of the commands that drew to the layer.
479 // To render the layer as it would have looked on the frame this DebugCanvas draws, we need
480 // to call fLayerManager->getLayerAsImage(id). This must be done just before
481 // drawTo(command), since it depends on the index into the layer's commands
482 // (managed by fLayerManager)
483 // Instead of adding a DrawImageRectCommand, we need a deferred command, that when
484 // executed, will call drawImageRect(fLayerManager->getLayerAsImage())
485 this->addDrawCommand(new DrawImageRectLayerCommand(
486 fLayerManager, fnextDrawImageRectLayerId, fFrame, src, dst, sampling,
487 paint, constraint));
488 } else {
489 this->addDrawCommand(new DrawImageRectCommand(image, src, dst, sampling, paint, constraint));
490 }
491 // Reset expectation so next drawImageRect is not special.
492 fnextDrawImageRectLayerId = -1;
493}
494
495void DebugCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint) {
496 this->addDrawCommand(new DrawOvalCommand(oval, paint));
497}
498
500 SkScalar startAngle,
501 SkScalar sweepAngle,
502 bool useCenter,
503 const SkPaint& paint) {
504 this->addDrawCommand(new DrawArcCommand(oval, startAngle, sweepAngle, useCenter, paint));
505}
506
508 this->addDrawCommand(new DrawPaintCommand(paint));
509}
510
512 this->addDrawCommand(new DrawBehindCommand(paint));
513}
514
515void DebugCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) {
516 this->addDrawCommand(new DrawPathCommand(path, paint));
517}
518
519void DebugCanvas::onDrawRegion(const SkRegion& region, const SkPaint& paint) {
520 this->addDrawCommand(new DrawRegionCommand(region, paint));
521}
522
524 const SkMatrix* matrix,
525 const SkPaint* paint) {
526 if (fnextDrawPictureLayerId != -1 && fLayerManager) {
527 fLayerManager->storeSkPicture(fnextDrawPictureLayerId, fFrame, sk_ref_sp(picture),
528 fnextDrawPictureDirtyRect);
529 } else {
530 this->addDrawCommand(new BeginDrawPictureCommand(picture, matrix, paint));
531 SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect());
532 picture->playback(this);
533 this->addDrawCommand(new EndDrawPictureCommand(SkToBool(matrix) || SkToBool(paint)));
534 }
535 fnextDrawPictureLayerId = -1;
536}
537
539 size_t count,
540 const SkPoint pts[],
541 const SkPaint& paint) {
542 this->addDrawCommand(new DrawPointsCommand(mode, count, pts, paint));
543}
544
545void DebugCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) {
546 // NOTE(chudy): Messing up when renamed to DrawRect... Why?
547 addDrawCommand(new DrawRectCommand(rect, paint));
548}
549
550void DebugCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) {
551 this->addDrawCommand(new DrawRRectCommand(rrect, paint));
552}
553
554void DebugCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint) {
555 this->addDrawCommand(new DrawDRRectCommand(outer, inner, paint));
556}
557
559 SkScalar x,
560 SkScalar y,
561 const SkPaint& paint) {
562 this->addDrawCommand(
563 new DrawTextBlobCommand(sk_ref_sp(const_cast<SkTextBlob*>(blob)), x, y, paint));
564}
565
566void DebugCanvas::onDrawPatch(const SkPoint cubics[12],
567 const SkColor colors[4],
568 const SkPoint texCoords[4],
569 SkBlendMode bmode,
570 const SkPaint& paint) {
571 this->addDrawCommand(new DrawPatchCommand(cubics, colors, texCoords, bmode, paint));
572}
573
575 SkBlendMode bmode,
576 const SkPaint& paint) {
577 this->addDrawCommand(
578 new DrawVerticesCommand(sk_ref_sp(const_cast<SkVertices*>(vertices)), bmode, paint));
579}
580
582 const SkRSXform xform[],
583 const SkRect tex[],
584 const SkColor colors[],
585 int count,
586 SkBlendMode bmode,
587 const SkSamplingOptions& sampling,
588 const SkRect* cull,
589 const SkPaint* paint) {
590 this->addDrawCommand(
591 new DrawAtlasCommand(image, xform, tex, colors, count, bmode, sampling, cull, paint));
592}
593
595 this->addDrawCommand(new DrawShadowCommand(path, rec));
596}
597
598void DebugCanvas::onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) {
599 this->addDrawCommand(new DrawDrawableCommand(drawable, matrix));
600}
601
603 const SkPoint clip[4],
604 QuadAAFlags aa,
605 const SkColor4f& color,
606 SkBlendMode mode) {
607 this->addDrawCommand(new DrawEdgeAAQuadCommand(rect, clip, aa, color, mode));
608}
609
611 int count,
612 const SkPoint dstClips[],
613 const SkMatrix preViewMatrices[],
614 const SkSamplingOptions& sampling,
615 const SkPaint* paint,
616 SrcRectConstraint constraint) {
617 this->addDrawCommand(new DrawEdgeAAImageSetCommand(
618 set, count, dstClips, preViewMatrices, sampling, paint, constraint));
619}
620
622 this->addDrawCommand(new RestoreCommand());
624}
625
627 this->addDrawCommand(new SaveCommand());
628 this->INHERITED::willSave();
629}
630
632 this->addDrawCommand(new SaveLayerCommand(rec));
633 (void)this->INHERITED::getSaveLayerStrategy(rec);
634 // No need for a full layer.
636}
637
639 // TODO
640 return false;
641}
642
643void DebugCanvas::didSetM44(const SkM44& matrix) {
644 this->addDrawCommand(new SetM44Command(matrix));
645 this->INHERITED::didSetM44(matrix);
646}
647
648void DebugCanvas::toggleCommand(int index, bool toggle) {
649 SkASSERT(index < fCommandVector.size());
650 fCommandVector[index]->setVisible(toggle);
651}
652
653std::map<int, std::vector<int>> DebugCanvas::getImageIdToCommandMap(UrlDataManager& udm) const {
654 // map from image ids to list of commands that reference them.
655 std::map<int, std::vector<int>> m;
656
657 for (int i = 0; i < this->getSize(); i++) {
658 const DrawCommand* command = this->getDrawCommandAt(i);
659 int imageIndex = -1;
660 // this is not an exaustive list of where images can be used, they show up in paints too.
661 switch (command->getOpType()) {
663 imageIndex = static_cast<const DrawImageCommand*>(command)->imageId(udm);
664 break;
665 }
667 imageIndex = static_cast<const DrawImageRectCommand*>(command)->imageId(udm);
668 break;
669 }
671 imageIndex = static_cast<const DrawImageLatticeCommand*>(command)->imageId(udm);
672 break;
673 }
674 default: break;
675 }
676 if (imageIndex >= 0) {
677 m[imageIndex].push_back(i);
678 }
679 }
680 return m;
681}
#define SKDEBUGCANVAS_ATTRIBUTE_COMMANDS
#define SKDEBUGCANVAS_ATTRIBUTE_AUDITTRAIL
#define SKDEBUGCANVAS_VERSION
#define SKDEBUGCANVAS_ATTRIBUTE_VERSION
int count
static GrDirectContext * GrAsDirectContext(GrContext_Base *base)
SkColor4f color
const SkRect fBounds
#define SkASSERT(cond)
Definition SkAssert.h:116
SkBlendMode
Definition SkBlendMode.h:38
@ kSrcOver
r = s + (1-sa)*d
SkClipOp
Definition SkClipOp.h:13
uint32_t SkColor
Definition SkColor.h:37
constexpr SkColor SK_ColorTRANSPARENT
Definition SkColor.h:99
constexpr SkColor SK_ColorRED
Definition SkColor.h:126
static constexpr SkColor SkColorSetARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
Definition SkColor.h:49
#define SkColorGetA(color)
Definition SkColor.h:61
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
Definition SkPath.cpp:3824
static bool equals(T *a, T *b)
static bool left(const SkPoint &p0, const SkPoint &p1)
sk_sp< T > sk_ref_sp(T *obj)
Definition SkRefCnt.h:381
SkFilterMode
#define SkScalarATan2(y, x)
Definition SkScalar.h:50
#define SK_ScalarPI
Definition SkScalar.h:21
void SkStrSplit(const char *str, const char *delimiters, SkStrSplitMode splitMode, TArray< SkString > *out)
@ kStrict_SkStrSplitMode
static constexpr bool SkToBool(const T &x)
Definition SkTo.h:35
void onClipRegion(const SkRegion &region, SkClipOp) override
DrawCommand * getDrawCommandAt(int index) const
void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], const SkPoint texCoords[4], SkBlendMode, const SkPaint &paint) override
SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec &) override
void onDrawTextBlob(const SkTextBlob *blob, SkScalar x, SkScalar y, const SkPaint &paint) override
void onResetClip() override
void setOverdrawViz(bool overdrawViz)
void willSave() override
DebugCanvas(int width, int height)
void onDrawRect(const SkRect &, const SkPaint &) override
void didScale(SkScalar, SkScalar) override
void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint &) override
void onDrawPath(const SkPath &, const SkPaint &) override
void onClipPath(const SkPath &, SkClipOp, ClipEdgeStyle) override
void didConcat44(const SkM44 &) override
void onDrawRRect(const SkRRect &, const SkPaint &) override
void onDrawAnnotation(const SkRect &, const char[], SkData *) override
void onDrawPicture(const SkPicture *, const SkMatrix *, const SkPaint *) override
std::map< int, std::vector< int > > getImageIdToCommandMap(UrlDataManager &udm) const
void onDrawAtlas2(const SkImage *, const SkRSXform[], const SkRect[], const SkColor[], int, SkBlendMode, const SkSamplingOptions &, const SkRect *, const SkPaint *) override
void onClipRRect(const SkRRect &, SkClipOp, ClipEdgeStyle) override
void onDrawDrawable(SkDrawable *, const SkMatrix *) override
void didTranslate(SkScalar, SkScalar) override
void drawTo(SkCanvas *canvas, int index, int m=-1)
void onDrawEdgeAAQuad(const SkRect &, const SkPoint[4], QuadAAFlags, const SkColor4f &, SkBlendMode) override
void onDrawEdgeAAImageSet2(const ImageSetEntry[], int count, const SkPoint[], const SkMatrix[], const SkSamplingOptions &, const SkPaint *, SrcRectConstraint) override
bool onDoSaveBehind(const SkRect *) override
void onClipRect(const SkRect &, SkClipOp, ClipEdgeStyle) override
void onDrawPaint(const SkPaint &) override
void onDrawDRRect(const SkRRect &, const SkRRect &, const SkPaint &) override
~DebugCanvas() override
void toggleCommand(int index, bool toggle)
void onDrawImageRect2(const SkImage *, const SkRect &, const SkRect &, const SkSamplingOptions &, const SkPaint *, SrcRectConstraint) override
void toJSONOpsTask(SkJSONWriter &writer, SkCanvas *)
void onDrawShadowRec(const SkPath &, const SkDrawShadowRec &) override
int getSize() const
void onDrawRegion(const SkRegion &, const SkPaint &) override
void toJSON(SkJSONWriter &writer, UrlDataManager &urlDataManager, SkCanvas *)
void onClipShader(sk_sp< SkShader >, SkClipOp) override
void onDrawImageLattice2(const SkImage *, const Lattice &, const SkRect &, SkFilterMode, const SkPaint *) override
void onDrawOval(const SkRect &, const SkPaint &) override
void onDrawImage2(const SkImage *, SkScalar, SkScalar, const SkSamplingOptions &, const SkPaint *) override
void onDrawBehind(const SkPaint &) override
void onDrawVerticesObject(const SkVertices *, SkBlendMode, const SkPaint &) override
void draw(SkCanvas *canvas)
void onDrawArc(const SkRect &, SkScalar, SkScalar, bool, const SkPaint &) override
void deleteDrawCommandAt(int index)
void didSetM44(const SkM44 &) override
void willRestore() override
void storeSkPicture(int nodeId, int frame, const sk_sp< SkPicture > &picture, SkIRect dirty)
DebugPaintFilterCanvas(SkCanvas *canvas)
void onDrawPicture(const SkPicture *picture, const SkMatrix *matrix, const SkPaint *paint) override
bool onFilter(SkPaint &paint) const override
@ kDrawImageLattice_OpType
Definition DrawCommand.h:71
@ kDrawImageRect_OpType
Definition DrawCommand.h:72
virtual void toJSON(SkJSONWriter &writer, UrlDataManager &urlDataManager) const
bool isEnabled()
void getBoundsByOpsTaskID(OpInfo *outInfo, int opsTaskID)
void getBoundsByClientID(skia_private::TArray< OpInfo > *outInfo, int clientID)
void toJson(SkJSONWriter &writer) const
UniqueID uniqueID() const
static void ResetClip(SkCanvas *canvas)
void drawRect(const SkRect &rect, const SkPaint &paint)
void restore()
Definition SkCanvas.cpp:465
void translate(SkScalar dx, SkScalar dy)
virtual void onDrawPicture(const SkPicture *picture, const SkMatrix *matrix, const SkPaint *paint)
virtual GrRecordingContext * recordingContext() const
virtual void didSetM44(const SkM44 &)
Definition SkCanvas.h:2280
void drawPaint(const SkPaint &paint)
void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint &paint)
virtual SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec &)
Definition SkCanvas.h:2270
virtual void onClipRect(const SkRect &rect, SkClipOp op, ClipEdgeStyle edgeStyle)
SrcRectConstraint
Definition SkCanvas.h:1541
SkM44 getLocalToDevice() const
SaveLayerStrategy
Definition SkCanvas.h:2263
@ kNoLayer_SaveLayerStrategy
Definition SkCanvas.h:2265
virtual void willRestore()
Definition SkCanvas.h:2276
void rotate(SkScalar degrees)
void restoreToCount(int saveCount)
Definition SkCanvas.cpp:482
void resetMatrix()
SkIRect getDeviceClipBounds() const
virtual void didConcat44(const SkM44 &)
Definition SkCanvas.h:2279
int save()
Definition SkCanvas.cpp:451
void drawPath(const SkPath &path, const SkPaint &paint)
@ kHard_ClipEdgeStyle
Definition SkCanvas.h:2336
@ kSoft_ClipEdgeStyle
Definition SkCanvas.h:2337
virtual void willSave()
Definition SkCanvas.h:2268
void appendS32(int32_t value)
void beginArray(const char *name=nullptr, bool multiline=true)
void beginObject(const char *name=nullptr, bool multiline=true)
void appendName(const char *name)
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
void setColor(SkColor color)
Definition SkPaint.cpp:119
@ kStroke_Style
set to stroke geometry
Definition SkPaint.h:194
void setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
Definition SkPaint.cpp:134
static SkPath Polygon(const SkPoint pts[], int count, bool isClosed, SkPathFillType=SkPathFillType::kWinding, bool isVolatile=false)
Definition SkPath.cpp:3546
virtual SkRect cullRect() const =0
virtual void playback(SkCanvas *canvas, AbortCallback *callback=nullptr) const =0
static SkIRect MakeILarge()
Definition SkRectPriv.h:22
int size() const
Definition SkTDArray.h:138
bool empty() const
Definition SkTDArray.h:135
void push_back(const T &v)
Definition SkTDArray.h:219
void reset()
Definition SkTDArray.h:171
void remove(int index, int count=1)
Definition SkTDArray.h:210
int size() const
Definition SkTArray.h:416
const Paint & paint
sk_sp< SkImage > image
Definition examples.cpp:29
float SkScalar
Definition extension.cpp:12
static bool b
struct MyStruct a[10]
uint8_t value
double y
double x
GrRenderTargetProxy * TopDeviceTargetProxy(const SkCanvas *canvas)
Definition GrCanvas.cpp:34
int32_t height
int32_t width
void inset(int32_t dx, int32_t dy)
Definition SkRect.h:411
static SkRect Make(const SkISize &size)
Definition SkRect.h:669
void roundOut(SkIRect *dst) const
Definition SkRect.h:1241