blob: 10806565d9f15fa5dcb393df36dbe36dd1e28f05 [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.)
22#define SK_RECORD_TYPES(M) \
23 M(Restore) \
24 M(Save) \
25 M(SaveLayer) \
26 M(Concat) \
27 M(SetMatrix) \
28 M(ClipPath) \
29 M(ClipRRect) \
30 M(ClipRect) \
31 M(ClipRegion) \
32 M(Clear) \
33 M(DrawBitmap) \
34 M(DrawBitmapMatrix) \
35 M(DrawBitmapNine) \
36 M(DrawBitmapRectToRect) \
37 M(DrawDRRect) \
38 M(DrawOval) \
39 M(DrawPaint) \
40 M(DrawPath) \
41 M(DrawPoints) \
42 M(DrawPosText) \
43 M(DrawPosTextH) \
44 M(DrawRRect) \
45 M(DrawRect) \
46 M(DrawSprite) \
47 M(DrawText) \
48 M(DrawTextOnPath) \
commit-bot@chromium.org03a99b82014-04-08 15:17:17 +000049 M(DrawVertices) \
50 M(PushCull) \
51 M(PopCull)
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +000052
53// Defines SkRecords::Type, an enum of all record types.
54#define ENUM(T) T##_Type,
55enum Type { SK_RECORD_TYPES(ENUM) };
56#undef ENUM
57
58// Macros to make it easier to define a record for a draw call with 0 args, 1 args, 2 args, etc.
59// These should be clearer when you look at their use below.
60#define RECORD0(T) \
61struct T { \
62 static const Type kType = T##_Type; \
63 T() {} \
64};
65
66// We try to be flexible about the types the constructors take. Instead of requring the exact type
67// A here, we take any type Z which implicitly casts to A. This allows the delay_copy() trick to
68// work, allowing the caller to decide whether to pass by value or by const&.
69
70#define RECORD1(T, A, a) \
71struct T { \
72 static const Type kType = T##_Type; \
73 template <typename Z> \
74 T(Z a) : a(a) {} \
75 A a; \
76};
77
78#define RECORD2(T, A, a, B, b) \
79struct T { \
80 static const Type kType = T##_Type; \
81 template <typename Z, typename Y> \
82 T(Z a, Y b) : a(a), b(b) {} \
83 A a; B b; \
84};
85
86#define RECORD3(T, A, a, B, b, C, c) \
87struct T { \
88 static const Type kType = T##_Type; \
89 template <typename Z, typename Y, typename X> \
90 T(Z a, Y b, X c) : a(a), b(b), c(c) {} \
91 A a; B b; C c; \
92};
93
94#define RECORD4(T, A, a, B, b, C, c, D, d) \
95struct T { \
96 static const Type kType = T##_Type; \
97 template <typename Z, typename Y, typename X, typename W> \
98 T(Z a, Y b, X c, W d) : a(a), b(b), c(c), d(d) {} \
99 A a; B b; C c; D d; \
100};
101
102#define RECORD5(T, A, a, B, b, C, c, D, d, E, e) \
103struct T { \
104 static const Type kType = T##_Type; \
105 template <typename Z, typename Y, typename X, typename W, typename V> \
106 T(Z a, Y b, X c, W d, V e) : a(a), b(b), c(c), d(d), e(e) {} \
107 A a; B b; C c; D d; E e; \
108};
109
commit-bot@chromium.org653d5182014-04-15 14:27:14 +0000110// An Optional doesn't own the pointer's memory, but may need to destroy non-POD data.
111template <typename T>
112class Optional : SkNoncopyable {
113public:
114 Optional(T* ptr) : fPtr(ptr) {}
115 ~Optional() { if (fPtr) fPtr->~T(); }
116
117 operator T*() { return fPtr; }
118 operator const T*() const { return fPtr; }
119private:
120 T* fPtr;
121};
122
123// PODArray doesn't own the pointer's memory, and we assume the data is POD.
124template <typename T>
125class PODArray : SkNoncopyable {
126public:
127 PODArray(T* ptr) : fPtr(ptr) {}
128
129 operator T*() { return fPtr; }
130 operator const T*() const { return fPtr; }
131private:
132 T* fPtr;
133};
134
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000135// Like SkBitmap, but deep copies pixels if they're not immutable.
136// Using this, we guarantee the immutability of all bitmaps we record.
137class ImmutableBitmap {
138public:
139 explicit ImmutableBitmap(const SkBitmap& bitmap) {
140 if (bitmap.isImmutable()) {
141 fBitmap = bitmap;
142 } else {
143 bitmap.copyTo(&fBitmap);
144 }
145 fBitmap.setImmutable();
146 }
147
148 operator const SkBitmap& () const { return fBitmap; }
149
150private:
151 SkBitmap fBitmap;
152};
153
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000154// None of these records manages the lifetimes of pointers, except for DrawVertices handling its
155// Xfermode specially.
156
157RECORD0(Restore);
158RECORD1(Save, SkCanvas::SaveFlags, flags);
commit-bot@chromium.org653d5182014-04-15 14:27:14 +0000159RECORD3(SaveLayer, Optional<SkRect>, bounds, Optional<SkPaint>, paint, SkCanvas::SaveFlags, flags);
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000160
commit-bot@chromium.org506db0b2014-04-08 23:31:35 +0000161static const unsigned kUnsetPopOffset = 0;
162RECORD2(PushCull, SkRect, rect, unsigned, popOffset);
commit-bot@chromium.org03a99b82014-04-08 15:17:17 +0000163RECORD0(PopCull);
164
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000165RECORD1(Concat, SkMatrix, matrix);
166RECORD1(SetMatrix, SkMatrix, matrix);
167
168RECORD3(ClipPath, SkPath, path, SkRegion::Op, op, bool, doAA);
169RECORD3(ClipRRect, SkRRect, rrect, SkRegion::Op, op, bool, doAA);
170RECORD3(ClipRect, SkRect, rect, SkRegion::Op, op, bool, doAA);
171RECORD2(ClipRegion, SkRegion, region, SkRegion::Op, op);
172
173RECORD1(Clear, SkColor, color);
commit-bot@chromium.org653d5182014-04-15 14:27:14 +0000174RECORD4(DrawBitmap, ImmutableBitmap, bitmap,
175 SkScalar, left,
176 SkScalar, top,
177 Optional<SkPaint>, paint);
178RECORD3(DrawBitmapMatrix, ImmutableBitmap, bitmap, SkMatrix, matrix, Optional<SkPaint>, paint);
179RECORD4(DrawBitmapNine, ImmutableBitmap, bitmap,
180 SkIRect, center,
181 SkRect, dst,
182 Optional<SkPaint>, paint);
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000183RECORD5(DrawBitmapRectToRect, ImmutableBitmap, bitmap,
commit-bot@chromium.org653d5182014-04-15 14:27:14 +0000184 Optional<SkRect>, src,
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000185 SkRect, dst,
commit-bot@chromium.org653d5182014-04-15 14:27:14 +0000186 Optional<SkPaint>, paint,
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000187 SkCanvas::DrawBitmapRectFlags, flags);
188RECORD3(DrawDRRect, SkRRect, outer, SkRRect, inner, SkPaint, paint);
189RECORD2(DrawOval, SkRect, oval, SkPaint, paint);
190RECORD1(DrawPaint, SkPaint, paint);
191RECORD2(DrawPath, SkPath, path, SkPaint, paint);
192RECORD4(DrawPoints, SkCanvas::PointMode, mode, size_t, count, SkPoint*, pts, SkPaint, paint);
commit-bot@chromium.org653d5182014-04-15 14:27:14 +0000193RECORD4(DrawPosText, PODArray<char>, text,
194 size_t, byteLength,
195 PODArray<SkPoint>, pos,
196 SkPaint, paint);
197RECORD5(DrawPosTextH, PODArray<char>, text,
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000198 size_t, byteLength,
commit-bot@chromium.org653d5182014-04-15 14:27:14 +0000199 PODArray<SkScalar>, xpos,
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000200 SkScalar, y,
201 SkPaint, paint);
202RECORD2(DrawRRect, SkRRect, rrect, SkPaint, paint);
203RECORD2(DrawRect, SkRect, rect, SkPaint, paint);
commit-bot@chromium.org653d5182014-04-15 14:27:14 +0000204RECORD4(DrawSprite, ImmutableBitmap, bitmap, int, left, int, top, Optional<SkPaint>, paint);
205RECORD5(DrawText, PODArray<char>, text,
206 size_t, byteLength,
207 SkScalar, x,
208 SkScalar, y,
209 SkPaint, paint);
210RECORD5(DrawTextOnPath, PODArray<char>, text,
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000211 size_t, byteLength,
212 SkPath, path,
commit-bot@chromium.org653d5182014-04-15 14:27:14 +0000213 Optional<SkMatrix>, matrix,
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000214 SkPaint, paint);
215
216// This guy is so ugly we just write it manually.
217struct DrawVertices {
218 static const Type kType = DrawVertices_Type;
219
220 DrawVertices(SkCanvas::VertexMode vmode,
221 int vertexCount,
222 SkPoint* vertices,
223 SkPoint* texs,
224 SkColor* colors,
225 SkXfermode* xmode,
226 uint16_t* indices,
227 int indexCount,
228 const SkPaint& paint)
229 : vmode(vmode)
230 , vertexCount(vertexCount)
231 , vertices(vertices)
232 , texs(texs)
233 , colors(colors)
234 , xmode(SkSafeRef(xmode))
235 , indices(indices)
236 , indexCount(indexCount)
237 , paint(paint) {}
238
239 SkCanvas::VertexMode vmode;
240 int vertexCount;
commit-bot@chromium.org653d5182014-04-15 14:27:14 +0000241 PODArray<SkPoint> vertices;
242 PODArray<SkPoint> texs;
243 PODArray<SkColor> colors;
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000244 SkAutoTUnref<SkXfermode> xmode;
commit-bot@chromium.org653d5182014-04-15 14:27:14 +0000245 PODArray<uint16_t> indices;
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000246 int indexCount;
247 SkPaint paint;
248};
249
250#undef RECORD0
251#undef RECORD1
252#undef RECORD2
253#undef RECORD3
254#undef RECORD4
255#undef RECORD5
256
257} // namespace SkRecords
258
259#endif//SkRecords_DEFINED