| 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 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 #ifdef SK_SUPPORT_LEGACY_DEFAULT_PICTURE_CTOR | 255 #ifdef SK_SUPPORT_LEGACY_DEFAULT_PICTURE_CTOR |
| 256 // fRecord OK | 256 // fRecord OK |
| 257 SkPicture::SkPicture() | 257 SkPicture::SkPicture() |
| 258 : fWidth(0) | 258 : fWidth(0) |
| 259 , fHeight(0) { | 259 , fHeight(0) { |
| 260 this->needsNewGenID(); | 260 this->needsNewGenID(); |
| 261 } | 261 } |
| 262 #endif | 262 #endif |
| 263 | 263 |
| 264 // fRecord OK | 264 // fRecord OK |
| 265 SkPicture::SkPicture(int width, int height, | 265 SkPicture::SkPicture(SkScalar width, SkScalar height, |
| 266 const SkPictureRecord& record, | 266 const SkPictureRecord& record, |
| 267 bool deepCopyOps) | 267 bool deepCopyOps) |
| 268 : fWidth(width) | 268 : fCullWidth(width) |
| 269 , fHeight(height) | 269 , fCullHeight(height) |
| 270 , fAnalysis() { | 270 , fAnalysis() { |
| 271 this->needsNewGenID(); | 271 this->needsNewGenID(); |
| 272 | 272 |
| 273 SkPictInfo info; | 273 SkPictInfo info; |
| 274 this->createHeader(&info); | 274 this->createHeader(&info); |
| 275 fData.reset(SkNEW_ARGS(SkPictureData, (record, info, deepCopyOps))); | 275 fData.reset(SkNEW_ARGS(SkPictureData, (record, info, deepCopyOps))); |
| 276 } | 276 } |
| 277 | 277 |
| 278 // Create an SkPictureData-backed SkPicture from an SkRecord. | 278 // Create an SkPictureData-backed SkPicture from an SkRecord. |
| 279 // This for compatibility with serialization code only. This is not cheap. | 279 // This for compatibility with serialization code only. This is not cheap. |
| 280 static SkPicture* backport(const SkRecord& src, int width, int height) { | 280 static SkPicture* backport(const SkRecord& src, const SkRect& cullRect) { |
| 281 SkPictureRecorder recorder; | 281 SkPictureRecorder recorder; |
| 282 SkRecordDraw(src, | 282 SkRecordDraw(src, |
| 283 recorder.DEPRECATED_beginRecording(width, height), NULL/*bbh*/,
NULL/*callback*/); | 283 recorder.DEPRECATED_beginRecording(cullRect.width(), cullRect.h
eight()), |
| 284 NULL/*bbh*/, NULL/*callback*/); |
| 284 return recorder.endRecording(); | 285 return recorder.endRecording(); |
| 285 } | 286 } |
| 286 | 287 |
| 287 // fRecord OK | 288 // fRecord OK |
| 288 SkPicture::~SkPicture() { | 289 SkPicture::~SkPicture() { |
| 289 this->callDeletionListeners(); | 290 this->callDeletionListeners(); |
| 290 } | 291 } |
| 291 | 292 |
| 292 // fRecord OK | 293 // fRecord OK |
| 293 #ifdef SK_SUPPORT_LEGACY_PICTURE_CLONE | 294 #ifdef SK_SUPPORT_LEGACY_PICTURE_CLONE |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 344 } | 345 } |
| 345 | 346 |
| 346 // fRecord OK | 347 // fRecord OK |
| 347 void SkPicture::draw(SkCanvas* canvas, SkDrawPictureCallback* callback) const { | 348 void SkPicture::draw(SkCanvas* canvas, SkDrawPictureCallback* callback) const { |
| 348 SkASSERT(NULL != canvas); | 349 SkASSERT(NULL != canvas); |
| 349 SkASSERT(NULL != fData.get() || NULL != fRecord.get()); | 350 SkASSERT(NULL != fData.get() || NULL != fRecord.get()); |
| 350 | 351 |
| 351 // If the query contains the whole picture, don't bother with the BBH. | 352 // If the query contains the whole picture, don't bother with the BBH. |
| 352 SkRect clipBounds = { 0, 0, 0, 0 }; | 353 SkRect clipBounds = { 0, 0, 0, 0 }; |
| 353 (void)canvas->getClipBounds(&clipBounds); | 354 (void)canvas->getClipBounds(&clipBounds); |
| 354 const bool useBBH = !clipBounds.contains(SkRect::MakeWH(this->width(), this-
>height())); | 355 const bool useBBH = !clipBounds.contains(this->cullRect()); |
| 355 | 356 |
| 356 if (NULL != fData.get()) { | 357 if (NULL != fData.get()) { |
| 357 SkPicturePlayback playback(this); | 358 SkPicturePlayback playback(this); |
| 358 playback.setUseBBH(useBBH); | 359 playback.setUseBBH(useBBH); |
| 359 playback.draw(canvas, callback); | 360 playback.draw(canvas, callback); |
| 360 } | 361 } |
| 361 if (NULL != fRecord.get()) { | 362 if (NULL != fRecord.get()) { |
| 362 SkRecordDraw(*fRecord, canvas, useBBH ? fBBH.get() : NULL, callback); | 363 SkRecordDraw(*fRecord, canvas, useBBH ? fBBH.get() : NULL, callback); |
| 363 } | 364 } |
| 364 } | 365 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 385 | 386 |
| 386 // fRecord OK | 387 // fRecord OK |
| 387 bool SkPicture::InternalOnly_StreamIsSKP(SkStream* stream, SkPictInfo* pInfo) { | 388 bool SkPicture::InternalOnly_StreamIsSKP(SkStream* stream, SkPictInfo* pInfo) { |
| 388 if (NULL == stream) { | 389 if (NULL == stream) { |
| 389 return false; | 390 return false; |
| 390 } | 391 } |
| 391 | 392 |
| 392 // Check magic bytes. | 393 // Check magic bytes. |
| 393 SkPictInfo info; | 394 SkPictInfo info; |
| 394 SkASSERT(sizeof(kMagic) == sizeof(info.fMagic)); | 395 SkASSERT(sizeof(kMagic) == sizeof(info.fMagic)); |
| 395 if (!stream->read(&info, sizeof(info)) || !IsValidPictInfo(info)) { | 396 |
| 397 if (!stream->read(&info.fMagic, sizeof(kMagic))) { |
| 396 return false; | 398 return false; |
| 397 } | 399 } |
| 398 | 400 |
| 401 info.fVersion = stream->readU32(); |
| 402 |
| 403 #ifndef V35_COMPATIBILITY_CODE |
| 404 if (info.fVersion < 35) { |
| 405 info.fCullRect.fLeft = 0; |
| 406 info.fCullRect.fTop = 0; |
| 407 info.fCullRect.fRight = SkIntToScalar(stream->readU32()); |
| 408 info.fCullRect.fBottom = SkIntToScalar(stream->readU32()); |
| 409 } else { |
| 410 #endif |
| 411 info.fCullRect.fLeft = stream->readScalar(); |
| 412 info.fCullRect.fTop = stream->readScalar(); |
| 413 info.fCullRect.fRight = stream->readScalar(); |
| 414 info.fCullRect.fBottom = stream->readScalar(); |
| 415 #ifndef V35_COMPATIBILITY_CODE |
| 416 } |
| 417 #endif |
| 418 |
| 419 info.fFlags = stream->readU32(); |
| 420 |
| 421 if (!IsValidPictInfo(info)) { |
| 422 return false; |
| 423 } |
| 424 |
| 399 if (pInfo != NULL) { | 425 if (pInfo != NULL) { |
| 400 *pInfo = info; | 426 *pInfo = info; |
| 401 } | 427 } |
| 402 return true; | 428 return true; |
| 403 } | 429 } |
| 404 | 430 |
| 405 // fRecord OK | 431 // fRecord OK |
| 406 bool SkPicture::InternalOnly_BufferIsSKP(SkReadBuffer& buffer, SkPictInfo* pInfo
) { | 432 bool SkPicture::InternalOnly_BufferIsSKP(SkReadBuffer* buffer, SkPictInfo* pInfo
) { |
| 407 // Check magic bytes. | 433 // Check magic bytes. |
| 408 SkPictInfo info; | 434 SkPictInfo info; |
| 409 SkASSERT(sizeof(kMagic) == sizeof(info.fMagic)); | 435 SkASSERT(sizeof(kMagic) == sizeof(info.fMagic)); |
| 410 if (!buffer.readByteArray(&info, sizeof(info)) || !IsValidPictInfo(info)) { | 436 |
| 437 if (!buffer->readByteArray(&info.fMagic, sizeof(kMagic))) { |
| 411 return false; | 438 return false; |
| 412 } | 439 } |
| 413 | 440 |
| 441 info.fVersion = buffer->readUInt(); |
| 442 |
| 443 #ifndef V35_COMPATIBILITY_CODE |
| 444 if (info.fVersion < 35) { |
| 445 info.fCullRect.fLeft = 0; |
| 446 info.fCullRect.fTop = 0; |
| 447 info.fCullRect.fRight = SkIntToScalar(buffer->readUInt()); |
| 448 info.fCullRect.fBottom = SkIntToScalar(buffer->readUInt()); |
| 449 } else { |
| 450 #endif |
| 451 buffer->readRect(&info.fCullRect); |
| 452 #ifndef V35_COMPATIBILITY_CODE |
| 453 } |
| 454 #endif |
| 455 |
| 456 info.fFlags = buffer->readUInt(); |
| 457 |
| 458 if (!IsValidPictInfo(info)) { |
| 459 return false; |
| 460 } |
| 461 |
| 414 if (pInfo != NULL) { | 462 if (pInfo != NULL) { |
| 415 *pInfo = info; | 463 *pInfo = info; |
| 416 } | 464 } |
| 417 return true; | 465 return true; |
| 418 } | 466 } |
| 419 | 467 |
| 420 // fRecord OK | 468 // fRecord OK |
| 421 SkPicture::SkPicture(SkPictureData* data, int width, int height) | 469 SkPicture::SkPicture(SkPictureData* data, SkScalar width, SkScalar height) |
| 422 : fData(data) | 470 : fData(data) |
| 423 , fWidth(width) | 471 , fCullWidth(width) |
| 424 , fHeight(height) | 472 , fCullHeight(height) |
| 425 , fAnalysis() { | 473 , fAnalysis() { |
| 426 this->needsNewGenID(); | 474 this->needsNewGenID(); |
| 427 } | 475 } |
| 428 | 476 |
| 429 SkPicture* SkPicture::Forwardport(const SkPicture& src) { | 477 SkPicture* SkPicture::Forwardport(const SkPicture& src) { |
| 430 SkAutoTDelete<SkRecord> record(SkNEW(SkRecord)); | 478 SkAutoTDelete<SkRecord> record(SkNEW(SkRecord)); |
| 431 SkRecorder canvas(record.get(), src.width(), src.height()); | 479 SkRecorder canvas(record.get(), src.cullRect().width(), src.cullRect().heigh
t()); |
| 432 src.draw(&canvas); | 480 src.draw(&canvas); |
| 433 return SkNEW_ARGS(SkPicture, (src.width(), src.height(), record.detach(), NU
LL/*bbh*/)); | 481 return SkNEW_ARGS(SkPicture, (src.cullRect().width(), src.cullRect().height(
), |
| 482 record.detach(), NULL/*bbh*/)); |
| 434 } | 483 } |
| 435 | 484 |
| 436 // fRecord OK | 485 // fRecord OK |
| 437 SkPicture* SkPicture::CreateFromStream(SkStream* stream, InstallPixelRefProc pro
c) { | 486 SkPicture* SkPicture::CreateFromStream(SkStream* stream, InstallPixelRefProc pro
c) { |
| 438 SkPictInfo info; | 487 SkPictInfo info; |
| 439 | 488 |
| 440 if (!InternalOnly_StreamIsSKP(stream, &info)) { | 489 if (!InternalOnly_StreamIsSKP(stream, &info)) { |
| 441 return NULL; | 490 return NULL; |
| 442 } | 491 } |
| 443 | 492 |
| 444 // Check to see if there is a playback to recreate. | 493 // Check to see if there is a playback to recreate. |
| 445 if (stream->readBool()) { | 494 if (stream->readBool()) { |
| 446 SkPictureData* data = SkPictureData::CreateFromStream(stream, info, proc
); | 495 SkPictureData* data = SkPictureData::CreateFromStream(stream, info, proc
); |
| 447 if (NULL == data) { | 496 if (NULL == data) { |
| 448 return NULL; | 497 return NULL; |
| 449 } | 498 } |
| 450 const SkPicture src(data, info.fWidth, info.fHeight); | 499 const SkPicture src(data, info.fCullRect.width(), info.fCullRect.height(
)); |
| 451 return Forwardport(src); | 500 return Forwardport(src); |
| 452 } | 501 } |
| 453 | 502 |
| 454 return NULL; | 503 return NULL; |
| 455 } | 504 } |
| 456 | 505 |
| 457 // fRecord OK | 506 // fRecord OK |
| 458 SkPicture* SkPicture::CreateFromBuffer(SkReadBuffer& buffer) { | 507 SkPicture* SkPicture::CreateFromBuffer(SkReadBuffer& buffer) { |
| 459 SkPictInfo info; | 508 SkPictInfo info; |
| 460 | 509 |
| 461 if (!InternalOnly_BufferIsSKP(buffer, &info)) { | 510 if (!InternalOnly_BufferIsSKP(&buffer, &info)) { |
| 462 return NULL; | 511 return NULL; |
| 463 } | 512 } |
| 464 | 513 |
| 465 // Check to see if there is a playback to recreate. | 514 // Check to see if there is a playback to recreate. |
| 466 if (buffer.readBool()) { | 515 if (buffer.readBool()) { |
| 467 SkPictureData* data = SkPictureData::CreateFromBuffer(buffer, info); | 516 SkPictureData* data = SkPictureData::CreateFromBuffer(buffer, info); |
| 468 if (NULL == data) { | 517 if (NULL == data) { |
| 469 return NULL; | 518 return NULL; |
| 470 } | 519 } |
| 471 const SkPicture src(data, info.fWidth, info.fHeight); | 520 const SkPicture src(data, info.fCullRect.width(), info.fCullRect.height(
)); |
| 472 return Forwardport(src); | 521 return Forwardport(src); |
| 473 } | 522 } |
| 474 | 523 |
| 475 return NULL; | 524 return NULL; |
| 476 } | 525 } |
| 477 | 526 |
| 478 // fRecord OK | 527 // fRecord OK |
| 479 void SkPicture::createHeader(SkPictInfo* info) const { | 528 void SkPicture::createHeader(SkPictInfo* info) const { |
| 480 // Copy magic bytes at the beginning of the header | 529 // Copy magic bytes at the beginning of the header |
| 481 SkASSERT(sizeof(kMagic) == 8); | 530 SkASSERT(sizeof(kMagic) == 8); |
| 482 SkASSERT(sizeof(kMagic) == sizeof(info->fMagic)); | 531 SkASSERT(sizeof(kMagic) == sizeof(info->fMagic)); |
| 483 memcpy(info->fMagic, kMagic, sizeof(kMagic)); | 532 memcpy(info->fMagic, kMagic, sizeof(kMagic)); |
| 484 | 533 |
| 485 // Set picture info after magic bytes in the header | 534 // Set picture info after magic bytes in the header |
| 486 info->fVersion = CURRENT_PICTURE_VERSION; | 535 info->fVersion = CURRENT_PICTURE_VERSION; |
| 487 info->fWidth = fWidth; | 536 info->fCullRect = this->cullRect(); |
| 488 info->fHeight = fHeight; | |
| 489 info->fFlags = SkPictInfo::kCrossProcess_Flag; | 537 info->fFlags = SkPictInfo::kCrossProcess_Flag; |
| 490 // TODO: remove this flag, since we're always float (now) | 538 // TODO: remove this flag, since we're always float (now) |
| 491 info->fFlags |= SkPictInfo::kScalarIsFloat_Flag; | 539 info->fFlags |= SkPictInfo::kScalarIsFloat_Flag; |
| 492 | 540 |
| 493 if (8 == sizeof(void*)) { | 541 if (8 == sizeof(void*)) { |
| 494 info->fFlags |= SkPictInfo::kPtrIs64Bit_Flag; | 542 info->fFlags |= SkPictInfo::kPtrIs64Bit_Flag; |
| 495 } | 543 } |
| 496 } | 544 } |
| 497 | 545 |
| 498 // fRecord OK | 546 // fRecord OK |
| 499 void SkPicture::serialize(SkWStream* stream, EncodeBitmap encoder) const { | 547 void SkPicture::serialize(SkWStream* stream, EncodeBitmap encoder) const { |
| 500 const SkPictureData* data = fData.get(); | 548 const SkPictureData* data = fData.get(); |
| 501 | 549 |
| 502 // If we're a new-format picture, backport to old format for serialization. | 550 // If we're a new-format picture, backport to old format for serialization. |
| 503 SkAutoTDelete<SkPicture> oldFormat; | 551 SkAutoTDelete<SkPicture> oldFormat; |
| 504 if (NULL == data && NULL != fRecord.get()) { | 552 if (NULL == data && NULL != fRecord.get()) { |
| 505 oldFormat.reset(backport(*fRecord, fWidth, fHeight)); | 553 oldFormat.reset(backport(*fRecord, this->cullRect())); |
| 506 data = oldFormat->fData.get(); | 554 data = oldFormat->fData.get(); |
| 507 SkASSERT(NULL != data); | 555 SkASSERT(NULL != data); |
| 508 } | 556 } |
| 509 | 557 |
| 510 SkPictInfo info; | 558 SkPictInfo info; |
| 511 this->createHeader(&info); | 559 this->createHeader(&info); |
| 560 SkASSERT(sizeof(SkPictInfo) == 32); |
| 512 stream->write(&info, sizeof(info)); | 561 stream->write(&info, sizeof(info)); |
| 513 | 562 |
| 514 if (NULL != data) { | 563 if (NULL != data) { |
| 515 stream->writeBool(true); | 564 stream->writeBool(true); |
| 516 data->serialize(stream, encoder); | 565 data->serialize(stream, encoder); |
| 517 } else { | 566 } else { |
| 518 stream->writeBool(false); | 567 stream->writeBool(false); |
| 519 } | 568 } |
| 520 } | 569 } |
| 521 | 570 |
| 522 // fRecord OK | 571 // fRecord OK |
| 523 void SkPicture::flatten(SkWriteBuffer& buffer) const { | 572 void SkPicture::flatten(SkWriteBuffer& buffer) const { |
| 524 const SkPictureData* data = fData.get(); | 573 const SkPictureData* data = fData.get(); |
| 525 | 574 |
| 526 // If we're a new-format picture, backport to old format for serialization. | 575 // If we're a new-format picture, backport to old format for serialization. |
| 527 SkAutoTDelete<SkPicture> oldFormat; | 576 SkAutoTDelete<SkPicture> oldFormat; |
| 528 if (NULL == data && NULL != fRecord.get()) { | 577 if (NULL == data && NULL != fRecord.get()) { |
| 529 oldFormat.reset(backport(*fRecord, fWidth, fHeight)); | 578 oldFormat.reset(backport(*fRecord, this->cullRect())); |
| 530 data = oldFormat->fData.get(); | 579 data = oldFormat->fData.get(); |
| 531 SkASSERT(NULL != data); | 580 SkASSERT(NULL != data); |
| 532 } | 581 } |
| 533 | 582 |
| 534 SkPictInfo info; | 583 SkPictInfo info; |
| 535 this->createHeader(&info); | 584 this->createHeader(&info); |
| 536 buffer.writeByteArray(&info, sizeof(info)); | 585 buffer.writeByteArray(&info.fMagic, sizeof(info.fMagic)); |
| 586 buffer.writeUInt(info.fVersion); |
| 587 buffer.writeRect(info.fCullRect); |
| 588 buffer.writeUInt(info.fFlags); |
| 537 | 589 |
| 538 if (NULL != data) { | 590 if (NULL != data) { |
| 539 buffer.writeBool(true); | 591 buffer.writeBool(true); |
| 540 data->flatten(buffer); | 592 data->flatten(buffer); |
| 541 } else { | 593 } else { |
| 542 buffer.writeBool(false); | 594 buffer.writeBool(false); |
| 543 } | 595 } |
| 544 } | 596 } |
| 545 | 597 |
| 546 #if SK_SUPPORT_GPU | 598 #if SK_SUPPORT_GPU |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 598 | 650 |
| 599 // fRecord OK | 651 // fRecord OK |
| 600 uint32_t SkPicture::uniqueID() const { | 652 uint32_t SkPicture::uniqueID() const { |
| 601 if (SK_InvalidGenID == fUniqueID) { | 653 if (SK_InvalidGenID == fUniqueID) { |
| 602 fUniqueID = next_picture_generation_id(); | 654 fUniqueID = next_picture_generation_id(); |
| 603 } | 655 } |
| 604 return fUniqueID; | 656 return fUniqueID; |
| 605 } | 657 } |
| 606 | 658 |
| 607 // fRecord OK | 659 // fRecord OK |
| 608 SkPicture::SkPicture(int width, int height, SkRecord* record, SkBBoxHierarchy* b
bh) | 660 SkPicture::SkPicture(SkScalar width, SkScalar height, SkRecord* record, SkBBoxHi
erarchy* bbh) |
| 609 : fWidth(width) | 661 : fCullWidth(width) |
| 610 , fHeight(height) | 662 , fCullHeight(height) |
| 611 , fRecord(record) | 663 , fRecord(record) |
| 612 , fBBH(SkSafeRef(bbh)) | 664 , fBBH(SkSafeRef(bbh)) |
| 613 , fAnalysis(*record) { | 665 , fAnalysis(*record) { |
| 614 // TODO: delay as much of this work until just before first playback? | 666 // TODO: delay as much of this work until just before first playback? |
| 615 if (fBBH.get()) { | 667 if (fBBH.get()) { |
| 616 SkRecordFillBounds(*record, fBBH.get()); | 668 SkRecordFillBounds(*record, fBBH.get()); |
| 617 } | 669 } |
| 618 this->needsNewGenID(); | 670 this->needsNewGenID(); |
| 619 } | 671 } |
| 620 | 672 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 640 int SkPicture::approximateOpCount() const { | 692 int SkPicture::approximateOpCount() const { |
| 641 SkASSERT(fRecord.get() || fData.get()); | 693 SkASSERT(fRecord.get() || fData.get()); |
| 642 if (fRecord.get()) { | 694 if (fRecord.get()) { |
| 643 return fRecord->count(); | 695 return fRecord->count(); |
| 644 } | 696 } |
| 645 if (fData.get()) { | 697 if (fData.get()) { |
| 646 return fData->opCount(); | 698 return fData->opCount(); |
| 647 } | 699 } |
| 648 return 0; | 700 return 0; |
| 649 } | 701 } |
| OLD | NEW |