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 #ifndef SKDRAWCOMMAND_H_
9 #define SKDRAWCOMMAND_H_
10 
11 #include "include/core/SkBitmap.h"
12 #include "include/core/SkCanvas.h"
13 #include "include/core/SkFlattenable.h"
14 #include "include/core/SkPath.h"
15 #include "include/core/SkRRect.h"
16 #include "include/core/SkRSXform.h"
17 #include "include/core/SkRegion.h"
18 #include "include/core/SkString.h"
19 #include "include/core/SkVertices.h"
20 #include "include/private/SkTDArray.h"
21 #include "src/core/SkDrawShadowInfo.h"
22 #include "src/core/SkTLazy.h"
23 #include "src/utils/SkJSONWriter.h"
24 #include "tools/UrlDataManager.h"
25 
26 class DebugLayerManager;
27 
28 class DrawCommand {
29 public:
30     enum OpType {
31         kBeginDrawPicture_OpType,
32         kClear_OpType,
33         kClipPath_OpType,
34         kClipRegion_OpType,
35         kClipRect_OpType,
36         kClipRRect_OpType,
37         kClipShader_OpType,
38         kConcat_OpType,
39         kConcat44_OpType,
40         kDrawAnnotation_OpType,
41         kDrawBitmap_OpType,
42         kDrawBitmapRect_OpType,
43         kDrawDRRect_OpType,
44         kDrawImage_OpType,
45         kDrawImageLattice_OpType,
46         kDrawImageNine_OpType,
47         kDrawImageRect_OpType,
48         kDrawImageRectLayer_OpType, // unique to DebugCanvas
49         kDrawOval_OpType,
50         kDrawArc_OpType,
51         kDrawPaint_OpType,
52         kDrawPatch_OpType,
53         kDrawPath_OpType,
54         kDrawPoints_OpType,
55         kDrawRect_OpType,
56         kDrawRRect_OpType,
57         kDrawRegion_OpType,
58         kDrawShadow_OpType,
59         kDrawTextBlob_OpType,
60         kDrawVertices_OpType,
61         kDrawAtlas_OpType,
62         kDrawDrawable_OpType,
63         kDrawEdgeAAQuad_OpType,
64         kDrawEdgeAAImageSet_OpType,
65         kEndDrawPicture_OpType,
66         kRestore_OpType,
67         kSave_OpType,
68         kSaveLayer_OpType,
69         kSetMatrix_OpType,
70 
71         kLast_OpType = kSetMatrix_OpType
72     };
73 
74     static const int kOpTypeCount = kLast_OpType + 1;
75 
76     static void WritePNG(SkBitmap bitmap, SkWStream& out);
77 
78     DrawCommand(OpType opType);
79 
~DrawCommand()80     virtual ~DrawCommand() {}
81 
isVisible()82     bool isVisible() const { return fVisible; }
83 
setVisible(bool toggle)84     void setVisible(bool toggle) { fVisible = toggle; }
85 
86     virtual void execute(SkCanvas*) const = 0;
87 
render(SkCanvas * canvas)88     virtual bool render(SkCanvas* canvas) const { return false; }
89 
90     virtual void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const;
91 
92     static const char* GetCommandString(OpType type);
93 
94     // Helper methods for converting things to JSON
95     static void MakeJsonColor(SkJSONWriter&, const SkColor color);
96     static void MakeJsonColor4f(SkJSONWriter&, const SkColor4f& color);
97     static void MakeJsonPoint(SkJSONWriter&, const SkPoint& point);
98     static void MakeJsonPoint(SkJSONWriter&, SkScalar x, SkScalar y);
99     static void MakeJsonPoint3(SkJSONWriter&, const SkPoint3& point);
100     static void MakeJsonRect(SkJSONWriter&, const SkRect& rect);
101     static void MakeJsonIRect(SkJSONWriter&, const SkIRect&);
102     static void MakeJsonMatrix(SkJSONWriter&, const SkMatrix&);
103     static void MakeJsonMatrix44(SkJSONWriter&, const SkM44&);
104     static void MakeJsonPath(SkJSONWriter&, const SkPath& path);
105     static void MakeJsonRegion(SkJSONWriter&, const SkRegion& region);
106     static void MakeJsonPaint(SkJSONWriter&, const SkPaint& paint, UrlDataManager& urlDataManager);
107     static void MakeJsonLattice(SkJSONWriter&, const SkCanvas::Lattice& lattice);
108 
109     static void flatten(const SkFlattenable* flattenable,
110                         SkJSONWriter&        writer,
111                         UrlDataManager&      urlDataManager);
112     static bool flatten(const SkImage& image, SkJSONWriter& writer, UrlDataManager& urlDataManager);
113     static bool flatten(const SkBitmap& bitmap,
114                         SkJSONWriter&   writer,
115                         UrlDataManager& urlDataManager);
getOpType()116     OpType getOpType() const { return fOpType; }
117 
118 private:
119     OpType fOpType;
120     bool   fVisible;
121 };
122 
123 class RestoreCommand : public DrawCommand {
124 public:
125     RestoreCommand();
126     void execute(SkCanvas* canvas) const override;
127 
128 private:
129     using INHERITED = DrawCommand;
130 };
131 
132 class ClearCommand : public DrawCommand {
133 public:
134     ClearCommand(SkColor color);
135     void execute(SkCanvas* canvas) const override;
136     void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
137 
138 private:
139     SkColor fColor;
140 
141     using INHERITED = DrawCommand;
142 };
143 
144 class ClipPathCommand : public DrawCommand {
145 public:
146     ClipPathCommand(const SkPath& path, SkClipOp op, bool doAA);
147     void execute(SkCanvas* canvas) const override;
148     bool render(SkCanvas* canvas) const override;
149     void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
150 
151 private:
152     SkPath   fPath;
153     SkClipOp fOp;
154     bool     fDoAA;
155 
156     using INHERITED = DrawCommand;
157 };
158 
159 class ClipRegionCommand : public DrawCommand {
160 public:
161     ClipRegionCommand(const SkRegion& region, SkClipOp op);
162     void execute(SkCanvas* canvas) const override;
163     void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
164 
165 private:
166     SkRegion fRegion;
167     SkClipOp fOp;
168 
169     using INHERITED = DrawCommand;
170 };
171 
172 class ClipRectCommand : public DrawCommand {
173 public:
174     ClipRectCommand(const SkRect& rect, SkClipOp op, bool doAA);
175     void execute(SkCanvas* canvas) const override;
176     void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
177 
178 private:
179     SkRect   fRect;
180     SkClipOp fOp;
181     bool     fDoAA;
182 
183     using INHERITED = DrawCommand;
184 };
185 
186 class ClipRRectCommand : public DrawCommand {
187 public:
188     ClipRRectCommand(const SkRRect& rrect, SkClipOp op, bool doAA);
189     void execute(SkCanvas* canvas) const override;
190     bool render(SkCanvas* canvas) const override;
191     void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
192 
193 private:
194     SkRRect  fRRect;
195     SkClipOp fOp;
196     bool     fDoAA;
197 
198     using INHERITED = DrawCommand;
199 };
200 
201 class ClipShaderCommand : public DrawCommand {
202 public:
203     ClipShaderCommand(sk_sp<SkShader>, SkClipOp);
204     void execute(SkCanvas* canvas) const override;
205     bool render(SkCanvas* canvas) const override;
206     void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
207 
208 private:
209     sk_sp<SkShader> fShader;
210     SkClipOp fOp;
211 
212     using INHERITED = DrawCommand;
213 };
214 
215 class ConcatCommand : public DrawCommand {
216 public:
217     ConcatCommand(const SkMatrix& matrix);
218     void execute(SkCanvas* canvas) const override;
219     void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
220 
221 private:
222     SkMatrix fMatrix;
223 
224     using INHERITED = DrawCommand;
225 };
226 
227 class Concat44Command : public DrawCommand {
228 public:
229     Concat44Command(const SkM44& matrix);
230     void execute(SkCanvas* canvas) const override;
231     void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
232 
233 private:
234     SkM44 fMatrix;
235 
236     using INHERITED = DrawCommand;
237 };
238 
239 class DrawAnnotationCommand : public DrawCommand {
240 public:
241     DrawAnnotationCommand(const SkRect&, const char key[], sk_sp<SkData> value);
242     void execute(SkCanvas* canvas) const override;
243     void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
244 
245 private:
246     SkRect        fRect;
247     SkString      fKey;
248     sk_sp<SkData> fValue;
249 
250     using INHERITED = DrawCommand;
251 };
252 
253 class DrawImageCommand : public DrawCommand {
254 public:
255     DrawImageCommand(const SkImage* image, SkScalar left, SkScalar top, const SkPaint* paint);
256     void execute(SkCanvas* canvas) const override;
257     bool render(SkCanvas* canvas) const override;
258     void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
259     uint64_t imageId(UrlDataManager& udb) const;
260 
261 private:
262     sk_sp<const SkImage> fImage;
263     SkScalar             fLeft;
264     SkScalar             fTop;
265     SkTLazy<SkPaint>     fPaint;
266 
267     using INHERITED = DrawCommand;
268 };
269 
270 class DrawImageLatticeCommand : public DrawCommand {
271 public:
272     DrawImageLatticeCommand(const SkImage*           image,
273                             const SkCanvas::Lattice& lattice,
274                             const SkRect&            dst,
275                             const SkPaint*           paint);
276     void execute(SkCanvas* canvas) const override;
277     bool render(SkCanvas* canvas) const override;
278     void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
279     uint64_t imageId(UrlDataManager& udb) const;
280 
281 private:
282     sk_sp<const SkImage> fImage;
283     SkCanvas::Lattice    fLattice;
284     SkRect               fDst;
285     SkTLazy<SkPaint>     fPaint;
286 
287     using INHERITED = DrawCommand;
288 };
289 
290 class DrawImageNineCommand : public DrawCommand {
291 public:
292     DrawImageNineCommand(const SkImage* image,
293                          const SkIRect& center,
294                          const SkRect&  dst,
295                          const SkPaint* paint);
296     void execute(SkCanvas* canvas) const override;
297     bool render(SkCanvas* canvas) const override;
298     void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
299     uint64_t imageId(UrlDataManager& udb) const;
300 
301 private:
302     sk_sp<const SkImage> fImage;
303     SkIRect              fCenter;
304     SkRect               fDst;
305     SkTLazy<SkPaint>     fPaint;
306 
307     using INHERITED = DrawCommand;
308 };
309 
310 class DrawImageRectCommand : public DrawCommand {
311 public:
312     DrawImageRectCommand(const SkImage*              image,
313                          const SkRect*               src,
314                          const SkRect&               dst,
315                          const SkPaint*              paint,
316                          SkCanvas::SrcRectConstraint constraint);
317     void execute(SkCanvas* canvas) const override;
318     bool render(SkCanvas* canvas) const override;
319     void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
320     uint64_t imageId(UrlDataManager& udm) const;
321 
322 private:
323     sk_sp<const SkImage>        fImage;
324     SkTLazy<SkRect>             fSrc;
325     SkRect                      fDst;
326     SkTLazy<SkPaint>            fPaint;
327     SkCanvas::SrcRectConstraint fConstraint;
328 
329     using INHERITED = DrawCommand;
330 };
331 
332 // Command for resolving the deferred SkImage representing an android layer
333 // Functions like DrawImageRect except it uses the saved UrlDataManager to resolve the image
334 // at the time execute() is called.
335 class DrawImageRectLayerCommand : public DrawCommand {
336 public:
337     DrawImageRectLayerCommand(DebugLayerManager*          layerManager,
338                               const int                   nodeId,
339                               const int                   frame,
340                               const SkRect*               src,
341                               const SkRect&               dst,
342                               const SkPaint*              paint,
343                               SkCanvas::SrcRectConstraint constraint);
344     void execute(SkCanvas* canvas) const override;
345     bool render(SkCanvas* canvas) const override;
346     void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
347 
348 private:
349     DebugLayerManager*          fLayerManager;
350     int                         fNodeId;
351     int                         fFrame;
352     SkTLazy<SkRect>             fSrc;
353     SkRect                      fDst;
354     SkTLazy<SkPaint>            fPaint;
355     SkCanvas::SrcRectConstraint fConstraint;
356 
357     using INHERITED = DrawCommand;
358 };
359 
360 class DrawOvalCommand : public DrawCommand {
361 public:
362     DrawOvalCommand(const SkRect& oval, const SkPaint& paint);
363     void execute(SkCanvas* canvas) const override;
364     bool render(SkCanvas* canvas) const override;
365     void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
366 
367 private:
368     SkRect  fOval;
369     SkPaint fPaint;
370 
371     using INHERITED = DrawCommand;
372 };
373 
374 class DrawArcCommand : public DrawCommand {
375 public:
376     DrawArcCommand(const SkRect&  oval,
377                    SkScalar       startAngle,
378                    SkScalar       sweepAngle,
379                    bool           useCenter,
380                    const SkPaint& paint);
381     void execute(SkCanvas* canvas) const override;
382     bool render(SkCanvas* canvas) const override;
383     void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
384 
385 private:
386     SkRect   fOval;
387     SkScalar fStartAngle;
388     SkScalar fSweepAngle;
389     bool     fUseCenter;
390     SkPaint  fPaint;
391 
392     using INHERITED = DrawCommand;
393 };
394 
395 class DrawPaintCommand : public DrawCommand {
396 public:
397     DrawPaintCommand(const SkPaint& paint);
398     void execute(SkCanvas* canvas) const override;
399     bool render(SkCanvas* canvas) const override;
400     void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
401 
402 private:
403     SkPaint fPaint;
404 
405     using INHERITED = DrawCommand;
406 };
407 
408 class DrawBehindCommand : public DrawCommand {
409 public:
410     DrawBehindCommand(const SkPaint& paint);
411     void execute(SkCanvas* canvas) const override;
412     bool render(SkCanvas* canvas) const override;
413     void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
414 
415 private:
416     SkPaint fPaint;
417 
418     using INHERITED = DrawCommand;
419 };
420 
421 class DrawPathCommand : public DrawCommand {
422 public:
423     DrawPathCommand(const SkPath& path, const SkPaint& paint);
424     void execute(SkCanvas* canvas) const override;
425     bool render(SkCanvas* canvas) const override;
426     void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
427 
428 private:
429     SkPath  fPath;
430     SkPaint fPaint;
431 
432     using INHERITED = DrawCommand;
433 };
434 
435 class BeginDrawPictureCommand : public DrawCommand {
436 public:
437     BeginDrawPictureCommand(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint);
438 
439     void execute(SkCanvas* canvas) const override;
440     bool render(SkCanvas* canvas) const override;
441 
442 private:
443     sk_sp<const SkPicture> fPicture;
444     SkTLazy<SkMatrix>      fMatrix;
445     SkTLazy<SkPaint>       fPaint;
446 
447     using INHERITED = DrawCommand;
448 };
449 
450 class EndDrawPictureCommand : public DrawCommand {
451 public:
452     EndDrawPictureCommand(bool restore);
453 
454     void execute(SkCanvas* canvas) const override;
455 
456 private:
457     bool fRestore;
458 
459     using INHERITED = DrawCommand;
460 };
461 
462 class DrawPointsCommand : public DrawCommand {
463 public:
464     DrawPointsCommand(SkCanvas::PointMode mode,
465                       size_t              count,
466                       const SkPoint       pts[],
467                       const SkPaint&      paint);
468     void execute(SkCanvas* canvas) const override;
469     bool render(SkCanvas* canvas) const override;
470     void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
471 
472 private:
473     SkCanvas::PointMode fMode;
474     SkTDArray<SkPoint>  fPts;
475     SkPaint             fPaint;
476 
477     using INHERITED = DrawCommand;
478 };
479 
480 class DrawRegionCommand : public DrawCommand {
481 public:
482     DrawRegionCommand(const SkRegion& region, const SkPaint& paint);
483     void execute(SkCanvas* canvas) const override;
484     bool render(SkCanvas* canvas) const override;
485     void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
486 
487 private:
488     SkRegion fRegion;
489     SkPaint  fPaint;
490 
491     using INHERITED = DrawCommand;
492 };
493 
494 class DrawTextBlobCommand : public DrawCommand {
495 public:
496     DrawTextBlobCommand(sk_sp<SkTextBlob> blob, SkScalar x, SkScalar y, const SkPaint& paint);
497 
498     void execute(SkCanvas* canvas) const override;
499     bool render(SkCanvas* canvas) const override;
500     void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
501 
502 private:
503     sk_sp<SkTextBlob> fBlob;
504     SkScalar          fXPos;
505     SkScalar          fYPos;
506     SkPaint           fPaint;
507 
508     using INHERITED = DrawCommand;
509 };
510 
511 class DrawPatchCommand : public DrawCommand {
512 public:
513     DrawPatchCommand(const SkPoint  cubics[12],
514                      const SkColor  colors[4],
515                      const SkPoint  texCoords[4],
516                      SkBlendMode    bmode,
517                      const SkPaint& paint);
518     void execute(SkCanvas* canvas) const override;
519     void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
520 
521 private:
522     SkPoint     fCubics[12];
523     SkColor*    fColorsPtr;
524     SkColor     fColors[4];
525     SkPoint*    fTexCoordsPtr;
526     SkPoint     fTexCoords[4];
527     SkBlendMode fBlendMode;
528     SkPaint     fPaint;
529 
530     using INHERITED = DrawCommand;
531 };
532 
533 class DrawRectCommand : public DrawCommand {
534 public:
535     DrawRectCommand(const SkRect& rect, const SkPaint& paint);
536     void execute(SkCanvas* canvas) const override;
537     void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
538 
539 private:
540     SkRect  fRect;
541     SkPaint fPaint;
542 
543     using INHERITED = DrawCommand;
544 };
545 
546 class DrawRRectCommand : public DrawCommand {
547 public:
548     DrawRRectCommand(const SkRRect& rrect, const SkPaint& paint);
549     void execute(SkCanvas* canvas) const override;
550     bool render(SkCanvas* canvas) const override;
551     void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
552 
553 private:
554     SkRRect fRRect;
555     SkPaint fPaint;
556 
557     using INHERITED = DrawCommand;
558 };
559 
560 class DrawDRRectCommand : public DrawCommand {
561 public:
562     DrawDRRectCommand(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint);
563     void execute(SkCanvas* canvas) const override;
564     bool render(SkCanvas* canvas) const override;
565     void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
566 
567 private:
568     SkRRect fOuter;
569     SkRRect fInner;
570     SkPaint fPaint;
571 
572     using INHERITED = DrawCommand;
573 };
574 
575 class DrawVerticesCommand : public DrawCommand {
576 public:
577     DrawVerticesCommand(sk_sp<SkVertices>, SkBlendMode, const SkPaint&);
578 
579     void execute(SkCanvas* canvas) const override;
580 
581 private:
582     sk_sp<SkVertices> fVertices;
583     SkBlendMode       fBlendMode;
584     SkPaint           fPaint;
585 
586     using INHERITED = DrawCommand;
587 };
588 
589 class DrawAtlasCommand : public DrawCommand {
590 public:
591     DrawAtlasCommand(const SkImage*,
592                      const SkRSXform[],
593                      const SkRect[],
594                      const SkColor[],
595                      int,
596                      SkBlendMode,
597                      const SkRect*,
598                      const SkPaint*);
599 
600     void execute(SkCanvas* canvas) const override;
601 
602 private:
603     sk_sp<const SkImage> fImage;
604     SkTDArray<SkRSXform> fXform;
605     SkTDArray<SkRect>    fTex;
606     SkTDArray<SkColor>   fColors;
607     SkBlendMode          fBlendMode;
608     SkTLazy<SkRect>      fCull;
609     SkTLazy<SkPaint>     fPaint;
610 
611     using INHERITED = DrawCommand;
612 };
613 
614 class SaveCommand : public DrawCommand {
615 public:
616     SaveCommand();
617     void execute(SkCanvas* canvas) const override;
618 
619 private:
620     using INHERITED = DrawCommand;
621 };
622 
623 class SaveLayerCommand : public DrawCommand {
624 public:
625     SaveLayerCommand(const SkCanvas::SaveLayerRec&);
626     void execute(SkCanvas* canvas) const override;
627     void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
628 
629 private:
630     SkTLazy<SkRect>            fBounds;
631     SkTLazy<SkPaint>           fPaint;
632     sk_sp<const SkImageFilter> fBackdrop;
633     uint32_t                   fSaveLayerFlags;
634 
635     using INHERITED = DrawCommand;
636 };
637 
638 class SetMatrixCommand : public DrawCommand {
639 public:
640     SetMatrixCommand(const SkMatrix& matrix);
641     void execute(SkCanvas* canvas) const override;
642     void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
643 
644 private:
645     SkMatrix fMatrix;
646 
647     using INHERITED = DrawCommand;
648 };
649 
650 class DrawShadowCommand : public DrawCommand {
651 public:
652     DrawShadowCommand(const SkPath& path, const SkDrawShadowRec& rec);
653     void execute(SkCanvas* canvas) const override;
654     bool render(SkCanvas* canvas) const override;
655     void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
656 
657 private:
658     SkPath          fPath;
659     SkDrawShadowRec fShadowRec;
660 
661     using INHERITED = DrawCommand;
662 };
663 
664 class DrawDrawableCommand : public DrawCommand {
665 public:
666     DrawDrawableCommand(SkDrawable*, const SkMatrix*);
667     void execute(SkCanvas* canvas) const override;
668 
669 private:
670     sk_sp<SkDrawable> fDrawable;
671     SkTLazy<SkMatrix> fMatrix;
672 
673     using INHERITED = DrawCommand;
674 };
675 
676 class DrawEdgeAAQuadCommand : public DrawCommand {
677 public:
678     DrawEdgeAAQuadCommand(const SkRect&         rect,
679                           const SkPoint         clip[4],
680                           SkCanvas::QuadAAFlags aa,
681                           const SkColor4f&      color,
682                           SkBlendMode           mode);
683     void execute(SkCanvas* canvas) const override;
684 
685 private:
686     SkRect                fRect;
687     SkPoint               fClip[4];
688     int                   fHasClip;
689     SkCanvas::QuadAAFlags fAA;
690     SkColor4f             fColor;
691     SkBlendMode           fMode;
692 
693     using INHERITED = DrawCommand;
694 };
695 
696 class DrawEdgeAAImageSetCommand : public DrawCommand {
697 public:
698     DrawEdgeAAImageSetCommand(const SkCanvas::ImageSetEntry[],
699                               int count,
700                               const SkPoint[],
701                               const SkMatrix[],
702                               const SkPaint*,
703                               SkCanvas::SrcRectConstraint);
704     void execute(SkCanvas* canvas) const override;
705 
706 private:
707     SkAutoTArray<SkCanvas::ImageSetEntry> fSet;
708     int                                   fCount;
709     SkAutoTArray<SkPoint>                 fDstClips;
710     SkAutoTArray<SkMatrix>                fPreViewMatrices;
711     SkTLazy<SkPaint>                      fPaint;
712     SkCanvas::SrcRectConstraint           fConstraint;
713 
714     using INHERITED = DrawCommand;
715 };
716 #endif
717