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