12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef CC_LAYERS_LAYER_ITERATOR_H_
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define CC_LAYERS_LAYER_ITERATOR_H_
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/base/cc_export.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/trees/layer_tree_host_common.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace cc {
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// These classes provide means to iterate over the
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// RenderSurface-Layer tree.
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Example code follows, for a tree of Layer/RenderSurface objects.
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// See below for details.
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// void DoStuffOnLayers(
20ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch//     const RenderSurfaceLayerList& render_surface_layer_list) {
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//   typedef LayerIterator<Layer> LayerIteratorType;
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//   LayerIteratorType end =
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//       LayerIteratorType::End(&render_surface_layer_list);
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//   for (LayerIteratorType
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//            it = LayerIteratorType::Begin(&render_surface_layer_list);
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//        it != end;
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//        ++it) {
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//     // Only one of these will be true
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//     if (it.represents_target_render_surface())
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//       foo(*it);  // *it is a layer representing a target RenderSurface
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//     if (it.represents_contributing_render_surface())
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//       bar(*it);  // *it is a layer representing a RenderSurface that
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//                  // contributes to the layer's target RenderSurface
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//     if (it.represents_itself())
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//       baz(*it);  // *it is a layer representing itself,
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//                  // as it contributes to its own target RenderSurface
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//   }
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// }
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// A RenderSurface R may be referred to in one of two different contexts.
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// One RenderSurface is "current" at any time, for whatever operation
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// is being performed. This current surface is referred to as a target surface.
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// For example, when R is being painted it would be the target surface.
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Once R has been painted, its contents may be included into another
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// surface S. While S is considered the target surface when it is being
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// painted, R is called a contributing surface in this context as it
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// contributes to the content of the target surface S.
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The iterator's current position in the tree always points to some layer.
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The state of the iterator indicates the role of the layer,
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// and will be one of the following three states.
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// A single layer L will appear in the iteration process in at least one,
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// and possibly all, of these states.
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 1. Representing the target surface: The iterator in this state,
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// pointing at layer L, indicates that the target RenderSurface
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// is now the surface owned by L. This will occur exactly once for each
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// RenderSurface in the tree.
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 2. Representing a contributing surface: The iterator in this state,
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// pointing at layer L, refers to the RenderSurface owned
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// by L as a contributing surface, without changing the current
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// target RenderSurface.
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 3. Representing itself: The iterator in this state, pointing at layer L,
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// refers to the layer itself, as a child of the
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// current target RenderSurface.
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// The FrontToBack iterator will iterate over children layers of a surface
684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// before the layer representing the surface as a target surface.
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// To use the iterators:
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Create a stepping iterator and end iterator by calling
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// LayerIterator::Begin() and LayerIterator::End() and passing in the
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// list of layers owning target RenderSurfaces. Step through the tree
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// by incrementing the stepping iterator while it is != to
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// the end iterator. At each step the iterator knows what the layer
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// is representing, and you can query the iterator to decide
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// what actions to perform with the layer given what it represents.
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Non-templated constants
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct LayerIteratorValue {
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static const int kInvalidTargetRenderSurfaceLayerIndex = -1;
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This must be -1 since the iterator action code assumes that this value can
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // be reached by subtracting one from the position of the first layer in the
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // current target surface's child layer list, which is 0.
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static const int kLayerIndexRepresentingTargetRenderSurface = -1;
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The position of a layer iterator that is independent
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// of its many template types.
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <typename LayerType> struct LayerIteratorPosition {
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool represents_target_render_surface;
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool represents_contributing_render_surface;
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool represents_itself;
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerType* target_render_surface_layer;
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerType* current_layer;
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// An iterator class for walking over layers in the
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// RenderSurface-Layer tree.
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)template <typename LayerType>
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class LayerIterator {
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  typedef LayerIterator<LayerType> LayerIteratorType;
1065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  typedef typename LayerType::LayerListType LayerList;
1075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  typedef typename LayerType::RenderSurfaceListType RenderSurfaceLayerList;
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  typedef typename LayerType::RenderSurfaceType RenderSurfaceType;
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerIterator() : render_surface_layer_list_(NULL) {}
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  static LayerIteratorType Begin(
1145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      const RenderSurfaceLayerList* render_surface_layer_list) {
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return LayerIteratorType(render_surface_layer_list, true);
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  static LayerIteratorType End(
1185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      const RenderSurfaceLayerList* render_surface_layer_list) {
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return LayerIteratorType(render_surface_layer_list, false);
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerIteratorType& operator++() {
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MoveToNext();
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return *this;
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool operator==(const LayerIterator& other) const {
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return target_render_surface_layer_index_ ==
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           other.target_render_surface_layer_index_ &&
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           current_layer_index_ == other.current_layer_index_;
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool operator!=(const LayerIteratorType& other) const {
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return !(*this == other);
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerType* operator->() const { return current_layer(); }
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerType* operator*() const { return current_layer(); }
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool represents_target_render_surface() const {
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return current_layer_represents_target_render_surface();
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool represents_contributing_render_surface() const {
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return !represents_target_render_surface() &&
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           current_layer_represents_contributing_render_surface();
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool represents_itself() const {
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return !represents_target_render_surface() &&
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           !represents_contributing_render_surface();
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerType* target_render_surface_layer() const {
151ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return render_surface_layer_list_->at(target_render_surface_layer_index_);
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  operator const LayerIteratorPosition<LayerType>() const {
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerIteratorPosition<LayerType> position;
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    position.represents_target_render_surface =
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        represents_target_render_surface();
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    position.represents_contributing_render_surface =
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        represents_contributing_render_surface();
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    position.represents_itself = represents_itself();
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    position.target_render_surface_layer = target_render_surface_layer();
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    position.current_layer = current_layer();
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return position;
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  LayerIterator(const RenderSurfaceLayerList* render_surface_layer_list,
1685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                bool start)
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : render_surface_layer_list_(render_surface_layer_list),
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        target_render_surface_layer_index_(0) {
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (size_t i = 0; i < render_surface_layer_list->size(); ++i) {
172ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      if (!render_surface_layer_list->at(i)->render_surface()) {
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        NOTREACHED();
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        MoveToEnd();
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return;
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (start && !render_surface_layer_list->empty())
1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      MoveToBegin();
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    else
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      MoveToEnd();
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void MoveToBegin() {
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    target_render_surface_layer_index_ = 0;
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    current_layer_index_ = target_render_surface_children().size() - 1;
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MoveToHighestInSubtree();
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void MoveToEnd() {
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    target_render_surface_layer_index_ =
1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        LayerIteratorValue::kInvalidTargetRenderSurfaceLayerIndex;
1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    current_layer_index_ = 0;
1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void MoveToNext() {
1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Moves to the previous layer in the current RS layer list.
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Then we check if the new current layer has its own RS,
2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // in which case there are things in that RS layer list that are higher,
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // so we find the highest layer in that subtree.
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // If we move back past the front of the list,
2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // we jump up to the previous RS layer list, picking up again where we
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // had previously recursed into the current RS layer list.
2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!current_layer_represents_target_render_surface()) {
2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Subtracting one here will eventually cause the current layer
2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // to become that layer representing the target render surface.
2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      --current_layer_index_;
2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      MoveToHighestInSubtree();
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else {
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      while (current_layer_represents_target_render_surface()) {
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        if (!target_render_surface_layer_index_) {
2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          // End of the list.
2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          target_render_surface_layer_index_ =
2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              LayerIteratorValue::kInvalidTargetRenderSurfaceLayerIndex;
2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          current_layer_index_ = 0;
2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          return;
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        }
2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        target_render_surface_layer_index_ =
2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            target_render_surface()->target_render_surface_layer_index_history_;
2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        current_layer_index_ =
2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            target_render_surface()->current_layer_index_history_;
2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      }
2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void MoveToHighestInSubtree() {
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (current_layer_represents_target_render_surface())
2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return;
2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    while (current_layer_represents_contributing_render_surface()) {
2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Save where we were in the current target surface, move to the next one,
2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // and save the target surface that we came from there
2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // so we can go back to it.
2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      target_render_surface()->current_layer_index_history_ =
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          current_layer_index_;
2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      int previous_target_render_surface_layer =
2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          target_render_surface_layer_index_;
2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      for (LayerType* layer = current_layer();
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)           target_render_surface_layer() != layer;
2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)           ++target_render_surface_layer_index_) {
2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      }
2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      current_layer_index_ = target_render_surface_children().size() - 1;
2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      target_render_surface()->target_render_surface_layer_index_history_ =
2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          previous_target_render_surface_layer;
2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  inline LayerType* current_layer() const {
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return current_layer_represents_target_render_surface()
2535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu               ? target_render_surface_layer()
2545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu               : LayerTreeHostCommon::get_layer_as_raw_ptr(
2555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                     target_render_surface_children(), current_layer_index_);
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  inline bool current_layer_represents_contributing_render_surface() const {
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return LayerTreeHostCommon::RenderSurfaceContributesToTarget<LayerType>(
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        current_layer(), target_render_surface_layer()->id());
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  inline bool current_layer_represents_target_render_surface() const {
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return current_layer_index_ ==
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           LayerIteratorValue::kLayerIndexRepresentingTargetRenderSurface;
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  inline RenderSurfaceType* target_render_surface() const {
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return target_render_surface_layer()->render_surface();
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  inline const LayerList& target_render_surface_children() const {
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return target_render_surface()->layer_list();
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  const RenderSurfaceLayerList* render_surface_layer_list_;
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The iterator's current position.
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // A position in the render_surface_layer_list. This points to a layer which
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // owns the current target surface. This is a value from 0 to n-1
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // (n = size of render_surface_layer_list = number of surfaces).
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // A value outside of this range
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // (for example, LayerIteratorValue::kInvalidTargetRenderSurfaceLayerIndex)
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // is used to indicate a position outside the bounds of the tree.
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int target_render_surface_layer_index_;
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // A position in the list of layers that are children of the
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // current target surface. When pointing to one of these layers,
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // this is a value from 0 to n-1 (n = number of children).
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Since the iterator must also stop at the layers representing
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the target surface, this is done by setting the current_layerIndex
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // to a value of LayerIteratorValue::LayerRepresentingTargetRenderSurface.
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int current_layer_index_;
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace cc
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif  // CC_LAYERS_LAYER_ITERATOR_H_
297