diff options
-rw-r--r-- | src/core/SkPicturePlayback.cpp | 6 | ||||
-rw-r--r-- | src/core/SkPictureStateTree.cpp | 64 | ||||
-rw-r--r-- | src/core/SkPictureStateTree.h | 8 |
3 files changed, 46 insertions, 32 deletions
diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp index 05a60e8db4..514769dbac 100644 --- a/src/core/SkPicturePlayback.cpp +++ b/src/core/SkPicturePlayback.cpp @@ -862,7 +862,7 @@ void SkPicturePlayback::draw(SkCanvas& canvas, SkDrawPictureCallback* callback) fStateTree->getIterator(*activeOps, &canvas); if (it.isValid()) { - uint32_t skipTo = it.draw(); + uint32_t skipTo = it.nextDraw(); if (kDrawComplete == skipTo) { return; } @@ -918,7 +918,7 @@ void SkPicturePlayback::draw(SkCanvas& canvas, SkDrawPictureCallback* callback) // iterator until at or after skipTo uint32_t adjustedSkipTo; do { - adjustedSkipTo = it.draw(); + adjustedSkipTo = it.nextDraw(); } while (adjustedSkipTo < skipTo); skipTo = adjustedSkipTo; } @@ -1257,7 +1257,7 @@ void SkPicturePlayback::draw(SkCanvas& canvas, SkDrawPictureCallback* callback) #endif if (it.isValid()) { - uint32_t skipTo = it.draw(); + uint32_t skipTo = it.nextDraw(); if (kDrawComplete == skipTo) { break; } diff --git a/src/core/SkPictureStateTree.cpp b/src/core/SkPictureStateTree.cpp index 891d04ca21..20a826aa92 100644 --- a/src/core/SkPictureStateTree.cpp +++ b/src/core/SkPictureStateTree.cpp @@ -99,24 +99,39 @@ SkPictureStateTree::Iterator::Iterator(const SkTDArray<void*>& draws, SkCanvas* , fValid(true) { } -uint32_t SkPictureStateTree::Iterator::draw() { +void SkPictureStateTree::Iterator::setCurrentMatrix(const SkMatrix* matrix) { + SkASSERT(NULL != matrix); + + if (matrix == fCurrentMatrix) { + return; + } + + // The matrix is in recording space, but we also inherit + // a playback matrix from out target canvas. + SkMatrix m = *matrix; + m.postConcat(fPlaybackMatrix); + fCanvas->setMatrix(m); + fCurrentMatrix = matrix; +} + +uint32_t SkPictureStateTree::Iterator::nextDraw() { SkASSERT(this->isValid()); if (fPlaybackIndex >= fDraws->count()) { - // restore back to where we started - fCanvas->setMatrix(fPlaybackMatrix); if (fCurrentNode->fFlags & Node::kSaveLayer_Flag) { fCanvas->restore(); } - fCurrentNode = fCurrentNode->fParent; - while (NULL != fCurrentNode) { - if (fCurrentNode->fFlags & Node::kSave_Flag) { - fCanvas->restore(); - } - if (fCurrentNode->fFlags & Node::kSaveLayer_Flag) { + + for (fCurrentNode = fCurrentNode->fParent; fCurrentNode; + fCurrentNode = fCurrentNode->fParent) { + if (fCurrentNode->fFlags & (Node::kSave_Flag | Node::kSaveLayer_Flag)) { fCanvas->restore(); } - fCurrentNode = fCurrentNode->fParent; } + + // restore back to where we started + fCanvas->setMatrix(fPlaybackMatrix); + fCurrentMatrix = NULL; + return kDrawComplete; } @@ -145,9 +160,13 @@ uint32_t SkPictureStateTree::Iterator::draw() { if (currentLevel >= targetLevel) { if (tmp != fCurrentNode && tmp->fFlags & Node::kSave_Flag) { fCanvas->restore(); + // restore() may change the matrix, so we need to reapply. + fCurrentMatrix = NULL; } if (tmp->fFlags & Node::kSaveLayer_Flag) { fCanvas->restore(); + // restore() may change the matrix, so we need to reapply. + fCurrentMatrix = NULL; } tmp = tmp->fParent; } @@ -155,17 +174,19 @@ uint32_t SkPictureStateTree::Iterator::draw() { fNodes.push(ancestor); ancestor = ancestor->fParent; } + + SkASSERT(NULL != tmp); + SkASSERT(NULL != ancestor); } if (ancestor->fFlags & Node::kSave_Flag) { if (fCurrentNode != ancestor) { fCanvas->restore(); + // restore() may change the matrix, so we need to reapply. + fCurrentMatrix = NULL; } if (targetNode != ancestor) { - // FIXME: the save below depends on soon-to-be-deprecated - // SaveFlags behavior: it relies on matrix changes persisting - // after restore. - fCanvas->save(SkCanvas::kClip_SaveFlag); + fCanvas->save(); } } fCurrentNode = ancestor; @@ -174,29 +195,18 @@ uint32_t SkPictureStateTree::Iterator::draw() { // If we're not at the target node yet, we'll need to return an offset to make the caller // apply the next clip or saveLayer. if (fCurrentNode != targetNode) { - if (fCurrentMatrix != fNodes.top()->fMatrix) { - fCurrentMatrix = fNodes.top()->fMatrix; - SkMatrix tmp = *fNodes.top()->fMatrix; - tmp.postConcat(fPlaybackMatrix); - fCanvas->setMatrix(tmp); - } uint32_t offset = fNodes.top()->fOffset; fCurrentNode = fNodes.top(); fSave = fCurrentNode != targetNode && fCurrentNode->fFlags & Node::kSave_Flag; fNodes.pop(); + this->setCurrentMatrix(fCurrentNode->fMatrix); return offset; } } // If we got this far, the clip/saveLayer state is all set, so we can proceed to set the matrix // for the draw, and return its offset. - - if (fCurrentMatrix != draw->fMatrix) { - SkMatrix tmp = *draw->fMatrix; - tmp.postConcat(fPlaybackMatrix); - fCanvas->setMatrix(tmp); - fCurrentMatrix = draw->fMatrix; - } + this->setCurrentMatrix(draw->fMatrix); ++fPlaybackIndex; return draw->fOffset; diff --git a/src/core/SkPictureStateTree.h b/src/core/SkPictureStateTree.h index 448c0d31ce..d61bf032cb 100644 --- a/src/core/SkPictureStateTree.h +++ b/src/core/SkPictureStateTree.h @@ -75,12 +75,16 @@ public: class Iterator { public: /** Returns the next offset into the picture stream, or kDrawComplete if complete. */ - uint32_t draw(); + uint32_t nextDraw(); static const uint32_t kDrawComplete = SK_MaxU32; Iterator() : fPlaybackMatrix(), fValid(false) { } bool isValid() const { return fValid; } + private: Iterator(const SkTDArray<void*>& draws, SkCanvas* canvas, Node* root); + + void setCurrentMatrix(const SkMatrix*); + // The draws this iterator is associated with const SkTDArray<void*>* fDraws; @@ -97,7 +101,7 @@ public: const SkMatrix fPlaybackMatrix; // Cache of current matrix, so we can avoid redundantly setting it - SkMatrix* fCurrentMatrix; + const SkMatrix* fCurrentMatrix; // current position in the array of draws int fPlaybackIndex; |