Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(115)

Side by Side Diff: cc/layers/effect_tree_layer_list_iterator.cc

Issue 2751783002: cc: Replace LayerIterator with iterator that walks layer list and effect tree (Closed)
Patch Set: Rebase Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 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 #include "cc/layers/effect_tree_layer_list_iterator.h"
6
7 namespace cc {
8
9 EffectTreeLayerListIterator::EffectTreeLayerListIterator(
10 LayerTreeImpl* layer_tree_impl)
11 : state_(EffectTreeLayerListIterator::State::END),
12 current_effect_tree_index_(EffectTree::kInvalidNodeId),
13 next_effect_tree_index_(EffectTree::kInvalidNodeId),
14 lowest_common_effect_tree_ancestor_index_(EffectTree::kInvalidNodeId),
15 layer_tree_impl_(layer_tree_impl),
16 effect_tree_(&layer_tree_impl->property_trees()->effect_tree) {
17 layer_list_iterator_ = layer_tree_impl->rbegin();
18
19 // Find the front-most drawn layer.
20 while (
21 layer_list_iterator_ != layer_tree_impl->rend() &&
22 !(*layer_list_iterator_)->is_drawn_render_surface_layer_list_member()) {
23 layer_list_iterator_++;
24 }
25
26 // If there are no drawn layers, start at the root render surface, if it
27 // exists.
28 if (layer_list_iterator_ == layer_tree_impl->rend()) {
29 DCHECK(effect_tree_->size() > EffectTree::kContentsRootNodeId);
30 state_ = State::TARGET_SURFACE;
31 current_effect_tree_index_ = EffectTree::kContentsRootNodeId;
32 } else {
33 state_ = State::LAYER;
34 current_effect_tree_index_ =
35 (*layer_list_iterator_)->render_target_effect_tree_index();
36 next_effect_tree_index_ = current_effect_tree_index_;
37 lowest_common_effect_tree_ancestor_index_ = current_effect_tree_index_;
38 }
39 }
40
41 EffectTreeLayerListIterator::EffectTreeLayerListIterator(
42 const EffectTreeLayerListIterator& iterator) = default;
43
44 EffectTreeLayerListIterator::~EffectTreeLayerListIterator() {}
45
46 // Finds the lowest common ancestor that has a render surface.
47 static int LowestCommonAncestor(int effect_id_1,
48 int effect_id_2,
49 const EffectTree* effect_tree) {
50 while (effect_id_1 != effect_id_2) {
51 if (effect_id_1 < effect_id_2)
52 effect_id_2 = effect_tree->Node(effect_id_2)->target_id;
53 else
54 effect_id_1 = effect_tree->Node(effect_id_1)->target_id;
55 }
56
57 return effect_id_1;
58 }
59
60 void EffectTreeLayerListIterator::operator++() {
61 switch (state_) {
62 case State::LAYER:
63 // Find the next drawn layer.
64 layer_list_iterator_++;
65 while (layer_list_iterator_ != layer_tree_impl_->rend() &&
66 !(*layer_list_iterator_)
67 ->is_drawn_render_surface_layer_list_member()) {
68 layer_list_iterator_++;
69 }
70 if (layer_list_iterator_ == layer_tree_impl_->rend()) {
71 next_effect_tree_index_ = EffectTree::kInvalidNodeId;
72 lowest_common_effect_tree_ancestor_index_ = EffectTree::kInvalidNodeId;
73 state_ = State::TARGET_SURFACE;
74 break;
75 }
76
77 next_effect_tree_index_ =
78 (*layer_list_iterator_)->render_target_effect_tree_index();
79
80 // If the next drawn layer has a different target effect tree index, check
81 // for surfaces whose contributors have all been visited.
82 if (next_effect_tree_index_ != current_effect_tree_index_) {
83 lowest_common_effect_tree_ancestor_index_ = LowestCommonAncestor(
84 current_effect_tree_index_, next_effect_tree_index_, effect_tree_);
85 // If the current layer's target effect node is an ancestor of the next
86 // layer's target effect node, then the current effect node still has
87 // more contributors that need to be visited. Otherwise, all
88 // contributors have been visited, so we visit the node's surface next.
89 if (current_effect_tree_index_ ==
90 lowest_common_effect_tree_ancestor_index_) {
91 current_effect_tree_index_ = next_effect_tree_index_;
92 lowest_common_effect_tree_ancestor_index_ = next_effect_tree_index_;
93 } else {
94 state_ = State::TARGET_SURFACE;
95 }
96 }
97 break;
98 case State::TARGET_SURFACE:
99 if (current_effect_tree_index_ == EffectTree::kContentsRootNodeId) {
100 current_effect_tree_index_ = EffectTree::kInvalidNodeId;
101 state_ = State::END;
102 DCHECK(next_effect_tree_index_ == EffectTree::kInvalidNodeId);
103 DCHECK(layer_list_iterator_ == layer_tree_impl_->rend());
104 } else {
105 state_ = State::CONTRIBUTING_SURFACE;
106 }
107 break;
108 case State::CONTRIBUTING_SURFACE:
109 DCHECK(current_effect_tree_index_ !=
110 lowest_common_effect_tree_ancestor_index_);
111 // Step towards the lowest common ancestor.
112 current_effect_tree_index_ =
113 effect_tree_->Node(current_effect_tree_index_)->target_id;
114 if (current_effect_tree_index_ == next_effect_tree_index_) {
115 state_ = State::LAYER;
116 } else if (current_effect_tree_index_ ==
117 lowest_common_effect_tree_ancestor_index_) {
118 // In this case, we know that more content contributes to the current
119 // effect node (since the next effect node is a descendant), so we're
120 // not yet ready to visit it as a target surface. The same holds for all
121 // effect nodes on the path from the current node to the next effect
122 // tree node.
123 state_ = State::LAYER;
124 current_effect_tree_index_ = next_effect_tree_index_;
125 lowest_common_effect_tree_ancestor_index_ = next_effect_tree_index_;
126 } else {
127 // In this case, the lowest common ancestor is a proper ancestor of the
128 // current effect node. This means that all contributors to the current
129 // effect node have been visited, so we're ready to visit it as a target
130 // surface.
131 state_ = State::TARGET_SURFACE;
132 }
133 break;
134 case State::END:
135 NOTREACHED();
136 }
137 }
138
139 } // namespace cc
OLDNEW
« no previous file with comments | « cc/layers/effect_tree_layer_list_iterator.h ('k') | cc/layers/effect_tree_layer_list_iterator_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698