OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkBigPicture.h" | 8 #include "SkBigPicture.h" |
9 #include "SkPatchUtils.h" | 9 #include "SkPatchUtils.h" |
10 #include "SkPicture.h" | 10 #include "SkPicture.h" |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
62 #define APPEND(T, ...) \ | 62 #define APPEND(T, ...) \ |
63 if (fMiniRecorder) { this->flushMiniRecorder(); } \ | 63 if (fMiniRecorder) { this->flushMiniRecorder(); } \ |
64 SkNEW_PLACEMENT_ARGS(fRecord->append<SkRecords::T>(), SkRecords::T, (__V
A_ARGS__)) | 64 SkNEW_PLACEMENT_ARGS(fRecord->append<SkRecords::T>(), SkRecords::T, (__V
A_ARGS__)) |
65 | 65 |
66 #define TRY_MINIRECORDER(method, ...) \ | 66 #define TRY_MINIRECORDER(method, ...) \ |
67 if (fMiniRecorder && fMiniRecorder->method(__VA_ARGS__)) { return; } | 67 if (fMiniRecorder && fMiniRecorder->method(__VA_ARGS__)) { return; } |
68 | 68 |
69 // For methods which must call back into SkCanvas. | 69 // For methods which must call back into SkCanvas. |
70 #define INHERITED(method, ...) this->SkCanvas::method(__VA_ARGS__) | 70 #define INHERITED(method, ...) this->SkCanvas::method(__VA_ARGS__) |
71 | 71 |
72 // The structs we're creating all copy their constructor arguments. Given the w
ay the SkRecords | |
73 // framework works, sometimes they happen to technically be copied twice, which
is fine and elided | |
74 // into a single copy unless the class has a non-trivial copy constructor. For
classes with | |
75 // non-trivial copy constructors, we skip the first copy (and its destruction) b
y wrapping the value | |
76 // with delay_copy(), forcing the argument to be passed by const&. | |
77 // | |
78 // This is used below for SkBitmap, SkPaint, SkPath, and SkRegion, which all hav
e non-trivial copy | |
79 // constructors and destructors. You'll know you've got a good candidate T if y
ou see ~T() show up | |
80 // unexpectedly on a profile of record time. Otherwise don't bother. | |
81 template <typename T> | |
82 class Reference { | |
83 public: | |
84 Reference(const T& x) : fX(x) {} | |
85 operator const T&() const { return fX; } | |
86 private: | |
87 const T& fX; | |
88 }; | |
89 | |
90 template <typename T> | |
91 static Reference<T> delay_copy(const T& x) { return Reference<T>(x); } | |
92 | |
93 // Use copy() only for optional arguments, to be copied if present or skipped if
not. | 72 // Use copy() only for optional arguments, to be copied if present or skipped if
not. |
94 // (For most types we just pass by value and let copy constructors do their thin
g.) | 73 // (For most types we just pass by value and let copy constructors do their thin
g.) |
95 template <typename T> | 74 template <typename T> |
96 T* SkRecorder::copy(const T* src) { | 75 T* SkRecorder::copy(const T* src) { |
97 if (NULL == src) { | 76 if (NULL == src) { |
98 return NULL; | 77 return NULL; |
99 } | 78 } |
100 return SkNEW_PLACEMENT_ARGS(fRecord->alloc<T>(), T, (*src)); | 79 return SkNEW_PLACEMENT_ARGS(fRecord->alloc<T>(), T, (*src)); |
101 } | 80 } |
102 | 81 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 | 114 |
136 void SkRecorder::flushMiniRecorder() { | 115 void SkRecorder::flushMiniRecorder() { |
137 if (fMiniRecorder) { | 116 if (fMiniRecorder) { |
138 SkMiniRecorder* mr = fMiniRecorder; | 117 SkMiniRecorder* mr = fMiniRecorder; |
139 fMiniRecorder = nullptr; // Needs to happen before flushAndReset() or w
e recurse forever. | 118 fMiniRecorder = nullptr; // Needs to happen before flushAndReset() or w
e recurse forever. |
140 mr->flushAndReset(this); | 119 mr->flushAndReset(this); |
141 } | 120 } |
142 } | 121 } |
143 | 122 |
144 void SkRecorder::onDrawPaint(const SkPaint& paint) { | 123 void SkRecorder::onDrawPaint(const SkPaint& paint) { |
145 APPEND(DrawPaint, delay_copy(paint)); | 124 APPEND(DrawPaint, paint); |
146 } | 125 } |
147 | 126 |
148 void SkRecorder::onDrawPoints(PointMode mode, | 127 void SkRecorder::onDrawPoints(PointMode mode, |
149 size_t count, | 128 size_t count, |
150 const SkPoint pts[], | 129 const SkPoint pts[], |
151 const SkPaint& paint) { | 130 const SkPaint& paint) { |
152 APPEND(DrawPoints, delay_copy(paint), mode, SkToUInt(count), this->copy(pts,
count)); | 131 APPEND(DrawPoints, paint, mode, SkToUInt(count), this->copy(pts, count)); |
153 } | 132 } |
154 | 133 |
155 void SkRecorder::onDrawRect(const SkRect& rect, const SkPaint& paint) { | 134 void SkRecorder::onDrawRect(const SkRect& rect, const SkPaint& paint) { |
156 TRY_MINIRECORDER(drawRect, rect, paint); | 135 TRY_MINIRECORDER(drawRect, rect, paint); |
157 APPEND(DrawRect, delay_copy(paint), rect); | 136 APPEND(DrawRect, paint, rect); |
158 } | 137 } |
159 | 138 |
160 void SkRecorder::onDrawOval(const SkRect& oval, const SkPaint& paint) { | 139 void SkRecorder::onDrawOval(const SkRect& oval, const SkPaint& paint) { |
161 APPEND(DrawOval, delay_copy(paint), oval); | 140 APPEND(DrawOval, paint, oval); |
162 } | 141 } |
163 | 142 |
164 void SkRecorder::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) { | 143 void SkRecorder::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) { |
165 APPEND(DrawRRect, delay_copy(paint), rrect); | 144 APPEND(DrawRRect, paint, rrect); |
166 } | 145 } |
167 | 146 |
168 void SkRecorder::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, const
SkPaint& paint) { | 147 void SkRecorder::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, const
SkPaint& paint) { |
169 APPEND(DrawDRRect, delay_copy(paint), outer, inner); | 148 APPEND(DrawDRRect, paint, outer, inner); |
170 } | 149 } |
171 | 150 |
172 void SkRecorder::onDrawDrawable(SkDrawable* drawable) { | 151 void SkRecorder::onDrawDrawable(SkDrawable* drawable) { |
173 if (!fDrawableList) { | 152 if (!fDrawableList) { |
174 fDrawableList.reset(SkNEW(SkDrawableList)); | 153 fDrawableList.reset(SkNEW(SkDrawableList)); |
175 } | 154 } |
176 fDrawableList->append(drawable); | 155 fDrawableList->append(drawable); |
177 APPEND(DrawDrawable, drawable->getBounds(), fDrawableList->count() - 1); | 156 APPEND(DrawDrawable, drawable->getBounds(), fDrawableList->count() - 1); |
178 } | 157 } |
179 | 158 |
180 void SkRecorder::onDrawPath(const SkPath& path, const SkPaint& paint) { | 159 void SkRecorder::onDrawPath(const SkPath& path, const SkPaint& paint) { |
181 TRY_MINIRECORDER(drawPath, path, paint); | 160 TRY_MINIRECORDER(drawPath, path, paint); |
182 APPEND(DrawPath, delay_copy(paint), delay_copy(path)); | 161 APPEND(DrawPath, paint, path); |
183 } | 162 } |
184 | 163 |
185 void SkRecorder::onDrawBitmap(const SkBitmap& bitmap, | 164 void SkRecorder::onDrawBitmap(const SkBitmap& bitmap, |
186 SkScalar left, | 165 SkScalar left, |
187 SkScalar top, | 166 SkScalar top, |
188 const SkPaint* paint) { | 167 const SkPaint* paint) { |
189 APPEND(DrawBitmap, this->copy(paint), delay_copy(bitmap), left, top); | 168 APPEND(DrawBitmap, this->copy(paint), bitmap, left, top); |
190 } | 169 } |
191 | 170 |
192 void SkRecorder::onDrawBitmapRect(const SkBitmap& bitmap, | 171 void SkRecorder::onDrawBitmapRect(const SkBitmap& bitmap, |
193 const SkRect* src, | 172 const SkRect* src, |
194 const SkRect& dst, | 173 const SkRect& dst, |
195 const SkPaint* paint, | 174 const SkPaint* paint, |
196 DrawBitmapRectFlags flags) { | 175 DrawBitmapRectFlags flags) { |
197 if (kBleed_DrawBitmapRectFlag == flags) { | 176 if (kBleed_DrawBitmapRectFlag == flags) { |
198 APPEND(DrawBitmapRectToRectBleed, | 177 APPEND(DrawBitmapRectToRectBleed, |
199 this->copy(paint), delay_copy(bitmap), this->copy(src), dst); | 178 this->copy(paint), bitmap, this->copy(src), dst); |
200 return; | 179 return; |
201 } | 180 } |
202 SkASSERT(kNone_DrawBitmapRectFlag == flags); | 181 SkASSERT(kNone_DrawBitmapRectFlag == flags); |
203 APPEND(DrawBitmapRectToRect, | 182 APPEND(DrawBitmapRectToRect, |
204 this->copy(paint), delay_copy(bitmap), this->copy(src), dst); | 183 this->copy(paint), bitmap, this->copy(src), dst); |
205 } | 184 } |
206 | 185 |
207 void SkRecorder::onDrawBitmapNine(const SkBitmap& bitmap, | 186 void SkRecorder::onDrawBitmapNine(const SkBitmap& bitmap, |
208 const SkIRect& center, | 187 const SkIRect& center, |
209 const SkRect& dst, | 188 const SkRect& dst, |
210 const SkPaint* paint) { | 189 const SkPaint* paint) { |
211 APPEND(DrawBitmapNine, this->copy(paint), delay_copy(bitmap), center, dst); | 190 APPEND(DrawBitmapNine, this->copy(paint), bitmap, center, dst); |
212 } | 191 } |
213 | 192 |
214 void SkRecorder::onDrawImage(const SkImage* image, SkScalar left, SkScalar top, | 193 void SkRecorder::onDrawImage(const SkImage* image, SkScalar left, SkScalar top, |
215 const SkPaint* paint) { | 194 const SkPaint* paint) { |
216 APPEND(DrawImage, this->copy(paint), image, left, top); | 195 APPEND(DrawImage, this->copy(paint), image, left, top); |
217 } | 196 } |
218 | 197 |
219 void SkRecorder::onDrawImageRect(const SkImage* image, const SkRect* src, | 198 void SkRecorder::onDrawImageRect(const SkImage* image, const SkRect* src, |
220 const SkRect& dst, | 199 const SkRect& dst, |
221 const SkPaint* paint) { | 200 const SkPaint* paint) { |
222 APPEND(DrawImageRect, this->copy(paint), image, this->copy(src), dst); | 201 APPEND(DrawImageRect, this->copy(paint), image, this->copy(src), dst); |
223 } | 202 } |
224 | 203 |
225 void SkRecorder::onDrawImageNine(const SkImage* image, const SkIRect& center, | 204 void SkRecorder::onDrawImageNine(const SkImage* image, const SkIRect& center, |
226 const SkRect& dst, const SkPaint* paint) { | 205 const SkRect& dst, const SkPaint* paint) { |
227 APPEND(DrawImageNine, this->copy(paint), image, center, dst); | 206 APPEND(DrawImageNine, this->copy(paint), image, center, dst); |
228 } | 207 } |
229 | 208 |
230 void SkRecorder::onDrawSprite(const SkBitmap& bitmap, int left, int top, const S
kPaint* paint) { | 209 void SkRecorder::onDrawSprite(const SkBitmap& bitmap, int left, int top, const S
kPaint* paint) { |
231 APPEND(DrawSprite, this->copy(paint), delay_copy(bitmap), left, top); | 210 APPEND(DrawSprite, this->copy(paint), bitmap, left, top); |
232 } | 211 } |
233 | 212 |
234 void SkRecorder::onDrawText(const void* text, size_t byteLength, | 213 void SkRecorder::onDrawText(const void* text, size_t byteLength, |
235 SkScalar x, SkScalar y, const SkPaint& paint) { | 214 SkScalar x, SkScalar y, const SkPaint& paint) { |
236 APPEND(DrawText, | 215 APPEND(DrawText, |
237 delay_copy(paint), this->copy((const char*)text, byteLength), byteLen
gth, x, y); | 216 paint, this->copy((const char*)text, byteLength), byteLength, x, y); |
238 } | 217 } |
239 | 218 |
240 void SkRecorder::onDrawPosText(const void* text, size_t byteLength, | 219 void SkRecorder::onDrawPosText(const void* text, size_t byteLength, |
241 const SkPoint pos[], const SkPaint& paint) { | 220 const SkPoint pos[], const SkPaint& paint) { |
242 const unsigned points = paint.countText(text, byteLength); | 221 const unsigned points = paint.countText(text, byteLength); |
243 APPEND(DrawPosText, | 222 APPEND(DrawPosText, |
244 delay_copy(paint), | 223 paint, |
245 this->copy((const char*)text, byteLength), | 224 this->copy((const char*)text, byteLength), |
246 byteLength, | 225 byteLength, |
247 this->copy(pos, points)); | 226 this->copy(pos, points)); |
248 } | 227 } |
249 | 228 |
250 void SkRecorder::onDrawPosTextH(const void* text, size_t byteLength, | 229 void SkRecorder::onDrawPosTextH(const void* text, size_t byteLength, |
251 const SkScalar xpos[], SkScalar constY, const Sk
Paint& paint) { | 230 const SkScalar xpos[], SkScalar constY, const Sk
Paint& paint) { |
252 const unsigned points = paint.countText(text, byteLength); | 231 const unsigned points = paint.countText(text, byteLength); |
253 APPEND(DrawPosTextH, | 232 APPEND(DrawPosTextH, |
254 delay_copy(paint), | 233 paint, |
255 this->copy((const char*)text, byteLength), | 234 this->copy((const char*)text, byteLength), |
256 SkToUInt(byteLength), | 235 SkToUInt(byteLength), |
257 constY, | 236 constY, |
258 this->copy(xpos, points)); | 237 this->copy(xpos, points)); |
259 } | 238 } |
260 | 239 |
261 void SkRecorder::onDrawTextOnPath(const void* text, size_t byteLength, const SkP
ath& path, | 240 void SkRecorder::onDrawTextOnPath(const void* text, size_t byteLength, const SkP
ath& path, |
262 const SkMatrix* matrix, const SkPaint& paint)
{ | 241 const SkMatrix* matrix, const SkPaint& paint)
{ |
263 APPEND(DrawTextOnPath, | 242 APPEND(DrawTextOnPath, |
264 delay_copy(paint), | 243 paint, |
265 this->copy((const char*)text, byteLength), | 244 this->copy((const char*)text, byteLength), |
266 byteLength, | 245 byteLength, |
267 delay_copy(path), | 246 path, |
268 matrix ? *matrix : SkMatrix::I()); | 247 matrix ? *matrix : SkMatrix::I()); |
269 } | 248 } |
270 | 249 |
271 void SkRecorder::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, | 250 void SkRecorder::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, |
272 const SkPaint& paint) { | 251 const SkPaint& paint) { |
273 TRY_MINIRECORDER(drawTextBlob, blob, x, y, paint); | 252 TRY_MINIRECORDER(drawTextBlob, blob, x, y, paint); |
274 APPEND(DrawTextBlob, delay_copy(paint), blob, x, y); | 253 APPEND(DrawTextBlob, paint, blob, x, y); |
275 } | 254 } |
276 | 255 |
277 void SkRecorder::onDrawPicture(const SkPicture* pic, const SkMatrix* matrix, con
st SkPaint* paint) { | 256 void SkRecorder::onDrawPicture(const SkPicture* pic, const SkMatrix* matrix, con
st SkPaint* paint) { |
278 fApproxBytesUsedBySubPictures += SkPictureUtils::ApproximateBytesUsed(pic); | 257 fApproxBytesUsedBySubPictures += SkPictureUtils::ApproximateBytesUsed(pic); |
279 APPEND(DrawPicture, this->copy(paint), pic, matrix ? *matrix : SkMatrix::I()
); | 258 APPEND(DrawPicture, this->copy(paint), pic, matrix ? *matrix : SkMatrix::I()
); |
280 } | 259 } |
281 | 260 |
282 void SkRecorder::onDrawVertices(VertexMode vmode, | 261 void SkRecorder::onDrawVertices(VertexMode vmode, |
283 int vertexCount, const SkPoint vertices[], | 262 int vertexCount, const SkPoint vertices[], |
284 const SkPoint texs[], const SkColor colors[], | 263 const SkPoint texs[], const SkColor colors[], |
285 SkXfermode* xmode, | 264 SkXfermode* xmode, |
286 const uint16_t indices[], int indexCount, const
SkPaint& paint) { | 265 const uint16_t indices[], int indexCount, const
SkPaint& paint) { |
287 APPEND(DrawVertices, delay_copy(paint), | 266 APPEND(DrawVertices, paint, |
288 vmode, | 267 vmode, |
289 vertexCount, | 268 vertexCount, |
290 this->copy(vertices, vertexCount), | 269 this->copy(vertices, vertexCount), |
291 texs ? this->copy(texs, vertexCount) : NULL, | 270 texs ? this->copy(texs, vertexCount) : NULL, |
292 colors ? this->copy(colors, vertexCount) : NULL, | 271 colors ? this->copy(colors, vertexCount) : NULL, |
293 xmode, | 272 xmode, |
294 this->copy(indices, indexCount), | 273 this->copy(indices, indexCount), |
295 indexCount); | 274 indexCount); |
296 } | 275 } |
297 | 276 |
298 void SkRecorder::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], | 277 void SkRecorder::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], |
299 const SkPoint texCoords[4], SkXfermode* xmode, cons
t SkPaint& paint) { | 278 const SkPoint texCoords[4], SkXfermode* xmode, cons
t SkPaint& paint) { |
300 APPEND(DrawPatch, delay_copy(paint), | 279 APPEND(DrawPatch, paint, |
301 cubics ? this->copy(cubics, SkPatchUtils::kNumCtrlPts) : NULL, | 280 cubics ? this->copy(cubics, SkPatchUtils::kNumCtrlPts) : NULL, |
302 colors ? this->copy(colors, SkPatchUtils::kNumCorners) : NULL, | 281 colors ? this->copy(colors, SkPatchUtils::kNumCorners) : NULL, |
303 texCoords ? this->copy(texCoords, SkPatchUtils::kNumCorners) : NULL, | 282 texCoords ? this->copy(texCoords, SkPatchUtils::kNumCorners) : NULL, |
304 xmode); | 283 xmode); |
305 } | 284 } |
306 | 285 |
307 void SkRecorder::onDrawAtlas(const SkImage* atlas, const SkRSXform xform[], cons
t SkRect tex[], | 286 void SkRecorder::onDrawAtlas(const SkImage* atlas, const SkRSXform xform[], cons
t SkRect tex[], |
308 const SkColor colors[], int count, SkXfermode::Mode
mode, | 287 const SkColor colors[], int count, SkXfermode::Mode
mode, |
309 const SkRect* cull, const SkPaint* paint) { | 288 const SkRect* cull, const SkPaint* paint) { |
310 APPEND(DrawAtlas, this->copy(paint), | 289 APPEND(DrawAtlas, this->copy(paint), |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
353 | 332 |
354 void SkRecorder::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyl
e edgeStyle) { | 333 void SkRecorder::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyl
e edgeStyle) { |
355 INHERITED(onClipRRect, rrect, op, edgeStyle); | 334 INHERITED(onClipRRect, rrect, op, edgeStyle); |
356 SkRecords::RegionOpAndAA opAA(op, kSoft_ClipEdgeStyle == edgeStyle); | 335 SkRecords::RegionOpAndAA opAA(op, kSoft_ClipEdgeStyle == edgeStyle); |
357 APPEND(ClipRRect, this->devBounds(), rrect, opAA); | 336 APPEND(ClipRRect, this->devBounds(), rrect, opAA); |
358 } | 337 } |
359 | 338 |
360 void SkRecorder::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle e
dgeStyle) { | 339 void SkRecorder::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle e
dgeStyle) { |
361 INHERITED(onClipPath, path, op, edgeStyle); | 340 INHERITED(onClipPath, path, op, edgeStyle); |
362 SkRecords::RegionOpAndAA opAA(op, kSoft_ClipEdgeStyle == edgeStyle); | 341 SkRecords::RegionOpAndAA opAA(op, kSoft_ClipEdgeStyle == edgeStyle); |
363 APPEND(ClipPath, this->devBounds(), delay_copy(path), opAA); | 342 APPEND(ClipPath, this->devBounds(), path, opAA); |
364 } | 343 } |
365 | 344 |
366 void SkRecorder::onClipRegion(const SkRegion& deviceRgn, SkRegion::Op op) { | 345 void SkRecorder::onClipRegion(const SkRegion& deviceRgn, SkRegion::Op op) { |
367 INHERITED(onClipRegion, deviceRgn, op); | 346 INHERITED(onClipRegion, deviceRgn, op); |
368 APPEND(ClipRegion, this->devBounds(), delay_copy(deviceRgn), op); | 347 APPEND(ClipRegion, this->devBounds(), deviceRgn, op); |
369 } | 348 } |
370 | 349 |
OLD | NEW |