1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131

cc / layers / effect_tree_layer_list_iterator.h [blame]

// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CC_LAYERS_EFFECT_TREE_LAYER_LIST_ITERATOR_H_
#define CC_LAYERS_EFFECT_TREE_LAYER_LIST_ITERATOR_H_

#include "base/memory/raw_ptr_exclusion.h"
#include "base/notreached.h"
#include "cc/cc_export.h"
#include "cc/trees/effect_node.h"
#include "cc/trees/layer_tree_impl.h"
#include "cc/trees/property_tree.h"

namespace cc {

class LayerImpl;
class LayerTreeImpl;

// This iterates over layers and render surfaces in front-to-back order (that
// is, in reverse-draw-order). Only layers that draw content to some render
// surface are visited. A render surface is visited immediately after all
// layers and surfaces that contribute content to that surface are visited.
// Surfaces are first visited in state kTargetSurface. Immediately after that,
// every surface other than the root surface is visited in state
// kContributingSurface, as it contributes to the next target surface.
//
// The iterator takes on the following states:
// 1. kLayer: The iterator is visiting layer |current_layer()| that contributes
//    to surface |target_render_surface()|.
// 2. kTargetSurface: The iterator is visiting render surface
//    |target_render_surface()|.
// 3. kContributingSurface: The iterator is visiting render surface
//    |current_render_surface()| that contributes to surface
//    |target_render_surface()|.
// 4. kEnd: All layers and render surfaces have already been visited.
class CC_EXPORT EffectTreeLayerListIterator {
 public:
  enum class State { kLayer, kTargetSurface, kContributingSurface, kEnd };

  explicit EffectTreeLayerListIterator(LayerTreeImpl* layer_tree_impl);
  EffectTreeLayerListIterator(const EffectTreeLayerListIterator& iterator);
  ~EffectTreeLayerListIterator();

  void operator++();

  State state() { return state_; }

  LayerImpl* current_layer() const {
    DCHECK(state_ == State::kLayer);
    return *layer_list_iterator_;
  }

  RenderSurfaceImpl* current_render_surface() const {
    DCHECK(state_ == State::kContributingSurface);
    return effect_tree_->GetRenderSurface(current_effect_tree_index_);
  }

  RenderSurfaceImpl* target_render_surface() const {
    switch (state_) {
      case State::kLayer:
      case State::kTargetSurface:
        return effect_tree_->GetRenderSurface(current_effect_tree_index_);
      case State::kContributingSurface: {
        int target_node_id =
            effect_tree_->Node(current_effect_tree_index_)->target_id;
        return effect_tree_->GetRenderSurface(target_node_id);
      }
      case State::kEnd:
        NOTREACHED();
    }
    NOTREACHED();
  }

  struct Position {
    State state = State::kEnd;
    // RAW_PTR_EXCLUSION: Renderer performance: visible in sampling profiler
    // stacks.
    RAW_PTR_EXCLUSION LayerImpl* current_layer = nullptr;
    RAW_PTR_EXCLUSION RenderSurfaceImpl* current_render_surface = nullptr;
    RAW_PTR_EXCLUSION RenderSurfaceImpl* target_render_surface = nullptr;
  };

  operator const Position() const {
    Position position;
    if (state_ == State::kEnd) {
      return position;
    }

    position.state = state_;
    position.target_render_surface = target_render_surface();
    if (state_ == State::kLayer) {
      position.current_layer = current_layer();
    } else if (state_ == State::kContributingSurface) {
      position.current_render_surface = current_render_surface();
    }

    return position;
  }

 private:
  State state_;

  // When in state kLayer, this is the layer that's currently being visited.
  // Otherwise, this is the layer that will be visited the next time we're in
  // state kLayer.
  LayerTreeImpl::const_reverse_iterator layer_list_iterator_;

  // When in state kLayer, this is the render target effect tree index for the
  // currently visited layer. Otherwise, this is the the effect tree index of
  // the currently visited render surface.
  int current_effect_tree_index_;

  // Render target effect tree index for the layer currently visited by
  // layer_list_iterator_.
  int next_effect_tree_index_;

  // The index in the effect tree of the lowest common ancestor
  // current_effect_tree_index_ and next_effect_tree_index_, that has a
  // render surface.
  int lowest_common_effect_tree_ancestor_index_;

  // RAW_PTR_EXCLUSION: Renderer performance: visible in sampling profiler
  // stacks.
  RAW_PTR_EXCLUSION LayerTreeImpl* layer_tree_impl_;
  RAW_PTR_EXCLUSION EffectTree* effect_tree_;
};

}  // namespace cc

#endif  // CC_LAYERS_EFFECT_TREE_LAYER_LIST_ITERATOR_H_