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
8 #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"
17
18 #include "include/gpu/GrContext.h"
19 #include "src/gpu/GrAuditTrail.h"
20 #include "src/gpu/GrContextPriv.h"
21 #include "src/gpu/GrRenderTargetContext.h"
22
23 #define SKDEBUGCANVAS_VERSION 1
24 #define SKDEBUGCANVAS_ATTRIBUTE_VERSION "version"
25 #define SKDEBUGCANVAS_ATTRIBUTE_COMMANDS "commands"
26 #define SKDEBUGCANVAS_ATTRIBUTE_AUDITTRAIL "auditTrail"
27
28 class DebugPaintFilterCanvas : public SkPaintFilterCanvas {
29 public:
DebugPaintFilterCanvas(SkCanvas * canvas,bool overdrawViz)30 DebugPaintFilterCanvas(SkCanvas* canvas, bool overdrawViz)
31 : INHERITED(canvas), fOverdrawViz(overdrawViz) {}
32
33 protected:
onFilter(SkPaint & paint) const34 bool onFilter(SkPaint& paint) const override {
35 if (fOverdrawViz) {
36 paint.setColor(SK_ColorRED);
37 paint.setAlpha(0x08);
38 paint.setBlendMode(SkBlendMode::kSrcOver);
39 }
40 return true;
41 }
42
onDrawPicture(const SkPicture * picture,const SkMatrix * matrix,const SkPaint * paint)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
50 private:
51 bool fOverdrawViz;
52
53 typedef SkPaintFilterCanvas INHERITED;
54 };
55
DebugCanvas(int width,int height)56 DebugCanvas::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
DebugCanvas(SkIRect bounds)80 DebugCanvas::DebugCanvas(SkIRect bounds) { DebugCanvas(bounds.width(), bounds.height()); }
81
~DebugCanvas()82 DebugCanvas::~DebugCanvas() { fCommandVector.deleteAll(); }
83
addDrawCommand(DrawCommand * command)84 void DebugCanvas::addDrawCommand(DrawCommand* command) { fCommandVector.push_back(command); }
85
draw(SkCanvas * canvas)86 void DebugCanvas::draw(SkCanvas* canvas) {
87 if (!fCommandVector.isEmpty()) {
88 this->drawTo(canvas, fCommandVector.count() - 1);
89 }
90 }
91
drawTo(SkCanvas * originalCanvas,int index,int m)92 void 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
101 originalCanvas->clear(SK_ColorTRANSPARENT);
102 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
175 at->getBoundsByOpListID(&childrenBounds.push_back(), m);
176 }
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
deleteDrawCommandAt(int index)201 void DebugCanvas::deleteDrawCommandAt(int index) {
202 SkASSERT(index < fCommandVector.count());
203 delete fCommandVector[index];
204 fCommandVector.remove(index);
205 }
206
getDrawCommandAt(int index)207 DrawCommand* DebugCanvas::getDrawCommandAt(int index) {
208 SkASSERT(index < fCommandVector.count());
209 return fCommandVector[index];
210 }
211
getAuditTrail(SkCanvas * canvas)212 GrAuditTrail* 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
drawAndCollectOps(int n,SkCanvas * canvas)221 void 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
cleanupAuditTrail(SkCanvas * canvas)239 void DebugCanvas::cleanupAuditTrail(SkCanvas* canvas) {
240 GrAuditTrail* at = this->getAuditTrail(canvas);
241 if (at) {
242 GrAuditTrail::AutoEnable ae(at);
243 at->fullReset();
244 }
245 }
246
toJSON(SkJSONWriter & writer,UrlDataManager & urlDataManager,int n,SkCanvas * canvas)247 void 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
toJSONOpList(SkJSONWriter & writer,int n,SkCanvas * canvas)273 void DebugCanvas::toJSONOpList(SkJSONWriter& writer, int n, SkCanvas* canvas) {
274 this->drawAndCollectOps(n, canvas);
275
276 GrAuditTrail* at = this->getAuditTrail(canvas);
277 if (at) {
278 GrAuditTrail::AutoManageOpList enable(at);
279 at->toJson(writer);
280 } else {
281 writer.beginObject();
282 writer.endObject();
283 }
284 this->cleanupAuditTrail(canvas);
285 }
286
setOverdrawViz(bool overdrawViz)287 void DebugCanvas::setOverdrawViz(bool overdrawViz) { fOverdrawViz = overdrawViz; }
288
onClipPath(const SkPath & path,SkClipOp op,ClipEdgeStyle edgeStyle)289 void DebugCanvas::onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle edgeStyle) {
290 this->addDrawCommand(new ClipPathCommand(path, op, kSoft_ClipEdgeStyle == edgeStyle));
291 }
292
onClipRect(const SkRect & rect,SkClipOp op,ClipEdgeStyle edgeStyle)293 void DebugCanvas::onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle edgeStyle) {
294 this->addDrawCommand(new ClipRectCommand(rect, op, kSoft_ClipEdgeStyle == edgeStyle));
295 }
296
onClipRRect(const SkRRect & rrect,SkClipOp op,ClipEdgeStyle edgeStyle)297 void DebugCanvas::onClipRRect(const SkRRect& rrect, SkClipOp op, ClipEdgeStyle edgeStyle) {
298 this->addDrawCommand(new ClipRRectCommand(rrect, op, kSoft_ClipEdgeStyle == edgeStyle));
299 }
300
onClipRegion(const SkRegion & region,SkClipOp op)301 void DebugCanvas::onClipRegion(const SkRegion& region, SkClipOp op) {
302 this->addDrawCommand(new ClipRegionCommand(region, op));
303 }
304
didConcat(const SkMatrix & matrix)305 void DebugCanvas::didConcat(const SkMatrix& matrix) {
306 this->addDrawCommand(new ConcatCommand(matrix));
307 this->INHERITED::didConcat(matrix);
308 }
309
onDrawAnnotation(const SkRect & rect,const char key[],SkData * value)310 void DebugCanvas::onDrawAnnotation(const SkRect& rect, const char key[], SkData* value) {
311 this->addDrawCommand(new DrawAnnotationCommand(rect, key, sk_ref_sp(value)));
312 }
313
onDrawBitmap(const SkBitmap & bitmap,SkScalar left,SkScalar top,const SkPaint * paint)314 void DebugCanvas::onDrawBitmap(const SkBitmap& bitmap,
315 SkScalar left,
316 SkScalar top,
317 const SkPaint* paint) {
318 this->addDrawCommand(new DrawBitmapCommand(bitmap, left, top, paint));
319 }
320
onDrawBitmapLattice(const SkBitmap & bitmap,const Lattice & lattice,const SkRect & dst,const SkPaint * paint)321 void DebugCanvas::onDrawBitmapLattice(const SkBitmap& bitmap,
322 const Lattice& lattice,
323 const SkRect& dst,
324 const SkPaint* paint) {
325 this->addDrawCommand(new DrawBitmapLatticeCommand(bitmap, lattice, dst, paint));
326 }
327
onDrawBitmapRect(const SkBitmap & bitmap,const SkRect * src,const SkRect & dst,const SkPaint * paint,SrcRectConstraint constraint)328 void DebugCanvas::onDrawBitmapRect(const SkBitmap& bitmap,
329 const SkRect* src,
330 const SkRect& dst,
331 const SkPaint* paint,
332 SrcRectConstraint constraint) {
333 this->addDrawCommand(
334 new DrawBitmapRectCommand(bitmap, src, dst, paint, (SrcRectConstraint)constraint));
335 }
336
onDrawBitmapNine(const SkBitmap & bitmap,const SkIRect & center,const SkRect & dst,const SkPaint * paint)337 void DebugCanvas::onDrawBitmapNine(const SkBitmap& bitmap,
338 const SkIRect& center,
339 const SkRect& dst,
340 const SkPaint* paint) {
341 this->addDrawCommand(new DrawBitmapNineCommand(bitmap, center, dst, paint));
342 }
343
onDrawImage(const SkImage * image,SkScalar left,SkScalar top,const SkPaint * paint)344 void DebugCanvas::onDrawImage(const SkImage* image,
345 SkScalar left,
346 SkScalar top,
347 const SkPaint* paint) {
348 this->addDrawCommand(new DrawImageCommand(image, left, top, paint));
349 }
350
onDrawImageLattice(const SkImage * image,const Lattice & lattice,const SkRect & dst,const SkPaint * paint)351 void DebugCanvas::onDrawImageLattice(const SkImage* image,
352 const Lattice& lattice,
353 const SkRect& dst,
354 const SkPaint* paint) {
355 this->addDrawCommand(new DrawImageLatticeCommand(image, lattice, dst, paint));
356 }
357
onDrawImageRect(const SkImage * image,const SkRect * src,const SkRect & dst,const SkPaint * paint,SrcRectConstraint constraint)358 void DebugCanvas::onDrawImageRect(const SkImage* image,
359 const SkRect* src,
360 const SkRect& dst,
361 const SkPaint* paint,
362 SrcRectConstraint constraint) {
363 this->addDrawCommand(new DrawImageRectCommand(image, src, dst, paint, constraint));
364 }
365
onDrawImageNine(const SkImage * image,const SkIRect & center,const SkRect & dst,const SkPaint * paint)366 void DebugCanvas::onDrawImageNine(const SkImage* image,
367 const SkIRect& center,
368 const SkRect& dst,
369 const SkPaint* paint) {
370 this->addDrawCommand(new DrawImageNineCommand(image, center, dst, paint));
371 }
372
onDrawOval(const SkRect & oval,const SkPaint & paint)373 void DebugCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint) {
374 this->addDrawCommand(new DrawOvalCommand(oval, paint));
375 }
376
onDrawArc(const SkRect & oval,SkScalar startAngle,SkScalar sweepAngle,bool useCenter,const SkPaint & paint)377 void DebugCanvas::onDrawArc(const SkRect& oval,
378 SkScalar startAngle,
379 SkScalar sweepAngle,
380 bool useCenter,
381 const SkPaint& paint) {
382 this->addDrawCommand(new DrawArcCommand(oval, startAngle, sweepAngle, useCenter, paint));
383 }
384
onDrawPaint(const SkPaint & paint)385 void DebugCanvas::onDrawPaint(const SkPaint& paint) {
386 this->addDrawCommand(new DrawPaintCommand(paint));
387 }
388
onDrawBehind(const SkPaint & paint)389 void DebugCanvas::onDrawBehind(const SkPaint& paint) {
390 this->addDrawCommand(new DrawBehindCommand(paint));
391 }
392
onDrawPath(const SkPath & path,const SkPaint & paint)393 void DebugCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) {
394 this->addDrawCommand(new DrawPathCommand(path, paint));
395 }
396
onDrawRegion(const SkRegion & region,const SkPaint & paint)397 void DebugCanvas::onDrawRegion(const SkRegion& region, const SkPaint& paint) {
398 this->addDrawCommand(new DrawRegionCommand(region, paint));
399 }
400
onDrawPicture(const SkPicture * picture,const SkMatrix * matrix,const SkPaint * paint)401 void DebugCanvas::onDrawPicture(const SkPicture* picture,
402 const SkMatrix* matrix,
403 const SkPaint* paint) {
404 this->addDrawCommand(new BeginDrawPictureCommand(picture, matrix, paint));
405 SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect());
406 picture->playback(this);
407 this->addDrawCommand(new EndDrawPictureCommand(SkToBool(matrix) || SkToBool(paint)));
408 }
409
onDrawPoints(PointMode mode,size_t count,const SkPoint pts[],const SkPaint & paint)410 void DebugCanvas::onDrawPoints(PointMode mode,
411 size_t count,
412 const SkPoint pts[],
413 const SkPaint& paint) {
414 this->addDrawCommand(new DrawPointsCommand(mode, count, pts, paint));
415 }
416
onDrawRect(const SkRect & rect,const SkPaint & paint)417 void DebugCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) {
418 // NOTE(chudy): Messing up when renamed to DrawRect... Why?
419 addDrawCommand(new DrawRectCommand(rect, paint));
420 }
421
onDrawRRect(const SkRRect & rrect,const SkPaint & paint)422 void DebugCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) {
423 this->addDrawCommand(new DrawRRectCommand(rrect, paint));
424 }
425
onDrawDRRect(const SkRRect & outer,const SkRRect & inner,const SkPaint & paint)426 void DebugCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint) {
427 this->addDrawCommand(new DrawDRRectCommand(outer, inner, paint));
428 }
429
onDrawTextBlob(const SkTextBlob * blob,SkScalar x,SkScalar y,const SkPaint & paint)430 void DebugCanvas::onDrawTextBlob(const SkTextBlob* blob,
431 SkScalar x,
432 SkScalar y,
433 const SkPaint& paint) {
434 this->addDrawCommand(
435 new DrawTextBlobCommand(sk_ref_sp(const_cast<SkTextBlob*>(blob)), x, y, paint));
436 }
437
onDrawPatch(const SkPoint cubics[12],const SkColor colors[4],const SkPoint texCoords[4],SkBlendMode bmode,const SkPaint & paint)438 void DebugCanvas::onDrawPatch(const SkPoint cubics[12],
439 const SkColor colors[4],
440 const SkPoint texCoords[4],
441 SkBlendMode bmode,
442 const SkPaint& paint) {
443 this->addDrawCommand(new DrawPatchCommand(cubics, colors, texCoords, bmode, paint));
444 }
445
onDrawVerticesObject(const SkVertices * vertices,const SkVertices::Bone bones[],int boneCount,SkBlendMode bmode,const SkPaint & paint)446 void 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(
453 new DrawVerticesCommand(sk_ref_sp(const_cast<SkVertices*>(vertices)), bmode, paint));
454 }
455
onDrawAtlas(const SkImage * image,const SkRSXform xform[],const SkRect tex[],const SkColor colors[],int count,SkBlendMode bmode,const SkRect * cull,const SkPaint * paint)456 void 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(
465 new DrawAtlasCommand(image, xform, tex, colors, count, bmode, cull, paint));
466 }
467
onDrawShadowRec(const SkPath & path,const SkDrawShadowRec & rec)468 void DebugCanvas::onDrawShadowRec(const SkPath& path, const SkDrawShadowRec& rec) {
469 this->addDrawCommand(new DrawShadowCommand(path, rec));
470 }
471
onDrawDrawable(SkDrawable * drawable,const SkMatrix * matrix)472 void DebugCanvas::onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) {
473 this->addDrawCommand(new DrawDrawableCommand(drawable, matrix));
474 }
475
onDrawEdgeAAQuad(const SkRect & rect,const SkPoint clip[4],QuadAAFlags aa,SkColor color,SkBlendMode mode)476 void DebugCanvas::onDrawEdgeAAQuad(const SkRect& rect,
477 const SkPoint clip[4],
478 QuadAAFlags aa,
479 SkColor color,
480 SkBlendMode mode) {
481 this->addDrawCommand(new DrawEdgeAAQuadCommand(rect, clip, aa, color, mode));
482 }
483
onDrawEdgeAAImageSet(const ImageSetEntry set[],int count,const SkPoint dstClips[],const SkMatrix preViewMatrices[],const SkPaint * paint,SrcRectConstraint constraint)484 void DebugCanvas::onDrawEdgeAAImageSet(const ImageSetEntry set[],
485 int count,
486 const SkPoint dstClips[],
487 const SkMatrix preViewMatrices[],
488 const SkPaint* paint,
489 SrcRectConstraint constraint) {
490 this->addDrawCommand(new DrawEdgeAAImageSetCommand(
491 set, count, dstClips, preViewMatrices, paint, constraint));
492 }
493
willRestore()494 void DebugCanvas::willRestore() {
495 this->addDrawCommand(new RestoreCommand());
496 this->INHERITED::willRestore();
497 }
498
willSave()499 void DebugCanvas::willSave() {
500 this->addDrawCommand(new SaveCommand());
501 this->INHERITED::willSave();
502 }
503
getSaveLayerStrategy(const SaveLayerRec & rec)504 SkCanvas::SaveLayerStrategy DebugCanvas::getSaveLayerStrategy(const SaveLayerRec& rec) {
505 this->addDrawCommand(new SaveLayerCommand(rec));
506 (void)this->INHERITED::getSaveLayerStrategy(rec);
507 // No need for a full layer.
508 return kNoLayer_SaveLayerStrategy;
509 }
510
onDoSaveBehind(const SkRect * subset)511 bool DebugCanvas::onDoSaveBehind(const SkRect* subset) {
512 // TODO
513 return false;
514 }
515
didSetMatrix(const SkMatrix & matrix)516 void DebugCanvas::didSetMatrix(const SkMatrix& matrix) {
517 this->addDrawCommand(new SetMatrixCommand(matrix));
518 this->INHERITED::didSetMatrix(matrix);
519 }
520
toggleCommand(int index,bool toggle)521 void DebugCanvas::toggleCommand(int index, bool toggle) {
522 SkASSERT(index < fCommandVector.count());
523 fCommandVector[index]->setVisible(toggle);
524 }
525