OLD | NEW |
---|---|
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...) Loading... | |
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 SkMatrix m = *matrix; | |
110 m.postConcat(fPlaybackMatrix); | |
Justin Novosad
2014/04/22 15:31:34
If I understand correctly, this is because 'matrix
f(malita)
2014/04/22 15:48:38
Exactly. Added comment.
| |
111 fCanvas->setMatrix(m); | |
112 fCurrentMatrix = matrix; | |
113 } | |
114 | |
115 uint32_t SkPictureStateTree::Iterator::nextDraw() { | |
Justin Novosad
2014/04/22 15:31:34
+1 for the name change.
| |
103 SkASSERT(this->isValid()); | 116 SkASSERT(this->isValid()); |
104 if (fPlaybackIndex >= fDraws->count()) { | 117 if (fPlaybackIndex >= fDraws->count()) { |
105 // restore back to where we started | |
106 fCanvas->setMatrix(fPlaybackMatrix); | |
107 if (fCurrentNode->fFlags & Node::kSaveLayer_Flag) { | 118 if (fCurrentNode->fFlags & Node::kSaveLayer_Flag) { |
108 fCanvas->restore(); | 119 fCanvas->restore(); |
109 } | 120 } |
110 fCurrentNode = fCurrentNode->fParent; | 121 |
111 while (NULL != fCurrentNode) { | 122 for (fCurrentNode = fCurrentNode->fParent; fCurrentNode; |
Justin Novosad
2014/04/22 15:31:34
The changes to this loop look mostly like a cleane
f(malita)
2014/04/22 15:48:38
Yes, the loop change itself is just cleanup.
The
| |
112 if (fCurrentNode->fFlags & Node::kSave_Flag) { | 123 fCurrentNode = fCurrentNode->fParent) { |
124 if (fCurrentNode->fFlags & (Node::kSave_Flag | Node::kSaveLayer_Flag )) { | |
113 fCanvas->restore(); | 125 fCanvas->restore(); |
114 } | 126 } |
115 if (fCurrentNode->fFlags & Node::kSaveLayer_Flag) { | |
116 fCanvas->restore(); | |
117 } | |
118 fCurrentNode = fCurrentNode->fParent; | |
119 } | 127 } |
128 | |
129 // restore back to where we started | |
130 fCanvas->setMatrix(fPlaybackMatrix); | |
131 fCurrentMatrix = NULL; | |
132 | |
120 return kDrawComplete; | 133 return kDrawComplete; |
121 } | 134 } |
122 | 135 |
123 Draw* draw = static_cast<Draw*>((*fDraws)[fPlaybackIndex]); | 136 Draw* draw = static_cast<Draw*>((*fDraws)[fPlaybackIndex]); |
124 Node* targetNode = draw->fNode; | 137 Node* targetNode = draw->fNode; |
125 | 138 |
126 if (fSave) { | 139 if (fSave) { |
127 fCanvas->save(); | 140 fCanvas->save(); |
128 fSave = false; | 141 fSave = false; |
129 } | 142 } |
130 | 143 |
131 if (fCurrentNode != targetNode) { | 144 if (fCurrentNode != targetNode) { |
132 // If we're not at the target and we don't have a list of nodes to get t here, we need to | 145 // If we're not at the target and we don't have a list of nodes to get t here, we need to |
133 // figure out the path from our current node, to the target | 146 // figure out the path from our current node, to the target |
134 if (fNodes.count() == 0) { | 147 if (fNodes.count() == 0) { |
135 // Trace back up to a common ancestor, restoring to get our current state to match that | 148 // Trace back up to a common ancestor, restoring to get our current state to match that |
136 // of the ancestor, and saving a list of nodes whose state we need t o apply to get to | 149 // of the ancestor, and saving a list of nodes whose state we need t o apply to get to |
137 // the target (we can restore up to the ancestor immediately, but we 'll need to return | 150 // the target (we can restore up to the ancestor immediately, but we 'll need to return |
138 // an offset for each node on the way down to the target, to apply t he desired clips and | 151 // an offset for each node on the way down to the target, to apply t he desired clips and |
139 // saveLayers, so it may take several draw() calls before the next d raw actually occurs) | 152 // saveLayers, so it may take several draw() calls before the next d raw actually occurs) |
140 Node* tmp = fCurrentNode; | 153 Node* tmp = fCurrentNode; |
141 Node* ancestor = targetNode; | 154 Node* ancestor = targetNode; |
142 while (tmp != ancestor) { | 155 while (tmp != ancestor) { |
143 uint16_t currentLevel = tmp->fLevel; | 156 uint16_t currentLevel = tmp->fLevel; |
144 uint16_t targetLevel = ancestor->fLevel; | 157 uint16_t targetLevel = ancestor->fLevel; |
145 if (currentLevel >= targetLevel) { | 158 if (currentLevel >= targetLevel) { |
146 if (tmp != fCurrentNode && tmp->fFlags & Node::kSave_Flag) { | 159 if (tmp != fCurrentNode && tmp->fFlags & Node::kSave_Flag) { |
147 fCanvas->restore(); | 160 fCanvas->restore(); |
161 // restore() may change the matrix, so we need to reappl y. | |
162 fCurrentMatrix = NULL; | |
148 } | 163 } |
149 if (tmp->fFlags & Node::kSaveLayer_Flag) { | 164 if (tmp->fFlags & Node::kSaveLayer_Flag) { |
150 fCanvas->restore(); | 165 fCanvas->restore(); |
166 // restore() may change the matrix, so we need to reappl y. | |
167 fCurrentMatrix = NULL; | |
151 } | 168 } |
152 tmp = tmp->fParent; | 169 tmp = tmp->fParent; |
153 } | 170 } |
154 if (currentLevel <= targetLevel) { | 171 if (currentLevel <= targetLevel) { |
155 fNodes.push(ancestor); | 172 fNodes.push(ancestor); |
156 ancestor = ancestor->fParent; | 173 ancestor = ancestor->fParent; |
157 } | 174 } |
175 | |
176 SkASSERT(NULL != tmp); | |
177 SkASSERT(NULL != ancestor); | |
158 } | 178 } |
159 | 179 |
160 if (ancestor->fFlags & Node::kSave_Flag) { | 180 if (ancestor->fFlags & Node::kSave_Flag) { |
161 if (fCurrentNode != ancestor) { | 181 if (fCurrentNode != ancestor) { |
162 fCanvas->restore(); | 182 fCanvas->restore(); |
183 // restore() may change the matrix, so we need to reapply. | |
184 fCurrentMatrix = NULL; | |
163 } | 185 } |
164 if (targetNode != ancestor) { | 186 if (targetNode != ancestor) { |
165 // FIXME: the save below depends on soon-to-be-deprecated | 187 fCanvas->save(); |
166 // SaveFlags behavior: it relies on matrix changes persistin g | |
167 // after restore. | |
168 fCanvas->save(SkCanvas::kClip_SaveFlag); | |
169 } | 188 } |
170 } | 189 } |
171 fCurrentNode = ancestor; | 190 fCurrentNode = ancestor; |
172 } | 191 } |
173 | 192 |
174 // 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 |
175 // apply the next clip or saveLayer. | 194 // apply the next clip or saveLayer. |
176 if (fCurrentNode != targetNode) { | 195 if (fCurrentNode != targetNode) { |
177 if (fCurrentMatrix != fNodes.top()->fMatrix) { | |
178 fCurrentMatrix = fNodes.top()->fMatrix; | |
179 SkMatrix tmp = *fNodes.top()->fMatrix; | |
180 tmp.postConcat(fPlaybackMatrix); | |
181 fCanvas->setMatrix(tmp); | |
182 } | |
183 uint32_t offset = fNodes.top()->fOffset; | 196 uint32_t offset = fNodes.top()->fOffset; |
184 fCurrentNode = fNodes.top(); | 197 fCurrentNode = fNodes.top(); |
185 fSave = fCurrentNode != targetNode && fCurrentNode->fFlags & Node::k Save_Flag; | 198 fSave = fCurrentNode != targetNode && fCurrentNode->fFlags & Node::k Save_Flag; |
186 fNodes.pop(); | 199 fNodes.pop(); |
200 this->setCurrentMatrix(fCurrentNode->fMatrix); | |
187 return offset; | 201 return offset; |
188 } | 202 } |
189 } | 203 } |
190 | 204 |
191 // 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 |
192 // for the draw, and return its offset. | 206 // for the draw, and return its offset. |
193 | 207 this->setCurrentMatrix(draw->fMatrix); |
194 if (fCurrentMatrix != draw->fMatrix) { | |
195 SkMatrix tmp = *draw->fMatrix; | |
196 tmp.postConcat(fPlaybackMatrix); | |
197 fCanvas->setMatrix(tmp); | |
198 fCurrentMatrix = draw->fMatrix; | |
199 } | |
200 | 208 |
201 ++fPlaybackIndex; | 209 ++fPlaybackIndex; |
202 return draw->fOffset; | 210 return draw->fOffset; |
203 } | 211 } |
OLD | NEW |