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