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