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