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 BackToFront iterator will return a layer representing the target surface 73 // before returning layers representing themselves as children of the current 74 // target surface. Whereas the FrontToBack ordering will iterate over children 75 // layers of a surface before the layer representing the surface 76 // as a target surface. 77 // 78 // To use the iterators: 79 // 80 // Create a stepping iterator and end iterator by calling 81 // LayerIterator::Begin() and LayerIterator::End() and passing in the 82 // list of layers owning target RenderSurfaces. Step through the tree 83 // by incrementing the stepping iterator while it is != to 84 // the end iterator. At each step the iterator knows what the layer 85 // is representing, and you can query the iterator to decide 86 // what actions to perform with the layer given what it represents. 87 88 //////////////////////////////////////////////////////////////////////////////// 89 90 // Non-templated constants 91 struct LayerIteratorValue { 92 static const int kInvalidTargetRenderSurfaceLayerIndex = -1; 93 // This must be -1 since the iterator action code assumes that this value can 94 // be reached by subtracting one from the position of the first layer in the 95 // current target surface's child layer list, which is 0. 96 static const int kLayerIndexRepresentingTargetRenderSurface = -1; 97 }; 98 99 // The position of a layer iterator that is independent 100 // of its many template types. 101 template <typename LayerType> struct LayerIteratorPosition { 102 bool represents_target_render_surface; 103 bool represents_contributing_render_surface; 104 bool represents_itself; 105 LayerType* target_render_surface_layer; 106 LayerType* current_layer; 107 }; 108 109 // An iterator class for walking over layers in the 110 // RenderSurface-Layer tree. 111 template <typename LayerType, 112 typename LayerList, 113 typename RenderSurfaceType, 114 typename IteratorActionType> 115 class LayerIterator { 116 typedef LayerIterator<LayerType, 117 LayerList, 118 RenderSurfaceType, 119 IteratorActionType> LayerIteratorType; 120 121 public: 122 LayerIterator() : render_surface_layer_list_(NULL) {} 123 124 static LayerIteratorType Begin(const LayerList* render_surface_layer_list) { 125 return LayerIteratorType(render_surface_layer_list, true); 126 } 127 static LayerIteratorType End(const LayerList* render_surface_layer_list) { 128 return LayerIteratorType(render_surface_layer_list, false); 129 } 130 131 LayerIteratorType& operator++() { 132 actions_.Next(this); 133 return *this; 134 } 135 bool operator==(const LayerIterator& other) const { 136 return target_render_surface_layer_index_ == 137 other.target_render_surface_layer_index_ && 138 current_layer_index_ == other.current_layer_index_; 139 } 140 bool operator!=(const LayerIteratorType& other) const { 141 return !(*this == other); 142 } 143 144 LayerType* operator->() const { return current_layer(); } 145 LayerType* operator*() const { return current_layer(); } 146 147 bool represents_target_render_surface() const { 148 return current_layer_represents_target_render_surface(); 149 } 150 bool represents_contributing_render_surface() const { 151 return !represents_target_render_surface() && 152 current_layer_represents_contributing_render_surface(); 153 } 154 bool represents_itself() const { 155 return !represents_target_render_surface() && 156 !represents_contributing_render_surface(); 157 } 158 159 LayerType* target_render_surface_layer() const { 160 return render_surface_layer_list_->at(target_render_surface_layer_index_); 161 } 162 163 operator const LayerIteratorPosition<LayerType>() const { 164 LayerIteratorPosition<LayerType> position; 165 position.represents_target_render_surface = 166 represents_target_render_surface(); 167 position.represents_contributing_render_surface = 168 represents_contributing_render_surface(); 169 position.represents_itself = represents_itself(); 170 position.target_render_surface_layer = target_render_surface_layer(); 171 position.current_layer = current_layer(); 172 return position; 173 } 174 175 private: 176 LayerIterator(const LayerList* render_surface_layer_list, bool start) 177 : render_surface_layer_list_(render_surface_layer_list), 178 target_render_surface_layer_index_(0) { 179 for (size_t i = 0; i < render_surface_layer_list->size(); ++i) { 180 if (!render_surface_layer_list->at(i)->render_surface()) { 181 NOTREACHED(); 182 actions_.End(this); 183 return; 184 } 185 } 186 187 if (start && !render_surface_layer_list->empty()) 188 actions_.Begin(this); 189 else 190 actions_.End(this); 191 } 192 193 inline LayerType* current_layer() const { 194 return current_layer_represents_target_render_surface() 195 ? target_render_surface_layer() 196 : target_render_surface_children().at(current_layer_index_); 197 } 198 199 inline bool current_layer_represents_contributing_render_surface() const { 200 return LayerTreeHostCommon::RenderSurfaceContributesToTarget<LayerType>( 201 current_layer(), target_render_surface_layer()->id()); 202 } 203 inline bool current_layer_represents_target_render_surface() const { 204 return current_layer_index_ == 205 LayerIteratorValue::kLayerIndexRepresentingTargetRenderSurface; 206 } 207 208 inline RenderSurfaceType* target_render_surface() const { 209 return target_render_surface_layer()->render_surface(); 210 } 211 inline const LayerList& target_render_surface_children() const { 212 return target_render_surface()->layer_list(); 213 } 214 215 IteratorActionType actions_; 216 const LayerList* render_surface_layer_list_; 217 218 // The iterator's current position. 219 220 // A position in the render_surface_layer_list. This points to a layer which 221 // owns the current target surface. This is a value from 0 to n-1 222 // (n = size of render_surface_layer_list = number of surfaces). 223 // A value outside of this range 224 // (for example, LayerIteratorValue::kInvalidTargetRenderSurfaceLayerIndex) 225 // is used to indicate a position outside the bounds of the tree. 226 int target_render_surface_layer_index_; 227 // A position in the list of layers that are children of the 228 // current target surface. When pointing to one of these layers, 229 // this is a value from 0 to n-1 (n = number of children). 230 // Since the iterator must also stop at the layers representing 231 // the target surface, this is done by setting the current_layerIndex 232 // to a value of LayerIteratorValue::LayerRepresentingTargetRenderSurface. 233 int current_layer_index_; 234 235 friend struct LayerIteratorActions; 236 }; 237 238 // Orderings for iterating over the RenderSurface-Layer tree. 239 struct CC_EXPORT LayerIteratorActions { 240 // Walks layers sorted by z-order from back to front. 241 class CC_EXPORT BackToFront { 242 public: 243 template <typename LayerType, 244 typename LayerList, 245 typename RenderSurfaceType, 246 typename ActionType> 247 void Begin( 248 LayerIterator<LayerType, LayerList, RenderSurfaceType, ActionType>* it); 249 250 template <typename LayerType, 251 typename LayerList, 252 typename RenderSurfaceType, 253 typename ActionType> 254 void End( 255 LayerIterator<LayerType, LayerList, RenderSurfaceType, ActionType>* it); 256 257 template <typename LayerType, 258 typename LayerList, 259 typename RenderSurfaceType, 260 typename ActionType> 261 void Next( 262 LayerIterator<LayerType, LayerList, RenderSurfaceType, ActionType>* it); 263 264 private: 265 int highest_target_render_surface_layer_; 266 }; 267 268 // Walks layers sorted by z-order from front to back 269 class CC_EXPORT FrontToBack { 270 public: 271 template <typename LayerType, 272 typename LayerList, 273 typename RenderSurfaceType, 274 typename ActionType> 275 void Begin( 276 LayerIterator<LayerType, LayerList, RenderSurfaceType, ActionType>* it); 277 278 template <typename LayerType, 279 typename LayerList, 280 typename RenderSurfaceType, 281 typename ActionType> 282 void End( 283 LayerIterator<LayerType, LayerList, RenderSurfaceType, ActionType>* it); 284 285 template <typename LayerType, 286 typename LayerList, 287 typename RenderSurfaceType, 288 typename ActionType> 289 void Next( 290 LayerIterator<LayerType, LayerList, RenderSurfaceType, ActionType>* it); 291 292 private: 293 template <typename LayerType, 294 typename LayerList, 295 typename RenderSurfaceType, 296 typename ActionType> 297 void GoToHighestInSubtree( 298 LayerIterator<LayerType, LayerList, RenderSurfaceType, ActionType>* it); 299 }; 300 }; 301 302 } // namespace cc 303 304 #endif // CC_LAYERS_LAYER_ITERATOR_H_ 305