2 * Copyright 2014 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
8 #ifndef SkRecords_DEFINED
9 #define SkRecords_DEFINED
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"
30 #include "include/private/chromium/Slug.h"
35 // A list of all the types of canvas calls we can record.
36 // Each of these is reified into a struct below.
38 // (We're using the macro-of-macro trick here to do several different things with the same list.)
40 // We leave this SK_RECORD_TYPES macro defined for use by code that wants to operate on SkRecords
41 // types polymorphically. (See SkRecord::Record::{visit,mutate} for an example.)
43 // Order doesn't technically matter here, but the compiler can generally generate better code if
44 // you keep them semantically grouped, especially the Draws. It's also nice to leave NoOp at 0.
45 #define SK_RECORD_TYPES(M) \
90 // Defines SkRecords::Type, an enum of all record types.
91 #define ENUM(T) T##_Type,
92 enum Type { SK_RECORD_TYPES(ENUM) };
95 #define ACT_AS_PTR(ptr) \
96 operator T*() const { return ptr; } \
97 T* operator->() const { return ptr; }
99 // An Optional doesn't own the pointer's memory, but may need to destroy non-POD data.
100 template <typename T>
103 Optional() : fPtr(nullptr) {}
104 Optional(T* ptr) : fPtr(ptr) {}
105 Optional(Optional&& o) : fPtr(o.fPtr) {
108 ~Optional() { if (fPtr) fPtr->~T(); }
113 Optional(const Optional&) = delete;
114 Optional& operator=(const Optional&) = delete;
117 // PODArray doesn't own the pointer's memory, and we assume the data is POD.
118 template <typename T>
122 PODArray(T* ptr) : fPtr(ptr) {}
123 // Default copy and assign.
132 // SkPath::getBounds() isn't thread safe unless we precache the bounds in a singlethreaded context.
133 // SkPath::cheapComputeDirection() is similar.
134 // Recording is a convenient time to cache these, or we can delay it to between record and playback.
135 struct PreCachedPath : public SkPath {
137 PreCachedPath(const SkPath& path);
140 // Like SkPath::getBounds(), SkMatrix::getType() isn't thread safe unless we precache it.
141 // This may not cover all SkMatrices used by the picture (e.g. some could be hiding in a shader).
142 struct TypedMatrix : public SkMatrix {
144 TypedMatrix(const SkMatrix& matrix);
148 kDraw_Tag = 1, // May draw something (usually named DrawFoo).
149 kHasImage_Tag = 2, // Contains an SkImage or SkBitmap.
150 kHasText_Tag = 4, // Contains text.
151 kHasPaint_Tag = 8, // May have an SkPaint field, at least optionally.
153 kDrawWithPaint_Tag = kDraw_Tag | kHasPaint_Tag,
156 // A macro to make it a little easier to define a struct that can be stored in SkRecord.
157 #define RECORD(T, tags, ...) \
159 static const Type kType = T##_Type; \
160 static const int kTags = tags; \
170 RECORD(SaveLayer, kHasPaint_Tag,
171 Optional<SkRect> bounds;
172 Optional<SkPaint> paint;
173 sk_sp<const SkImageFilter> backdrop;
174 SkCanvas::SaveLayerFlags saveLayerFlags;
175 SkScalar backdropScale);
177 RECORD(SaveBehind, 0,
178 Optional<SkRect> subset);
199 ClipOpAndAA(SkClipOp op, bool aa) : fOp(static_cast<unsigned>(op)), fAA(aa) {}
201 SkClipOp op() const { return static_cast<SkClipOp>(fOp); }
202 bool aa() const { return fAA != 0; }
205 unsigned fOp : 31; // This really only needs to be 3, but there's no win today to do so.
206 unsigned fAA : 1; // MSVC won't pack an enum with an bool, so we call this an unsigned.
208 static_assert(sizeof(ClipOpAndAA) == 4, "ClipOpAndAASize");
219 RECORD(ClipRegion, 0,
222 RECORD(ClipShader, 0,
223 sk_sp<SkShader> shader;
225 RECORD(ResetClip, 0);
227 // While not strictly required, if you have an SkPaint, it's fastest to put it first.
228 RECORD(DrawArc, kDraw_Tag|kHasPaint_Tag,
234 RECORD(DrawDRRect, kDraw_Tag|kHasPaint_Tag,
238 RECORD(DrawDrawable, kDraw_Tag,
239 Optional<SkMatrix> matrix;
240 SkRect worstCaseBounds;
242 RECORD(DrawImage, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag,
243 Optional<SkPaint> paint;
244 sk_sp<const SkImage> image;
247 SkSamplingOptions sampling);
248 RECORD(DrawImageLattice, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag,
249 Optional<SkPaint> paint;
250 sk_sp<const SkImage> image;
256 PODArray<SkCanvas::Lattice::RectType> flags;
257 PODArray<SkColor> colors;
260 SkFilterMode filter);
261 RECORD(DrawImageRect, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag,
262 Optional<SkPaint> paint;
263 sk_sp<const SkImage> image;
266 SkSamplingOptions sampling;
267 SkCanvas::SrcRectConstraint constraint);
268 RECORD(DrawOval, kDraw_Tag|kHasPaint_Tag,
271 RECORD(DrawPaint, kDraw_Tag|kHasPaint_Tag,
273 RECORD(DrawBehind, kDraw_Tag|kHasPaint_Tag,
275 RECORD(DrawPath, kDraw_Tag|kHasPaint_Tag,
278 RECORD(DrawPicture, kDraw_Tag|kHasPaint_Tag,
279 Optional<SkPaint> paint;
280 sk_sp<const SkPicture> picture;
282 RECORD(DrawPoints, kDraw_Tag|kHasPaint_Tag,
284 SkCanvas::PointMode mode;
286 PODArray<SkPoint> pts);
287 RECORD(DrawRRect, kDraw_Tag|kHasPaint_Tag,
290 RECORD(DrawRect, kDraw_Tag|kHasPaint_Tag,
293 RECORD(DrawRegion, kDraw_Tag|kHasPaint_Tag,
296 RECORD(DrawTextBlob, kDraw_Tag|kHasText_Tag|kHasPaint_Tag,
298 sk_sp<const SkTextBlob> blob;
302 RECORD(DrawSlug, kDraw_Tag|kHasText_Tag,
303 sk_sp<const sktext::gpu::Slug> slug);
307 RECORD(DrawPatch, kDraw_Tag|kHasPaint_Tag,
309 PODArray<SkPoint> cubics;
310 PODArray<SkColor> colors;
311 PODArray<SkPoint> texCoords;
313 RECORD(DrawAtlas, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag,
314 Optional<SkPaint> paint;
315 sk_sp<const SkImage> atlas;
316 PODArray<SkRSXform> xforms;
317 PODArray<SkRect> texs;
318 PODArray<SkColor> colors;
321 SkSamplingOptions sampling;
322 Optional<SkRect> cull);
323 RECORD(DrawVertices, kDraw_Tag|kHasPaint_Tag,
325 sk_sp<SkVertices> vertices;
327 RECORD(DrawShadowRec, kDraw_Tag,
329 SkDrawShadowRec rec);
330 RECORD(DrawAnnotation, 0, // TODO: kDraw_Tag, skia:5548
333 sk_sp<SkData> value);
334 RECORD(DrawEdgeAAQuad, kDraw_Tag,
336 PODArray<SkPoint> clip;
337 SkCanvas::QuadAAFlags aa;
340 RECORD(DrawEdgeAAImageSet, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag,
341 Optional<SkPaint> paint;
342 SkAutoTArray<SkCanvas::ImageSetEntry> set;
344 PODArray<SkPoint> dstClips;
345 PODArray<SkMatrix> preViewMatrices;
346 SkSamplingOptions sampling;
347 SkCanvas::SrcRectConstraint constraint);
350 } // namespace SkRecords
352 #endif//SkRecords_DEFINED