OLD | NEW |
| (Empty) |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef CC_LAYERS_LAYER_ITERATOR_H_ | |
6 #define CC_LAYERS_LAYER_ITERATOR_H_ | |
7 | |
8 #include <stddef.h> | |
9 | |
10 #include "cc/cc_export.h" | |
11 #include "cc/layers/layer_impl.h" | |
12 #include "cc/trees/layer_tree_host_common.h" | |
13 | |
14 namespace cc { | |
15 | |
16 // These classes provide means to iterate over the | |
17 // RenderSurfaceImpl-LayerImpl tree. | |
18 | |
19 // Example code follows, for a tree of LayerImpl/RenderSurfaceImpl objects. | |
20 // See below for details. | |
21 // | |
22 // void DoStuffOnLayers( | |
23 // const LayerImplList& render_surface_layer_list) { | |
24 // | |
25 // LayerIterator end = | |
26 // LayerIterator::End(&render_surface_layer_list); | |
27 // for (LayerIterator | |
28 // it = LayerIterator::Begin(&render_surface_layer_list); | |
29 // it != end; | |
30 // ++it) { | |
31 // // Only one of these will be true | |
32 // if (it.represents_target_render_surface()) | |
33 // foo(*it); // *it is a layer representing a target RenderSurface | |
34 // if (it.represents_contributing_render_surface()) | |
35 // bar(*it); // *it is a layer representing a RenderSurface that | |
36 // // contributes to the layer's target RenderSurface | |
37 // if (it.represents_itself()) | |
38 // baz(*it); // *it is a layer representing itself, | |
39 // // as it contributes to its own target RenderSurface | |
40 // } | |
41 // } | |
42 | |
43 // A RenderSurface R may be referred to in one of two different contexts. | |
44 // One RenderSurface is "current" at any time, for whatever operation | |
45 // is being performed. This current surface is referred to as a target surface. | |
46 // For example, when R is being painted it would be the target surface. | |
47 // Once R has been painted, its contents may be included into another | |
48 // surface S. While S is considered the target surface when it is being | |
49 // painted, R is called a contributing surface in this context as it | |
50 // contributes to the content of the target surface S. | |
51 // | |
52 // The iterator's current position in the tree always points to some layer. | |
53 // The state of the iterator indicates the role of the layer, | |
54 // and will be one of the following three states. | |
55 // A single layer L will appear in the iteration process in at least one, | |
56 // and possibly all, of these states. | |
57 // 1. Representing the target surface: The iterator in this state, | |
58 // pointing at layer L, indicates that the target RenderSurface | |
59 // is now the surface owned by L. This will occur exactly once for each | |
60 // RenderSurface in the tree. | |
61 // 2. Representing a contributing surface: The iterator in this state, | |
62 // pointing at layer L, refers to the RenderSurface owned | |
63 // by L as a contributing surface, without changing the current | |
64 // target RenderSurface. | |
65 // 3. Representing itself: The iterator in this state, pointing at layer L, | |
66 // refers to the layer itself, as a child of the | |
67 // current target RenderSurface. | |
68 // | |
69 // The FrontToBack iterator will iterate over children layers of a surface | |
70 // before the layer representing the surface as a target surface. | |
71 // | |
72 // To use the iterators: | |
73 // | |
74 // Create a stepping iterator and end iterator by calling | |
75 // LayerIterator::Begin() and LayerIterator::End() and passing in the | |
76 // list of layers owning target RenderSurfaces. Step through the tree | |
77 // by incrementing the stepping iterator while it is != to | |
78 // the end iterator. At each step the iterator knows what the layer | |
79 // is representing, and you can query the iterator to decide | |
80 // what actions to perform with the layer given what it represents. | |
81 | |
82 //////////////////////////////////////////////////////////////////////////////// | |
83 | |
84 struct LayerIteratorValue { | |
85 static const int kInvalidTargetRenderSurfaceLayerIndex = -1; | |
86 // This must be (size_t)-1 since the iterator action code assumes that this | |
87 // value can be reached by subtracting one from the position of the first | |
88 // layer in the current target surface's child layer list, which is 0. | |
89 static const size_t kLayerIndexRepresentingTargetRenderSurface = | |
90 static_cast<size_t>(-1); | |
91 }; | |
92 | |
93 // The position of a layer iterator that is independent | |
94 // of its many template types. | |
95 struct LayerIteratorPosition { | |
96 bool represents_target_render_surface; | |
97 bool represents_contributing_render_surface; | |
98 bool represents_itself; | |
99 LayerImpl* target_render_surface_layer; | |
100 LayerImpl* current_layer; | |
101 }; | |
102 | |
103 // An iterator class for walking over layers in the | |
104 // RenderSurface-Layer tree. | |
105 // TODO(enne): This class probably shouldn't be entirely inline and | |
106 // should get moved to a .cc file where it makes sense. | |
107 class LayerIterator { | |
108 public: | |
109 LayerIterator() : render_surface_layer_list_(nullptr) {} | |
110 | |
111 static LayerIterator Begin(const LayerImplList* render_surface_layer_list) { | |
112 return LayerIterator(render_surface_layer_list, true); | |
113 } | |
114 static LayerIterator End(const LayerImplList* render_surface_layer_list) { | |
115 return LayerIterator(render_surface_layer_list, false); | |
116 } | |
117 | |
118 LayerIterator& operator++() { | |
119 MoveToNext(); | |
120 return *this; | |
121 } | |
122 bool operator==(const LayerIterator& other) const { | |
123 return target_render_surface_layer_index_ == | |
124 other.target_render_surface_layer_index_ && | |
125 current_layer_index_ == other.current_layer_index_; | |
126 } | |
127 bool operator!=(const LayerIterator& other) const { | |
128 return !(*this == other); | |
129 } | |
130 | |
131 LayerImpl* operator->() const { return current_layer(); } | |
132 LayerImpl* operator*() const { return current_layer(); } | |
133 | |
134 bool represents_target_render_surface() const { | |
135 return current_layer_represents_target_render_surface(); | |
136 } | |
137 bool represents_contributing_render_surface() const { | |
138 return !represents_target_render_surface() && | |
139 current_layer_represents_contributing_render_surface(); | |
140 } | |
141 bool represents_itself() const { | |
142 return !represents_target_render_surface() && | |
143 !represents_contributing_render_surface(); | |
144 } | |
145 | |
146 LayerImpl* target_render_surface_layer() const { | |
147 return render_surface_layer_list_->at(target_render_surface_layer_index_); | |
148 } | |
149 | |
150 operator const LayerIteratorPosition() const { | |
151 LayerIteratorPosition position; | |
152 position.represents_target_render_surface = | |
153 represents_target_render_surface(); | |
154 position.represents_contributing_render_surface = | |
155 represents_contributing_render_surface(); | |
156 position.represents_itself = represents_itself(); | |
157 position.target_render_surface_layer = target_render_surface_layer(); | |
158 position.current_layer = current_layer(); | |
159 return position; | |
160 } | |
161 | |
162 private: | |
163 LayerIterator(const LayerImplList* render_surface_layer_list, bool start) | |
164 : render_surface_layer_list_(render_surface_layer_list), | |
165 target_render_surface_layer_index_(0) { | |
166 for (size_t i = 0; i < render_surface_layer_list->size(); ++i) { | |
167 if (!render_surface_layer_list->at(i)->GetRenderSurface()) { | |
168 NOTREACHED(); | |
169 MoveToEnd(); | |
170 return; | |
171 } | |
172 } | |
173 | |
174 if (start && !render_surface_layer_list->empty()) | |
175 MoveToBegin(); | |
176 else | |
177 MoveToEnd(); | |
178 } | |
179 | |
180 void MoveToBegin() { | |
181 target_render_surface_layer_index_ = 0; | |
182 current_layer_index_ = target_render_surface_children().size() - 1; | |
183 MoveToHighestInSubtree(); | |
184 } | |
185 | |
186 void MoveToEnd() { | |
187 target_render_surface_layer_index_ = | |
188 LayerIteratorValue::kInvalidTargetRenderSurfaceLayerIndex; | |
189 current_layer_index_ = 0; | |
190 } | |
191 | |
192 void MoveToNext() { | |
193 // Moves to the previous layer in the current RS layer list. | |
194 // Then we check if the new current layer has its own RS, | |
195 // in which case there are things in that RS layer list that are higher, | |
196 // so we find the highest layer in that subtree. | |
197 // If we move back past the front of the list, | |
198 // we jump up to the previous RS layer list, picking up again where we | |
199 // had previously recursed into the current RS layer list. | |
200 | |
201 if (!current_layer_represents_target_render_surface()) { | |
202 // Subtracting one here will eventually cause the current layer | |
203 // to become that layer representing the target render surface. | |
204 --current_layer_index_; | |
205 MoveToHighestInSubtree(); | |
206 } else { | |
207 while (current_layer_represents_target_render_surface()) { | |
208 if (!target_render_surface_layer_index_) { | |
209 // End of the list. | |
210 target_render_surface_layer_index_ = | |
211 LayerIteratorValue::kInvalidTargetRenderSurfaceLayerIndex; | |
212 current_layer_index_ = 0; | |
213 return; | |
214 } | |
215 target_render_surface_layer_index_ = | |
216 target_render_surface()->target_render_surface_layer_index_history_; | |
217 current_layer_index_ = | |
218 target_render_surface()->current_layer_index_history_; | |
219 } | |
220 } | |
221 } | |
222 | |
223 void MoveToHighestInSubtree() { | |
224 if (current_layer_represents_target_render_surface()) | |
225 return; | |
226 while (current_layer_represents_contributing_render_surface()) { | |
227 // Save where we were in the current target surface, move to the next one, | |
228 // and save the target surface that we came from there | |
229 // so we can go back to it. | |
230 target_render_surface()->current_layer_index_history_ = | |
231 current_layer_index_; | |
232 int previous_target_render_surface_layer = | |
233 target_render_surface_layer_index_; | |
234 | |
235 for (LayerImpl* layer = current_layer(); | |
236 target_render_surface_layer() != layer; | |
237 ++target_render_surface_layer_index_) { | |
238 } | |
239 current_layer_index_ = target_render_surface_children().size() - 1; | |
240 | |
241 target_render_surface()->target_render_surface_layer_index_history_ = | |
242 previous_target_render_surface_layer; | |
243 } | |
244 } | |
245 | |
246 inline LayerImpl* current_layer() const { | |
247 return current_layer_represents_target_render_surface() | |
248 ? target_render_surface_layer() | |
249 : target_render_surface_children().at(current_layer_index_); | |
250 } | |
251 | |
252 inline bool current_layer_represents_contributing_render_surface() const { | |
253 RenderSurfaceImpl* render_surface = current_layer()->GetRenderSurface(); | |
254 return render_surface && render_surface != target_render_surface(); | |
255 } | |
256 inline bool current_layer_represents_target_render_surface() const { | |
257 return current_layer_index_ == | |
258 LayerIteratorValue::kLayerIndexRepresentingTargetRenderSurface; | |
259 } | |
260 | |
261 inline RenderSurfaceImpl* target_render_surface() const { | |
262 return target_render_surface_layer()->GetRenderSurface(); | |
263 } | |
264 inline const LayerImplList& target_render_surface_children() const { | |
265 return target_render_surface()->layer_list(); | |
266 } | |
267 | |
268 const LayerImplList* render_surface_layer_list_; | |
269 | |
270 // The iterator's current position. | |
271 | |
272 // A position in the render_surface_layer_list. This points to a layer which | |
273 // owns the current target surface. This is a value from 0 to n-1 | |
274 // (n = size of render_surface_layer_list = number of surfaces). | |
275 // A value outside of this range | |
276 // (for example, LayerIteratorValue::kInvalidTargetRenderSurfaceLayerIndex) | |
277 // is used to indicate a position outside the bounds of the tree. | |
278 int target_render_surface_layer_index_; | |
279 // A position in the list of layers that are children of the | |
280 // current target surface. When pointing to one of these layers, | |
281 // this is a value from 0 to n-1 (n = number of children). | |
282 // Since the iterator must also stop at the layers representing | |
283 // the target surface, this is done by setting the current_layer_index | |
284 // to a value of | |
285 // LayerIteratorValue::kLayerIndexRepresentingTargetRenderSurface. | |
286 size_t current_layer_index_; | |
287 }; | |
288 | |
289 } // namespace cc | |
290 | |
291 #endif // CC_LAYERS_LAYER_ITERATOR_H_ | |
OLD | NEW |