| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
| 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 #include <new> |
| 9 #include "SkBBoxHierarchy.h" |
| 10 #include "SkOffsetTable.h" |
| 8 #include "SkPicturePlayback.h" | 11 #include "SkPicturePlayback.h" |
| 9 #include "SkPictureRecord.h" | 12 #include "SkPictureRecord.h" |
| 13 #include "SkPictureStateTree.h" |
| 14 #include "SkReadBuffer.h" |
| 10 #include "SkTypeface.h" | 15 #include "SkTypeface.h" |
| 11 #include "SkReadBuffer.h" | 16 #include "SkTSort.h" |
| 12 #include "SkWriteBuffer.h" | 17 #include "SkWriteBuffer.h" |
| 13 #include <new> | |
| 14 #include "SkBBoxHierarchy.h" | |
| 15 #include "SkPictureStateTree.h" | |
| 16 #include "SkTSort.h" | |
| 17 | 18 |
| 18 template <typename T> int SafeCount(const T* obj) { | 19 template <typename T> int SafeCount(const T* obj) { |
| 19 return obj ? obj->count() : 0; | 20 return obj ? obj->count() : 0; |
| 20 } | 21 } |
| 21 | 22 |
| 22 /* Define this to spew out a debug statement whenever we skip the remainder of | 23 /* Define this to spew out a debug statement whenever we skip the remainder of |
| 23 a save/restore block because a clip... command returned false (empty). | 24 a save/restore block because a clip... command returned false (empty). |
| 24 */ | 25 */ |
| 25 #define SPEW_CLIP_SKIPPINGx | 26 #define SPEW_CLIP_SKIPPINGx |
| 26 | 27 |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 | 95 |
| 95 // copy over the refcnt dictionary to our reader | 96 // copy over the refcnt dictionary to our reader |
| 96 record.fFlattenableHeap.setupPlaybacks(); | 97 record.fFlattenableHeap.setupPlaybacks(); |
| 97 | 98 |
| 98 fBitmaps = record.fBitmapHeap->extractBitmaps(); | 99 fBitmaps = record.fBitmapHeap->extractBitmaps(); |
| 99 fPaints = record.fPaints.unflattenToArray(); | 100 fPaints = record.fPaints.unflattenToArray(); |
| 100 | 101 |
| 101 fBitmapHeap.reset(SkSafeRef(record.fBitmapHeap)); | 102 fBitmapHeap.reset(SkSafeRef(record.fBitmapHeap)); |
| 102 fPathHeap.reset(SkSafeRef(record.fPathHeap)); | 103 fPathHeap.reset(SkSafeRef(record.fPathHeap)); |
| 103 | 104 |
| 105 fBitmapUseOffsets.reset(SkSafeRef(record.fBitmapUseOffsets.get())); |
| 106 |
| 104 // ensure that the paths bounds are pre-computed | 107 // ensure that the paths bounds are pre-computed |
| 105 if (fPathHeap.get()) { | 108 if (fPathHeap.get()) { |
| 106 for (int i = 0; i < fPathHeap->count(); i++) { | 109 for (int i = 0; i < fPathHeap->count(); i++) { |
| 107 (*fPathHeap)[i].updateBoundsCache(); | 110 (*fPathHeap)[i].updateBoundsCache(); |
| 108 } | 111 } |
| 109 } | 112 } |
| 110 | 113 |
| 111 const SkTDArray<SkPicture* >& pictures = record.getPictureRefs(); | 114 const SkTDArray<SkPicture* >& pictures = record.getPictureRefs(); |
| 112 fPictureCount = pictures.count(); | 115 fPictureCount = pictures.count(); |
| 113 if (fPictureCount > 0) { | 116 if (fPictureCount > 0) { |
| (...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 711 *size = 0; | 714 *size = 0; |
| 712 } else { | 715 } else { |
| 713 UNPACK_8_24(temp, op, *size); | 716 UNPACK_8_24(temp, op, *size); |
| 714 if (MASK_24 == *size) { | 717 if (MASK_24 == *size) { |
| 715 *size = reader->readInt(); | 718 *size = reader->readInt(); |
| 716 } | 719 } |
| 717 } | 720 } |
| 718 return (DrawType) op; | 721 return (DrawType) op; |
| 719 } | 722 } |
| 720 | 723 |
| 724 // The activeOps parameter is actually "const SkTDArray<SkPictureStateTree::Draw
*>&". |
| 725 // It represents the operations about to be drawn, as generated by some spatial |
| 726 // subdivision helper class. It should already be in 'fOffset' sorted order. |
| 727 void SkPicturePlayback::preLoadBitmaps(const SkTDArray<void*>& activeOps) { |
| 728 if (0 == activeOps.count() || NULL == fBitmapUseOffsets) { |
| 729 return; |
| 730 } |
| 731 |
| 732 SkTDArray<int> active; |
| 733 |
| 734 SkAutoTDeleteArray<bool> needToCheck(new bool[fBitmapUseOffsets->numIDs()]); |
| 735 for (int i = 0; i < fBitmapUseOffsets->numIDs(); ++i) { |
| 736 needToCheck.get()[i] = true; |
| 737 } |
| 738 |
| 739 uint32_t max = ((SkPictureStateTree::Draw*)activeOps[activeOps.count()-1])->
fOffset; |
| 740 |
| 741 for (int i = 0; i < activeOps.count(); ++i) { |
| 742 SkPictureStateTree::Draw* draw = (SkPictureStateTree::Draw*) activeOps[i
]; |
| 743 |
| 744 for (int j = 0; j < fBitmapUseOffsets->numIDs(); ++j) { |
| 745 if (!needToCheck.get()[j]) { |
| 746 continue; |
| 747 } |
| 748 |
| 749 if (!fBitmapUseOffsets->overlap(j, draw->fOffset, max)) { |
| 750 needToCheck.get()[j] = false; |
| 751 continue; |
| 752 } |
| 753 |
| 754 if (!fBitmapUseOffsets->includes(j, draw->fOffset)) { |
| 755 continue; |
| 756 } |
| 757 |
| 758 *active.append() = j; |
| 759 needToCheck.get()[j] = false; |
| 760 } |
| 761 } |
| 762 |
| 763 for (int i = 0; i < active.count(); ++i) { |
| 764 SkDebugf("preload texture %d\n", active[i]); |
| 765 } |
| 766 } |
| 767 |
| 721 void SkPicturePlayback::draw(SkCanvas& canvas, SkDrawPictureCallback* callback)
{ | 768 void SkPicturePlayback::draw(SkCanvas& canvas, SkDrawPictureCallback* callback)
{ |
| 722 #ifdef ENABLE_TIME_DRAW | 769 #ifdef ENABLE_TIME_DRAW |
| 723 SkAutoTime at("SkPicture::draw", 50); | 770 SkAutoTime at("SkPicture::draw", 50); |
| 724 #endif | 771 #endif |
| 725 | 772 |
| 726 #ifdef SPEW_CLIP_SKIPPING | 773 #ifdef SPEW_CLIP_SKIPPING |
| 727 SkipClipRec skipRect, skipRRect, skipRegion, skipPath, skipCull; | 774 SkipClipRec skipRect, skipRRect, skipRegion, skipPath, skipCull; |
| 728 int opCount = 0; | 775 int opCount = 0; |
| 729 #endif | 776 #endif |
| 730 | 777 |
| 731 #ifdef SK_BUILD_FOR_ANDROID | 778 #ifdef SK_BUILD_FOR_ANDROID |
| 732 SkAutoMutexAcquire autoMutex(fDrawMutex); | 779 SkAutoMutexAcquire autoMutex(fDrawMutex); |
| 733 #endif | 780 #endif |
| 734 | 781 |
| 735 // kDrawComplete will be the signal that we have reached the end of | 782 // kDrawComplete will be the signal that we have reached the end of |
| 736 // the command stream | 783 // the command stream |
| 737 static const uint32_t kDrawComplete = SK_MaxU32; | 784 static const uint32_t kDrawComplete = SK_MaxU32; |
| 738 | 785 |
| 739 SkReader32 reader(fOpData->bytes(), fOpData->size()); | 786 SkReader32 reader(fOpData->bytes(), fOpData->size()); |
| 740 TextContainer text; | 787 TextContainer text; |
| 741 SkTDArray<void*> results; | 788 SkTDArray<void*> activeOps; |
| 742 | 789 |
| 743 if (NULL != fStateTree && NULL != fBoundingHierarchy) { | 790 if (NULL != fStateTree && NULL != fBoundingHierarchy) { |
| 744 SkRect clipBounds; | 791 SkRect clipBounds; |
| 745 if (canvas.getClipBounds(&clipBounds)) { | 792 if (canvas.getClipBounds(&clipBounds)) { |
| 746 SkIRect query; | 793 SkIRect query; |
| 747 clipBounds.roundOut(&query); | 794 clipBounds.roundOut(&query); |
| 748 fBoundingHierarchy->search(query, &results); | 795 fBoundingHierarchy->search(query, &activeOps); |
| 749 if (results.count() == 0) { | 796 if (activeOps.count() == 0) { |
| 750 return; | 797 return; |
| 751 } | 798 } |
| 752 SkTQSort<SkPictureStateTree::Draw>( | 799 SkTQSort<SkPictureStateTree::Draw>( |
| 753 reinterpret_cast<SkPictureStateTree::Draw**>(results.begin()), | 800 reinterpret_cast<SkPictureStateTree::Draw**>(activeOps.begin()), |
| 754 reinterpret_cast<SkPictureStateTree::Draw**>(results.end()-1)); | 801 reinterpret_cast<SkPictureStateTree::Draw**>(activeOps.end()-1))
; |
| 755 } | 802 } |
| 756 } | 803 } |
| 757 | 804 |
| 758 SkPictureStateTree::Iterator it = (NULL == fStateTree) ? | 805 SkPictureStateTree::Iterator it = (NULL == fStateTree) ? |
| 759 SkPictureStateTree::Iterator() : | 806 SkPictureStateTree::Iterator() : |
| 760 fStateTree->getIterator(results, &canvas); | 807 fStateTree->getIterator(activeOps, &canvas); |
| 761 | 808 |
| 762 if (it.isValid()) { | 809 if (it.isValid()) { |
| 763 uint32_t skipTo = it.draw(); | 810 uint32_t skipTo = it.draw(); |
| 764 if (kDrawComplete == skipTo) { | 811 if (kDrawComplete == skipTo) { |
| 765 return; | 812 return; |
| 766 } | 813 } |
| 767 reader.setOffset(skipTo); | 814 reader.setOffset(skipTo); |
| 768 } | 815 } |
| 769 | 816 |
| 817 this->preLoadBitmaps(activeOps); |
| 818 |
| 770 // Record this, so we can concat w/ it if we encounter a setMatrix() | 819 // Record this, so we can concat w/ it if we encounter a setMatrix() |
| 771 SkMatrix initialMatrix = canvas.getTotalMatrix(); | 820 SkMatrix initialMatrix = canvas.getTotalMatrix(); |
| 772 int originalSaveCount = canvas.getSaveCount(); | 821 int originalSaveCount = canvas.getSaveCount(); |
| 773 | 822 |
| 774 #ifdef SK_BUILD_FOR_ANDROID | 823 #ifdef SK_BUILD_FOR_ANDROID |
| 775 fAbortCurrentPlayback = false; | 824 fAbortCurrentPlayback = false; |
| 776 #endif | 825 #endif |
| 777 | 826 |
| 778 #ifdef SK_DEVELOPER | 827 #ifdef SK_DEVELOPER |
| 779 int opIndex = -1; | 828 int opIndex = -1; |
| (...skipping 900 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1680 for (index = 0; index < fPictureCount; index++) | 1729 for (index = 0; index < fPictureCount; index++) |
| 1681 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer
), | 1730 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer
), |
| 1682 "picture%p, ", fPictureRefs[index]); | 1731 "picture%p, ", fPictureRefs[index]); |
| 1683 if (fPictureCount > 0) | 1732 if (fPictureCount > 0) |
| 1684 SkDebugf("%s0};\n", pBuffer); | 1733 SkDebugf("%s0};\n", pBuffer); |
| 1685 | 1734 |
| 1686 const_cast<SkPicturePlayback*>(this)->dumpStream(); | 1735 const_cast<SkPicturePlayback*>(this)->dumpStream(); |
| 1687 } | 1736 } |
| 1688 | 1737 |
| 1689 #endif | 1738 #endif |
| OLD | NEW |