| 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" |
| 11 #include "SkPicturePlayback.h" | 11 #include "SkPictureData.h" |
| 12 #include "SkPictureRecord.h" | 12 #include "SkPictureRecord.h" |
| 13 #include "SkPictureRecorder.h" | 13 #include "SkPictureRecorder.h" |
| 14 | 14 |
| 15 #include "SkBBHFactory.h" | 15 #include "SkBBHFactory.h" |
| 16 #include "SkBitmapDevice.h" | 16 #include "SkBitmapDevice.h" |
| 17 #include "SkCanvas.h" | 17 #include "SkCanvas.h" |
| 18 #include "SkChunkAlloc.h" | 18 #include "SkChunkAlloc.h" |
| 19 #include "SkDrawPictureCallback.h" | 19 #include "SkDrawPictureCallback.h" |
| 20 #include "SkPaintPriv.h" | 20 #include "SkPaintPriv.h" |
| 21 #include "SkPicture.h" | 21 #include "SkPicture.h" |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 139 // fRecord OK | 139 // fRecord OK |
| 140 SkPicture::SkPicture(int width, int height, | 140 SkPicture::SkPicture(int width, int height, |
| 141 const SkPictureRecord& record, | 141 const SkPictureRecord& record, |
| 142 bool deepCopyOps) | 142 bool deepCopyOps) |
| 143 : fWidth(width) | 143 : fWidth(width) |
| 144 , fHeight(height) { | 144 , fHeight(height) { |
| 145 this->needsNewGenID(); | 145 this->needsNewGenID(); |
| 146 | 146 |
| 147 SkPictInfo info; | 147 SkPictInfo info; |
| 148 this->createHeader(&info); | 148 this->createHeader(&info); |
| 149 fPlayback.reset(SkNEW_ARGS(SkPicturePlayback, (record, info, deepCopyOps))); | 149 fData.reset(SkNEW_ARGS(SkPictureData, (record, info, deepCopyOps))); |
| 150 } | 150 } |
| 151 | 151 |
| 152 // The simplest / safest way to copy an SkRecord is to replay it into a new one. | 152 // The simplest / safest way to copy an SkRecord is to replay it into a new one. |
| 153 static SkRecord* copy(const SkRecord& src, int width, int height) { | 153 static SkRecord* copy(const SkRecord& src, int width, int height) { |
| 154 SkRecord* dst = SkNEW(SkRecord); | 154 SkRecord* dst = SkNEW(SkRecord); |
| 155 SkRecorder recorder(dst, width, height); | 155 SkRecorder recorder(dst, width, height); |
| 156 SkRecordDraw(src, &recorder); | 156 SkRecordDraw(src, &recorder); |
| 157 return dst; | 157 return dst; |
| 158 } | 158 } |
| 159 | 159 |
| 160 // Create an SkPicturePlayback-backed SkPicture from an SkRecord. | 160 // Create an SkPictureData-backed SkPicture from an SkRecord. |
| 161 // This for compatibility with serialization code only. This is not cheap. | 161 // This for compatibility with serialization code only. This is not cheap. |
| 162 static SkPicture* backport(const SkRecord& src, int width, int height) { | 162 static SkPicture* backport(const SkRecord& src, int width, int height) { |
| 163 SkPictureRecorder recorder; | 163 SkPictureRecorder recorder; |
| 164 SkRecordDraw(src, recorder.beginRecording(width, height)); | 164 SkRecordDraw(src, recorder.beginRecording(width, height)); |
| 165 return recorder.endRecording(); | 165 return recorder.endRecording(); |
| 166 } | 166 } |
| 167 | 167 |
| 168 // fRecord OK | 168 // fRecord OK |
| 169 SkPicture::SkPicture(const SkPicture& src) : INHERITED() { | 169 SkPicture::SkPicture(const SkPicture& src) : INHERITED() { |
| 170 this->needsNewGenID(); | 170 this->needsNewGenID(); |
| 171 fWidth = src.fWidth; | 171 fWidth = src.fWidth; |
| 172 fHeight = src.fHeight; | 172 fHeight = src.fHeight; |
| 173 | 173 |
| 174 if (NULL != src.fPlayback.get()) { | 174 if (NULL != src.fData.get()) { |
| 175 fPlayback.reset(SkNEW_ARGS(SkPicturePlayback, (*src.fPlayback))); | 175 fData.reset(SkNEW_ARGS(SkPictureData, (*src.fData))); |
| 176 fUniqueID = src.uniqueID(); // need to call method to ensure != 0 | 176 fUniqueID = src.uniqueID(); // need to call method to ensure != 0 |
| 177 } | 177 } |
| 178 | 178 |
| 179 if (NULL != src.fRecord.get()) { | 179 if (NULL != src.fRecord.get()) { |
| 180 fRecord.reset(copy(*src.fRecord, fWidth, fHeight)); | 180 fRecord.reset(copy(*src.fRecord, fWidth, fHeight)); |
| 181 fUniqueID = src.uniqueID(); // need to call method to ensure != 0 | 181 fUniqueID = src.uniqueID(); // need to call method to ensure != 0 |
| 182 } | 182 } |
| 183 } | 183 } |
| 184 | 184 |
| 185 // fRecord OK | 185 // fRecord OK |
| (...skipping 10 matching lines...) Expand all Loading... |
| 196 // fRecord TODO, fix by deleting this method | 196 // fRecord TODO, fix by deleting this method |
| 197 void SkPicture::clone(SkPicture* pictures, int count) const { | 197 void SkPicture::clone(SkPicture* pictures, int count) const { |
| 198 SkPictCopyInfo copyInfo; | 198 SkPictCopyInfo copyInfo; |
| 199 | 199 |
| 200 for (int i = 0; i < count; i++) { | 200 for (int i = 0; i < count; i++) { |
| 201 SkPicture* clone = &pictures[i]; | 201 SkPicture* clone = &pictures[i]; |
| 202 | 202 |
| 203 clone->needsNewGenID(); | 203 clone->needsNewGenID(); |
| 204 clone->fWidth = fWidth; | 204 clone->fWidth = fWidth; |
| 205 clone->fHeight = fHeight; | 205 clone->fHeight = fHeight; |
| 206 clone->fPlayback.reset(NULL); | 206 clone->fData.reset(NULL); |
| 207 | 207 |
| 208 /* We want to copy the src's playback. However, if that hasn't been bui
lt | 208 /* We want to copy the src's playback. However, if that hasn't been bui
lt |
| 209 yet, we need to fake a call to endRecording() without actually calli
ng | 209 yet, we need to fake a call to endRecording() without actually calli
ng |
| 210 it (since it is destructive, and we don't want to change src). | 210 it (since it is destructive, and we don't want to change src). |
| 211 */ | 211 */ |
| 212 if (fPlayback.get()) { | 212 if (fData.get()) { |
| 213 if (!copyInfo.initialized) { | 213 if (!copyInfo.initialized) { |
| 214 int paintCount = SafeCount(fPlayback->fPaints); | 214 int paintCount = SafeCount(fData->fPaints); |
| 215 | 215 |
| 216 /* The alternative to doing this is to have a clone method on th
e paint and have it | 216 /* The alternative to doing this is to have a clone method on th
e paint and have it |
| 217 * make the deep copy of its internal structures as needed. The
holdup to doing | 217 * make the deep copy of its internal structures as needed. The
holdup to doing |
| 218 * that is at this point we would need to pass the SkBitmapHeap
so that we don't | 218 * that is at this point we would need to pass the SkBitmapHeap
so that we don't |
| 219 * unnecessarily flatten the pixels in a bitmap shader. | 219 * unnecessarily flatten the pixels in a bitmap shader. |
| 220 */ | 220 */ |
| 221 copyInfo.paintData.setCount(paintCount); | 221 copyInfo.paintData.setCount(paintCount); |
| 222 | 222 |
| 223 /* Use an SkBitmapHeap to avoid flattening bitmaps in shaders. I
f there already is | 223 /* Use an SkBitmapHeap to avoid flattening bitmaps in shaders. I
f there already is |
| 224 * one, use it. If this SkPicturePlayback was created from a str
eam, fBitmapHeap | 224 * one, use it. If this SkPictureData was created from a stream,
fBitmapHeap |
| 225 * will be NULL, so create a new one. | 225 * will be NULL, so create a new one. |
| 226 */ | 226 */ |
| 227 if (fPlayback->fBitmapHeap.get() == NULL) { | 227 if (fData->fBitmapHeap.get() == NULL) { |
| 228 // FIXME: Put this on the stack inside SkPicture::clone. | 228 // FIXME: Put this on the stack inside SkPicture::clone. |
| 229 SkBitmapHeap* heap = SkNEW(SkBitmapHeap); | 229 SkBitmapHeap* heap = SkNEW(SkBitmapHeap); |
| 230 copyInfo.controller.setBitmapStorage(heap); | 230 copyInfo.controller.setBitmapStorage(heap); |
| 231 heap->unref(); | 231 heap->unref(); |
| 232 } else { | 232 } else { |
| 233 copyInfo.controller.setBitmapStorage(fPlayback->fBitmapHeap)
; | 233 copyInfo.controller.setBitmapStorage(fData->fBitmapHeap); |
| 234 } | 234 } |
| 235 | 235 |
| 236 SkDEBUGCODE(int heapSize = SafeCount(fPlayback->fBitmapHeap.get(
));) | 236 SkDEBUGCODE(int heapSize = SafeCount(fData->fBitmapHeap.get());) |
| 237 for (int i = 0; i < paintCount; i++) { | 237 for (int i = 0; i < paintCount; i++) { |
| 238 if (NeedsDeepCopy(fPlayback->fPaints->at(i))) { | 238 if (NeedsDeepCopy(fData->fPaints->at(i))) { |
| 239 copyInfo.paintData[i] = | 239 copyInfo.paintData[i] = |
| 240 SkFlatData::Create<SkPaint::FlatteningTraits>(©I
nfo.controller, | 240 SkFlatData::Create<SkPaint::FlatteningTraits>(©I
nfo.controller, |
| 241 fPlayback->fPaints
->at(i), 0); | 241 fData->fPaints->at
(i), 0); |
| 242 | 242 |
| 243 } else { | 243 } else { |
| 244 // this is our sentinel, which we use in the unflatten l
oop | 244 // this is our sentinel, which we use in the unflatten l
oop |
| 245 copyInfo.paintData[i] = NULL; | 245 copyInfo.paintData[i] = NULL; |
| 246 } | 246 } |
| 247 } | 247 } |
| 248 SkASSERT(SafeCount(fPlayback->fBitmapHeap.get()) == heapSize); | 248 SkASSERT(SafeCount(fData->fBitmapHeap.get()) == heapSize); |
| 249 | 249 |
| 250 // needed to create typeface playback | 250 // needed to create typeface playback |
| 251 copyInfo.controller.setupPlaybacks(); | 251 copyInfo.controller.setupPlaybacks(); |
| 252 copyInfo.initialized = true; | 252 copyInfo.initialized = true; |
| 253 } | 253 } |
| 254 | 254 |
| 255 clone->fPlayback.reset(SkNEW_ARGS(SkPicturePlayback, (*fPlayback, &c
opyInfo))); | 255 clone->fData.reset(SkNEW_ARGS(SkPictureData, (*fData, ©Info))); |
| 256 clone->fUniqueID = this->uniqueID(); // need to call method to ensur
e != 0 | 256 clone->fUniqueID = this->uniqueID(); // need to call method to ensur
e != 0 |
| 257 } | 257 } |
| 258 } | 258 } |
| 259 } | 259 } |
| 260 #endif//SK_SUPPORT_LEGACY_PICTURE_CLONE | 260 #endif//SK_SUPPORT_LEGACY_PICTURE_CLONE |
| 261 | 261 |
| 262 // fRecord OK | 262 // fRecord OK |
| 263 void SkPicture::EXPERIMENTAL_addAccelData(const SkPicture::AccelData* data) cons
t { | 263 void SkPicture::EXPERIMENTAL_addAccelData(const SkPicture::AccelData* data) cons
t { |
| 264 fAccelData.reset(SkRef(data)); | 264 fAccelData.reset(SkRef(data)); |
| 265 } | 265 } |
| (...skipping 22 matching lines...) Expand all Loading... |
| 288 /////////////////////////////////////////////////////////////////////////////// | 288 /////////////////////////////////////////////////////////////////////////////// |
| 289 | 289 |
| 290 // fRecord OK | 290 // fRecord OK |
| 291 const SkPicture::OperationList& SkPicture::OperationList::InvalidList() { | 291 const SkPicture::OperationList& SkPicture::OperationList::InvalidList() { |
| 292 static OperationList gInvalid; | 292 static OperationList gInvalid; |
| 293 return gInvalid; | 293 return gInvalid; |
| 294 } | 294 } |
| 295 | 295 |
| 296 // fRecord TODO | 296 // fRecord TODO |
| 297 const SkPicture::OperationList& SkPicture::EXPERIMENTAL_getActiveOps(const SkIRe
ct& queryRect) const { | 297 const SkPicture::OperationList& SkPicture::EXPERIMENTAL_getActiveOps(const SkIRe
ct& queryRect) const { |
| 298 SkASSERT(NULL != fPlayback.get()); | 298 SkASSERT(NULL != fData.get()); |
| 299 if (NULL != fPlayback.get()) { | 299 if (NULL != fData.get()) { |
| 300 return fPlayback->getActiveOps(queryRect); | 300 return fData->getActiveOps(queryRect); |
| 301 } | 301 } |
| 302 return OperationList::InvalidList(); | 302 return OperationList::InvalidList(); |
| 303 } | 303 } |
| 304 | 304 |
| 305 // fRecord TODO | 305 // fRecord TODO |
| 306 size_t SkPicture::EXPERIMENTAL_curOpID() const { | 306 size_t SkPicture::EXPERIMENTAL_curOpID() const { |
| 307 if (NULL != fPlayback.get()) { | 307 if (NULL != fData.get()) { |
| 308 return fPlayback->curOpID(); | 308 return fData->curOpID(); |
| 309 } | 309 } |
| 310 return 0; | 310 return 0; |
| 311 } | 311 } |
| 312 | 312 |
| 313 // fRecord OK | 313 // fRecord OK |
| 314 void SkPicture::draw(SkCanvas* canvas, SkDrawPictureCallback* callback) const { | 314 void SkPicture::draw(SkCanvas* canvas, SkDrawPictureCallback* callback) const { |
| 315 SkASSERT(NULL != canvas); | 315 SkASSERT(NULL != canvas); |
| 316 SkASSERT(NULL != fPlayback.get() || NULL != fRecord.get()); | 316 SkASSERT(NULL != fData.get() || NULL != fRecord.get()); |
| 317 | 317 |
| 318 if (NULL != fPlayback.get()) { | 318 if (NULL != fData.get()) { |
| 319 fPlayback->draw(*canvas, callback); | 319 fData->draw(*canvas, callback); |
| 320 } | 320 } |
| 321 if (NULL != fRecord.get()) { | 321 if (NULL != fRecord.get()) { |
| 322 SkRecordDraw(*fRecord, canvas, callback); | 322 SkRecordDraw(*fRecord, canvas, callback); |
| 323 } | 323 } |
| 324 } | 324 } |
| 325 | 325 |
| 326 /////////////////////////////////////////////////////////////////////////////// | 326 /////////////////////////////////////////////////////////////////////////////// |
| 327 | 327 |
| 328 #include "SkStream.h" | 328 #include "SkStream.h" |
| 329 | 329 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 371 return false; | 371 return false; |
| 372 } | 372 } |
| 373 | 373 |
| 374 if (pInfo != NULL) { | 374 if (pInfo != NULL) { |
| 375 *pInfo = info; | 375 *pInfo = info; |
| 376 } | 376 } |
| 377 return true; | 377 return true; |
| 378 } | 378 } |
| 379 | 379 |
| 380 // fRecord OK | 380 // fRecord OK |
| 381 SkPicture::SkPicture(SkPicturePlayback* playback, int width, int height) | 381 SkPicture::SkPicture(SkPictureData* data, int width, int height) |
| 382 : fPlayback(playback) | 382 : fData(data) |
| 383 , fWidth(width) | 383 , fWidth(width) |
| 384 , fHeight(height) { | 384 , fHeight(height) { |
| 385 this->needsNewGenID(); | 385 this->needsNewGenID(); |
| 386 } | 386 } |
| 387 | 387 |
| 388 // fRecord OK | 388 // fRecord OK |
| 389 SkPicture* SkPicture::CreateFromStream(SkStream* stream, InstallPixelRefProc pro
c) { | 389 SkPicture* SkPicture::CreateFromStream(SkStream* stream, InstallPixelRefProc pro
c) { |
| 390 SkPictInfo info; | 390 SkPictInfo info; |
| 391 | 391 |
| 392 if (!InternalOnly_StreamIsSKP(stream, &info)) { | 392 if (!InternalOnly_StreamIsSKP(stream, &info)) { |
| 393 return NULL; | 393 return NULL; |
| 394 } | 394 } |
| 395 | 395 |
| 396 // Check to see if there is a playback to recreate. | 396 // Check to see if there is a playback to recreate. |
| 397 if (stream->readBool()) { | 397 if (stream->readBool()) { |
| 398 SkPicturePlayback* playback = SkPicturePlayback::CreateFromStream(stream
, info, proc); | 398 SkPictureData* data = SkPictureData::CreateFromStream(stream, info, proc
); |
| 399 if (NULL == playback) { | 399 if (NULL == data) { |
| 400 return NULL; | 400 return NULL; |
| 401 } | 401 } |
| 402 | 402 |
| 403 return SkNEW_ARGS(SkPicture, (playback, info.fWidth, info.fHeight)); | 403 return SkNEW_ARGS(SkPicture, (data, info.fWidth, info.fHeight)); |
| 404 } | 404 } |
| 405 | 405 |
| 406 return NULL; | 406 return NULL; |
| 407 } | 407 } |
| 408 | 408 |
| 409 // fRecord OK | 409 // fRecord OK |
| 410 SkPicture* SkPicture::CreateFromBuffer(SkReadBuffer& buffer) { | 410 SkPicture* SkPicture::CreateFromBuffer(SkReadBuffer& buffer) { |
| 411 SkPictInfo info; | 411 SkPictInfo info; |
| 412 | 412 |
| 413 if (!InternalOnly_BufferIsSKP(buffer, &info)) { | 413 if (!InternalOnly_BufferIsSKP(buffer, &info)) { |
| 414 return NULL; | 414 return NULL; |
| 415 } | 415 } |
| 416 | 416 |
| 417 // Check to see if there is a playback to recreate. | 417 // Check to see if there is a playback to recreate. |
| 418 if (buffer.readBool()) { | 418 if (buffer.readBool()) { |
| 419 SkPicturePlayback* playback = SkPicturePlayback::CreateFromBuffer(buffer
, info); | 419 SkPictureData* data = SkPictureData::CreateFromBuffer(buffer, info); |
| 420 if (NULL == playback) { | 420 if (NULL == data) { |
| 421 return NULL; | 421 return NULL; |
| 422 } | 422 } |
| 423 | 423 |
| 424 return SkNEW_ARGS(SkPicture, (playback, info.fWidth, info.fHeight)); | 424 return SkNEW_ARGS(SkPicture, (data, info.fWidth, info.fHeight)); |
| 425 } | 425 } |
| 426 | 426 |
| 427 return NULL; | 427 return NULL; |
| 428 } | 428 } |
| 429 | 429 |
| 430 // fRecord OK | 430 // fRecord OK |
| 431 void SkPicture::createHeader(SkPictInfo* info) const { | 431 void SkPicture::createHeader(SkPictInfo* info) const { |
| 432 // Copy magic bytes at the beginning of the header | 432 // Copy magic bytes at the beginning of the header |
| 433 SkASSERT(sizeof(kMagic) == 8); | 433 SkASSERT(sizeof(kMagic) == 8); |
| 434 SkASSERT(sizeof(kMagic) == sizeof(info->fMagic)); | 434 SkASSERT(sizeof(kMagic) == sizeof(info->fMagic)); |
| 435 memcpy(info->fMagic, kMagic, sizeof(kMagic)); | 435 memcpy(info->fMagic, kMagic, sizeof(kMagic)); |
| 436 | 436 |
| 437 // Set picture info after magic bytes in the header | 437 // Set picture info after magic bytes in the header |
| 438 info->fVersion = CURRENT_PICTURE_VERSION; | 438 info->fVersion = CURRENT_PICTURE_VERSION; |
| 439 info->fWidth = fWidth; | 439 info->fWidth = fWidth; |
| 440 info->fHeight = fHeight; | 440 info->fHeight = fHeight; |
| 441 info->fFlags = SkPictInfo::kCrossProcess_Flag; | 441 info->fFlags = SkPictInfo::kCrossProcess_Flag; |
| 442 // TODO: remove this flag, since we're always float (now) | 442 // TODO: remove this flag, since we're always float (now) |
| 443 info->fFlags |= SkPictInfo::kScalarIsFloat_Flag; | 443 info->fFlags |= SkPictInfo::kScalarIsFloat_Flag; |
| 444 | 444 |
| 445 if (8 == sizeof(void*)) { | 445 if (8 == sizeof(void*)) { |
| 446 info->fFlags |= SkPictInfo::kPtrIs64Bit_Flag; | 446 info->fFlags |= SkPictInfo::kPtrIs64Bit_Flag; |
| 447 } | 447 } |
| 448 } | 448 } |
| 449 | 449 |
| 450 // fRecord OK | 450 // fRecord OK |
| 451 void SkPicture::serialize(SkWStream* stream, EncodeBitmap encoder) const { | 451 void SkPicture::serialize(SkWStream* stream, EncodeBitmap encoder) const { |
| 452 const SkPicturePlayback* playback = fPlayback.get(); | 452 const SkPictureData* data = fData.get(); |
| 453 | 453 |
| 454 // If we're a new-format picture, backport to old format for serialization. | 454 // If we're a new-format picture, backport to old format for serialization. |
| 455 SkAutoTDelete<SkPicture> oldFormat; | 455 SkAutoTDelete<SkPicture> oldFormat; |
| 456 if (NULL == playback && NULL != fRecord.get()) { | 456 if (NULL == data && NULL != fRecord.get()) { |
| 457 oldFormat.reset(backport(*fRecord, fWidth, fHeight)); | 457 oldFormat.reset(backport(*fRecord, fWidth, fHeight)); |
| 458 playback = oldFormat->fPlayback.get(); | 458 data = oldFormat->fData.get(); |
| 459 SkASSERT(NULL != playback); | 459 SkASSERT(NULL != data); |
| 460 } | 460 } |
| 461 | 461 |
| 462 SkPictInfo info; | 462 SkPictInfo info; |
| 463 this->createHeader(&info); | 463 this->createHeader(&info); |
| 464 stream->write(&info, sizeof(info)); | 464 stream->write(&info, sizeof(info)); |
| 465 | 465 |
| 466 if (NULL != playback) { | 466 if (NULL != data) { |
| 467 stream->writeBool(true); | 467 stream->writeBool(true); |
| 468 playback->serialize(stream, encoder); | 468 data->serialize(stream, encoder); |
| 469 } else { | 469 } else { |
| 470 stream->writeBool(false); | 470 stream->writeBool(false); |
| 471 } | 471 } |
| 472 } | 472 } |
| 473 | 473 |
| 474 // fRecord OK | 474 // fRecord OK |
| 475 void SkPicture::WriteTagSize(SkWriteBuffer& buffer, uint32_t tag, size_t size) { | 475 void SkPicture::WriteTagSize(SkWriteBuffer& buffer, uint32_t tag, size_t size) { |
| 476 buffer.writeUInt(tag); | 476 buffer.writeUInt(tag); |
| 477 buffer.writeUInt(SkToU32(size)); | 477 buffer.writeUInt(SkToU32(size)); |
| 478 } | 478 } |
| 479 | 479 |
| 480 // fRecord OK | 480 // fRecord OK |
| 481 void SkPicture::WriteTagSize(SkWStream* stream, uint32_t tag, size_t size) { | 481 void SkPicture::WriteTagSize(SkWStream* stream, uint32_t tag, size_t size) { |
| 482 stream->write32(tag); | 482 stream->write32(tag); |
| 483 stream->write32(SkToU32(size)); | 483 stream->write32(SkToU32(size)); |
| 484 } | 484 } |
| 485 | 485 |
| 486 // fRecord OK | 486 // fRecord OK |
| 487 void SkPicture::flatten(SkWriteBuffer& buffer) const { | 487 void SkPicture::flatten(SkWriteBuffer& buffer) const { |
| 488 const SkPicturePlayback* playback = fPlayback.get(); | 488 const SkPictureData* data = fData.get(); |
| 489 | 489 |
| 490 // If we're a new-format picture, backport to old format for serialization. | 490 // If we're a new-format picture, backport to old format for serialization. |
| 491 SkAutoTDelete<SkPicture> oldFormat; | 491 SkAutoTDelete<SkPicture> oldFormat; |
| 492 if (NULL == playback && NULL != fRecord.get()) { | 492 if (NULL == data && NULL != fRecord.get()) { |
| 493 oldFormat.reset(backport(*fRecord, fWidth, fHeight)); | 493 oldFormat.reset(backport(*fRecord, fWidth, fHeight)); |
| 494 playback = oldFormat->fPlayback.get(); | 494 data = oldFormat->fData.get(); |
| 495 SkASSERT(NULL != playback); | 495 SkASSERT(NULL != data); |
| 496 } | 496 } |
| 497 | 497 |
| 498 SkPictInfo info; | 498 SkPictInfo info; |
| 499 this->createHeader(&info); | 499 this->createHeader(&info); |
| 500 buffer.writeByteArray(&info, sizeof(info)); | 500 buffer.writeByteArray(&info, sizeof(info)); |
| 501 | 501 |
| 502 if (NULL != playback) { | 502 if (NULL != data) { |
| 503 buffer.writeBool(true); | 503 buffer.writeBool(true); |
| 504 playback->flatten(buffer); | 504 data->flatten(buffer); |
| 505 } else { | 505 } else { |
| 506 buffer.writeBool(false); | 506 buffer.writeBool(false); |
| 507 } | 507 } |
| 508 } | 508 } |
| 509 | 509 |
| 510 #if SK_SUPPORT_GPU | 510 #if SK_SUPPORT_GPU |
| 511 // fRecord TODO | 511 // fRecord TODO |
| 512 bool SkPicture::suitableForGpuRasterization(GrContext* context, const char **rea
son) const { | 512 bool SkPicture::suitableForGpuRasterization(GrContext* context, const char **rea
son) const { |
| 513 if (NULL == fPlayback.get()) { | 513 if (NULL == fData.get()) { |
| 514 if (NULL != reason) { | 514 if (NULL != reason) { |
| 515 *reason = "Missing playback object."; | 515 *reason = "Missing internal data."; |
| 516 } | 516 } |
| 517 return false; | 517 return false; |
| 518 } | 518 } |
| 519 | 519 |
| 520 return fPlayback->suitableForGpuRasterization(context, reason); | 520 return fData->suitableForGpuRasterization(context, reason); |
| 521 } | 521 } |
| 522 #endif | 522 #endif |
| 523 | 523 |
| 524 // fRecord TODO | 524 // fRecord TODO |
| 525 bool SkPicture::willPlayBackBitmaps() const { | 525 bool SkPicture::willPlayBackBitmaps() const { |
| 526 if (!fPlayback.get()) { | 526 if (!fData.get()) { |
| 527 return false; | 527 return false; |
| 528 } | 528 } |
| 529 return fPlayback->containsBitmaps(); | 529 return fData->containsBitmaps(); |
| 530 } | 530 } |
| 531 | 531 |
| 532 #ifdef SK_BUILD_FOR_ANDROID | 532 #ifdef SK_BUILD_FOR_ANDROID |
| 533 // fRecord TODO, fix by switching Android to SkDrawPictureCallback, then deletin
g this method | 533 // fRecord TODO, fix by switching Android to SkDrawPictureCallback, then deletin
g this method |
| 534 void SkPicture::abortPlayback() { | 534 void SkPicture::abortPlayback() { |
| 535 if (NULL == fPlayback.get()) { | 535 if (NULL == fData.get()) { |
| 536 return; | 536 return; |
| 537 } | 537 } |
| 538 fPlayback->abort(); | 538 fData->abort(); |
| 539 } | 539 } |
| 540 #endif | 540 #endif |
| 541 | 541 |
| 542 // fRecord OK | 542 // fRecord OK |
| 543 static int32_t next_picture_generation_id() { | 543 static int32_t next_picture_generation_id() { |
| 544 static int32_t gPictureGenerationID = 0; | 544 static int32_t gPictureGenerationID = 0; |
| 545 // do a loop in case our global wraps around, as we never want to | 545 // do a loop in case our global wraps around, as we never want to |
| 546 // return a 0 | 546 // return a 0 |
| 547 int32_t genID; | 547 int32_t genID; |
| 548 do { | 548 do { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 559 return fUniqueID; | 559 return fUniqueID; |
| 560 } | 560 } |
| 561 | 561 |
| 562 // fRecord OK | 562 // fRecord OK |
| 563 SkPicture::SkPicture(int width, int height, SkRecord* record) | 563 SkPicture::SkPicture(int width, int height, SkRecord* record) |
| 564 : fWidth(width) | 564 : fWidth(width) |
| 565 , fHeight(height) | 565 , fHeight(height) |
| 566 , fRecord(record) { | 566 , fRecord(record) { |
| 567 this->needsNewGenID(); | 567 this->needsNewGenID(); |
| 568 } | 568 } |
| OLD | NEW |