blob: e6d98f7a1d2a424de800fe08da8002856c8c23fa [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.org37f6e622014-05-07 22:59:38 +000022//
23// Order doesn't technically matter here, but the compiler can generally generate better code if
24// you keep them semantically grouped, especially the Draws. It's also nice to leave NoOp at 0.
commit-bot@chromium.org88c3e272014-04-22 16:57:20 +000025#define SK_RECORD_TYPES(M) \
26 M(NoOp) \
27 M(Restore) \
28 M(Save) \
29 M(SaveLayer) \
commit-bot@chromium.org37f6e622014-05-07 22:59:38 +000030 M(PushCull) \
31 M(PopCull) \
32 M(PairedPushCull) /*From SkRecordAnnotateCullingPairs*/ \
commit-bot@chromium.org88c3e272014-04-22 16:57:20 +000033 M(Concat) \
34 M(SetMatrix) \
35 M(ClipPath) \
36 M(ClipRRect) \
37 M(ClipRect) \
38 M(ClipRegion) \
39 M(Clear) \
40 M(DrawBitmap) \
41 M(DrawBitmapMatrix) \
42 M(DrawBitmapNine) \
43 M(DrawBitmapRectToRect) \
44 M(DrawDRRect) \
45 M(DrawOval) \
46 M(DrawPaint) \
47 M(DrawPath) \
dandov963137b2014-08-07 07:49:53 -070048 M(DrawPatch) \
commit-bot@chromium.org88c3e272014-04-22 16:57:20 +000049 M(DrawPoints) \
50 M(DrawPosText) \
51 M(DrawPosTextH) \
52 M(DrawRRect) \
53 M(DrawRect) \
54 M(DrawSprite) \
55 M(DrawText) \
56 M(DrawTextOnPath) \
57 M(DrawVertices) \
commit-bot@chromium.org88c3e272014-04-22 16:57:20 +000058 M(BoundedDrawPosTextH) /*From SkRecordBoundDrawPosTextH*/
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +000059
60// Defines SkRecords::Type, an enum of all record types.
61#define ENUM(T) T##_Type,
62enum Type { SK_RECORD_TYPES(ENUM) };
63#undef ENUM
64
65// Macros to make it easier to define a record for a draw call with 0 args, 1 args, 2 args, etc.
66// These should be clearer when you look at their use below.
67#define RECORD0(T) \
68struct T { \
69 static const Type kType = T##_Type; \
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +000070};
71
72// We try to be flexible about the types the constructors take. Instead of requring the exact type
73// A here, we take any type Z which implicitly casts to A. This allows the delay_copy() trick to
74// work, allowing the caller to decide whether to pass by value or by const&.
75
76#define RECORD1(T, A, a) \
77struct T { \
78 static const Type kType = T##_Type; \
79 template <typename Z> \
80 T(Z a) : a(a) {} \
81 A a; \
82};
83
84#define RECORD2(T, A, a, B, b) \
85struct T { \
86 static const Type kType = T##_Type; \
87 template <typename Z, typename Y> \
88 T(Z a, Y b) : a(a), b(b) {} \
89 A a; B b; \
90};
91
92#define RECORD3(T, A, a, B, b, C, c) \
93struct T { \
94 static const Type kType = T##_Type; \
95 template <typename Z, typename Y, typename X> \
96 T(Z a, Y b, X c) : a(a), b(b), c(c) {} \
97 A a; B b; C c; \
98};
99
100#define RECORD4(T, A, a, B, b, C, c, D, d) \
101struct T { \
102 static const Type kType = T##_Type; \
103 template <typename Z, typename Y, typename X, typename W> \
104 T(Z a, Y b, X c, W d) : a(a), b(b), c(c), d(d) {} \
105 A a; B b; C c; D d; \
106};
107
108#define RECORD5(T, A, a, B, b, C, c, D, d, E, e) \
109struct T { \
110 static const Type kType = T##_Type; \
111 template <typename Z, typename Y, typename X, typename W, typename V> \
112 T(Z a, Y b, X c, W d, V e) : a(a), b(b), c(c), d(d), e(e) {} \
113 A a; B b; C c; D d; E e; \
114};
115
commit-bot@chromium.org88c3e272014-04-22 16:57:20 +0000116#define ACT_AS_PTR(ptr) \
117 operator T*() { return ptr; } \
118 operator const T*() const { return ptr; } \
119 T* operator->() { return ptr; } \
120 const T* operator->() const { return ptr; }
121
commit-bot@chromium.org653d5182014-04-15 14:27:14 +0000122// An Optional doesn't own the pointer's memory, but may need to destroy non-POD data.
123template <typename T>
124class Optional : SkNoncopyable {
125public:
126 Optional(T* ptr) : fPtr(ptr) {}
127 ~Optional() { if (fPtr) fPtr->~T(); }
128
commit-bot@chromium.org88c3e272014-04-22 16:57:20 +0000129 ACT_AS_PTR(fPtr);
130private:
131 T* fPtr;
132};
133
134// Like Optional, but ptr must not be NULL.
135template <typename T>
136class Adopted : SkNoncopyable {
137public:
138 Adopted(T* ptr) : fPtr(ptr) { SkASSERT(fPtr); }
commit-bot@chromium.orgf0ae5e42014-04-24 15:33:48 +0000139 Adopted(Adopted* source) {
140 // Transfer ownership from source to this.
141 fPtr = source->fPtr;
142 source->fPtr = NULL;
143 }
144 ~Adopted() { if (fPtr) fPtr->~T(); }
commit-bot@chromium.org88c3e272014-04-22 16:57:20 +0000145
146 ACT_AS_PTR(fPtr);
commit-bot@chromium.org653d5182014-04-15 14:27:14 +0000147private:
148 T* fPtr;
149};
150
151// PODArray doesn't own the pointer's memory, and we assume the data is POD.
152template <typename T>
commit-bot@chromium.orgf0ae5e42014-04-24 15:33:48 +0000153class PODArray {
commit-bot@chromium.org653d5182014-04-15 14:27:14 +0000154public:
155 PODArray(T* ptr) : fPtr(ptr) {}
commit-bot@chromium.orgf0ae5e42014-04-24 15:33:48 +0000156 // Default copy and assign.
commit-bot@chromium.org653d5182014-04-15 14:27:14 +0000157
commit-bot@chromium.org88c3e272014-04-22 16:57:20 +0000158 ACT_AS_PTR(fPtr);
commit-bot@chromium.org653d5182014-04-15 14:27:14 +0000159private:
160 T* fPtr;
161};
162
commit-bot@chromium.org16307bd2014-04-22 18:32:58 +0000163#undef ACT_AS_PTR
164
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000165// Like SkBitmap, but deep copies pixels if they're not immutable.
166// Using this, we guarantee the immutability of all bitmaps we record.
167class ImmutableBitmap {
168public:
169 explicit ImmutableBitmap(const SkBitmap& bitmap) {
170 if (bitmap.isImmutable()) {
171 fBitmap = bitmap;
172 } else {
173 bitmap.copyTo(&fBitmap);
174 }
175 fBitmap.setImmutable();
176 }
177
178 operator const SkBitmap& () const { return fBitmap; }
179
180private:
181 SkBitmap fBitmap;
182};
183
commit-bot@chromium.org88c3e272014-04-22 16:57:20 +0000184RECORD0(NoOp);
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000185
186RECORD0(Restore);
Florin Malita5f6102d2014-06-30 10:13:28 -0400187RECORD0(Save);
commit-bot@chromium.org653d5182014-04-15 14:27:14 +0000188RECORD3(SaveLayer, Optional<SkRect>, bounds, Optional<SkPaint>, paint, SkCanvas::SaveFlags, flags);
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000189
commit-bot@chromium.org88c3e272014-04-22 16:57:20 +0000190RECORD1(PushCull, SkRect, rect);
commit-bot@chromium.org03a99b82014-04-08 15:17:17 +0000191RECORD0(PopCull);
192
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000193RECORD1(Concat, SkMatrix, matrix);
194RECORD1(SetMatrix, SkMatrix, matrix);
195
196RECORD3(ClipPath, SkPath, path, SkRegion::Op, op, bool, doAA);
197RECORD3(ClipRRect, SkRRect, rrect, SkRegion::Op, op, bool, doAA);
198RECORD3(ClipRect, SkRect, rect, SkRegion::Op, op, bool, doAA);
199RECORD2(ClipRegion, SkRegion, region, SkRegion::Op, op);
200
201RECORD1(Clear, SkColor, color);
commit-bot@chromium.org37f6e622014-05-07 22:59:38 +0000202// While not strictly required, if you have an SkPaint, it's fastest to put it first.
203RECORD4(DrawBitmap, Optional<SkPaint>, paint,
204 ImmutableBitmap, bitmap,
commit-bot@chromium.org653d5182014-04-15 14:27:14 +0000205 SkScalar, left,
commit-bot@chromium.org37f6e622014-05-07 22:59:38 +0000206 SkScalar, top);
207RECORD3(DrawBitmapMatrix, Optional<SkPaint>, paint, ImmutableBitmap, bitmap, SkMatrix, matrix);
208RECORD4(DrawBitmapNine, Optional<SkPaint>, paint,
209 ImmutableBitmap, bitmap,
commit-bot@chromium.org653d5182014-04-15 14:27:14 +0000210 SkIRect, center,
commit-bot@chromium.org37f6e622014-05-07 22:59:38 +0000211 SkRect, dst);
212RECORD5(DrawBitmapRectToRect, Optional<SkPaint>, paint,
213 ImmutableBitmap, bitmap,
commit-bot@chromium.org653d5182014-04-15 14:27:14 +0000214 Optional<SkRect>, src,
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000215 SkRect, dst,
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000216 SkCanvas::DrawBitmapRectFlags, flags);
commit-bot@chromium.org37f6e622014-05-07 22:59:38 +0000217RECORD3(DrawDRRect, SkPaint, paint, SkRRect, outer, SkRRect, inner);
218RECORD2(DrawOval, SkPaint, paint, SkRect, oval);
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000219RECORD1(DrawPaint, SkPaint, paint);
commit-bot@chromium.org37f6e622014-05-07 22:59:38 +0000220RECORD2(DrawPath, SkPaint, paint, SkPath, path);
dandov963137b2014-08-07 07:49:53 -0700221RECORD2(DrawPatch, SkPaint, paint, SkPatch, patch);
commit-bot@chromium.org37f6e622014-05-07 22:59:38 +0000222RECORD4(DrawPoints, SkPaint, paint, SkCanvas::PointMode, mode, size_t, count, SkPoint*, pts);
223RECORD4(DrawPosText, SkPaint, paint,
224 PODArray<char>, text,
commit-bot@chromium.org653d5182014-04-15 14:27:14 +0000225 size_t, byteLength,
commit-bot@chromium.org37f6e622014-05-07 22:59:38 +0000226 PODArray<SkPoint>, pos);
227RECORD5(DrawPosTextH, SkPaint, paint,
228 PODArray<char>, text,
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000229 size_t, byteLength,
commit-bot@chromium.org653d5182014-04-15 14:27:14 +0000230 PODArray<SkScalar>, xpos,
commit-bot@chromium.org37f6e622014-05-07 22:59:38 +0000231 SkScalar, y);
232RECORD2(DrawRRect, SkPaint, paint, SkRRect, rrect);
233RECORD2(DrawRect, SkPaint, paint, SkRect, rect);
234RECORD4(DrawSprite, Optional<SkPaint>, paint, ImmutableBitmap, bitmap, int, left, int, top);
235RECORD5(DrawText, SkPaint, paint,
236 PODArray<char>, text,
commit-bot@chromium.org653d5182014-04-15 14:27:14 +0000237 size_t, byteLength,
238 SkScalar, x,
commit-bot@chromium.org37f6e622014-05-07 22:59:38 +0000239 SkScalar, y);
240RECORD5(DrawTextOnPath, SkPaint, paint,
241 PODArray<char>, text,
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000242 size_t, byteLength,
243 SkPath, path,
commit-bot@chromium.org37f6e622014-05-07 22:59:38 +0000244 Optional<SkMatrix>, matrix);
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000245
246// This guy is so ugly we just write it manually.
247struct DrawVertices {
248 static const Type kType = DrawVertices_Type;
249
commit-bot@chromium.org37f6e622014-05-07 22:59:38 +0000250 DrawVertices(const SkPaint& paint,
251 SkCanvas::VertexMode vmode,
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000252 int vertexCount,
253 SkPoint* vertices,
254 SkPoint* texs,
255 SkColor* colors,
256 SkXfermode* xmode,
257 uint16_t* indices,
commit-bot@chromium.org37f6e622014-05-07 22:59:38 +0000258 int indexCount)
259 : paint(paint)
260 , vmode(vmode)
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000261 , vertexCount(vertexCount)
262 , vertices(vertices)
263 , texs(texs)
264 , colors(colors)
265 , xmode(SkSafeRef(xmode))
266 , indices(indices)
commit-bot@chromium.org37f6e622014-05-07 22:59:38 +0000267 , indexCount(indexCount) {}
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000268
commit-bot@chromium.org37f6e622014-05-07 22:59:38 +0000269 SkPaint paint;
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000270 SkCanvas::VertexMode vmode;
271 int vertexCount;
commit-bot@chromium.org653d5182014-04-15 14:27:14 +0000272 PODArray<SkPoint> vertices;
273 PODArray<SkPoint> texs;
274 PODArray<SkColor> colors;
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000275 SkAutoTUnref<SkXfermode> xmode;
commit-bot@chromium.org653d5182014-04-15 14:27:14 +0000276 PODArray<uint16_t> indices;
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000277 int indexCount;
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000278};
279
commit-bot@chromium.org88c3e272014-04-22 16:57:20 +0000280// Records added by optimizations.
281RECORD2(PairedPushCull, Adopted<PushCull>, base, unsigned, skip);
282RECORD3(BoundedDrawPosTextH, Adopted<DrawPosTextH>, base, SkScalar, minY, SkScalar, maxY);
283
commit-bot@chromium.orge3ff5582014-04-01 16:24:06 +0000284#undef RECORD0
285#undef RECORD1
286#undef RECORD2
287#undef RECORD3
288#undef RECORD4
289#undef RECORD5
290
291} // namespace SkRecords
292
293#endif//SkRecords_DEFINED