diff options
author | robertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2014-03-17 14:56:13 +0000 |
---|---|---|
committer | robertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2014-03-17 14:56:13 +0000 |
commit | 0b23f9e15f87363249cb66db2dd9918bc42d72ab (patch) | |
tree | 12c28a5bb6e9342732d30da5cffceb1790f58df4 /src/core/SkPicturePlayback.cpp | |
parent | d1c85d29204ad94950b23014c03e781409b9b682 (diff) |
Add a means of extracting active operations from SkPicture
https://codereview.chromium.org/195793010/
git-svn-id: http://skia.googlecode.com/svn/trunk@13831 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/core/SkPicturePlayback.cpp')
-rw-r--r-- | src/core/SkPicturePlayback.cpp | 76 |
1 files changed, 61 insertions, 15 deletions
diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp index d61e616c4d..c989061619 100644 --- a/src/core/SkPicturePlayback.cpp +++ b/src/core/SkPicturePlayback.cpp @@ -69,7 +69,7 @@ SkPicturePlayback::SkPicturePlayback(const SkPictureRecord& record, bool deepCop 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 +261,7 @@ void SkPicturePlayback::init() { fFactoryPlayback = NULL; fBoundingHierarchy = NULL; fStateTree = NULL; + fCachedActiveOps = NULL; } SkPicturePlayback::~SkPicturePlayback() { @@ -271,6 +272,8 @@ SkPicturePlayback::~SkPicturePlayback() { SkSafeUnref(fBoundingHierarchy); SkSafeUnref(fStateTree); + SkDELETE(fCachedActiveOps); + for (int i = 0; i < fPictureCount; i++) { fPictureRefs[i]->unref(); } @@ -754,8 +757,13 @@ static DrawType read_op_and_size(SkReader32* reader, uint32_t* size) { // 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; } @@ -766,10 +774,10 @@ void SkPicturePlayback::preLoadBitmaps(const SkTDArray<void*>& activeOps) { 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 +803,41 @@ void SkPicturePlayback::preLoadBitmaps(const SkTDArray<void*>& activeOps) { } } +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)); + + 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 @@ void SkPicturePlayback::draw(SkCanvas& canvas, SkDrawPictureCallback* callback) 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(); |