Index: src/core/SkPicturePlayback.cpp |
=================================================================== |
--- src/core/SkPicturePlayback.cpp (revision 13850) |
+++ src/core/SkPicturePlayback.cpp (working copy) |
@@ -1,4 +1,3 @@ |
- |
/* |
* Copyright 2011 Google Inc. |
* |
@@ -69,7 +68,7 @@ |
record.validate(record.writeStream().bytesWritten(), 0); |
const SkWriter32& writer = record.writeStream(); |
- init(); |
+ this->init(); |
SkASSERT(!fOpData); |
if (writer.bytesWritten() == 0) { |
fOpData = SkData::NewEmpty(); |
@@ -261,6 +260,7 @@ |
fFactoryPlayback = NULL; |
fBoundingHierarchy = NULL; |
fStateTree = NULL; |
+ fCachedActiveOps = NULL; |
} |
SkPicturePlayback::~SkPicturePlayback() { |
@@ -271,6 +271,8 @@ |
SkSafeUnref(fBoundingHierarchy); |
SkSafeUnref(fStateTree); |
+ SkDELETE(fCachedActiveOps); |
+ |
for (int i = 0; i < fPictureCount; i++) { |
fPictureRefs[i]->unref(); |
} |
@@ -754,11 +756,16 @@ |
// The activeOps parameter is actually "const SkTDArray<SkPictureStateTree::Draw*>&". |
// It represents the operations about to be drawn, as generated by some spatial |
// subdivision helper class. It should already be in 'fOffset' sorted order. |
-void SkPicturePlayback::preLoadBitmaps(const SkTDArray<void*>& activeOps) { |
- if (0 == activeOps.count() || NULL == fBitmapUseOffsets) { |
+void SkPicturePlayback::preLoadBitmaps(const SkTDArray<void*>* activeOps) { |
+ if ((NULL != activeOps && 0 == activeOps->count()) || NULL == fBitmapUseOffsets) { |
return; |
} |
+ if (NULL == activeOps) { |
+ // going to need everything |
+ return; |
+ } |
+ |
SkTDArray<int> active; |
SkAutoTDeleteArray<bool> needToCheck(new bool[fBitmapUseOffsets->numIDs()]); |
@@ -766,10 +773,10 @@ |
needToCheck.get()[i] = true; |
} |
- uint32_t max = ((SkPictureStateTree::Draw*)activeOps[activeOps.count()-1])->fOffset; |
+ uint32_t max = ((SkPictureStateTree::Draw*)(*activeOps)[(*activeOps).count()-1])->fOffset; |
- for (int i = 0; i < activeOps.count(); ++i) { |
- SkPictureStateTree::Draw* draw = (SkPictureStateTree::Draw*) activeOps[i]; |
+ for (int i = 0; i < activeOps->count(); ++i) { |
+ SkPictureStateTree::Draw* draw = (SkPictureStateTree::Draw*) (*activeOps)[i]; |
for (int j = 0; j < fBitmapUseOffsets->numIDs(); ++j) { |
if (!needToCheck.get()[j]) { |
@@ -795,6 +802,42 @@ |
} |
} |
+uint32_t SkPicturePlayback::CachedOperationList::offset(int index) const { |
+ SkASSERT(index < fOps.count()); |
+ return ((SkPictureStateTree::Draw*)fOps[index])->fOffset; |
+} |
+ |
+const SkMatrix& SkPicturePlayback::CachedOperationList::matrix(int index) const { |
+ SkASSERT(index < fOps.count()); |
+ return *((SkPictureStateTree::Draw*)fOps[index])->fMatrix; |
+} |
+ |
+const SkPicture::OperationList& SkPicturePlayback::getActiveOps(const SkIRect& query) { |
+ if (NULL == fStateTree || NULL == fBoundingHierarchy) { |
+ return SkPicture::OperationList::InvalidList(); |
+ } |
+ |
+ if (NULL == fCachedActiveOps) { |
+ fCachedActiveOps = SkNEW(CachedOperationList); |
+ } |
+ |
+ if (query == fCachedActiveOps->fCacheQueryRect) { |
+ return *fCachedActiveOps; |
+ } |
+ |
+ fCachedActiveOps->fOps.rewind(); |
+ |
+ fBoundingHierarchy->search(query, &(fCachedActiveOps->fOps)); |
+ if (0 != fCachedActiveOps->fOps.count()) { |
+ SkTQSort<SkPictureStateTree::Draw>( |
+ reinterpret_cast<SkPictureStateTree::Draw**>(fCachedActiveOps->fOps.begin()), |
+ reinterpret_cast<SkPictureStateTree::Draw**>(fCachedActiveOps->fOps.end()-1)); |
+ } |
+ |
+ fCachedActiveOps->fCacheQueryRect = query; |
+ return *fCachedActiveOps; |
+} |
+ |
void SkPicturePlayback::draw(SkCanvas& canvas, SkDrawPictureCallback* callback) { |
#ifdef ENABLE_TIME_DRAW |
SkAutoTime at("SkPicture::draw", 50); |
@@ -815,26 +858,29 @@ |
SkReader32 reader(fOpData->bytes(), fOpData->size()); |
TextContainer text; |
- SkTDArray<void*> activeOps; |
+ const SkTDArray<void*>* activeOps = NULL; |
if (NULL != fStateTree && NULL != fBoundingHierarchy) { |
SkRect clipBounds; |
if (canvas.getClipBounds(&clipBounds)) { |
SkIRect query; |
clipBounds.roundOut(&query); |
- fBoundingHierarchy->search(query, &activeOps); |
- if (activeOps.count() == 0) { |
- return; |
+ |
+ const SkPicture::OperationList& activeOpsList = this->getActiveOps(query); |
+ if (activeOpsList.valid()) { |
+ if (0 == activeOpsList.numOps()) { |
+ return; // nothing to draw |
+ } |
+ |
+ // Since the opList is valid we know it is our derived class |
+ activeOps = &((const CachedOperationList&)activeOpsList).fOps; |
} |
- SkTQSort<SkPictureStateTree::Draw>( |
- reinterpret_cast<SkPictureStateTree::Draw**>(activeOps.begin()), |
- reinterpret_cast<SkPictureStateTree::Draw**>(activeOps.end()-1)); |
} |
} |
- SkPictureStateTree::Iterator it = (NULL == fStateTree) ? |
+ SkPictureStateTree::Iterator it = (NULL == activeOps) ? |
SkPictureStateTree::Iterator() : |
- fStateTree->getIterator(activeOps, &canvas); |
+ fStateTree->getIterator(*activeOps, &canvas); |
if (it.isValid()) { |
uint32_t skipTo = it.draw(); |