blob: 24d467ca01a7b8ffdc7f779efee04060c2f139fd [file] [log] [blame]
Mike Klein8f4e2242019-03-20 11:59:00 -05001/*
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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "include/core/SkPicture.h"
9#include "include/core/SkTextBlob.h"
10#include "include/utils/SkPaintFilterCanvas.h"
11#include "src/core/SkCanvasPriv.h"
12#include "src/core/SkClipOpPriv.h"
13#include "src/core/SkRectPriv.h"
14#include "src/utils/SkJSONWriter.h"
15#include "tools/debugger/DebugCanvas.h"
16#include "tools/debugger/DrawCommand.h"
Mike Klein8f4e2242019-03-20 11:59:00 -050017
Mike Kleinc0bd9f92019-04-23 12:05:21 -050018#include "include/gpu/GrContext.h"
Greg Danielf91aeb22019-06-18 09:58:02 -040019#include "src/gpu/GrAuditTrail.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050020#include "src/gpu/GrContextPriv.h"
21#include "src/gpu/GrRenderTargetContext.h"
Mike Klein8f4e2242019-03-20 11:59:00 -050022
23#define SKDEBUGCANVAS_VERSION 1
24#define SKDEBUGCANVAS_ATTRIBUTE_VERSION "version"
25#define SKDEBUGCANVAS_ATTRIBUTE_COMMANDS "commands"
26#define SKDEBUGCANVAS_ATTRIBUTE_AUDITTRAIL "auditTrail"
27
28class DebugPaintFilterCanvas : public SkPaintFilterCanvas {
29public:
30 DebugPaintFilterCanvas(SkCanvas* canvas, bool overdrawViz)
31 : INHERITED(canvas), fOverdrawViz(overdrawViz) {}
32
33protected:
Ben Wagnerf55fa0d2018-08-27 18:11:57 -040034 bool onFilter(SkPaint& paint) const override {
35 if (fOverdrawViz) {
36 paint.setColor(SK_ColorRED);
37 paint.setAlpha(0x08);
38 paint.setBlendMode(SkBlendMode::kSrcOver);
Mike Klein8f4e2242019-03-20 11:59:00 -050039 }
40 return true;
41 }
42
43 void onDrawPicture(const SkPicture* picture,
44 const SkMatrix* matrix,
45 const SkPaint* paint) override {
46 // We need to replay the picture onto this canvas in order to filter its internal paints.
47 this->SkCanvas::onDrawPicture(picture, matrix, paint);
48 }
49
50private:
51 bool fOverdrawViz;
52
53 typedef SkPaintFilterCanvas INHERITED;
54};
55
56DebugCanvas::DebugCanvas(int width, int height)
57 : INHERITED(width, height)
58 , fOverdrawViz(false)
59 , fClipVizColor(SK_ColorTRANSPARENT)
60 , fDrawGpuOpBounds(false) {
61 // SkPicturePlayback uses the base-class' quickReject calls to cull clipped
62 // operations. This can lead to problems in the debugger which expects all
63 // the operations in the captured skp to appear in the debug canvas. To
64 // circumvent this we create a wide open clip here (an empty clip rect
65 // is not sufficient).
66 // Internally, the SkRect passed to clipRect is converted to an SkIRect and
67 // rounded out. The following code creates a nearly maximal rect that will
68 // not get collapsed by the coming conversions (Due to precision loss the
69 // inset has to be surprisingly large).
70 SkIRect largeIRect = SkRectPriv::MakeILarge();
71 largeIRect.inset(1024, 1024);
72 SkRect large = SkRect::Make(largeIRect);
73#ifdef SK_DEBUG
74 SkASSERT(!large.roundOut().isEmpty());
75#endif
76 // call the base class' version to avoid adding a draw command
77 this->INHERITED::onClipRect(large, kReplace_SkClipOp, kHard_ClipEdgeStyle);
78}
79
80DebugCanvas::DebugCanvas(SkIRect bounds) { DebugCanvas(bounds.width(), bounds.height()); }
81
82DebugCanvas::~DebugCanvas() { fCommandVector.deleteAll(); }
83
84void DebugCanvas::addDrawCommand(DrawCommand* command) { fCommandVector.push_back(command); }
85
86void DebugCanvas::draw(SkCanvas* canvas) {
87 if (!fCommandVector.isEmpty()) {
88 this->drawTo(canvas, fCommandVector.count() - 1);
89 }
90}
91
92void DebugCanvas::drawTo(SkCanvas* originalCanvas, int index, int m) {
93 SkASSERT(!fCommandVector.isEmpty());
94 SkASSERT(index < fCommandVector.count());
95
96 int saveCount = originalCanvas->save();
97
98 SkRect windowRect = SkRect::MakeWH(SkIntToScalar(originalCanvas->getBaseLayerSize().width()),
99 SkIntToScalar(originalCanvas->getBaseLayerSize().height()));
100
Nathaniel Nifongde5df652019-03-28 13:08:51 -0400101 originalCanvas->clear(SK_ColorTRANSPARENT);
Mike Klein8f4e2242019-03-20 11:59:00 -0500102 originalCanvas->resetMatrix();
103 if (!windowRect.isEmpty()) {
104 originalCanvas->clipRect(windowRect, kReplace_SkClipOp);
105 }
106
107 DebugPaintFilterCanvas filterCanvas(originalCanvas, fOverdrawViz);
108
109 // If we have a GPU backend we can also visualize the op information
110 GrAuditTrail* at = nullptr;
111 if (fDrawGpuOpBounds || m != -1) {
112 // The audit trail must be obtained from the original canvas.
113 at = this->getAuditTrail(originalCanvas);
114 }
115
116 for (int i = 0; i <= index; i++) {
117 // We need to flush any pending operations, or they might combine with commands below.
118 // Previous operations were not registered with the audit trail when they were
119 // created, so if we allow them to combine, the audit trail will fail to find them.
120 filterCanvas.flush();
121
122 GrAuditTrail::AutoCollectOps* acb = nullptr;
123 if (at) {
124 acb = new GrAuditTrail::AutoCollectOps(at, i);
125 }
126
127 if (fCommandVector[i]->isVisible()) {
128 fCommandVector[i]->execute(&filterCanvas);
129 }
130 if (at && acb) {
131 delete acb;
132 }
133 }
134
135 if (SkColorGetA(fClipVizColor) != 0) {
136 filterCanvas.save();
137#define LARGE_COORD 1000000000
138 filterCanvas.clipRect(
139 SkRect::MakeLTRB(-LARGE_COORD, -LARGE_COORD, LARGE_COORD, LARGE_COORD),
140 kReverseDifference_SkClipOp);
141 SkPaint clipPaint;
142 clipPaint.setColor(fClipVizColor);
143 filterCanvas.drawPaint(clipPaint);
144 filterCanvas.restore();
145 }
146
147 fMatrix = filterCanvas.getTotalMatrix();
148 fClip = filterCanvas.getDeviceClipBounds();
149 filterCanvas.restoreToCount(saveCount);
150
151 // draw any ops if required and issue a full reset onto GrAuditTrail
152 if (at) {
153 // just in case there is global reordering, we flush the canvas before querying
154 // GrAuditTrail
155 GrAuditTrail::AutoEnable ae(at);
156 filterCanvas.flush();
157
158 // we pick three colorblind-safe colors, 75% alpha
159 static const SkColor kTotalBounds = SkColorSetARGB(0xC0, 0x6A, 0x3D, 0x9A);
160 static const SkColor kCommandOpBounds = SkColorSetARGB(0xC0, 0xE3, 0x1A, 0x1C);
161 static const SkColor kOtherOpBounds = SkColorSetARGB(0xC0, 0xFF, 0x7F, 0x00);
162
163 // get the render target of the top device (from the original canvas) so we can ignore ops
164 // drawn offscreen
165 GrRenderTargetContext* rtc =
166 originalCanvas->internal_private_accessTopLayerRenderTargetContext();
167 GrSurfaceProxy::UniqueID proxyID = rtc->asSurfaceProxy()->uniqueID();
168
169 // get the bounding boxes to draw
170 SkTArray<GrAuditTrail::OpInfo> childrenBounds;
171 if (m == -1) {
172 at->getBoundsByClientID(&childrenBounds, index);
173 } else {
174 // the client wants us to draw the mth op
Greg Danielf21bf9e2019-08-22 20:12:20 +0000175 at->getBoundsByOpListID(&childrenBounds.push_back(), m);
Mike Klein8f4e2242019-03-20 11:59:00 -0500176 }
177 SkPaint paint;
178 paint.setStyle(SkPaint::kStroke_Style);
179 paint.setStrokeWidth(1);
180 for (int i = 0; i < childrenBounds.count(); i++) {
181 if (childrenBounds[i].fProxyUniqueID != proxyID) {
182 // offscreen draw, ignore for now
183 continue;
184 }
185 paint.setColor(kTotalBounds);
186 filterCanvas.drawRect(childrenBounds[i].fBounds, paint);
187 for (int j = 0; j < childrenBounds[i].fOps.count(); j++) {
188 const GrAuditTrail::OpInfo::Op& op = childrenBounds[i].fOps[j];
189 if (op.fClientID != index) {
190 paint.setColor(kOtherOpBounds);
191 } else {
192 paint.setColor(kCommandOpBounds);
193 }
194 filterCanvas.drawRect(op.fBounds, paint);
195 }
196 }
197 }
198 this->cleanupAuditTrail(originalCanvas);
199}
200
201void DebugCanvas::deleteDrawCommandAt(int index) {
202 SkASSERT(index < fCommandVector.count());
203 delete fCommandVector[index];
204 fCommandVector.remove(index);
205}
206
207DrawCommand* DebugCanvas::getDrawCommandAt(int index) {
208 SkASSERT(index < fCommandVector.count());
209 return fCommandVector[index];
210}
211
212GrAuditTrail* DebugCanvas::getAuditTrail(SkCanvas* canvas) {
213 GrAuditTrail* at = nullptr;
214 GrContext* ctx = canvas->getGrContext();
215 if (ctx) {
216 at = ctx->priv().auditTrail();
217 }
218 return at;
219}
220
221void DebugCanvas::drawAndCollectOps(int n, SkCanvas* canvas) {
222 GrAuditTrail* at = this->getAuditTrail(canvas);
223 if (at) {
224 // loop over all of the commands and draw them, this is to collect reordering
225 // information
226 for (int i = 0; i < this->getSize() && i <= n; i++) {
227 GrAuditTrail::AutoCollectOps enable(at, i);
228 fCommandVector[i]->execute(canvas);
229 }
230
231 // in case there is some kind of global reordering
232 {
233 GrAuditTrail::AutoEnable ae(at);
234 canvas->flush();
235 }
236 }
237}
238
239void DebugCanvas::cleanupAuditTrail(SkCanvas* canvas) {
240 GrAuditTrail* at = this->getAuditTrail(canvas);
241 if (at) {
242 GrAuditTrail::AutoEnable ae(at);
243 at->fullReset();
244 }
245}
246
247void DebugCanvas::toJSON(SkJSONWriter& writer,
248 UrlDataManager& urlDataManager,
249 int n,
250 SkCanvas* canvas) {
251 this->drawAndCollectOps(n, canvas);
252
253 // now collect json
254 GrAuditTrail* at = this->getAuditTrail(canvas);
255 writer.appendS32(SKDEBUGCANVAS_ATTRIBUTE_VERSION, SKDEBUGCANVAS_VERSION);
256 writer.beginArray(SKDEBUGCANVAS_ATTRIBUTE_COMMANDS);
257
258 for (int i = 0; i < this->getSize() && i <= n; i++) {
259 writer.beginObject(); // command
260 this->getDrawCommandAt(i)->toJSON(writer, urlDataManager);
261
262 if (at) {
263 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_AUDITTRAIL);
264 at->toJson(writer, i);
265 }
266 writer.endObject(); // command
267 }
268
269 writer.endArray(); // commands
270 this->cleanupAuditTrail(canvas);
271}
272
Greg Danielf21bf9e2019-08-22 20:12:20 +0000273void DebugCanvas::toJSONOpList(SkJSONWriter& writer, int n, SkCanvas* canvas) {
Mike Klein8f4e2242019-03-20 11:59:00 -0500274 this->drawAndCollectOps(n, canvas);
275
276 GrAuditTrail* at = this->getAuditTrail(canvas);
277 if (at) {
Greg Danielf21bf9e2019-08-22 20:12:20 +0000278 GrAuditTrail::AutoManageOpList enable(at);
Mike Klein8f4e2242019-03-20 11:59:00 -0500279 at->toJson(writer);
280 } else {
281 writer.beginObject();
282 writer.endObject();
283 }
284 this->cleanupAuditTrail(canvas);
285}
286
287void DebugCanvas::setOverdrawViz(bool overdrawViz) { fOverdrawViz = overdrawViz; }
288
289void DebugCanvas::onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle edgeStyle) {
Mike Klein17428132019-03-20 13:02:32 -0500290 this->addDrawCommand(new ClipPathCommand(path, op, kSoft_ClipEdgeStyle == edgeStyle));
Mike Klein8f4e2242019-03-20 11:59:00 -0500291}
292
293void DebugCanvas::onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle edgeStyle) {
Mike Klein17428132019-03-20 13:02:32 -0500294 this->addDrawCommand(new ClipRectCommand(rect, op, kSoft_ClipEdgeStyle == edgeStyle));
Mike Klein8f4e2242019-03-20 11:59:00 -0500295}
296
297void DebugCanvas::onClipRRect(const SkRRect& rrect, SkClipOp op, ClipEdgeStyle edgeStyle) {
Mike Klein17428132019-03-20 13:02:32 -0500298 this->addDrawCommand(new ClipRRectCommand(rrect, op, kSoft_ClipEdgeStyle == edgeStyle));
Mike Klein8f4e2242019-03-20 11:59:00 -0500299}
300
301void DebugCanvas::onClipRegion(const SkRegion& region, SkClipOp op) {
Mike Klein17428132019-03-20 13:02:32 -0500302 this->addDrawCommand(new ClipRegionCommand(region, op));
Mike Klein8f4e2242019-03-20 11:59:00 -0500303}
304
305void DebugCanvas::didConcat(const SkMatrix& matrix) {
Mike Klein17428132019-03-20 13:02:32 -0500306 this->addDrawCommand(new ConcatCommand(matrix));
Mike Klein8f4e2242019-03-20 11:59:00 -0500307 this->INHERITED::didConcat(matrix);
308}
309
310void DebugCanvas::onDrawAnnotation(const SkRect& rect, const char key[], SkData* value) {
Mike Klein17428132019-03-20 13:02:32 -0500311 this->addDrawCommand(new DrawAnnotationCommand(rect, key, sk_ref_sp(value)));
Mike Klein8f4e2242019-03-20 11:59:00 -0500312}
313
314void DebugCanvas::onDrawBitmap(const SkBitmap& bitmap,
315 SkScalar left,
316 SkScalar top,
317 const SkPaint* paint) {
Mike Klein17428132019-03-20 13:02:32 -0500318 this->addDrawCommand(new DrawBitmapCommand(bitmap, left, top, paint));
Mike Klein8f4e2242019-03-20 11:59:00 -0500319}
320
321void DebugCanvas::onDrawBitmapLattice(const SkBitmap& bitmap,
322 const Lattice& lattice,
323 const SkRect& dst,
324 const SkPaint* paint) {
Mike Klein17428132019-03-20 13:02:32 -0500325 this->addDrawCommand(new DrawBitmapLatticeCommand(bitmap, lattice, dst, paint));
Mike Klein8f4e2242019-03-20 11:59:00 -0500326}
327
328void DebugCanvas::onDrawBitmapRect(const SkBitmap& bitmap,
329 const SkRect* src,
330 const SkRect& dst,
331 const SkPaint* paint,
332 SrcRectConstraint constraint) {
333 this->addDrawCommand(
Mike Klein17428132019-03-20 13:02:32 -0500334 new DrawBitmapRectCommand(bitmap, src, dst, paint, (SrcRectConstraint)constraint));
Mike Klein8f4e2242019-03-20 11:59:00 -0500335}
336
337void DebugCanvas::onDrawBitmapNine(const SkBitmap& bitmap,
338 const SkIRect& center,
339 const SkRect& dst,
340 const SkPaint* paint) {
Mike Klein17428132019-03-20 13:02:32 -0500341 this->addDrawCommand(new DrawBitmapNineCommand(bitmap, center, dst, paint));
Mike Klein8f4e2242019-03-20 11:59:00 -0500342}
343
344void DebugCanvas::onDrawImage(const SkImage* image,
345 SkScalar left,
346 SkScalar top,
347 const SkPaint* paint) {
Mike Klein17428132019-03-20 13:02:32 -0500348 this->addDrawCommand(new DrawImageCommand(image, left, top, paint));
Mike Klein8f4e2242019-03-20 11:59:00 -0500349}
350
351void DebugCanvas::onDrawImageLattice(const SkImage* image,
352 const Lattice& lattice,
353 const SkRect& dst,
354 const SkPaint* paint) {
Mike Klein17428132019-03-20 13:02:32 -0500355 this->addDrawCommand(new DrawImageLatticeCommand(image, lattice, dst, paint));
Mike Klein8f4e2242019-03-20 11:59:00 -0500356}
357
358void DebugCanvas::onDrawImageRect(const SkImage* image,
359 const SkRect* src,
360 const SkRect& dst,
361 const SkPaint* paint,
362 SrcRectConstraint constraint) {
Mike Klein17428132019-03-20 13:02:32 -0500363 this->addDrawCommand(new DrawImageRectCommand(image, src, dst, paint, constraint));
Mike Klein8f4e2242019-03-20 11:59:00 -0500364}
365
366void DebugCanvas::onDrawImageNine(const SkImage* image,
367 const SkIRect& center,
368 const SkRect& dst,
369 const SkPaint* paint) {
Mike Klein17428132019-03-20 13:02:32 -0500370 this->addDrawCommand(new DrawImageNineCommand(image, center, dst, paint));
Mike Klein8f4e2242019-03-20 11:59:00 -0500371}
372
373void DebugCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint) {
Mike Klein17428132019-03-20 13:02:32 -0500374 this->addDrawCommand(new DrawOvalCommand(oval, paint));
Mike Klein8f4e2242019-03-20 11:59:00 -0500375}
376
377void DebugCanvas::onDrawArc(const SkRect& oval,
378 SkScalar startAngle,
379 SkScalar sweepAngle,
380 bool useCenter,
381 const SkPaint& paint) {
Mike Klein17428132019-03-20 13:02:32 -0500382 this->addDrawCommand(new DrawArcCommand(oval, startAngle, sweepAngle, useCenter, paint));
Mike Klein8f4e2242019-03-20 11:59:00 -0500383}
384
385void DebugCanvas::onDrawPaint(const SkPaint& paint) {
Mike Klein17428132019-03-20 13:02:32 -0500386 this->addDrawCommand(new DrawPaintCommand(paint));
Mike Klein8f4e2242019-03-20 11:59:00 -0500387}
388
Mike Reedd5674082019-04-19 15:00:47 -0400389void DebugCanvas::onDrawBehind(const SkPaint& paint) {
390 this->addDrawCommand(new DrawBehindCommand(paint));
391}
392
Mike Klein8f4e2242019-03-20 11:59:00 -0500393void DebugCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) {
Mike Klein17428132019-03-20 13:02:32 -0500394 this->addDrawCommand(new DrawPathCommand(path, paint));
Mike Klein8f4e2242019-03-20 11:59:00 -0500395}
396
397void DebugCanvas::onDrawRegion(const SkRegion& region, const SkPaint& paint) {
Mike Klein17428132019-03-20 13:02:32 -0500398 this->addDrawCommand(new DrawRegionCommand(region, paint));
Mike Klein8f4e2242019-03-20 11:59:00 -0500399}
400
401void DebugCanvas::onDrawPicture(const SkPicture* picture,
402 const SkMatrix* matrix,
403 const SkPaint* paint) {
Mike Klein17428132019-03-20 13:02:32 -0500404 this->addDrawCommand(new BeginDrawPictureCommand(picture, matrix, paint));
Mike Klein8f4e2242019-03-20 11:59:00 -0500405 SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect());
406 picture->playback(this);
Mike Klein17428132019-03-20 13:02:32 -0500407 this->addDrawCommand(new EndDrawPictureCommand(SkToBool(matrix) || SkToBool(paint)));
Mike Klein8f4e2242019-03-20 11:59:00 -0500408}
409
410void DebugCanvas::onDrawPoints(PointMode mode,
411 size_t count,
412 const SkPoint pts[],
413 const SkPaint& paint) {
Mike Klein17428132019-03-20 13:02:32 -0500414 this->addDrawCommand(new DrawPointsCommand(mode, count, pts, paint));
Mike Klein8f4e2242019-03-20 11:59:00 -0500415}
416
417void DebugCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) {
418 // NOTE(chudy): Messing up when renamed to DrawRect... Why?
Mike Klein17428132019-03-20 13:02:32 -0500419 addDrawCommand(new DrawRectCommand(rect, paint));
Mike Klein8f4e2242019-03-20 11:59:00 -0500420}
421
422void DebugCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) {
Mike Klein17428132019-03-20 13:02:32 -0500423 this->addDrawCommand(new DrawRRectCommand(rrect, paint));
Mike Klein8f4e2242019-03-20 11:59:00 -0500424}
425
426void DebugCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint) {
Mike Klein17428132019-03-20 13:02:32 -0500427 this->addDrawCommand(new DrawDRRectCommand(outer, inner, paint));
Mike Klein8f4e2242019-03-20 11:59:00 -0500428}
429
430void DebugCanvas::onDrawTextBlob(const SkTextBlob* blob,
431 SkScalar x,
432 SkScalar y,
433 const SkPaint& paint) {
434 this->addDrawCommand(
Mike Klein17428132019-03-20 13:02:32 -0500435 new DrawTextBlobCommand(sk_ref_sp(const_cast<SkTextBlob*>(blob)), x, y, paint));
Mike Klein8f4e2242019-03-20 11:59:00 -0500436}
437
438void DebugCanvas::onDrawPatch(const SkPoint cubics[12],
439 const SkColor colors[4],
440 const SkPoint texCoords[4],
441 SkBlendMode bmode,
442 const SkPaint& paint) {
Mike Klein17428132019-03-20 13:02:32 -0500443 this->addDrawCommand(new DrawPatchCommand(cubics, colors, texCoords, bmode, paint));
Mike Klein8f4e2242019-03-20 11:59:00 -0500444}
445
446void DebugCanvas::onDrawVerticesObject(const SkVertices* vertices,
447 const SkVertices::Bone bones[],
448 int boneCount,
449 SkBlendMode bmode,
450 const SkPaint& paint) {
451 // TODO: ANIMATION NOT LOGGED
452 this->addDrawCommand(
Mike Klein17428132019-03-20 13:02:32 -0500453 new DrawVerticesCommand(sk_ref_sp(const_cast<SkVertices*>(vertices)), bmode, paint));
Mike Klein8f4e2242019-03-20 11:59:00 -0500454}
455
456void DebugCanvas::onDrawAtlas(const SkImage* image,
457 const SkRSXform xform[],
458 const SkRect tex[],
459 const SkColor colors[],
460 int count,
461 SkBlendMode bmode,
462 const SkRect* cull,
463 const SkPaint* paint) {
464 this->addDrawCommand(
Mike Klein17428132019-03-20 13:02:32 -0500465 new DrawAtlasCommand(image, xform, tex, colors, count, bmode, cull, paint));
Mike Klein8f4e2242019-03-20 11:59:00 -0500466}
467
468void DebugCanvas::onDrawShadowRec(const SkPath& path, const SkDrawShadowRec& rec) {
Mike Klein17428132019-03-20 13:02:32 -0500469 this->addDrawCommand(new DrawShadowCommand(path, rec));
Mike Klein8f4e2242019-03-20 11:59:00 -0500470}
471
472void DebugCanvas::onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) {
Mike Klein17428132019-03-20 13:02:32 -0500473 this->addDrawCommand(new DrawDrawableCommand(drawable, matrix));
Mike Klein8f4e2242019-03-20 11:59:00 -0500474}
475
476void DebugCanvas::onDrawEdgeAAQuad(const SkRect& rect,
477 const SkPoint clip[4],
478 QuadAAFlags aa,
479 SkColor color,
480 SkBlendMode mode) {
Mike Klein17428132019-03-20 13:02:32 -0500481 this->addDrawCommand(new DrawEdgeAAQuadCommand(rect, clip, aa, color, mode));
Mike Klein8f4e2242019-03-20 11:59:00 -0500482}
483
484void DebugCanvas::onDrawEdgeAAImageSet(const ImageSetEntry set[],
485 int count,
486 const SkPoint dstClips[],
487 const SkMatrix preViewMatrices[],
488 const SkPaint* paint,
489 SrcRectConstraint constraint) {
Mike Klein17428132019-03-20 13:02:32 -0500490 this->addDrawCommand(new DrawEdgeAAImageSetCommand(
Mike Klein8f4e2242019-03-20 11:59:00 -0500491 set, count, dstClips, preViewMatrices, paint, constraint));
492}
493
494void DebugCanvas::willRestore() {
Mike Klein17428132019-03-20 13:02:32 -0500495 this->addDrawCommand(new RestoreCommand());
Mike Klein8f4e2242019-03-20 11:59:00 -0500496 this->INHERITED::willRestore();
497}
498
499void DebugCanvas::willSave() {
Mike Klein17428132019-03-20 13:02:32 -0500500 this->addDrawCommand(new SaveCommand());
Mike Klein8f4e2242019-03-20 11:59:00 -0500501 this->INHERITED::willSave();
502}
503
504SkCanvas::SaveLayerStrategy DebugCanvas::getSaveLayerStrategy(const SaveLayerRec& rec) {
Mike Klein17428132019-03-20 13:02:32 -0500505 this->addDrawCommand(new SaveLayerCommand(rec));
Mike Klein8f4e2242019-03-20 11:59:00 -0500506 (void)this->INHERITED::getSaveLayerStrategy(rec);
507 // No need for a full layer.
508 return kNoLayer_SaveLayerStrategy;
509}
510
511bool DebugCanvas::onDoSaveBehind(const SkRect* subset) {
512 // TODO
513 return false;
514}
515
516void DebugCanvas::didSetMatrix(const SkMatrix& matrix) {
Mike Klein17428132019-03-20 13:02:32 -0500517 this->addDrawCommand(new SetMatrixCommand(matrix));
Mike Klein8f4e2242019-03-20 11:59:00 -0500518 this->INHERITED::didSetMatrix(matrix);
519}
520
521void DebugCanvas::toggleCommand(int index, bool toggle) {
522 SkASSERT(index < fCommandVector.count());
523 fCommandVector[index]->setVisible(toggle);
524}