• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2014 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 SkRecords_DEFINED
9 #define SkRecords_DEFINED
10 
11 #include "SkData.h"
12 #include "SkCanvas.h"
13 #include "SkDrawable.h"
14 #include "SkDrawShadowInfo.h"
15 #include "SkImage.h"
16 #include "SkImageFilter.h"
17 #include "SkMatrix.h"
18 #include "SkPath.h"
19 #include "SkPicture.h"
20 #include "SkRect.h"
21 #include "SkRegion.h"
22 #include "SkRRect.h"
23 #include "SkRSXform.h"
24 #include "SkString.h"
25 #include "SkTextBlob.h"
26 #include "SkVertices.h"
27 
28 namespace SkRecords {
29 
30 // A list of all the types of canvas calls we can record.
31 // Each of these is reified into a struct below.
32 //
33 // (We're using the macro-of-macro trick here to do several different things with the same list.)
34 //
35 // We leave this SK_RECORD_TYPES macro defined for use by code that wants to operate on SkRecords
36 // types polymorphically.  (See SkRecord::Record::{visit,mutate} for an example.)
37 //
38 // Order doesn't technically matter here, but the compiler can generally generate better code if
39 // you keep them semantically grouped, especially the Draws.  It's also nice to leave NoOp at 0.
40 #define SK_RECORD_TYPES(M)                                          \
41     M(NoOp)                                                         \
42     M(Flush)                                                        \
43     M(Restore)                                                      \
44     M(Save)                                                         \
45     M(SaveLayer)                                                    \
46     M(SaveBehind)                                                   \
47     M(SetMatrix)                                                    \
48     M(Translate)                                                    \
49     M(Concat)                                                       \
50     M(ClipPath)                                                     \
51     M(ClipRRect)                                                    \
52     M(ClipRect)                                                     \
53     M(ClipRegion)                                                   \
54     M(DrawArc)                                                      \
55     M(DrawDrawable)                                                 \
56     M(DrawImage)                                                    \
57     M(DrawImageLattice)                                             \
58     M(DrawImageRect)                                                \
59     M(DrawImageNine)                                                \
60     M(DrawImageSet)                                                 \
61     M(DrawDRRect)                                                   \
62     M(DrawOval)                                                     \
63     M(DrawPaint)                                                    \
64     M(DrawPath)                                                     \
65     M(DrawPatch)                                                    \
66     M(DrawPicture)                                                  \
67     M(DrawPoints)                                                   \
68     M(DrawRRect)                                                    \
69     M(DrawRect)                                                     \
70     M(DrawEdgeAARect)                                               \
71     M(DrawRegion)                                                   \
72     M(DrawTextBlob)                                                 \
73     M(DrawAtlas)                                                    \
74     M(DrawVertices)                                                 \
75     M(DrawShadowRec)                                                \
76     M(DrawAnnotation)
77 
78 // Defines SkRecords::Type, an enum of all record types.
79 #define ENUM(T) T##_Type,
80 enum Type { SK_RECORD_TYPES(ENUM) };
81 #undef ENUM
82 
83 #define ACT_AS_PTR(ptr)                 \
84     operator T*() const { return ptr; } \
85     T* operator->() const { return ptr; }
86 
87 // An Optional doesn't own the pointer's memory, but may need to destroy non-POD data.
88 template <typename T>
89 class Optional : SkNoncopyable {
90 public:
Optional()91     Optional() : fPtr(nullptr) {}
Optional(T * ptr)92     Optional(T* ptr) : fPtr(ptr) {}
Optional(Optional && o)93     Optional(Optional&& o) : fPtr(o.fPtr) {
94         o.fPtr = nullptr;
95     }
~Optional()96     ~Optional() { if (fPtr) fPtr->~T(); }
97 
98     ACT_AS_PTR(fPtr)
99 private:
100     T* fPtr;
101 };
102 
103 // Like Optional, but ptr must not be NULL.
104 template <typename T>
105 class Adopted : SkNoncopyable {
106 public:
107     Adopted(T* ptr) : fPtr(ptr) { SkASSERT(fPtr); }
108     Adopted(Adopted* source) {
109         // Transfer ownership from source to this.
110         fPtr = source->fPtr;
111         source->fPtr = NULL;
112     }
113     ~Adopted() { if (fPtr) fPtr->~T(); }
114 
115     ACT_AS_PTR(fPtr)
116 private:
117     T* fPtr;
118 };
119 
120 // PODArray doesn't own the pointer's memory, and we assume the data is POD.
121 template <typename T>
122 class PODArray {
123 public:
124     PODArray() {}
125     PODArray(T* ptr) : fPtr(ptr) {}
126     // Default copy and assign.
127 
128     ACT_AS_PTR(fPtr)
129 private:
130     T* fPtr;
131 };
132 
133 #undef ACT_AS_PTR
134 
135 // SkPath::getBounds() isn't thread safe unless we precache the bounds in a singlethreaded context.
136 // SkPath::cheapComputeDirection() is similar.
137 // Recording is a convenient time to cache these, or we can delay it to between record and playback.
138 struct PreCachedPath : public SkPath {
139     PreCachedPath() {}
140     PreCachedPath(const SkPath& path);
141 };
142 
143 // Like SkPath::getBounds(), SkMatrix::getType() isn't thread safe unless we precache it.
144 // This may not cover all SkMatrices used by the picture (e.g. some could be hiding in a shader).
145 struct TypedMatrix : public SkMatrix {
146     TypedMatrix() {}
147     TypedMatrix(const SkMatrix& matrix);
148 };
149 
150 enum Tags {
151     kDraw_Tag      = 1,   // May draw something (usually named DrawFoo).
152     kHasImage_Tag  = 2,   // Contains an SkImage or SkBitmap.
153     kHasText_Tag   = 4,   // Contains text.
154     kHasPaint_Tag  = 8,   // May have an SkPaint field, at least optionally.
155 
156     kDrawWithPaint_Tag = kDraw_Tag | kHasPaint_Tag,
157 };
158 
159 // A macro to make it a little easier to define a struct that can be stored in SkRecord.
160 #define RECORD(T, tags, ...)            \
161 struct T {                              \
162     static const Type kType = T##_Type; \
163     static const int kTags = tags;      \
164     __VA_ARGS__;                        \
165 };
166 
167 RECORD(NoOp, 0);
168 RECORD(Flush, 0);
169 RECORD(Restore, 0,
170         TypedMatrix matrix);
171 RECORD(Save, 0);
172 
173 RECORD(SaveLayer, kHasPaint_Tag,
174        Optional<SkRect> bounds;
175        Optional<SkPaint> paint;
176        sk_sp<const SkImageFilter> backdrop;
177        sk_sp<const SkImage> clipMask;
178        Optional<SkMatrix> clipMatrix;
179        SkCanvas::SaveLayerFlags saveLayerFlags);
180 
181 RECORD(SaveBehind, 0,
182        Optional<SkRect> subset);
183 
184 RECORD(SetMatrix, 0,
185         TypedMatrix matrix);
186 RECORD(Concat, 0,
187         TypedMatrix matrix);
188 
189 RECORD(Translate, 0,
190         SkScalar dx;
191         SkScalar dy);
192 
193 struct ClipOpAndAA {
194     ClipOpAndAA() {}
195     ClipOpAndAA(SkClipOp op, bool aa) : fOp(static_cast<unsigned>(op)), fAA(aa) {}
196 
197     SkClipOp op() const { return static_cast<SkClipOp>(fOp); }
198     bool aa() const { return fAA != 0; }
199 
200 private:
201     unsigned fOp : 31;  // This really only needs to be 3, but there's no win today to do so.
202     unsigned fAA :  1;  // MSVC won't pack an enum with an bool, so we call this an unsigned.
203 };
204 static_assert(sizeof(ClipOpAndAA) == 4, "ClipOpAndAASize");
205 
206 RECORD(ClipPath, 0,
207         PreCachedPath path;
208         ClipOpAndAA opAA);
209 RECORD(ClipRRect, 0,
210         SkRRect rrect;
211         ClipOpAndAA opAA);
212 RECORD(ClipRect, 0,
213         SkRect rect;
214         ClipOpAndAA opAA);
215 RECORD(ClipRegion, 0,
216         SkRegion region;
217         SkClipOp op);
218 
219 // While not strictly required, if you have an SkPaint, it's fastest to put it first.
220 RECORD(DrawArc, kDraw_Tag|kHasPaint_Tag,
221        SkPaint paint;
222        SkRect oval;
223        SkScalar startAngle;
224        SkScalar sweepAngle;
225        unsigned useCenter);
226 RECORD(DrawDRRect, kDraw_Tag|kHasPaint_Tag,
227         SkPaint paint;
228         SkRRect outer;
229         SkRRect inner);
230 RECORD(DrawDrawable, kDraw_Tag,
231         Optional<SkMatrix> matrix;
232         SkRect worstCaseBounds;
233         int32_t index);
234 RECORD(DrawImage, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag,
235         Optional<SkPaint> paint;
236         sk_sp<const SkImage> image;
237         SkScalar left;
238         SkScalar top);
239 RECORD(DrawImageLattice, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag,
240         Optional<SkPaint> paint;
241         sk_sp<const SkImage> image;
242         int xCount;
243         PODArray<int> xDivs;
244         int yCount;
245         PODArray<int> yDivs;
246         int flagCount;
247         PODArray<SkCanvas::Lattice::RectType> flags;
248         PODArray<SkColor> colors;
249         SkIRect src;
250         SkRect dst);
251 RECORD(DrawImageRect, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag,
252         Optional<SkPaint> paint;
253         sk_sp<const SkImage> image;
254         Optional<SkRect> src;
255         SkRect dst;
256         SkCanvas::SrcRectConstraint constraint);
257 RECORD(DrawImageNine, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag,
258         Optional<SkPaint> paint;
259         sk_sp<const SkImage> image;
260         SkIRect center;
261         SkRect dst);
262 RECORD(DrawImageSet, kDraw_Tag|kHasImage_Tag,
263        SkAutoTArray<SkCanvas::ImageSetEntry> set;
264        int count;
265        SkFilterQuality quality;
266        SkBlendMode mode);
267 RECORD(DrawOval, kDraw_Tag|kHasPaint_Tag,
268         SkPaint paint;
269         SkRect oval);
270 RECORD(DrawPaint, kDraw_Tag|kHasPaint_Tag,
271         SkPaint paint);
272 RECORD(DrawPath, kDraw_Tag|kHasPaint_Tag,
273         SkPaint paint;
274         PreCachedPath path);
275 RECORD(DrawPicture, kDraw_Tag|kHasPaint_Tag,
276         Optional<SkPaint> paint;
277         sk_sp<const SkPicture> picture;
278         TypedMatrix matrix);
279 RECORD(DrawPoints, kDraw_Tag|kHasPaint_Tag,
280         SkPaint paint;
281         SkCanvas::PointMode mode;
282         unsigned count;
283         SkPoint* pts);
284 RECORD(DrawRRect, kDraw_Tag|kHasPaint_Tag,
285         SkPaint paint;
286         SkRRect rrect);
287 RECORD(DrawRect, kDraw_Tag|kHasPaint_Tag,
288         SkPaint paint;
289         SkRect rect);
290 RECORD(DrawEdgeAARect, kDraw_Tag,
291        SkRect rect;
292        SkCanvas::QuadAAFlags aa;
293        SkColor color;
294        SkBlendMode mode);
295 RECORD(DrawRegion, kDraw_Tag|kHasPaint_Tag,
296         SkPaint paint;
297         SkRegion region);
298 RECORD(DrawTextBlob, kDraw_Tag|kHasText_Tag|kHasPaint_Tag,
299         SkPaint paint;
300         sk_sp<const SkTextBlob> blob;
301         SkScalar x;
302         SkScalar y);
303 RECORD(DrawPatch, kDraw_Tag|kHasPaint_Tag,
304         SkPaint paint;
305         PODArray<SkPoint> cubics;
306         PODArray<SkColor> colors;
307         PODArray<SkPoint> texCoords;
308         SkBlendMode bmode);
309 RECORD(DrawAtlas, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag,
310         Optional<SkPaint> paint;
311         sk_sp<const SkImage> atlas;
312         PODArray<SkRSXform> xforms;
313         PODArray<SkRect> texs;
314         PODArray<SkColor> colors;
315         int count;
316         SkBlendMode mode;
317         Optional<SkRect> cull);
318 RECORD(DrawVertices, kDraw_Tag|kHasPaint_Tag,
319         SkPaint paint;
320         sk_sp<SkVertices> vertices;
321         PODArray<SkVertices::Bone> bones;
322         int boneCount;
323         SkBlendMode bmode);
324 RECORD(DrawShadowRec, kDraw_Tag,
325        PreCachedPath path;
326        SkDrawShadowRec rec);
327 RECORD(DrawAnnotation, 0,  // TODO: kDraw_Tag, skia:5548
328        SkRect rect;
329        SkString key;
330        sk_sp<SkData> value);
331 #undef RECORD
332 
333 }  // namespace SkRecords
334 
335 #endif//SkRecords_DEFINED
336