• 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 "SkDrawShadowRec.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 // Windows.h, will pull in all of the GDI defines.  GDI #defines
29 // DrawText to DrawTextA or DrawTextW, but SkRecord has a struct
30 // called DrawText. Since this file does not use GDI, undefing
31 // DrawText makes things less confusing.
32 #ifdef DrawText
33 #undef DrawText
34 #endif
35 
36 namespace SkRecords {
37 
38 // A list of all the types of canvas calls we can record.
39 // Each of these is reified into a struct below.
40 //
41 // (We're using the macro-of-macro trick here to do several different things with the same list.)
42 //
43 // We leave this SK_RECORD_TYPES macro defined for use by code that wants to operate on SkRecords
44 // types polymorphically.  (See SkRecord::Record::{visit,mutate} for an example.)
45 //
46 // Order doesn't technically matter here, but the compiler can generally generate better code if
47 // you keep them semantically grouped, especially the Draws.  It's also nice to leave NoOp at 0.
48 #define SK_RECORD_TYPES(M)                                          \
49     M(NoOp)                                                         \
50     M(Restore)                                                      \
51     M(Save)                                                         \
52     M(SaveLayer)                                                    \
53     M(SetMatrix)                                                    \
54     M(Translate)                                                    \
55     M(Concat)                                                       \
56     M(ClipPath)                                                     \
57     M(ClipRRect)                                                    \
58     M(ClipRect)                                                     \
59     M(ClipRegion)                                                   \
60     M(DrawArc)                                                      \
61     M(DrawDrawable)                                                 \
62     M(DrawImage)                                                    \
63     M(DrawImageLattice)                                             \
64     M(DrawImageRect)                                                \
65     M(DrawImageNine)                                                \
66     M(DrawDRRect)                                                   \
67     M(DrawOval)                                                     \
68     M(DrawPaint)                                                    \
69     M(DrawPath)                                                     \
70     M(DrawPatch)                                                    \
71     M(DrawPicture)                                                  \
72     M(DrawPoints)                                                   \
73     M(DrawPosText)                                                  \
74     M(DrawPosTextH)                                                 \
75     M(DrawText)                                                     \
76     M(DrawTextOnPath)                                               \
77     M(DrawTextRSXform)                                              \
78     M(DrawRRect)                                                    \
79     M(DrawRect)                                                     \
80     M(DrawRegion)                                                   \
81     M(DrawTextBlob)                                                 \
82     M(DrawAtlas)                                                    \
83     M(DrawVertices)                                                 \
84     M(DrawShadowRec)                                                \
85     M(DrawAnnotation)
86 
87 // Defines SkRecords::Type, an enum of all record types.
88 #define ENUM(T) T##_Type,
89 enum Type { SK_RECORD_TYPES(ENUM) };
90 #undef ENUM
91 
92 #define ACT_AS_PTR(ptr)                 \
93     operator T*() const { return ptr; } \
94     T* operator->() const { return ptr; }
95 
96 // An Optional doesn't own the pointer's memory, but may need to destroy non-POD data.
97 template <typename T>
98 class Optional : SkNoncopyable {
99 public:
Optional()100     Optional() : fPtr(nullptr) {}
Optional(T * ptr)101     Optional(T* ptr) : fPtr(ptr) {}
Optional(Optional && o)102     Optional(Optional&& o) : fPtr(o.fPtr) {
103         o.fPtr = nullptr;
104     }
~Optional()105     ~Optional() { if (fPtr) fPtr->~T(); }
106 
107     ACT_AS_PTR(fPtr)
108 private:
109     T* fPtr;
110 };
111 
112 // Like Optional, but ptr must not be NULL.
113 template <typename T>
114 class Adopted : SkNoncopyable {
115 public:
116     Adopted(T* ptr) : fPtr(ptr) { SkASSERT(fPtr); }
117     Adopted(Adopted* source) {
118         // Transfer ownership from source to this.
119         fPtr = source->fPtr;
120         source->fPtr = NULL;
121     }
122     ~Adopted() { if (fPtr) fPtr->~T(); }
123 
124     ACT_AS_PTR(fPtr)
125 private:
126     T* fPtr;
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:
133     PODArray() {}
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 enum Tags {
160     kDraw_Tag      = 1,   // May draw something (usually named DrawFoo).
161     kHasImage_Tag  = 2,   // Contains an SkImage or SkBitmap.
162     kHasText_Tag   = 4,   // Contains text.
163     kHasPaint_Tag  = 8,   // May have an SkPaint field, at least optionally.
164 
165     kDrawWithPaint_Tag = kDraw_Tag | kHasPaint_Tag,
166 };
167 
168 // A macro to make it a little easier to define a struct that can be stored in SkRecord.
169 #define RECORD(T, tags, ...)            \
170 struct T {                              \
171     static const Type kType = T##_Type; \
172     static const int kTags = tags;      \
173     __VA_ARGS__;                        \
174 };
175 
176 RECORD(NoOp, 0);
177 RECORD(Restore, 0,
178         SkIRect devBounds;
179         TypedMatrix matrix);
180 RECORD(Save, 0);
181 
182 RECORD(SaveLayer, kHasPaint_Tag,
183        Optional<SkRect> bounds;
184        Optional<SkPaint> paint;
185        sk_sp<const SkImageFilter> backdrop;
186        sk_sp<const SkImage> clipMask;
187        Optional<SkMatrix> clipMatrix;
188        SkCanvas::SaveLayerFlags saveLayerFlags);
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         SkIRect devBounds;
214         PreCachedPath path;
215         ClipOpAndAA opAA);
216 RECORD(ClipRRect, 0,
217         SkIRect devBounds;
218         SkRRect rrect;
219         ClipOpAndAA opAA);
220 RECORD(ClipRect, 0,
221         SkIRect devBounds;
222         SkRect rect;
223         ClipOpAndAA opAA);
224 RECORD(ClipRegion, 0,
225         SkIRect devBounds;
226         SkRegion region;
227         SkClipOp op);
228 
229 // While not strictly required, if you have an SkPaint, it's fastest to put it first.
230 RECORD(DrawArc, kDraw_Tag|kHasPaint_Tag,
231        SkPaint paint;
232        SkRect oval;
233        SkScalar startAngle;
234        SkScalar sweepAngle;
235        unsigned useCenter);
236 RECORD(DrawDRRect, kDraw_Tag|kHasPaint_Tag,
237         SkPaint paint;
238         SkRRect outer;
239         SkRRect inner);
240 RECORD(DrawDrawable, kDraw_Tag,
241         Optional<SkMatrix> matrix;
242         SkRect worstCaseBounds;
243         int32_t index);
244 RECORD(DrawImage, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag,
245         Optional<SkPaint> paint;
246         sk_sp<const SkImage> image;
247         SkScalar left;
248         SkScalar top);
249 RECORD(DrawImageLattice, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag,
250         Optional<SkPaint> paint;
251         sk_sp<const SkImage> image;
252         int xCount;
253         PODArray<int> xDivs;
254         int yCount;
255         PODArray<int> yDivs;
256         int flagCount;
257         PODArray<SkCanvas::Lattice::Flags> flags;
258         SkIRect src;
259         SkRect dst);
260 RECORD(DrawImageRect, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag,
261         Optional<SkPaint> paint;
262         sk_sp<const SkImage> image;
263         Optional<SkRect> src;
264         SkRect dst;
265         SkCanvas::SrcRectConstraint constraint);
266 RECORD(DrawImageNine, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag,
267         Optional<SkPaint> paint;
268         sk_sp<const SkImage> image;
269         SkIRect center;
270         SkRect dst);
271 RECORD(DrawOval, kDraw_Tag|kHasPaint_Tag,
272         SkPaint paint;
273         SkRect oval);
274 RECORD(DrawPaint, kDraw_Tag|kHasPaint_Tag,
275         SkPaint paint);
276 RECORD(DrawPath, kDraw_Tag|kHasPaint_Tag,
277         SkPaint paint;
278         PreCachedPath path);
279 RECORD(DrawPicture, kDraw_Tag|kHasPaint_Tag,
280         Optional<SkPaint> paint;
281         sk_sp<const SkPicture> picture;
282         TypedMatrix matrix);
283 RECORD(DrawPoints, kDraw_Tag|kHasPaint_Tag,
284         SkPaint paint;
285         SkCanvas::PointMode mode;
286         unsigned count;
287         SkPoint* pts);
288 RECORD(DrawPosText, kDraw_Tag|kHasText_Tag|kHasPaint_Tag,
289         SkPaint paint;
290         PODArray<char> text;
291         size_t byteLength;
292         PODArray<SkPoint> pos);
293 RECORD(DrawPosTextH, kDraw_Tag|kHasText_Tag|kHasPaint_Tag,
294         SkPaint paint;
295         PODArray<char> text;
296         unsigned byteLength;
297         SkScalar y;
298         PODArray<SkScalar> xpos);
299 RECORD(DrawRRect, kDraw_Tag|kHasPaint_Tag,
300         SkPaint paint;
301         SkRRect rrect);
302 RECORD(DrawRect, kDraw_Tag|kHasPaint_Tag,
303         SkPaint paint;
304         SkRect rect);
305 RECORD(DrawRegion, kDraw_Tag|kHasPaint_Tag,
306         SkPaint paint;
307         SkRegion region);
308 RECORD(DrawText, kDraw_Tag|kHasText_Tag|kHasPaint_Tag,
309         SkPaint paint;
310         PODArray<char> text;
311         size_t byteLength;
312         SkScalar x;
313         SkScalar y);
314 RECORD(DrawTextBlob, kDraw_Tag|kHasText_Tag|kHasPaint_Tag,
315         SkPaint paint;
316         sk_sp<const SkTextBlob> blob;
317         SkScalar x;
318         SkScalar y);
319 RECORD(DrawTextOnPath, kDraw_Tag|kHasText_Tag|kHasPaint_Tag,
320         SkPaint paint;
321         PODArray<char> text;
322         size_t byteLength;
323         PreCachedPath path;
324         TypedMatrix matrix);
325 RECORD(DrawTextRSXform, kDraw_Tag|kHasText_Tag|kHasPaint_Tag,
326         SkPaint paint;
327         PODArray<char> text;
328         size_t byteLength;
329         PODArray<SkRSXform> xforms;
330         Optional<SkRect> cull);
331 RECORD(DrawPatch, kDraw_Tag|kHasPaint_Tag,
332         SkPaint paint;
333         PODArray<SkPoint> cubics;
334         PODArray<SkColor> colors;
335         PODArray<SkPoint> texCoords;
336         SkBlendMode bmode);
337 RECORD(DrawAtlas, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag,
338         Optional<SkPaint> paint;
339         sk_sp<const SkImage> atlas;
340         PODArray<SkRSXform> xforms;
341         PODArray<SkRect> texs;
342         PODArray<SkColor> colors;
343         int count;
344         SkBlendMode mode;
345         Optional<SkRect> cull);
346 RECORD(DrawVertices, kDraw_Tag|kHasPaint_Tag,
347         SkPaint paint;
348         sk_sp<SkVertices> vertices;
349         SkBlendMode bmode);
350 RECORD(DrawShadowRec, kDraw_Tag,
351        PreCachedPath path;
352        SkDrawShadowRec rec);
353 RECORD(DrawAnnotation, 0,  // TODO: kDraw_Tag, skia:5548
354        SkRect rect;
355        SkString key;
356        sk_sp<SkData> value);
357 #undef RECORD
358 
359 }  // namespace SkRecords
360 
361 #endif//SkRecords_DEFINED
362