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