aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2014-04-23 02:46:20 +0000
committerGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2014-04-23 02:46:20 +0000
commit8798ae37dac4e28a8feb05ae4fae32c915d8cd8d (patch)
tree9a3d2fb4a8f36d7d3c5aec762353d2298e780602 /src
parent80894678ca7b54413ba50de4355b7816d5bc0e10 (diff)
Refactor SkPictureStateTree::Iterator to avoid use of kClip_SaveFlag.
The current implementation relies on soon-to-be-deprecated kClip_SaveFlag behavior. Updated to use default save flags (kMatrixClip_SaveFlag) and stop assuming that the matrix survives restore() calls. R=junov@chromium.org, reed@google.com, robertphillips@chromium.org, robertphillips@google.com Author: fmalita@chromium.org Review URL: https://codereview.chromium.org/246893005 git-svn-id: http://skia.googlecode.com/svn/trunk@14319 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src')
-rw-r--r--src/core/SkPicturePlayback.cpp6
-rw-r--r--src/core/SkPictureStateTree.cpp64
-rw-r--r--src/core/SkPictureStateTree.h8
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;