Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(149)

Side by Side Diff: src/core/SkPictureStateTree.cpp

Issue 246893005: Refactor SkPictureStateTree::Iterator to avoid use of kClip_SaveFlag. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: http://crbug.com/366889 fix + test Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 1
2 /* 2 /*
3 * Copyright 2012 Google Inc. 3 * Copyright 2012 Google Inc.
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 #include "SkPictureStateTree.h" 9 #include "SkPictureStateTree.h"
10 #include "SkCanvas.h" 10 #include "SkCanvas.h"
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 : fDraws(&draws) 92 : fDraws(&draws)
93 , fCanvas(canvas) 93 , fCanvas(canvas)
94 , fCurrentNode(root) 94 , fCurrentNode(root)
95 , fPlaybackMatrix(canvas->getTotalMatrix()) 95 , fPlaybackMatrix(canvas->getTotalMatrix())
96 , fCurrentMatrix(NULL) 96 , fCurrentMatrix(NULL)
97 , fPlaybackIndex(0) 97 , fPlaybackIndex(0)
98 , fSave(false) 98 , fSave(false)
99 , fValid(true) { 99 , fValid(true) {
100 } 100 }
101 101
102 uint32_t SkPictureStateTree::Iterator::draw() { 102 void SkPictureStateTree::Iterator::setCurrentMatrix(const SkMatrix* matrix) {
103 SkASSERT(NULL != matrix);
104
105 if (matrix == fCurrentMatrix) {
106 return;
107 }
108
109 // The matrix is in recording space, but we also inherit
110 // a playback matrix from out target canvas.
111 SkMatrix m = *matrix;
112 m.postConcat(fPlaybackMatrix);
113 fCanvas->setMatrix(m);
114 fCurrentMatrix = matrix;
115 }
116
117 uint32_t SkPictureStateTree::Iterator::nextDraw() {
103 SkASSERT(this->isValid()); 118 SkASSERT(this->isValid());
104 if (fPlaybackIndex >= fDraws->count()) { 119 if (fPlaybackIndex >= fDraws->count()) {
105 // restore back to where we started
106 fCanvas->setMatrix(fPlaybackMatrix);
107 if (fCurrentNode->fFlags & Node::kSaveLayer_Flag) { 120 if (fCurrentNode->fFlags & Node::kSaveLayer_Flag) {
108 fCanvas->restore(); 121 fCanvas->restore();
109 } 122 }
110 fCurrentNode = fCurrentNode->fParent; 123
111 while (NULL != fCurrentNode) { 124 for (fCurrentNode = fCurrentNode->fParent; fCurrentNode;
125 fCurrentNode = fCurrentNode->fParent) {
112 if (fCurrentNode->fFlags & Node::kSave_Flag) { 126 if (fCurrentNode->fFlags & Node::kSave_Flag) {
113 fCanvas->restore(); 127 fCanvas->restore();
114 } 128 }
115 if (fCurrentNode->fFlags & Node::kSaveLayer_Flag) { 129 if (fCurrentNode->fFlags & Node::kSaveLayer_Flag) {
Justin Novosad 2014/04/25 22:43:41 At first glance this code looks like it was not wr
f(malita) 2014/04/28 13:10:25 Done.
116 fCanvas->restore(); 130 fCanvas->restore();
117 } 131 }
118 fCurrentNode = fCurrentNode->fParent;
119 } 132 }
133
134 fCanvas->setMatrix(fPlaybackMatrix);
135 fCurrentMatrix = NULL;
120 return kDrawComplete; 136 return kDrawComplete;
121 } 137 }
122 138
123 Draw* draw = static_cast<Draw*>((*fDraws)[fPlaybackIndex]); 139 Draw* draw = static_cast<Draw*>((*fDraws)[fPlaybackIndex]);
124 Node* targetNode = draw->fNode; 140 Node* targetNode = draw->fNode;
125 141
126 if (fSave) { 142 if (fSave) {
127 // FIXME: the save below depends on soon-to-be-deprecated 143 fCanvas->save();
128 // SaveFlags behavior: it relies on matrix changes persisting
129 // after restore.
130 fCanvas->save(SkCanvas::kClip_SaveFlag);
131 fSave = false; 144 fSave = false;
132 } 145 }
133 146
134 if (fCurrentNode != targetNode) { 147 if (fCurrentNode != targetNode) {
135 // If we're not at the target and we don't have a list of nodes to get t here, we need to 148 // If we're not at the target and we don't have a list of nodes to get t here, we need to
136 // figure out the path from our current node, to the target 149 // figure out the path from our current node, to the target
137 if (fNodes.count() == 0) { 150 if (fNodes.count() == 0) {
138 // Trace back up to a common ancestor, restoring to get our current state to match that 151 // Trace back up to a common ancestor, restoring to get our current state to match that
139 // of the ancestor, and saving a list of nodes whose state we need t o apply to get to 152 // of the ancestor, and saving a list of nodes whose state we need t o apply to get to
140 // the target (we can restore up to the ancestor immediately, but we 'll need to return 153 // the target (we can restore up to the ancestor immediately, but we 'll need to return
141 // an offset for each node on the way down to the target, to apply t he desired clips and 154 // an offset for each node on the way down to the target, to apply t he desired clips and
142 // saveLayers, so it may take several draw() calls before the next d raw actually occurs) 155 // saveLayers, so it may take several draw() calls before the next d raw actually occurs)
143 Node* tmp = fCurrentNode; 156 Node* tmp = fCurrentNode;
144 Node* ancestor = targetNode; 157 Node* ancestor = targetNode;
145 while (tmp != ancestor) { 158 while (tmp != ancestor) {
146 uint16_t currentLevel = tmp->fLevel; 159 uint16_t currentLevel = tmp->fLevel;
147 uint16_t targetLevel = ancestor->fLevel; 160 uint16_t targetLevel = ancestor->fLevel;
148 if (currentLevel >= targetLevel) { 161 if (currentLevel >= targetLevel) {
149 if (tmp != fCurrentNode && tmp->fFlags & Node::kSave_Flag) { 162 if (tmp != fCurrentNode && tmp->fFlags & Node::kSave_Flag) {
150 fCanvas->restore(); 163 fCanvas->restore();
164 // restore() may change the matrix, so we need to reappl y.
165 fCurrentMatrix = NULL;
151 } 166 }
152 if (tmp->fFlags & Node::kSaveLayer_Flag) { 167 if (tmp->fFlags & Node::kSaveLayer_Flag) {
153 fCanvas->restore(); 168 fCanvas->restore();
169 // restore() may change the matrix, so we need to reappl y.
170 fCurrentMatrix = NULL;
154 } 171 }
155 tmp = tmp->fParent; 172 tmp = tmp->fParent;
156 } 173 }
157 if (currentLevel <= targetLevel) { 174 if (currentLevel <= targetLevel) {
158 fNodes.push(ancestor); 175 fNodes.push(ancestor);
159 ancestor = ancestor->fParent; 176 ancestor = ancestor->fParent;
160 } 177 }
161 } 178 }
162 179
163 if (ancestor->fFlags & Node::kSave_Flag) { 180 if (ancestor->fFlags & Node::kSave_Flag) {
164 if (fCurrentNode != ancestor) { 181 if (fCurrentNode != ancestor) {
165 fCanvas->restore(); 182 fCanvas->restore();
183 // restore() may change the matrix, so we need to reapply.
184 fCurrentMatrix = NULL;
166 } 185 }
167 if (targetNode != ancestor) { 186 if (targetNode != ancestor) {
168 // FIXME: the save below depends on soon-to-be-deprecated 187 fCanvas->save();
169 // SaveFlags behavior: it relies on matrix changes persistin g
170 // after restore.
171 fCanvas->save(SkCanvas::kClip_SaveFlag);
172 } 188 }
173 } 189 }
174 fCurrentNode = ancestor; 190 fCurrentNode = ancestor;
175 } 191 }
176 192
177 // If we're not at the target node yet, we'll need to return an offset t o make the caller 193 // If we're not at the target node yet, we'll need to return an offset t o make the caller
178 // apply the next clip or saveLayer. 194 // apply the next clip or saveLayer.
179 if (fCurrentNode != targetNode) { 195 if (fCurrentNode != targetNode) {
180 if (fCurrentMatrix != fNodes.top()->fMatrix) {
181 fCurrentMatrix = fNodes.top()->fMatrix;
182 SkMatrix tmp = *fNodes.top()->fMatrix;
183 tmp.postConcat(fPlaybackMatrix);
184 fCanvas->setMatrix(tmp);
185 }
186 uint32_t offset = fNodes.top()->fOffset; 196 uint32_t offset = fNodes.top()->fOffset;
187 fCurrentNode = fNodes.top(); 197 fCurrentNode = fNodes.top();
188 fSave = fCurrentNode != targetNode && fCurrentNode->fFlags & Node::k Save_Flag; 198 fSave = fCurrentNode != targetNode && fCurrentNode->fFlags & Node::k Save_Flag;
189 fNodes.pop(); 199 fNodes.pop();
200 this->setCurrentMatrix(fCurrentNode->fMatrix);
190 return offset; 201 return offset;
191 } 202 }
192 } 203 }
193 204
194 // If we got this far, the clip/saveLayer state is all set, so we can procee d to set the matrix 205 // If we got this far, the clip/saveLayer state is all set, so we can procee d to set the matrix
195 // for the draw, and return its offset. 206 // for the draw, and return its offset.
196 207 this->setCurrentMatrix(draw->fMatrix);
197 if (fCurrentMatrix != draw->fMatrix) {
198 SkMatrix tmp = *draw->fMatrix;
199 tmp.postConcat(fPlaybackMatrix);
200 fCanvas->setMatrix(tmp);
201 fCurrentMatrix = draw->fMatrix;
202 }
203 208
204 ++fPlaybackIndex; 209 ++fPlaybackIndex;
205 return draw->fOffset; 210 return draw->fOffset;
206 } 211 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698