Chromium Code Reviews| Index: src/core/SkPicturePlayback.cpp |
| =================================================================== |
| --- src/core/SkPicturePlayback.cpp (revision 13766) |
| +++ src/core/SkPicturePlayback.cpp (working copy) |
| @@ -69,7 +69,7 @@ |
| record.validate(record.writeStream().bytesWritten(), 0); |
| const SkWriter32& writer = record.writeStream(); |
| - init(); |
| + this->init(); |
| if (writer.bytesWritten() == 0) { |
| fOpData = SkData::NewEmpty(); |
| return; |
| @@ -267,6 +267,8 @@ |
| fFactoryPlayback = NULL; |
| fBoundingHierarchy = NULL; |
| fStateTree = NULL; |
| + fCacheQueryRect.setEmpty(); |
| + fCachedActiveOps = NULL; |
| } |
| SkPicturePlayback::~SkPicturePlayback() { |
| @@ -277,6 +279,8 @@ |
| SkSafeUnref(fBoundingHierarchy); |
| SkSafeUnref(fStateTree); |
| + SkDELETE(fCachedActiveOps); |
| + |
| for (int i = 0; i < fPictureCount; i++) { |
| fPictureRefs[i]->unref(); |
| } |
| @@ -760,11 +764,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()]); |
| @@ -772,10 +781,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]) { |
| @@ -801,6 +810,31 @@ |
| } |
| } |
| +const SkTDArray<void*>* SkPicturePlayback::getActiveOps(const SkIRect& query) { |
| + if (NULL == fStateTree || NULL == fBoundingHierarchy) { |
| + return NULL; |
| + } |
| + |
| + if (query == fCacheQueryRect) { |
| + return fCachedActiveOps; |
| + } |
| + |
| + if (NULL == fCachedActiveOps) { |
| + fCachedActiveOps = SkNEW(SkTDArray<void*>); |
| + } |
| + |
| + fCachedActiveOps->rewind(); |
| + |
| + fBoundingHierarchy->search(query, fCachedActiveOps); |
| + |
| + SkTQSort<SkPictureStateTree::Draw>( |
|
bsalomon
2014/03/13 17:59:34
Is this sorting by offset?
robertphillips
2014/03/14 17:59:34
Yep - that is pre-existing behavior.
|
| + reinterpret_cast<SkPictureStateTree::Draw**>(fCachedActiveOps->begin()), |
| + reinterpret_cast<SkPictureStateTree::Draw**>(fCachedActiveOps->end()-1)); |
| + |
| + fCacheQueryRect = query; |
| + return fCachedActiveOps; |
| +} |
| + |
| void SkPicturePlayback::draw(SkCanvas& canvas, SkDrawPictureCallback* callback) { |
| #ifdef ENABLE_TIME_DRAW |
| SkAutoTime at("SkPicture::draw", 50); |
| @@ -821,26 +855,24 @@ |
| 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; |
| + |
| + activeOps = this->getActiveOps(query); |
| + if (NULL != activeOps && 0 == activeOps->count()) { |
| + return; // nothing to draw |
| } |
| - 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(); |