blob: c9991638ed0abaf0bd2d9217c77e029296002412 [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// 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 "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 TARGET_SURFACE. Immediately after that,
// every surface other than the root surface is visited in state
// CONTRIBUTING_SURFACE, as it contributes to the next target surface.
//
// The iterator takes on the following states:
// 1. LAYER: The iterator is visiting layer |current_layer()| that contributes
// to surface |target_render_surface()|.
// 2. TARGET_SURFACE: The iterator is visiting render surface
// |target_render_surface()|.
// 3. CONTRIBUTING_SURFACE: The iterator is visiting render surface
// |current_render_surface()| that contributes to surface
// |target_render_surface()|.
// 4. END: All layers and render surfaces have already been visited.
class CC_EXPORT EffectTreeLayerListIterator {
public:
enum class State { LAYER, TARGET_SURFACE, CONTRIBUTING_SURFACE, END };
explicit EffectTreeLayerListIterator(LayerTreeImpl* layer_tree_impl);
EffectTreeLayerListIterator(const EffectTreeLayerListIterator& iterator);
~EffectTreeLayerListIterator();
void operator++();
State state() { return state_; }
LayerImpl* current_layer() const {
DCHECK(state_ == State::LAYER);
return *layer_list_iterator_;
}
RenderSurfaceImpl* current_render_surface() const {
DCHECK(state_ == State::CONTRIBUTING_SURFACE);
return effect_tree_->GetRenderSurface(current_effect_tree_index_);
}
RenderSurfaceImpl* target_render_surface() const {
switch (state_) {
case State::LAYER:
case State::TARGET_SURFACE:
return effect_tree_->GetRenderSurface(current_effect_tree_index_);
case State::CONTRIBUTING_SURFACE: {
int target_node_id =
effect_tree_->Node(current_effect_tree_index_)->target_id;
return effect_tree_->GetRenderSurface(target_node_id);
}
case State::END:
NOTREACHED();
}
NOTREACHED();
return nullptr;
}
struct Position {
State state = State::END;
LayerImpl* current_layer = nullptr;
RenderSurfaceImpl* current_render_surface = nullptr;
RenderSurfaceImpl* target_render_surface = nullptr;
};
operator const Position() const {
Position position;
if (state_ == State::END)
return position;
position.state = state_;
position.target_render_surface = target_render_surface();
if (state_ == State::LAYER)
position.current_layer = current_layer();
else if (state_ == State::CONTRIBUTING_SURFACE)
position.current_render_surface = current_render_surface();
return position;
}
private:
State state_;
// When in state LAYER, 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 LAYER.
LayerImplList::reverse_iterator layer_list_iterator_;
// When in state LAYER, 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_;
LayerTreeImpl* layer_tree_impl_;
EffectTree* effect_tree_;
};
} // namespace cc
#endif // CC_LAYERS_EFFECT_TREE_LAYER_LIST_ITERATOR_H_