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