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 |