| Index: src/core/SkPictureStateTree.cpp
 | 
| diff --git a/src/core/SkPictureStateTree.cpp b/src/core/SkPictureStateTree.cpp
 | 
| index 20a826aa9246b4ef265b46a579f8ff2f9de3a3ed..891d04ca21bc4ae7a9b11b679afb7b2434c2fba6 100644
 | 
| --- a/src/core/SkPictureStateTree.cpp
 | 
| +++ b/src/core/SkPictureStateTree.cpp
 | 
| @@ -99,39 +99,24 @@
 | 
|      , fValid(true) {
 | 
|  }
 | 
|  
 | 
| -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() {
 | 
| +uint32_t SkPictureStateTree::Iterator::draw() {
 | 
|      SkASSERT(this->isValid());
 | 
|      if (fPlaybackIndex >= fDraws->count()) {
 | 
| +        // restore back to where we started
 | 
| +        fCanvas->setMatrix(fPlaybackMatrix);
 | 
|          if (fCurrentNode->fFlags & Node::kSaveLayer_Flag) {
 | 
|              fCanvas->restore();
 | 
|          }
 | 
| -
 | 
| -        for (fCurrentNode = fCurrentNode->fParent; fCurrentNode;
 | 
| -             fCurrentNode = fCurrentNode->fParent) {
 | 
| -            if (fCurrentNode->fFlags & (Node::kSave_Flag | Node::kSaveLayer_Flag)) {
 | 
| +        fCurrentNode = fCurrentNode->fParent;
 | 
| +        while (NULL != fCurrentNode) {
 | 
| +            if (fCurrentNode->fFlags & Node::kSave_Flag) {
 | 
|                  fCanvas->restore();
 | 
|              }
 | 
| -        }
 | 
| -
 | 
| -        // restore back to where we started
 | 
| -        fCanvas->setMatrix(fPlaybackMatrix);
 | 
| -        fCurrentMatrix = NULL;
 | 
| -
 | 
| +            if (fCurrentNode->fFlags & Node::kSaveLayer_Flag) {
 | 
| +                fCanvas->restore();
 | 
| +            }
 | 
| +            fCurrentNode = fCurrentNode->fParent;
 | 
| +        }
 | 
|          return kDrawComplete;
 | 
|      }
 | 
|  
 | 
| @@ -160,13 +145,9 @@
 | 
|                  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;
 | 
|                  }
 | 
| @@ -174,19 +155,17 @@
 | 
|                      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) {
 | 
| -                    fCanvas->save();
 | 
| +                    // 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);
 | 
|                  }
 | 
|              }
 | 
|              fCurrentNode = ancestor;
 | 
| @@ -195,18 +174,29 @@
 | 
|          // 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.
 | 
| -    this->setCurrentMatrix(draw->fMatrix);
 | 
| +
 | 
| +    if (fCurrentMatrix != draw->fMatrix) {
 | 
| +        SkMatrix tmp = *draw->fMatrix;
 | 
| +        tmp.postConcat(fPlaybackMatrix);
 | 
| +        fCanvas->setMatrix(tmp);
 | 
| +        fCurrentMatrix = draw->fMatrix;
 | 
| +    }
 | 
|  
 | 
|      ++fPlaybackIndex;
 | 
|      return draw->fOffset;
 | 
| 
 |