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
12namespace 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
88struct 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.
98template <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.
108template <typename LayerType,
109          typename LayerList,
110          typename RenderSurfaceType,
111          typename IteratorActionType>
112class LayerIterator {
113  typedef LayerIterator<LayerType,
114                        LayerList,
115                        RenderSurfaceType,
116                        IteratorActionType> LayerIteratorType;
117
118 public:
119  LayerIterator() : render_surface_layer_list_(NULL) {}
120
121  static LayerIteratorType Begin(const LayerList* render_surface_layer_list) {
122    return LayerIteratorType(render_surface_layer_list, true);
123  }
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
144  bool represents_target_render_surface() const {
145    return current_layer_represents_target_render_surface();
146  }
147  bool represents_contributing_render_surface() const {
148    return !represents_target_render_surface() &&
149           current_layer_represents_contributing_render_surface();
150  }
151  bool represents_itself() const {
152    return !represents_target_render_surface() &&
153           !represents_contributing_render_surface();
154  }
155
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:
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
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
196  inline bool current_layer_represents_contributing_render_surface() const {
197    return LayerTreeHostCommon::RenderSurfaceContributesToTarget<LayerType>(
198        current_layer(), target_render_surface_layer()->id());
199  }
200  inline bool current_layer_represents_target_render_surface() const {
201    return current_layer_index_ ==
202           LayerIteratorValue::kLayerIndexRepresentingTargetRenderSurface;
203  }
204
205  inline RenderSurfaceType* target_render_surface() const {
206    return target_render_surface_layer()->render_surface();
207  }
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.
236struct 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