blob: bfa15496f31746284dfdc1358baaa2f68a421997 [file] [log] [blame]
commit-bot@chromium.orgc4b21e62014-04-11 18:33:31 +00001/*
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
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +00008#ifndef SkRecords_DEFINED
9#define SkRecords_DEFINED
10
11#include "SkCanvas.h"
12
13namespace SkRecords {
14
15// A list of all the types of canvas calls we can record.
16// Each of these is reified into a struct below.
17//
18// (We're using the macro-of-macro trick here to do several different things with the same list.)
19//
20// We leave this SK_RECORD_TYPES macro defined for use by code that wants to operate on SkRecords
21// types polymorphically. (See SkRecord::Record::{visit,mutate} for an example.)
commit-bot@chromium.org88c3e272014-04-22 16:57:20 +000022#define SK_RECORD_TYPES(M) \
23 M(NoOp) \
24 M(Restore) \
25 M(Save) \
26 M(SaveLayer) \
27 M(Concat) \
28 M(SetMatrix) \
29 M(ClipPath) \
30 M(ClipRRect) \
31 M(ClipRect) \
32 M(ClipRegion) \
33 M(Clear) \
34 M(DrawBitmap) \
35 M(DrawBitmapMatrix) \
36 M(DrawBitmapNine) \
37 M(DrawBitmapRectToRect) \
38 M(DrawDRRect) \
39 M(DrawOval) \
40 M(DrawPaint) \
41 M(DrawPath) \
42 M(DrawPoints) \
43 M(DrawPosText) \
44 M(DrawPosTextH) \
45 M(DrawRRect) \
46 M(DrawRect) \
47 M(DrawSprite) \
48 M(DrawText) \
49 M(DrawTextOnPath) \
50 M(DrawVertices) \
51 M(PushCull) \
52 M(PopCull) \
53 M(PairedPushCull) /*From SkRecordAnnotateCullingPairs*/ \
54 M(BoundedDrawPosTextH) /*From SkRecordBoundDrawPosTextH*/
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +000055
56// Defines SkRecords::Type, an enum of all record types.
57#define ENUM(T) T##_Type,
58enum Type { SK_RECORD_TYPES(ENUM) };
59#undef ENUM
60
61// Macros to make it easier to define a record for a draw call with 0 args, 1 args, 2 args, etc.
62// These should be clearer when you look at their use below.
63#define RECORD0(T) \
64struct T { \
65 static const Type kType = T##_Type; \
66 T() {} \
67};
68
69// We try to be flexible about the types the constructors take. Instead of requring the exact type
70// A here, we take any type Z which implicitly casts to A. This allows the delay_copy() trick to
71// work, allowing the caller to decide whether to pass by value or by const&.
72
73#define RECORD1(T, A, a) \
74struct T { \
75 static const Type kType = T##_Type; \
76 template <typename Z> \
77 T(Z a) : a(a) {} \
78 A a; \
79};
80
81#define RECORD2(T, A, a, B, b) \
82struct T { \
83 static const Type kType = T##_Type; \
84 template <typename Z, typename Y> \
85 T(Z a, Y b) : a(a), b(b) {} \
86 A a; B b; \
87};
88
89#define RECORD3(T, A, a, B, b, C, c) \
90struct T { \
91 static const Type kType = T##_Type; \
92 template <typename Z, typename Y, typename X> \
93 T(Z a, Y b, X c) : a(a), b(b), c(c) {} \
94 A a; B b; C c; \
95};
96
97#define RECORD4(T, A, a, B, b, C, c, D, d) \
98struct T { \
99 static const Type kType = T##_Type; \
100 template <typename Z, typename Y, typename X, typename W> \
101 T(Z a, Y b, X c, W d) : a(a), b(b), c(c), d(d) {} \
102 A a; B b; C c; D d; \
103};
104
105#define RECORD5(T, A, a, B, b, C, c, D, d, E, e) \
106struct T { \
107 static const Type kType = T##_Type; \
108 template <typename Z, typename Y, typename X, typename W, typename V> \
109 T(Z a, Y b, X c, W d, V e) : a(a), b(b), c(c), d(d), e(e) {} \
110 A a; B b; C c; D d; E e; \
111};
112
commit-bot@chromium.org88c3e272014-04-22 16:57:20 +0000113#define ACT_AS_PTR(ptr) \
114 operator T*() { return ptr; } \
115 operator const T*() const { return ptr; } \
116 T* operator->() { return ptr; } \
117 const T* operator->() const { return ptr; }
118
commit-bot@chromium.org653d5182014-04-15 14:27:14 +0000119// An Optional doesn't own the pointer's memory, but may need to destroy non-POD data.
120template <typename T>
121class Optional : SkNoncopyable {
122public:
123 Optional(T* ptr) : fPtr(ptr) {}
124 ~Optional() { if (fPtr) fPtr->~T(); }
125
commit-bot@chromium.org88c3e272014-04-22 16:57:20 +0000126 ACT_AS_PTR(fPtr);
127private:
128 T* fPtr;
129};
130
131// Like Optional, but ptr must not be NULL.
132template <typename T>
133class Adopted : SkNoncopyable {
134public:
135 Adopted(T* ptr) : fPtr(ptr) { SkASSERT(fPtr); }
commit-bot@chromium.orgf0ae5e42014-04-24 15:33:48 +0000136 Adopted(Adopted* source) {
137 // Transfer ownership from source to this.
138 fPtr = source->fPtr;
139 source->fPtr = NULL;
140 }
141 ~Adopted() { if (fPtr) fPtr->~T(); }
commit-bot@chromium.org88c3e272014-04-22 16:57:20 +0000142
143 ACT_AS_PTR(fPtr);
commit-bot@chromium.org653d5182014-04-15 14:27:14 +0000144private:
145 T* fPtr;
146};
147
148// PODArray doesn't own the pointer's memory, and we assume the data is POD.
149template <typename T>
commit-bot@chromium.orgf0ae5e42014-04-24 15:33:48 +0000150class PODArray {
commit-bot@chromium.org653d5182014-04-15 14:27:14 +0000151public:
152 PODArray(T* ptr) : fPtr(ptr) {}
commit-bot@chromium.orgf0ae5e42014-04-24 15:33:48 +0000153 // Default copy and assign.
commit-bot@chromium.org653d5182014-04-15 14:27:14 +0000154
commit-bot@chromium.org88c3e272014-04-22 16:57:20 +0000155 ACT_AS_PTR(fPtr);
commit-bot@chromium.org653d5182014-04-15 14:27:14 +0000156private:
157 T* fPtr;
158};
159
commit-bot@chromium.org16307bd2014-04-22 18:32:58 +0000160#undef ACT_AS_PTR
161
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000162// Like SkBitmap, but deep copies pixels if they're not immutable.
163// Using this, we guarantee the immutability of all bitmaps we record.
164class ImmutableBitmap {
165public:
166 explicit ImmutableBitmap(const SkBitmap& bitmap) {
167 if (bitmap.isImmutable()) {
168 fBitmap = bitmap;
169 } else {
170 bitmap.copyTo(&fBitmap);
171 }
172 fBitmap.setImmutable();
173 }
174
175 operator const SkBitmap& () const { return fBitmap; }
176
177private:
178 SkBitmap fBitmap;
179};
180
commit-bot@chromium.org88c3e272014-04-22 16:57:20 +0000181RECORD0(NoOp);
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000182
183RECORD0(Restore);
184RECORD1(Save, SkCanvas::SaveFlags, flags);
commit-bot@chromium.org653d5182014-04-15 14:27:14 +0000185RECORD3(SaveLayer, Optional<SkRect>, bounds, Optional<SkPaint>, paint, SkCanvas::SaveFlags, flags);
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000186
commit-bot@chromium.org88c3e272014-04-22 16:57:20 +0000187RECORD1(PushCull, SkRect, rect);
commit-bot@chromium.org03a99b82014-04-08 15:17:17 +0000188RECORD0(PopCull);
189
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000190RECORD1(Concat, SkMatrix, matrix);
191RECORD1(SetMatrix, SkMatrix, matrix);
192
193RECORD3(ClipPath, SkPath, path, SkRegion::Op, op, bool, doAA);
194RECORD3(ClipRRect, SkRRect, rrect, SkRegion::Op, op, bool, doAA);
195RECORD3(ClipRect, SkRect, rect, SkRegion::Op, op, bool, doAA);
196RECORD2(ClipRegion, SkRegion, region, SkRegion::Op, op);
197
198RECORD1(Clear, SkColor, color);
commit-bot@chromium.org653d5182014-04-15 14:27:14 +0000199RECORD4(DrawBitmap, ImmutableBitmap, bitmap,
200 SkScalar, left,
201 SkScalar, top,
202 Optional<SkPaint>, paint);
203RECORD3(DrawBitmapMatrix, ImmutableBitmap, bitmap, SkMatrix, matrix, Optional<SkPaint>, paint);
204RECORD4(DrawBitmapNine, ImmutableBitmap, bitmap,
205 SkIRect, center,
206 SkRect, dst,
207 Optional<SkPaint>, paint);
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000208RECORD5(DrawBitmapRectToRect, ImmutableBitmap, bitmap,
commit-bot@chromium.org653d5182014-04-15 14:27:14 +0000209 Optional<SkRect>, src,
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000210 SkRect, dst,
commit-bot@chromium.org653d5182014-04-15 14:27:14 +0000211 Optional<SkPaint>, paint,
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000212 SkCanvas::DrawBitmapRectFlags, flags);
213RECORD3(DrawDRRect, SkRRect, outer, SkRRect, inner, SkPaint, paint);
214RECORD2(DrawOval, SkRect, oval, SkPaint, paint);
215RECORD1(DrawPaint, SkPaint, paint);
216RECORD2(DrawPath, SkPath, path, SkPaint, paint);
217RECORD4(DrawPoints, SkCanvas::PointMode, mode, size_t, count, SkPoint*, pts, SkPaint, paint);
commit-bot@chromium.org653d5182014-04-15 14:27:14 +0000218RECORD4(DrawPosText, PODArray<char>, text,
219 size_t, byteLength,
220 PODArray<SkPoint>, pos,
221 SkPaint, paint);
222RECORD5(DrawPosTextH, PODArray<char>, text,
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000223 size_t, byteLength,
commit-bot@chromium.org653d5182014-04-15 14:27:14 +0000224 PODArray<SkScalar>, xpos,
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000225 SkScalar, y,
226 SkPaint, paint);
227RECORD2(DrawRRect, SkRRect, rrect, SkPaint, paint);
228RECORD2(DrawRect, SkRect, rect, SkPaint, paint);
commit-bot@chromium.org653d5182014-04-15 14:27:14 +0000229RECORD4(DrawSprite, ImmutableBitmap, bitmap, int, left, int, top, Optional<SkPaint>, paint);
230RECORD5(DrawText, PODArray<char>, text,
231 size_t, byteLength,
232 SkScalar, x,
233 SkScalar, y,
234 SkPaint, paint);
235RECORD5(DrawTextOnPath, PODArray<char>, text,
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000236 size_t, byteLength,
237 SkPath, path,
commit-bot@chromium.org653d5182014-04-15 14:27:14 +0000238 Optional<SkMatrix>, matrix,
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000239 SkPaint, paint);
240
241// This guy is so ugly we just write it manually.
242struct DrawVertices {
243 static const Type kType = DrawVertices_Type;
244
245 DrawVertices(SkCanvas::VertexMode vmode,
246 int vertexCount,
247 SkPoint* vertices,
248 SkPoint* texs,
249 SkColor* colors,
250 SkXfermode* xmode,
251 uint16_t* indices,
252 int indexCount,
253 const SkPaint& paint)
254 : vmode(vmode)
255 , vertexCount(vertexCount)
256 , vertices(vertices)
257 , texs(texs)
258 , colors(colors)
259 , xmode(SkSafeRef(xmode))
260 , indices(indices)
261 , indexCount(indexCount)
262 , paint(paint) {}
263
264 SkCanvas::VertexMode vmode;
265 int vertexCount;
commit-bot@chromium.org653d5182014-04-15 14:27:14 +0000266 PODArray<SkPoint> vertices;
267 PODArray<SkPoint> texs;
268 PODArray<SkColor> colors;
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000269 SkAutoTUnref<SkXfermode> xmode;
commit-bot@chromium.org653d5182014-04-15 14:27:14 +0000270 PODArray<uint16_t> indices;
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000271 int indexCount;
272 SkPaint paint;
273};
274
commit-bot@chromium.org88c3e272014-04-22 16:57:20 +0000275// Records added by optimizations.
276RECORD2(PairedPushCull, Adopted<PushCull>, base, unsigned, skip);
277RECORD3(BoundedDrawPosTextH, Adopted<DrawPosTextH>, base, SkScalar, minY, SkScalar, maxY);
278
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000279#undef RECORD0
280#undef RECORD1
281#undef RECORD2
282#undef RECORD3
283#undef RECORD4
284#undef RECORD5
285
286} // namespace SkRecords
287
288#endif//SkRecords_DEFINED