[go: nahoru, domu]

blob: 5914ba46cd08efb64104197267eb7fc538617077 [file] [log] [blame]
epoger@google.com685cfc02011-07-28 14:26:00 +00001
reed@android.combcd4d5a2008-12-17 15:59:43 +00002/*
epoger@google.com685cfc02011-07-28 14:26:00 +00003 * Copyright 2007 The Android Open Source Project
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
scroggo@google.com8b854502013-05-07 14:45:40 +00009
reed@android.combcd4d5a2008-12-17 15:59:43 +000010#include "SkPictureFlat.h"
11#include "SkPicturePlayback.h"
12#include "SkPictureRecord.h"
13
robertphillips@google.com2fd23902013-08-29 11:54:56 +000014#include "SkBitmapDevice.h"
reed@android.combcd4d5a2008-12-17 15:59:43 +000015#include "SkCanvas.h"
16#include "SkChunkAlloc.h"
17#include "SkPicture.h"
18#include "SkRegion.h"
19#include "SkStream.h"
20#include "SkTDArray.h"
21#include "SkTSearch.h"
22#include "SkTime.h"
23
24#include "SkReader32.h"
25#include "SkWriter32.h"
rileya@google.com7fb3d2f2012-09-13 21:41:51 +000026#include "SkRTree.h"
27#include "SkBBoxHierarchyRecord.h"
reed@android.combcd4d5a2008-12-17 15:59:43 +000028
commit-bot@chromium.org95cdc162014-03-19 21:24:25 +000029#if SK_SUPPORT_GPU
30#include "GrContext.h"
31#endif
32
reed@android.combcd4d5a2008-12-17 15:59:43 +000033#define DUMP_BUFFER_SIZE 65536
34
35//#define ENABLE_TIME_DRAW // dumps milliseconds for each draw
36
37
38#ifdef SK_DEBUG
reed@google.com91911482011-02-07 15:30:46 +000039// enable SK_DEBUG_TRACE to trace DrawType elements when
reed@android.combcd4d5a2008-12-17 15:59:43 +000040// recorded and played back
41// #define SK_DEBUG_TRACE
42// enable SK_DEBUG_SIZE to see the size of picture components
43// #define SK_DEBUG_SIZE
44// enable SK_DEBUG_DUMP to see the contents of recorded elements
45// #define SK_DEBUG_DUMP
46// enable SK_DEBUG_VALIDATE to check internal structures for consistency
47// #define SK_DEBUG_VALIDATE
48#endif
49
50#if defined SK_DEBUG_TRACE || defined SK_DEBUG_DUMP
51const char* DrawTypeToString(DrawType drawType) {
52 switch (drawType) {
53 case UNUSED: SkDebugf("DrawType UNUSED\n"); SkASSERT(0); break;
54 case CLIP_PATH: return "CLIP_PATH";
55 case CLIP_REGION: return "CLIP_REGION";
56 case CLIP_RECT: return "CLIP_RECT";
robertphillips@google.come7189be2013-02-15 17:19:15 +000057 case CLIP_RRECT: return "CLIP_RRECT";
reed@android.combcd4d5a2008-12-17 15:59:43 +000058 case CONCAT: return "CONCAT";
59 case DRAW_BITMAP: return "DRAW_BITMAP";
60 case DRAW_BITMAP_MATRIX: return "DRAW_BITMAP_MATRIX";
robertphillips@google.come7189be2013-02-15 17:19:15 +000061 case DRAW_BITMAP_NINE: return "DRAW_BITMAP_NINE";
62 case DRAW_BITMAP_RECT_TO_RECT: return "DRAW_BITMAP_RECT_TO_RECT";
63 case DRAW_CLEAR: return "DRAW_CLEAR";
64 case DRAW_DATA: return "DRAW_DATA";
65 case DRAW_OVAL: return "DRAW_OVAL";
reed@android.combcd4d5a2008-12-17 15:59:43 +000066 case DRAW_PAINT: return "DRAW_PAINT";
67 case DRAW_PATH: return "DRAW_PATH";
68 case DRAW_PICTURE: return "DRAW_PICTURE";
69 case DRAW_POINTS: return "DRAW_POINTS";
70 case DRAW_POS_TEXT: return "DRAW_POS_TEXT";
robertphillips@google.come7189be2013-02-15 17:19:15 +000071 case DRAW_POS_TEXT_TOP_BOTTOM: return "DRAW_POS_TEXT_TOP_BOTTOM";
reed@android.combcd4d5a2008-12-17 15:59:43 +000072 case DRAW_POS_TEXT_H: return "DRAW_POS_TEXT_H";
robertphillips@google.come7189be2013-02-15 17:19:15 +000073 case DRAW_POS_TEXT_H_TOP_BOTTOM: return "DRAW_POS_TEXT_H_TOP_BOTTOM";
74 case DRAW_RECT: return "DRAW_RECT";
75 case DRAW_RRECT: return "DRAW_RRECT";
reed@android.combcd4d5a2008-12-17 15:59:43 +000076 case DRAW_SPRITE: return "DRAW_SPRITE";
77 case DRAW_TEXT: return "DRAW_TEXT";
78 case DRAW_TEXT_ON_PATH: return "DRAW_TEXT_ON_PATH";
robertphillips@google.come7189be2013-02-15 17:19:15 +000079 case DRAW_TEXT_TOP_BOTTOM: return "DRAW_TEXT_TOP_BOTTOM";
80 case DRAW_VERTICES: return "DRAW_VERTICES";
reed@android.combcd4d5a2008-12-17 15:59:43 +000081 case RESTORE: return "RESTORE";
82 case ROTATE: return "ROTATE";
83 case SAVE: return "SAVE";
84 case SAVE_LAYER: return "SAVE_LAYER";
85 case SCALE: return "SCALE";
robertphillips@google.come7189be2013-02-15 17:19:15 +000086 case SET_MATRIX: return "SET_MATRIX";
reed@android.combcd4d5a2008-12-17 15:59:43 +000087 case SKEW: return "SKEW";
88 case TRANSLATE: return "TRANSLATE";
robertphillips@google.come7189be2013-02-15 17:19:15 +000089 case NOOP: return "NOOP";
reed@google.com91911482011-02-07 15:30:46 +000090 default:
91 SkDebugf("DrawType error 0x%08x\n", drawType);
92 SkASSERT(0);
reed@android.combcd4d5a2008-12-17 15:59:43 +000093 break;
94 }
reed@google.com91911482011-02-07 15:30:46 +000095 SkASSERT(0);
reed@android.combcd4d5a2008-12-17 15:59:43 +000096 return NULL;
97}
98#endif
99
100#ifdef SK_DEBUG_VALIDATE
101static void validateMatrix(const SkMatrix* matrix) {
102 SkScalar scaleX = matrix->getScaleX();
103 SkScalar scaleY = matrix->getScaleY();
104 SkScalar skewX = matrix->getSkewX();
105 SkScalar skewY = matrix->getSkewY();
106 SkScalar perspX = matrix->getPerspX();
107 SkScalar perspY = matrix->getPerspY();
108 if (scaleX != 0 && skewX != 0)
109 SkDebugf("scaleX != 0 && skewX != 0\n");
110 SkASSERT(scaleX == 0 || skewX == 0);
111 SkASSERT(scaleY == 0 || skewY == 0);
112 SkASSERT(perspX == 0);
113 SkASSERT(perspY == 0);
114}
115#endif
116
117
118///////////////////////////////////////////////////////////////////////////////
119
120SkPicture::SkPicture() {
121 fRecord = NULL;
122 fPlayback = NULL;
123 fWidth = fHeight = 0;
commit-bot@chromium.org73857a32014-03-16 19:46:36 +0000124 fAccelData = NULL;
reed@android.combcd4d5a2008-12-17 15:59:43 +0000125}
126
skia.committer@gmail.com8b5598b2014-03-17 03:02:17 +0000127SkPicture::SkPicture(const SkPicture& src)
commit-bot@chromium.org73857a32014-03-16 19:46:36 +0000128 : INHERITED()
129 , fAccelData(NULL) {
reed@android.combcd4d5a2008-12-17 15:59:43 +0000130 fWidth = src.fWidth;
131 fHeight = src.fHeight;
132 fRecord = NULL;
133
134 /* We want to copy the src's playback. However, if that hasn't been built
135 yet, we need to fake a call to endRecording() without actually calling
136 it (since it is destructive, and we don't want to change src).
137 */
138 if (src.fPlayback) {
139 fPlayback = SkNEW_ARGS(SkPicturePlayback, (*src.fPlayback));
140 } else if (src.fRecord) {
commit-bot@chromium.org206dc582014-03-28 18:05:47 +0000141 SkPictInfo info;
142 this->createHeader(&info);
reed@android.combcd4d5a2008-12-17 15:59:43 +0000143 // here we do a fake src.endRecording()
commit-bot@chromium.org206dc582014-03-28 18:05:47 +0000144 fPlayback = SkNEW_ARGS(SkPicturePlayback, (*src.fRecord, info));
reed@android.combcd4d5a2008-12-17 15:59:43 +0000145 } else {
146 fPlayback = NULL;
147 }
148}
149
150SkPicture::~SkPicture() {
reed@google.com91911482011-02-07 15:30:46 +0000151 SkSafeUnref(fRecord);
reed@android.combcd4d5a2008-12-17 15:59:43 +0000152 SkDELETE(fPlayback);
commit-bot@chromium.org73857a32014-03-16 19:46:36 +0000153 SkSafeUnref(fAccelData);
reed@android.combcd4d5a2008-12-17 15:59:43 +0000154}
155
commit-bot@chromium.orge6e785e2014-03-04 19:08:57 +0000156void SkPicture::internalOnly_EnableOpts(bool enableOpts) {
157 if (NULL != fRecord) {
158 fRecord->internalOnly_EnableOpts(enableOpts);
159 }
160}
161
reed@android.combcd4d5a2008-12-17 15:59:43 +0000162void SkPicture::swap(SkPicture& other) {
163 SkTSwap(fRecord, other.fRecord);
164 SkTSwap(fPlayback, other.fPlayback);
commit-bot@chromium.org73857a32014-03-16 19:46:36 +0000165 SkTSwap(fAccelData, other.fAccelData);
reed@android.combcd4d5a2008-12-17 15:59:43 +0000166 SkTSwap(fWidth, other.fWidth);
167 SkTSwap(fHeight, other.fHeight);
168}
169
djsollen@google.com3855f872012-08-29 18:52:07 +0000170SkPicture* SkPicture::clone() const {
171 SkPicture* clonedPicture = SkNEW(SkPicture);
172 clone(clonedPicture, 1);
173 return clonedPicture;
174}
175
176void SkPicture::clone(SkPicture* pictures, int count) const {
177 SkPictCopyInfo copyInfo;
commit-bot@chromium.org206dc582014-03-28 18:05:47 +0000178 SkPictInfo info;
179 this->createHeader(&info);
djsollen@google.com3855f872012-08-29 18:52:07 +0000180
181 for (int i = 0; i < count; i++) {
182 SkPicture* clone = &pictures[i];
183
184 clone->fWidth = fWidth;
185 clone->fHeight = fHeight;
commit-bot@chromium.orgefea6992014-02-14 17:27:10 +0000186 SkSafeSetNull(clone->fRecord);
scroggo@google.coma0dd4332012-11-02 20:51:19 +0000187 SkDELETE(clone->fPlayback);
188
djsollen@google.com3855f872012-08-29 18:52:07 +0000189 /* We want to copy the src's playback. However, if that hasn't been built
190 yet, we need to fake a call to endRecording() without actually calling
191 it (since it is destructive, and we don't want to change src).
192 */
193 if (fPlayback) {
194 clone->fPlayback = SkNEW_ARGS(SkPicturePlayback, (*fPlayback, &copyInfo));
195 } else if (fRecord) {
196 // here we do a fake src.endRecording()
commit-bot@chromium.org206dc582014-03-28 18:05:47 +0000197 clone->fPlayback = SkNEW_ARGS(SkPicturePlayback, (*fRecord, info, true));
djsollen@google.com3855f872012-08-29 18:52:07 +0000198 } else {
199 clone->fPlayback = NULL;
200 }
201 }
202}
203
commit-bot@chromium.org73857a32014-03-16 19:46:36 +0000204SkPicture::AccelData::Domain SkPicture::AccelData::GenerateDomain() {
205 static int32_t gNextID = 0;
206
207 int32_t id = sk_atomic_inc(&gNextID);
208 if (id >= 1 << (8 * sizeof(Domain))) {
209 SK_CRASH();
210 }
211
212 return static_cast<Domain>(id);
213}
214
reed@android.combcd4d5a2008-12-17 15:59:43 +0000215///////////////////////////////////////////////////////////////////////////////
216
reed@android.comc4a55d72009-02-13 14:56:09 +0000217SkCanvas* SkPicture::beginRecording(int width, int height,
218 uint32_t recordingFlags) {
reed@android.combcd4d5a2008-12-17 15:59:43 +0000219 if (fPlayback) {
220 SkDELETE(fPlayback);
221 fPlayback = NULL;
222 }
commit-bot@chromium.org73857a32014-03-16 19:46:36 +0000223 SkSafeUnref(fAccelData);
commit-bot@chromium.orgefea6992014-02-14 17:27:10 +0000224 SkSafeSetNull(fRecord);
reed@android.combcd4d5a2008-12-17 15:59:43 +0000225
junov@chromium.orgbb78c442012-11-01 17:10:32 +0000226 // Must be set before calling createBBoxHierarchy
227 fWidth = width;
228 fHeight = height;
229
commit-bot@chromium.orgca101d62014-02-17 15:28:00 +0000230 const SkISize size = SkISize::Make(width, height);
231
rileya@google.com7fb3d2f2012-09-13 21:41:51 +0000232 if (recordingFlags & kOptimizeForClippedPlayback_RecordingFlag) {
junov@chromium.orgbb78c442012-11-01 17:10:32 +0000233 SkBBoxHierarchy* tree = this->createBBoxHierarchy();
rileya@google.com7fb3d2f2012-09-13 21:41:51 +0000234 SkASSERT(NULL != tree);
commit-bot@chromium.orgca101d62014-02-17 15:28:00 +0000235 fRecord = SkNEW_ARGS(SkBBoxHierarchyRecord, (size, recordingFlags, tree));
rileya@google.com7fb3d2f2012-09-13 21:41:51 +0000236 tree->unref();
237 } else {
commit-bot@chromium.orgca101d62014-02-17 15:28:00 +0000238 fRecord = SkNEW_ARGS(SkPictureRecord, (size, recordingFlags));
rileya@google.com7fb3d2f2012-09-13 21:41:51 +0000239 }
reed@google.com118a6d02012-09-27 20:31:31 +0000240 fRecord->beginRecording();
reed@android.combcd4d5a2008-12-17 15:59:43 +0000241
reed@android.combcd4d5a2008-12-17 15:59:43 +0000242 return fRecord;
243}
244
junov@chromium.orgbb78c442012-11-01 17:10:32 +0000245SkBBoxHierarchy* SkPicture::createBBoxHierarchy() const {
skia.committer@gmail.com8d230dd2012-11-02 02:01:24 +0000246 // These values were empirically determined to produce reasonable
junov@chromium.orgbb78c442012-11-01 17:10:32 +0000247 // performance in most cases.
248 static const int kRTreeMinChildren = 6;
249 static const int kRTreeMaxChildren = 11;
250
251 SkScalar aspectRatio = SkScalarDiv(SkIntToScalar(fWidth),
252 SkIntToScalar(fHeight));
sglez@google.com9baab6f2013-08-30 17:27:47 +0000253 bool sortDraws = false; // Do not sort draw calls when bulk loading.
254
junov@chromium.orgbb78c442012-11-01 17:10:32 +0000255 return SkRTree::Create(kRTreeMinChildren, kRTreeMaxChildren,
sglez@google.com9baab6f2013-08-30 17:27:47 +0000256 aspectRatio, sortDraws);
junov@chromium.orgbb78c442012-11-01 17:10:32 +0000257}
258
reed@android.combcd4d5a2008-12-17 15:59:43 +0000259SkCanvas* SkPicture::getRecordingCanvas() const {
260 // will be null if we are not recording
261 return fRecord;
262}
263
264void SkPicture::endRecording() {
265 if (NULL == fPlayback) {
266 if (NULL != fRecord) {
junov@chromium.org9aa18db2012-07-12 17:47:34 +0000267 fRecord->endRecording();
commit-bot@chromium.org206dc582014-03-28 18:05:47 +0000268 SkPictInfo info;
269 this->createHeader(&info);
270 fPlayback = SkNEW_ARGS(SkPicturePlayback, (*fRecord, info));
commit-bot@chromium.orgefea6992014-02-14 17:27:10 +0000271 SkSafeSetNull(fRecord);
reed@android.combcd4d5a2008-12-17 15:59:43 +0000272 }
273 }
274 SkASSERT(NULL == fRecord);
275}
276
commit-bot@chromium.org4b918972014-03-18 17:45:32 +0000277const SkPicture::OperationList& SkPicture::OperationList::InvalidList() {
278 static OperationList gInvalid;
279 return gInvalid;
280}
281
282const SkPicture::OperationList& SkPicture::EXPERIMENTAL_getActiveOps(const SkIRect& queryRect) {
283 this->endRecording();
284 if (NULL != fPlayback) {
285 return fPlayback->getActiveOps(queryRect);
286 }
287 return OperationList::InvalidList();
288}
289
commit-bot@chromium.org0ea71132014-03-24 19:40:49 +0000290size_t SkPicture::EXPERIMENTAL_curOpID() const {
291 if (NULL != fPlayback) {
292 return fPlayback->curOpID();
293 }
294 return 0;
295}
296
reed@google.com2b3a5082013-05-20 17:02:41 +0000297void SkPicture::draw(SkCanvas* surface, SkDrawPictureCallback* callback) {
reed@android.combcd4d5a2008-12-17 15:59:43 +0000298 this->endRecording();
commit-bot@chromium.org73857a32014-03-16 19:46:36 +0000299 if (NULL != fPlayback) {
reed@google.com2b3a5082013-05-20 17:02:41 +0000300 fPlayback->draw(*surface, callback);
reed@android.combcd4d5a2008-12-17 15:59:43 +0000301 }
302}
303
304///////////////////////////////////////////////////////////////////////////////
305
306#include "SkStream.h"
307
rmistry@google.com8793ad72013-12-02 13:50:38 +0000308static const char kMagic[] = { 's', 'k', 'i', 'a', 'p', 'i', 'c', 't' };
commit-bot@chromium.org060e3a52014-03-12 14:46:41 +0000309
310bool SkPicture::IsValidPictInfo(const SkPictInfo& info) {
311 if (0 != memcmp(info.fMagic, kMagic, sizeof(kMagic))) {
312 return false;
313 }
314
315 if (info.fVersion < MIN_PICTURE_VERSION ||
316 info.fVersion > CURRENT_PICTURE_VERSION) {
317 return false;
318 }
319
320 return true;
321}
rmistry@google.com8793ad72013-12-02 13:50:38 +0000322
commit-bot@chromium.orgabad6d62014-03-03 19:18:39 +0000323bool SkPicture::InternalOnly_StreamIsSKP(SkStream* stream, SkPictInfo* pInfo) {
scroggo@google.com3b990302013-06-28 21:32:00 +0000324 if (NULL == stream) {
325 return false;
borenet@google.com30dda202012-09-17 18:26:06 +0000326 }
reed@google.com4bca7f62012-06-22 15:38:39 +0000327
rmistry@google.com8793ad72013-12-02 13:50:38 +0000328 // Check magic bytes.
reed@google.com4bca7f62012-06-22 15:38:39 +0000329 SkPictInfo info;
commit-bot@chromium.org060e3a52014-03-12 14:46:41 +0000330 SkASSERT(sizeof(kMagic) == sizeof(info.fMagic));
331 if (!stream->read(&info, sizeof(info)) || !IsValidPictInfo(info)) {
scroggo@google.com3b990302013-06-28 21:32:00 +0000332 return false;
reed@google.com4bca7f62012-06-22 15:38:39 +0000333 }
reed@android.combcd4d5a2008-12-17 15:59:43 +0000334
scroggo@google.com3b990302013-06-28 21:32:00 +0000335 if (pInfo != NULL) {
336 *pInfo = info;
337 }
338 return true;
339}
340
commit-bot@chromium.orgabad6d62014-03-03 19:18:39 +0000341bool SkPicture::InternalOnly_BufferIsSKP(SkReadBuffer& buffer, SkPictInfo* pInfo) {
commit-bot@chromium.org7183ff62014-02-07 12:20:04 +0000342 // Check magic bytes.
commit-bot@chromium.org7183ff62014-02-07 12:20:04 +0000343 SkPictInfo info;
commit-bot@chromium.org060e3a52014-03-12 14:46:41 +0000344 SkASSERT(sizeof(kMagic) == sizeof(info.fMagic));
345 if (!buffer.readByteArray(&info, sizeof(info)) || !IsValidPictInfo(info)) {
commit-bot@chromium.org7183ff62014-02-07 12:20:04 +0000346 return false;
347 }
348
349 if (pInfo != NULL) {
350 *pInfo = info;
351 }
352 return true;
353}
354
scroggo@google.com3b990302013-06-28 21:32:00 +0000355SkPicture::SkPicture(SkPicturePlayback* playback, int width, int height)
356 : fPlayback(playback)
357 , fRecord(NULL)
358 , fWidth(width)
commit-bot@chromium.org73857a32014-03-16 19:46:36 +0000359 , fHeight(height)
360 , fAccelData(NULL) {}
scroggo@google.com3b990302013-06-28 21:32:00 +0000361
362SkPicture* SkPicture::CreateFromStream(SkStream* stream, InstallPixelRefProc proc) {
363 SkPictInfo info;
364
commit-bot@chromium.orgabad6d62014-03-03 19:18:39 +0000365 if (!InternalOnly_StreamIsSKP(stream, &info)) {
scroggo@google.com3b990302013-06-28 21:32:00 +0000366 return NULL;
367 }
368
369 SkPicturePlayback* playback;
370 // Check to see if there is a playback to recreate.
reed@android.combcd4d5a2008-12-17 15:59:43 +0000371 if (stream->readBool()) {
scroggo@google.com3b7431c2013-10-01 15:30:46 +0000372 playback = SkPicturePlayback::CreateFromStream(stream, info, proc);
373 if (NULL == playback) {
374 return NULL;
375 }
scroggo@google.com3b990302013-06-28 21:32:00 +0000376 } else {
377 playback = NULL;
reed@android.combcd4d5a2008-12-17 15:59:43 +0000378 }
reed@google.com4bca7f62012-06-22 15:38:39 +0000379
scroggo@google.com3b990302013-06-28 21:32:00 +0000380 return SkNEW_ARGS(SkPicture, (playback, info.fWidth, info.fHeight));
reed@android.combcd4d5a2008-12-17 15:59:43 +0000381}
382
commit-bot@chromium.org7183ff62014-02-07 12:20:04 +0000383SkPicture* SkPicture::CreateFromBuffer(SkReadBuffer& buffer) {
384 SkPictInfo info;
385
commit-bot@chromium.orgabad6d62014-03-03 19:18:39 +0000386 if (!InternalOnly_BufferIsSKP(buffer, &info)) {
commit-bot@chromium.org7183ff62014-02-07 12:20:04 +0000387 return NULL;
388 }
389
390 SkPicturePlayback* playback;
391 // Check to see if there is a playback to recreate.
392 if (buffer.readBool()) {
commit-bot@chromium.org206dc582014-03-28 18:05:47 +0000393 playback = SkPicturePlayback::CreateFromBuffer(buffer, info);
commit-bot@chromium.org7183ff62014-02-07 12:20:04 +0000394 if (NULL == playback) {
395 return NULL;
396 }
397 } else {
398 playback = NULL;
399 }
400
401 return SkNEW_ARGS(SkPicture, (playback, info.fWidth, info.fHeight));
402}
403
commit-bot@chromium.org060e3a52014-03-12 14:46:41 +0000404void SkPicture::createHeader(SkPictInfo* info) const {
commit-bot@chromium.org7183ff62014-02-07 12:20:04 +0000405 // Copy magic bytes at the beginning of the header
406 SkASSERT(sizeof(kMagic) == 8);
commit-bot@chromium.org060e3a52014-03-12 14:46:41 +0000407 SkASSERT(sizeof(kMagic) == sizeof(info->fMagic));
408 memcpy(info->fMagic, kMagic, sizeof(kMagic));
commit-bot@chromium.org7183ff62014-02-07 12:20:04 +0000409
commit-bot@chromium.orgabad6d62014-03-03 19:18:39 +0000410 // Set picture info after magic bytes in the header
commit-bot@chromium.org338284f2014-02-25 02:16:10 +0000411 info->fVersion = CURRENT_PICTURE_VERSION;
commit-bot@chromium.org7183ff62014-02-07 12:20:04 +0000412 info->fWidth = fWidth;
413 info->fHeight = fHeight;
414 info->fFlags = SkPictInfo::kCrossProcess_Flag;
415 // TODO: remove this flag, since we're always float (now)
416 info->fFlags |= SkPictInfo::kScalarIsFloat_Flag;
417
418 if (8 == sizeof(void*)) {
419 info->fFlags |= SkPictInfo::kPtrIs64Bit_Flag;
420 }
421}
422
scroggo@google.com2e727312013-02-22 22:04:19 +0000423void SkPicture::serialize(SkWStream* stream, EncodeBitmap encoder) const {
reed@android.combcd4d5a2008-12-17 15:59:43 +0000424 SkPicturePlayback* playback = fPlayback;
reed@google.com91911482011-02-07 15:30:46 +0000425
commit-bot@chromium.org206dc582014-03-28 18:05:47 +0000426 SkPictInfo info;
427 this->createHeader(&info);
reed@android.combcd4d5a2008-12-17 15:59:43 +0000428 if (NULL == playback && fRecord) {
commit-bot@chromium.org206dc582014-03-28 18:05:47 +0000429 playback = SkNEW_ARGS(SkPicturePlayback, (*fRecord, info));
reed@android.combcd4d5a2008-12-17 15:59:43 +0000430 }
431
commit-bot@chromium.org206dc582014-03-28 18:05:47 +0000432 stream->write(&info, sizeof(info));
reed@android.combcd4d5a2008-12-17 15:59:43 +0000433 if (playback) {
434 stream->writeBool(true);
scroggo@google.com6ff73172012-10-04 21:46:08 +0000435 playback->serialize(stream, encoder);
reed@android.combcd4d5a2008-12-17 15:59:43 +0000436 // delete playback if it is a local version (i.e. cons'd up just now)
437 if (playback != fPlayback) {
438 SkDELETE(playback);
439 }
440 } else {
441 stream->writeBool(false);
442 }
443}
444
commit-bot@chromium.org7183ff62014-02-07 12:20:04 +0000445void SkPicture::flatten(SkWriteBuffer& buffer) const {
446 SkPicturePlayback* playback = fPlayback;
447
commit-bot@chromium.org206dc582014-03-28 18:05:47 +0000448 SkPictInfo info;
449 this->createHeader(&info);
commit-bot@chromium.org7183ff62014-02-07 12:20:04 +0000450 if (NULL == playback && fRecord) {
commit-bot@chromium.org206dc582014-03-28 18:05:47 +0000451 playback = SkNEW_ARGS(SkPicturePlayback, (*fRecord, info));
commit-bot@chromium.org7183ff62014-02-07 12:20:04 +0000452 }
453
commit-bot@chromium.org206dc582014-03-28 18:05:47 +0000454 buffer.writeByteArray(&info, sizeof(info));
commit-bot@chromium.org7183ff62014-02-07 12:20:04 +0000455 if (playback) {
456 buffer.writeBool(true);
457 playback->flatten(buffer);
458 // delete playback if it is a local version (i.e. cons'd up just now)
459 if (playback != fPlayback) {
460 SkDELETE(playback);
461 }
462 } else {
463 buffer.writeBool(false);
464 }
465}
466
commit-bot@chromium.org05937b42014-03-19 22:54:40 +0000467#if SK_SUPPORT_GPU
commit-bot@chromium.org95cdc162014-03-19 21:24:25 +0000468bool SkPicture::suitableForGpuRasterization(GrContext* context) const {
469 // Stub for now; never veto GPu rasterization.
470 return true;
471}
commit-bot@chromium.org05937b42014-03-19 22:54:40 +0000472#endif
commit-bot@chromium.org95cdc162014-03-19 21:24:25 +0000473
tomhudson@google.comc7941702013-10-24 11:12:47 +0000474bool SkPicture::willPlayBackBitmaps() const {
commit-bot@chromium.org73857a32014-03-16 19:46:36 +0000475 if (!fPlayback) {
476 return false;
477 }
tomhudson@google.comc7941702013-10-24 11:12:47 +0000478 return fPlayback->containsBitmaps();
479}
480
djsollen@google.com6789a342013-02-01 16:18:09 +0000481#ifdef SK_BUILD_FOR_ANDROID
reed@android.combcd4d5a2008-12-17 15:59:43 +0000482void SkPicture::abortPlayback() {
483 if (NULL == fPlayback) {
484 return;
485 }
486 fPlayback->abort();
487}
djsollen@google.com6789a342013-02-01 16:18:09 +0000488#endif