| Index: src/core/SkPictureStateTree.cpp
|
| diff --git a/src/core/SkPictureStateTree.cpp b/src/core/SkPictureStateTree.cpp
|
| index 21ae3cb9f09f466036057ab2b1f9c640cea7d962..f6d54ffedc49e55a0a4fbb5389b1da3cd729cb57 100644
|
| --- a/src/core/SkPictureStateTree.cpp
|
| +++ b/src/core/SkPictureStateTree.cpp
|
| @@ -99,24 +99,41 @@ 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) {
|
| +
|
| + for (fCurrentNode = fCurrentNode->fParent; fCurrentNode;
|
| + fCurrentNode = fCurrentNode->fParent) {
|
| + // Note: we call restore() twice when both flags are set.
|
| if (fCurrentNode->fFlags & Node::kSave_Flag) {
|
| fCanvas->restore();
|
| }
|
| if (fCurrentNode->fFlags & Node::kSaveLayer_Flag) {
|
| fCanvas->restore();
|
| }
|
| - fCurrentNode = fCurrentNode->fParent;
|
| }
|
| +
|
| + fCanvas->setMatrix(fPlaybackMatrix);
|
| + fCurrentMatrix = NULL;
|
| return kDrawComplete;
|
| }
|
|
|
| @@ -124,10 +141,7 @@ uint32_t SkPictureStateTree::Iterator::draw() {
|
| Node* targetNode = draw->fNode;
|
|
|
| if (fSave) {
|
| - // 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();
|
| fSave = false;
|
| }
|
|
|
| @@ -148,9 +162,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;
|
| }
|
| @@ -163,12 +181,11 @@ uint32_t SkPictureStateTree::Iterator::draw() {
|
| 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;
|
| @@ -177,29 +194,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;
|
|
|