OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2007 The Android Open Source Project | 3 * Copyright 2007 The Android Open Source Project |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 | 9 |
10 #include "SkPictureFlat.h" | 10 #include "SkPictureFlat.h" |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 SkASSERT(perspY == 0); | 119 SkASSERT(perspY == 0); |
120 } | 120 } |
121 #endif | 121 #endif |
122 | 122 |
123 | 123 |
124 /////////////////////////////////////////////////////////////////////////////// | 124 /////////////////////////////////////////////////////////////////////////////// |
125 | 125 |
126 SkPicture::SkPicture() | 126 SkPicture::SkPicture() |
127 : fAccelData(NULL) { | 127 : fAccelData(NULL) { |
128 this->needsNewGenID(); | 128 this->needsNewGenID(); |
129 fRecord = NULL; | |
130 fPlayback = NULL; | 129 fPlayback = NULL; |
131 fWidth = fHeight = 0; | 130 fWidth = fHeight = 0; |
132 } | 131 } |
133 | 132 |
134 // This method makes a SkPicturePlayback object from an in-progress recording. | 133 // This method makes a SkPicturePlayback object from an in-progress recording. |
135 // Unfortunately, it does not include the restoreToCount of a real endRecording | 134 // Unfortunately, it does not include the restoreToCount of a real endRecording |
136 // call. | 135 // call. |
137 SkPicturePlayback* SkPicture::FakeEndRecording(const SkPicture* resourceSrc, | 136 SkPicturePlayback* SkPicture::FakeEndRecording(const SkPicture* resourceSrc, |
138 const SkPictureRecord& record, | 137 const SkPictureRecord& record, |
139 bool deepCopy) { | 138 bool deepCopy) { |
140 SkPictInfo info; | 139 SkPictInfo info; |
141 resourceSrc->createHeader(&info); | 140 resourceSrc->createHeader(&info); |
142 return SkNEW_ARGS(SkPicturePlayback, (resourceSrc, record, info, deepCopy)); | 141 return SkNEW_ARGS(SkPicturePlayback, (resourceSrc, record, info, deepCopy)); |
143 } | 142 } |
144 | 143 |
145 SkPicture::SkPicture(const SkPicture& src) | 144 SkPicture::SkPicture(const SkPicture& src) |
146 : INHERITED() | 145 : INHERITED() |
147 , fAccelData(NULL) | 146 , fAccelData(NULL) |
148 , fContentInfo(src.fContentInfo) { | 147 , fContentInfo(src.fContentInfo) { |
149 this->needsNewGenID(); | 148 this->needsNewGenID(); |
150 fWidth = src.fWidth; | 149 fWidth = src.fWidth; |
151 fHeight = src.fHeight; | 150 fHeight = src.fHeight; |
152 fRecord = NULL; | |
153 | 151 |
154 /* We want to copy the src's playback. However, if that hasn't been built | 152 /* We want to copy the src's playback. However, if that hasn't been built |
155 yet, we need to fake a call to endRecording() without actually calling | 153 yet, we need to fake a call to endRecording() without actually calling |
156 it (since it is destructive, and we don't want to change src). | 154 it (since it is destructive, and we don't want to change src). |
157 */ | 155 */ |
158 if (src.fPlayback) { | 156 if (src.fPlayback) { |
159 fPlayback = SkNEW_ARGS(SkPicturePlayback, (this, *src.fPlayback)); | 157 fPlayback = SkNEW_ARGS(SkPicturePlayback, (this, *src.fPlayback)); |
160 SkASSERT(NULL == src.fRecord); | |
161 fUniqueID = src.uniqueID(); // need to call method to ensure != 0 | 158 fUniqueID = src.uniqueID(); // need to call method to ensure != 0 |
162 } else if (src.fRecord) { | |
163 fPlayback = FakeEndRecording(this, *src.fRecord, false); | |
164 } else { | 159 } else { |
165 fPlayback = NULL; | 160 fPlayback = NULL; |
166 } | 161 } |
167 | 162 |
168 fPathHeap.reset(SkSafeRef(src.fPathHeap.get())); | 163 fPathHeap.reset(SkSafeRef(src.fPathHeap.get())); |
169 } | 164 } |
170 | 165 |
171 const SkPath& SkPicture::getPath(int index) const { | 166 const SkPath& SkPicture::getPath(int index) const { |
172 return (*fPathHeap.get())[index]; | 167 return (*fPathHeap.get())[index]; |
173 } | 168 } |
(...skipping 17 matching lines...) Expand all Loading... |
191 } | 186 } |
192 } | 187 } |
193 } | 188 } |
194 | 189 |
195 void SkPicture::dumpSize() const { | 190 void SkPicture::dumpSize() const { |
196 SkDebugf("--- picture size: paths=%d\n", | 191 SkDebugf("--- picture size: paths=%d\n", |
197 SafeCount(fPathHeap.get())); | 192 SafeCount(fPathHeap.get())); |
198 } | 193 } |
199 | 194 |
200 SkPicture::~SkPicture() { | 195 SkPicture::~SkPicture() { |
201 SkSafeUnref(fRecord); | |
202 SkDELETE(fPlayback); | 196 SkDELETE(fPlayback); |
203 SkSafeUnref(fAccelData); | 197 SkSafeUnref(fAccelData); |
204 } | 198 } |
205 | 199 |
206 void SkPicture::internalOnly_EnableOpts(bool enableOpts) { | |
207 if (NULL != fRecord) { | |
208 fRecord->internalOnly_EnableOpts(enableOpts); | |
209 } | |
210 } | |
211 | |
212 void SkPicture::swap(SkPicture& other) { | 200 void SkPicture::swap(SkPicture& other) { |
213 SkTSwap(fUniqueID, other.fUniqueID); | 201 SkTSwap(fUniqueID, other.fUniqueID); |
214 SkTSwap(fRecord, other.fRecord); | |
215 SkTSwap(fPlayback, other.fPlayback); | 202 SkTSwap(fPlayback, other.fPlayback); |
216 SkTSwap(fAccelData, other.fAccelData); | 203 SkTSwap(fAccelData, other.fAccelData); |
217 SkTSwap(fWidth, other.fWidth); | 204 SkTSwap(fWidth, other.fWidth); |
218 SkTSwap(fHeight, other.fHeight); | 205 SkTSwap(fHeight, other.fHeight); |
219 fPathHeap.swap(&other.fPathHeap); | 206 fPathHeap.swap(&other.fPathHeap); |
220 fContentInfo.swap(&other.fContentInfo); | 207 fContentInfo.swap(&other.fContentInfo); |
221 } | 208 } |
222 | 209 |
223 SkPicture* SkPicture::clone() const { | 210 SkPicture* SkPicture::clone() const { |
224 SkPicture* clonedPicture = SkNEW(SkPicture); | 211 SkPicture* clonedPicture = SkNEW(SkPicture); |
225 this->clone(clonedPicture, 1); | 212 this->clone(clonedPicture, 1); |
226 return clonedPicture; | 213 return clonedPicture; |
227 } | 214 } |
228 | 215 |
229 void SkPicture::clone(SkPicture* pictures, int count) const { | 216 void SkPicture::clone(SkPicture* pictures, int count) const { |
230 SkPictCopyInfo copyInfo; | 217 SkPictCopyInfo copyInfo; |
231 | 218 |
232 for (int i = 0; i < count; i++) { | 219 for (int i = 0; i < count; i++) { |
233 SkPicture* clone = &pictures[i]; | 220 SkPicture* clone = &pictures[i]; |
234 | 221 |
235 clone->needsNewGenID(); | 222 clone->needsNewGenID(); |
236 clone->fWidth = fWidth; | 223 clone->fWidth = fWidth; |
237 clone->fHeight = fHeight; | 224 clone->fHeight = fHeight; |
238 SkSafeSetNull(clone->fRecord); | |
239 SkDELETE(clone->fPlayback); | 225 SkDELETE(clone->fPlayback); |
240 clone->fContentInfo.set(fContentInfo); | 226 clone->fContentInfo.set(fContentInfo); |
241 | 227 |
242 /* We want to copy the src's playback. However, if that hasn't been bui
lt | 228 /* We want to copy the src's playback. However, if that hasn't been bui
lt |
243 yet, we need to fake a call to endRecording() without actually calli
ng | 229 yet, we need to fake a call to endRecording() without actually calli
ng |
244 it (since it is destructive, and we don't want to change src). | 230 it (since it is destructive, and we don't want to change src). |
245 */ | 231 */ |
246 if (fPlayback) { | 232 if (fPlayback) { |
247 if (!copyInfo.initialized) { | 233 if (!copyInfo.initialized) { |
248 int paintCount = SafeCount(fPlayback->fPaints); | 234 int paintCount = SafeCount(fPlayback->fPaints); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
280 } | 266 } |
281 } | 267 } |
282 SkASSERT(SafeCount(fPlayback->fBitmapHeap.get()) == heapSize); | 268 SkASSERT(SafeCount(fPlayback->fBitmapHeap.get()) == heapSize); |
283 | 269 |
284 // needed to create typeface playback | 270 // needed to create typeface playback |
285 copyInfo.controller.setupPlaybacks(); | 271 copyInfo.controller.setupPlaybacks(); |
286 copyInfo.initialized = true; | 272 copyInfo.initialized = true; |
287 } | 273 } |
288 | 274 |
289 clone->fPlayback = SkNEW_ARGS(SkPicturePlayback, (clone, *fPlayback,
©Info)); | 275 clone->fPlayback = SkNEW_ARGS(SkPicturePlayback, (clone, *fPlayback,
©Info)); |
290 SkASSERT(NULL == fRecord); | |
291 clone->fUniqueID = this->uniqueID(); // need to call method to ensur
e != 0 | 276 clone->fUniqueID = this->uniqueID(); // need to call method to ensur
e != 0 |
292 } else if (fRecord) { | |
293 clone->fPlayback = FakeEndRecording(clone, *fRecord, true); | |
294 } else { | 277 } else { |
295 clone->fPlayback = NULL; | 278 clone->fPlayback = NULL; |
296 } | 279 } |
297 | 280 |
298 clone->fPathHeap.reset(SkSafeRef(fPathHeap.get())); | 281 clone->fPathHeap.reset(SkSafeRef(fPathHeap.get())); |
299 } | 282 } |
300 } | 283 } |
301 | 284 |
302 SkPicture::AccelData::Domain SkPicture::AccelData::GenerateDomain() { | 285 SkPicture::AccelData::Domain SkPicture::AccelData::GenerateDomain() { |
303 static int32_t gNextID = 0; | 286 static int32_t gNextID = 0; |
304 | 287 |
305 int32_t id = sk_atomic_inc(&gNextID); | 288 int32_t id = sk_atomic_inc(&gNextID); |
306 if (id >= 1 << (8 * sizeof(Domain))) { | 289 if (id >= 1 << (8 * sizeof(Domain))) { |
307 SK_CRASH(); | 290 SK_CRASH(); |
308 } | 291 } |
309 | 292 |
310 return static_cast<Domain>(id); | 293 return static_cast<Domain>(id); |
311 } | 294 } |
312 | 295 |
313 /////////////////////////////////////////////////////////////////////////////// | 296 /////////////////////////////////////////////////////////////////////////////// |
314 | 297 |
315 SkCanvas* SkPicture::beginRecording(int width, int height, | |
316 SkBBHFactory* bbhFactory, | |
317 uint32_t recordingFlags) { | |
318 if (fPlayback) { | |
319 SkDELETE(fPlayback); | |
320 fPlayback = NULL; | |
321 } | |
322 SkSafeUnref(fAccelData); | |
323 SkSafeSetNull(fRecord); | |
324 SkASSERT(NULL == fPathHeap); | |
325 fContentInfo.reset(); | |
326 | |
327 this->needsNewGenID(); | |
328 | |
329 fWidth = width; | |
330 fHeight = height; | |
331 | |
332 const SkISize size = SkISize::Make(width, height); | |
333 | |
334 if (NULL != bbhFactory) { | |
335 SkAutoTUnref<SkBBoxHierarchy> tree((*bbhFactory)(width, height)); | |
336 SkASSERT(NULL != tree); | |
337 fRecord = SkNEW_ARGS(SkBBoxHierarchyRecord, (this, size, recordingFlags,
tree.get())); | |
338 } else { | |
339 fRecord = SkNEW_ARGS(SkPictureRecord, (this, size, recordingFlags)); | |
340 } | |
341 fRecord->beginRecording(); | |
342 | |
343 return fRecord; | |
344 } | |
345 | |
346 SkCanvas* SkPicture::getRecordingCanvas() const { | |
347 // will be null if we are not recording | |
348 return fRecord; | |
349 } | |
350 | |
351 void SkPicture::endRecording() { | |
352 if (NULL == fPlayback) { | |
353 if (NULL != fRecord) { | |
354 fRecord->endRecording(); | |
355 SkPictInfo info; | |
356 this->createHeader(&info); | |
357 fPlayback = SkNEW_ARGS(SkPicturePlayback, (this, *fRecord, info)); | |
358 SkSafeSetNull(fRecord); | |
359 } | |
360 } | |
361 SkASSERT(NULL == fRecord); | |
362 } | |
363 | |
364 const SkPicture::OperationList& SkPicture::OperationList::InvalidList() { | 298 const SkPicture::OperationList& SkPicture::OperationList::InvalidList() { |
365 static OperationList gInvalid; | 299 static OperationList gInvalid; |
366 return gInvalid; | 300 return gInvalid; |
367 } | 301 } |
368 | 302 |
369 const SkPicture::OperationList& SkPicture::EXPERIMENTAL_getActiveOps(const SkIRe
ct& queryRect) const { | 303 const SkPicture::OperationList& SkPicture::EXPERIMENTAL_getActiveOps(const SkIRe
ct& queryRect) const { |
370 SkASSERT(NULL != fPlayback && NULL == fRecord); | 304 SkASSERT(NULL != fPlayback); |
371 if (NULL != fPlayback) { | 305 if (NULL != fPlayback) { |
372 return fPlayback->getActiveOps(queryRect); | 306 return fPlayback->getActiveOps(queryRect); |
373 } | 307 } |
374 return OperationList::InvalidList(); | 308 return OperationList::InvalidList(); |
375 } | 309 } |
376 | 310 |
377 size_t SkPicture::EXPERIMENTAL_curOpID() const { | 311 size_t SkPicture::EXPERIMENTAL_curOpID() const { |
378 if (NULL != fPlayback) { | 312 if (NULL != fPlayback) { |
379 return fPlayback->curOpID(); | 313 return fPlayback->curOpID(); |
380 } | 314 } |
381 return 0; | 315 return 0; |
382 } | 316 } |
383 | 317 |
384 void SkPicture::draw(SkCanvas* surface, SkDrawPictureCallback* callback) const { | 318 void SkPicture::draw(SkCanvas* surface, SkDrawPictureCallback* callback) const { |
385 SkASSERT(NULL != fPlayback && NULL == fRecord); | 319 SkASSERT(NULL != fPlayback); |
386 if (NULL != fPlayback) { | 320 if (NULL != fPlayback) { |
387 fPlayback->draw(*surface, callback); | 321 fPlayback->draw(*surface, callback); |
388 } | 322 } |
389 } | 323 } |
390 | 324 |
391 /////////////////////////////////////////////////////////////////////////////// | 325 /////////////////////////////////////////////////////////////////////////////// |
392 | 326 |
393 #include "SkStream.h" | 327 #include "SkStream.h" |
394 | 328 |
395 static const char kMagic[] = { 's', 'k', 'i', 'a', 'p', 'i', 'c', 't' }; | 329 static const char kMagic[] = { 's', 'k', 'i', 'a', 'p', 'i', 'c', 't' }; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
434 } | 368 } |
435 | 369 |
436 if (pInfo != NULL) { | 370 if (pInfo != NULL) { |
437 *pInfo = info; | 371 *pInfo = info; |
438 } | 372 } |
439 return true; | 373 return true; |
440 } | 374 } |
441 | 375 |
442 SkPicture::SkPicture(SkPicturePlayback* playback, int width, int height) | 376 SkPicture::SkPicture(SkPicturePlayback* playback, int width, int height) |
443 : fPlayback(playback) | 377 : fPlayback(playback) |
444 , fRecord(NULL) | |
445 , fWidth(width) | 378 , fWidth(width) |
446 , fHeight(height) | 379 , fHeight(height) |
447 , fAccelData(NULL) { | 380 , fAccelData(NULL) { |
448 this->needsNewGenID(); | 381 this->needsNewGenID(); |
449 } | 382 } |
450 | 383 |
451 SkPicture* SkPicture::CreateFromStream(SkStream* stream, InstallPixelRefProc pro
c) { | 384 SkPicture* SkPicture::CreateFromStream(SkStream* stream, InstallPixelRefProc pro
c) { |
452 SkPictInfo info; | 385 SkPictInfo info; |
453 | 386 |
454 if (!InternalOnly_StreamIsSKP(stream, &info)) { | 387 if (!InternalOnly_StreamIsSKP(stream, &info)) { |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
508 info->fFlags |= SkPictInfo::kScalarIsFloat_Flag; | 441 info->fFlags |= SkPictInfo::kScalarIsFloat_Flag; |
509 | 442 |
510 if (8 == sizeof(void*)) { | 443 if (8 == sizeof(void*)) { |
511 info->fFlags |= SkPictInfo::kPtrIs64Bit_Flag; | 444 info->fFlags |= SkPictInfo::kPtrIs64Bit_Flag; |
512 } | 445 } |
513 } | 446 } |
514 | 447 |
515 void SkPicture::serialize(SkWStream* stream, EncodeBitmap encoder) const { | 448 void SkPicture::serialize(SkWStream* stream, EncodeBitmap encoder) const { |
516 SkPicturePlayback* playback = fPlayback; | 449 SkPicturePlayback* playback = fPlayback; |
517 | 450 |
518 if (NULL == playback && fRecord) { | |
519 playback = FakeEndRecording(this, *fRecord, false); | |
520 } | |
521 | |
522 SkPictInfo info; | 451 SkPictInfo info; |
523 this->createHeader(&info); | 452 this->createHeader(&info); |
524 stream->write(&info, sizeof(info)); | 453 stream->write(&info, sizeof(info)); |
525 if (playback) { | 454 if (playback) { |
526 stream->writeBool(true); | 455 stream->writeBool(true); |
527 playback->serialize(stream, encoder); | 456 playback->serialize(stream, encoder); |
528 // delete playback if it is a local version (i.e. cons'd up just now) | 457 // delete playback if it is a local version (i.e. cons'd up just now) |
529 if (playback != fPlayback) { | 458 if (playback != fPlayback) { |
530 SkDELETE(playback); | 459 SkDELETE(playback); |
531 } | 460 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
566 | 495 |
567 if ((n = SafeCount(fPathHeap.get())) > 0) { | 496 if ((n = SafeCount(fPathHeap.get())) > 0) { |
568 WriteTagSize(buffer, SK_PICT_PATH_BUFFER_TAG, n); | 497 WriteTagSize(buffer, SK_PICT_PATH_BUFFER_TAG, n); |
569 fPathHeap->flatten(buffer); | 498 fPathHeap->flatten(buffer); |
570 } | 499 } |
571 } | 500 } |
572 | 501 |
573 void SkPicture::flatten(SkWriteBuffer& buffer) const { | 502 void SkPicture::flatten(SkWriteBuffer& buffer) const { |
574 SkPicturePlayback* playback = fPlayback; | 503 SkPicturePlayback* playback = fPlayback; |
575 | 504 |
576 if (NULL == playback && fRecord) { | |
577 playback = FakeEndRecording(this, *fRecord, false); | |
578 } | |
579 | |
580 SkPictInfo info; | 505 SkPictInfo info; |
581 this->createHeader(&info); | 506 this->createHeader(&info); |
582 buffer.writeByteArray(&info, sizeof(info)); | 507 buffer.writeByteArray(&info, sizeof(info)); |
583 if (playback) { | 508 if (playback) { |
584 buffer.writeBool(true); | 509 buffer.writeBool(true); |
585 playback->flatten(buffer); | 510 playback->flatten(buffer); |
586 // delete playback if it is a local version (i.e. cons'd up just now) | 511 // delete playback if it is a local version (i.e. cons'd up just now) |
587 if (playback != fPlayback) { | 512 if (playback != fPlayback) { |
588 SkDELETE(playback); | 513 SkDELETE(playback); |
589 } | 514 } |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
635 // do a loop in case our global wraps around, as we never want to | 560 // do a loop in case our global wraps around, as we never want to |
636 // return a 0 | 561 // return a 0 |
637 int32_t genID; | 562 int32_t genID; |
638 do { | 563 do { |
639 genID = sk_atomic_inc(&gPictureGenerationID) + 1; | 564 genID = sk_atomic_inc(&gPictureGenerationID) + 1; |
640 } while (SK_InvalidGenID == genID); | 565 } while (SK_InvalidGenID == genID); |
641 return genID; | 566 return genID; |
642 } | 567 } |
643 | 568 |
644 uint32_t SkPicture::uniqueID() const { | 569 uint32_t SkPicture::uniqueID() const { |
645 if (NULL != fRecord) { | |
646 SkASSERT(NULL == fPlayback); | |
647 return SK_InvalidGenID; | |
648 } | |
649 | |
650 if (SK_InvalidGenID == fUniqueID) { | 570 if (SK_InvalidGenID == fUniqueID) { |
651 fUniqueID = next_picture_generation_id(); | 571 fUniqueID = next_picture_generation_id(); |
652 } | 572 } |
653 return fUniqueID; | 573 return fUniqueID; |
654 } | 574 } |
OLD | NEW |