• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "base/memory/ref_counted.h"
9 #include "cc/base/cc_export.h"
10 #include "cc/trees/layer_tree_host_common.h"
11 
12 namespace cc {
13 
14 // These classes provide means to iterate over the
15 // RenderSurface-Layer tree.
16 
17 // Example code follows, for a tree of Layer/RenderSurface objects.
18 // See below for details.
19 //
20 // void DoStuffOnLayers(
21 //     const RenderSurfaceLayerList& render_surface_layer_list) {
22 //   typedef LayerIterator<Layer,
23 //                         RenderSurfaceLayerList,
24 //                         RenderSurface,
25 //                         LayerIteratorActions::FrontToBack>
26 //       LayerIteratorType;
27 //
28 //   LayerIteratorType end =
29 //       LayerIteratorType::End(&render_surface_layer_list);
30 //   for (LayerIteratorType
31 //            it = LayerIteratorType::Begin(&render_surface_layer_list);
32 //        it != end;
33 //        ++it) {
34 //     // Only one of these will be true
35 //     if (it.represents_target_render_surface())
36 //       foo(*it);  // *it is a layer representing a target RenderSurface
37 //     if (it.represents_contributing_render_surface())
38 //       bar(*it);  // *it is a layer representing a RenderSurface that
39 //                  // contributes to the layer's target RenderSurface
40 //     if (it.represents_itself())
41 //       baz(*it);  // *it is a layer representing itself,
42 //                  // as it contributes to its own target RenderSurface
43 //   }
44 // }
45 
46 // A RenderSurface R may be referred to in one of two different contexts.
47 // One RenderSurface is "current" at any time, for whatever operation
48 // is being performed. This current surface is referred to as a target surface.
49 // For example, when R is being painted it would be the target surface.
50 // Once R has been painted, its contents may be included into another
51 // surface S. While S is considered the target surface when it is being
52 // painted, R is called a contributing surface in this context as it
53 // contributes to the content of the target surface S.
54 //
55 // The iterator's current position in the tree always points to some layer.
56 // The state of the iterator indicates the role of the layer,
57 // and will be one of the following three states.
58 // A single layer L will appear in the iteration process in at least one,
59 // and possibly all, of these states.
60 // 1. Representing the target surface: The iterator in this state,
61 // pointing at layer L, indicates that the target RenderSurface
62 // is now the surface owned by L. This will occur exactly once for each
63 // RenderSurface in the tree.
64 // 2. Representing a contributing surface: The iterator in this state,
65 // pointing at layer L, refers to the RenderSurface owned
66 // by L as a contributing surface, without changing the current
67 // target RenderSurface.
68 // 3. Representing itself: The iterator in this state, pointing at layer L,
69 // refers to the layer itself, as a child of the
70 // current target RenderSurface.
71 //
72 // The FrontToBack iterator will iterate over children layers of a surface
73 // before the layer representing the surface as a target surface.
74 //
75 // To use the iterators:
76 //
77 // Create a stepping iterator and end iterator by calling
78 // LayerIterator::Begin() and LayerIterator::End() and passing in the
79 // list of layers owning target RenderSurfaces. Step through the tree
80 // by incrementing the stepping iterator while it is != to
81 // the end iterator. At each step the iterator knows what the layer
82 // is representing, and you can query the iterator to decide
83 // what actions to perform with the layer given what it represents.
84 
85 ////////////////////////////////////////////////////////////////////////////////
86 
87 // Non-templated constants
88 struct LayerIteratorValue {
89   static const int kInvalidTargetRenderSurfaceLayerIndex = -1;
90   // This must be -1 since the iterator action code assumes that this value can
91   // be reached by subtracting one from the position of the first layer in the
92   // current target surface's child layer list, which is 0.
93   static const int kLayerIndexRepresentingTargetRenderSurface = -1;
94 };
95 
96 // The position of a layer iterator that is independent
97 // of its many template types.
98 template <typename LayerType> struct LayerIteratorPosition {
99   bool represents_target_render_surface;
100   bool represents_contributing_render_surface;
101   bool represents_itself;
102   LayerType* target_render_surface_layer;
103   LayerType* current_layer;
104 };
105 
106 // An iterator class for walking over layers in the
107 // RenderSurface-Layer tree.
108 template <typename LayerType,
109           typename LayerList,
110           typename RenderSurfaceType,
111           typename IteratorActionType>
112 class LayerIterator {
113   typedef LayerIterator<LayerType,
114                         LayerList,
115                         RenderSurfaceType,
116                         IteratorActionType> LayerIteratorType;
117 
118  public:
LayerIterator()119   LayerIterator() : render_surface_layer_list_(NULL) {}
120 
Begin(const LayerList * render_surface_layer_list)121   static LayerIteratorType Begin(const LayerList* render_surface_layer_list) {
122     return LayerIteratorType(render_surface_layer_list, true);
123   }
End(const LayerList * render_surface_layer_list)124   static LayerIteratorType End(const LayerList* render_surface_layer_list) {
125     return LayerIteratorType(render_surface_layer_list, false);
126   }
127 
128   LayerIteratorType& operator++() {
129     actions_.Next(this);
130     return *this;
131   }
132   bool operator==(const LayerIterator& other) const {
133     return target_render_surface_layer_index_ ==
134            other.target_render_surface_layer_index_ &&
135            current_layer_index_ == other.current_layer_index_;
136   }
137   bool operator!=(const LayerIteratorType& other) const {
138     return !(*this == other);
139   }
140 
141   LayerType* operator->() const { return current_layer(); }
142   LayerType* operator*() const { return current_layer(); }
143 
represents_target_render_surface()144   bool represents_target_render_surface() const {
145     return current_layer_represents_target_render_surface();
146   }
represents_contributing_render_surface()147   bool represents_contributing_render_surface() const {
148     return !represents_target_render_surface() &&
149            current_layer_represents_contributing_render_surface();
150   }
represents_itself()151   bool represents_itself() const {
152     return !represents_target_render_surface() &&
153            !represents_contributing_render_surface();
154   }
155 
target_render_surface_layer()156   LayerType* target_render_surface_layer() const {
157     return render_surface_layer_list_->at(target_render_surface_layer_index_);
158   }
159 
160   operator const LayerIteratorPosition<LayerType>() const {
161     LayerIteratorPosition<LayerType> position;
162     position.represents_target_render_surface =
163         represents_target_render_surface();
164     position.represents_contributing_render_surface =
165         represents_contributing_render_surface();
166     position.represents_itself = represents_itself();
167     position.target_render_surface_layer = target_render_surface_layer();
168     position.current_layer = current_layer();
169     return position;
170   }
171 
172  private:
LayerIterator(const LayerList * render_surface_layer_list,bool start)173   LayerIterator(const LayerList* render_surface_layer_list, bool start)
174       : render_surface_layer_list_(render_surface_layer_list),
175         target_render_surface_layer_index_(0) {
176     for (size_t i = 0; i < render_surface_layer_list->size(); ++i) {
177       if (!render_surface_layer_list->at(i)->render_surface()) {
178         NOTREACHED();
179         actions_.End(this);
180         return;
181       }
182     }
183 
184     if (start && !render_surface_layer_list->empty())
185       actions_.Begin(this);
186     else
187       actions_.End(this);
188   }
189 
current_layer()190   inline LayerType* current_layer() const {
191     return current_layer_represents_target_render_surface()
192            ? target_render_surface_layer()
193            : target_render_surface_children().at(current_layer_index_);
194   }
195 
current_layer_represents_contributing_render_surface()196   inline bool current_layer_represents_contributing_render_surface() const {
197     return LayerTreeHostCommon::RenderSurfaceContributesToTarget<LayerType>(
198         current_layer(), target_render_surface_layer()->id());
199   }
current_layer_represents_target_render_surface()200   inline bool current_layer_represents_target_render_surface() const {
201     return current_layer_index_ ==
202            LayerIteratorValue::kLayerIndexRepresentingTargetRenderSurface;
203   }
204 
target_render_surface()205   inline RenderSurfaceType* target_render_surface() const {
206     return target_render_surface_layer()->render_surface();
207   }
target_render_surface_children()208   inline const LayerList& target_render_surface_children() const {
209     return target_render_surface()->layer_list();
210   }
211 
212   IteratorActionType actions_;
213   const LayerList* render_surface_layer_list_;
214 
215   // The iterator's current position.
216 
217   // A position in the render_surface_layer_list. This points to a layer which
218   // owns the current target surface. This is a value from 0 to n-1
219   // (n = size of render_surface_layer_list = number of surfaces).
220   // A value outside of this range
221   // (for example, LayerIteratorValue::kInvalidTargetRenderSurfaceLayerIndex)
222   // is used to indicate a position outside the bounds of the tree.
223   int target_render_surface_layer_index_;
224   // A position in the list of layers that are children of the
225   // current target surface. When pointing to one of these layers,
226   // this is a value from 0 to n-1 (n = number of children).
227   // Since the iterator must also stop at the layers representing
228   // the target surface, this is done by setting the current_layerIndex
229   // to a value of LayerIteratorValue::LayerRepresentingTargetRenderSurface.
230   int current_layer_index_;
231 
232   friend struct LayerIteratorActions;
233 };
234 
235 // Orderings for iterating over the RenderSurface-Layer tree.
236 struct CC_EXPORT LayerIteratorActions {
237   // Walks layers sorted by z-order from front to back
238   class CC_EXPORT FrontToBack {
239    public:
240     template <typename LayerType,
241               typename LayerList,
242               typename RenderSurfaceType,
243               typename ActionType>
244     void Begin(
245         LayerIterator<LayerType, LayerList, RenderSurfaceType, ActionType>* it);
246 
247     template <typename LayerType,
248               typename LayerList,
249               typename RenderSurfaceType,
250               typename ActionType>
251     void End(
252         LayerIterator<LayerType, LayerList, RenderSurfaceType, ActionType>* it);
253 
254     template <typename LayerType,
255               typename LayerList,
256               typename RenderSurfaceType,
257               typename ActionType>
258     void Next(
259         LayerIterator<LayerType, LayerList, RenderSurfaceType, ActionType>* it);
260 
261    private:
262     template <typename LayerType,
263               typename LayerList,
264               typename RenderSurfaceType,
265               typename ActionType>
266     void GoToHighestInSubtree(
267         LayerIterator<LayerType, LayerList, RenderSurfaceType, ActionType>* it);
268   };
269 };
270 
271 }  // namespace cc
272 
273 #endif  // CC_LAYERS_LAYER_ITERATOR_H_
274