| 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 |