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

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

Issue 617953002: Strip old backend recording down to essentials (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: debug-only Created 6 years, 2 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
« no previous file with comments | « src/core/SkPictureStateTree.h ('k') | tests/PictureStateTreeTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1
2 /*
3 * Copyright 2012 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9 #include "SkPictureStateTree.h"
10 #include "SkCanvas.h"
11
12 SkPictureStateTree::SkPictureStateTree()
13 : fAlloc(2048)
14 , fLastRestoredNode(NULL)
15 , fStateStack(sizeof(Draw), 16) {
16 fRootMatrix.reset();
17 fRoot.fParent = NULL;
18 fRoot.fMatrix = &fRootMatrix;
19 fRoot.fFlags = Node::kSave_Flag;
20 fRoot.fOffset = 0;
21 fRoot.fLevel = 0;
22 fCurrentState.fNode = &fRoot;
23 fCurrentState.fMatrix = &fRootMatrix;
24 *static_cast<Draw*>(fStateStack.push_back()) = fCurrentState;
25 }
26
27 SkPictureStateTree::~SkPictureStateTree() {
28 }
29
30 SkPictureStateTree::Draw* SkPictureStateTree::appendDraw(size_t offset) {
31 Draw* draw = static_cast<Draw*>(fAlloc.allocThrow(sizeof(Draw)));
32 *draw = fCurrentState;
33 draw->fOffset = SkToU32(offset);
34 return draw;
35 }
36
37 void SkPictureStateTree::appendSave() {
38 *static_cast<Draw*>(fStateStack.push_back()) = fCurrentState;
39 fCurrentState.fNode->fFlags |= Node::kSave_Flag;
40 }
41
42 void SkPictureStateTree::appendSaveLayer(size_t offset) {
43 *static_cast<Draw*>(fStateStack.push_back()) = fCurrentState;
44 this->appendNode(offset);
45 fCurrentState.fNode->fFlags |= Node::kSaveLayer_Flag;
46 }
47
48 void SkPictureStateTree::saveCollapsed() {
49 SkASSERT(fLastRestoredNode);
50 SkASSERT(SkToBool(fLastRestoredNode->fFlags & \
51 (Node::kSaveLayer_Flag | Node::kSave_Flag)));
52 SkASSERT(fLastRestoredNode->fParent == fCurrentState.fNode);
53 // The structure of the tree is not modified here. We just turn off
54 // the save or saveLayer flag to prevent the iterator from making state
55 // changing calls on the playback canvas when traversing a save or
56 // saveLayerNode node.
57 fLastRestoredNode->fFlags = 0;
58 }
59
60 void SkPictureStateTree::appendRestore() {
61 fLastRestoredNode = fCurrentState.fNode;
62 fCurrentState = *static_cast<Draw*>(fStateStack.back());
63 fStateStack.pop_back();
64 }
65
66 void SkPictureStateTree::appendTransform(const SkMatrix& trans) {
67 SkMatrix* m = static_cast<SkMatrix*>(fAlloc.allocThrow(sizeof(SkMatrix)));
68 *m = trans;
69 fCurrentState.fMatrix = m;
70 }
71
72 void SkPictureStateTree::appendClip(size_t offset) {
73 this->appendNode(offset);
74 }
75
76 void SkPictureStateTree::initIterator(SkPictureStateTree::Iterator* iter,
77 const SkTDArray<void*>& draws,
78 SkCanvas* canvas) {
79 iter->init(draws, canvas, &fRoot);
80 }
81
82 void SkPictureStateTree::appendNode(size_t offset) {
83 Node* n = static_cast<Node*>(fAlloc.allocThrow(sizeof(Node)));
84 n->fOffset = SkToU32(offset);
85 n->fFlags = 0;
86 n->fParent = fCurrentState.fNode;
87 n->fLevel = fCurrentState.fNode->fLevel + 1;
88 n->fMatrix = fCurrentState.fMatrix;
89 fCurrentState.fNode = n;
90 }
91
92 void SkPictureStateTree::Iterator::init(const SkTDArray<void*>& draws, SkCanvas* canvas, Node* root) {
93 SkASSERT(!fValid);
94 fDraws = &draws;
95 fCanvas = canvas;
96 fCurrentNode = root;
97 fPlaybackMatrix = canvas->getTotalMatrix();
98 fCurrentMatrix = NULL;
99 fPlaybackIndex = 0;
100 fSave = false;
101 fValid = true;
102 }
103
104 void SkPictureStateTree::Iterator::setCurrentMatrix(const SkMatrix* matrix) {
105 SkASSERT(matrix);
106
107 if (matrix == fCurrentMatrix) {
108 return;
109 }
110
111 // The matrix is in recording space, but we also inherit
112 // a playback matrix from out target canvas.
113 SkMatrix m = *matrix;
114 m.postConcat(fPlaybackMatrix);
115 fCanvas->setMatrix(m);
116 fCurrentMatrix = matrix;
117 }
118
119 uint32_t SkPictureStateTree::Iterator::finish() {
120 if (fCurrentNode->fFlags & Node::kSaveLayer_Flag) {
121 fCanvas->restore();
122 }
123
124 for (fCurrentNode = fCurrentNode->fParent; fCurrentNode;
125 fCurrentNode = fCurrentNode->fParent) {
126 // Note: we call restore() twice when both flags are set.
127 if (fCurrentNode->fFlags & Node::kSave_Flag) {
128 fCanvas->restore();
129 }
130 if (fCurrentNode->fFlags & Node::kSaveLayer_Flag) {
131 fCanvas->restore();
132 }
133 }
134
135 fCanvas->setMatrix(fPlaybackMatrix);
136 fCurrentMatrix = NULL;
137 return kDrawComplete;
138 }
139
140 uint32_t SkPictureStateTree::Iterator::nextDraw() {
141 SkASSERT(this->isValid());
142 if (fPlaybackIndex >= fDraws->count()) {
143 return this->finish();
144 }
145
146 Draw* draw = static_cast<Draw*>((*fDraws)[fPlaybackIndex]);
147 Node* targetNode = draw->fNode;
148
149 if (fSave) {
150 fCanvas->save();
151 fSave = false;
152 }
153
154 if (fCurrentNode != targetNode) {
155 // If we're not at the target and we don't have a list of nodes to get t here, we need to
156 // figure out the path from our current node, to the target
157 if (fNodes.count() == 0) {
158 // Trace back up to a common ancestor, restoring to get our current state to match that
159 // of the ancestor, and saving a list of nodes whose state we need t o apply to get to
160 // the target (we can restore up to the ancestor immediately, but we 'll need to return
161 // an offset for each node on the way down to the target, to apply t he desired clips and
162 // saveLayers, so it may take several draw() calls before the next d raw actually occurs)
163 Node* tmp = fCurrentNode;
164 Node* ancestor = targetNode;
165 while (tmp != ancestor) {
166 uint16_t currentLevel = tmp->fLevel;
167 uint16_t targetLevel = ancestor->fLevel;
168 if (currentLevel >= targetLevel) {
169 if (tmp != fCurrentNode && tmp->fFlags & Node::kSave_Flag) {
170 fCanvas->restore();
171 // restore() may change the matrix, so we need to reappl y.
172 fCurrentMatrix = NULL;
173 }
174 if (tmp->fFlags & Node::kSaveLayer_Flag) {
175 fCanvas->restore();
176 // restore() may change the matrix, so we need to reappl y.
177 fCurrentMatrix = NULL;
178 }
179 tmp = tmp->fParent;
180 }
181 if (currentLevel <= targetLevel) {
182 fNodes.push(ancestor);
183 ancestor = ancestor->fParent;
184 }
185 }
186
187 if (ancestor->fFlags & Node::kSave_Flag) {
188 if (fCurrentNode != ancestor) {
189 fCanvas->restore();
190 // restore() may change the matrix, so we need to reapply.
191 fCurrentMatrix = NULL;
192 }
193 if (targetNode != ancestor) {
194 fCanvas->save();
195 }
196 }
197 fCurrentNode = ancestor;
198 }
199
200 // If we're not at the target node yet, we'll need to return an offset t o make the caller
201 // apply the next clip or saveLayer.
202 if (fCurrentNode != targetNode) {
203 uint32_t offset = fNodes.top()->fOffset;
204 fCurrentNode = fNodes.top();
205 fSave = fCurrentNode != targetNode && fCurrentNode->fFlags & Node::k Save_Flag;
206 fNodes.pop();
207 this->setCurrentMatrix(fCurrentNode->fMatrix);
208 return offset;
209 }
210 }
211
212 // If we got this far, the clip/saveLayer state is all set, so we can procee d to set the matrix
213 // for the draw, and return its offset.
214 this->setCurrentMatrix(draw->fMatrix);
215
216 ++fPlaybackIndex;
217 return draw->fOffset;
218 }
OLDNEW
« no previous file with comments | « src/core/SkPictureStateTree.h ('k') | tests/PictureStateTreeTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698