• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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