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

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: Clean up #includes Created 3 years, 9 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 if (effect_tree_->size() > EffectTree::kContentsRootNodeId &&
jaydasika 2017/03/22 20:49:42 Root render surface should always exist, right ? I
ajuma 2017/03/24 17:25:07 Done. A root render surface exists as long as we h
30 effect_tree_->GetRenderSurface(EffectTree::kContentsRootNodeId)) {
31 state_ = State::TARGET_SURFACE;
32 current_effect_tree_index_ = EffectTree::kContentsRootNodeId;
33 }
34 } else {
35 state_ = State::LAYER;
36 current_effect_tree_index_ =
37 (*layer_list_iterator_)->render_target_effect_tree_index();
38 next_effect_tree_index_ = current_effect_tree_index_;
39 lowest_common_effect_tree_ancestor_index_ = current_effect_tree_index_;
40 }
41 }
42
43 EffectTreeLayerListIterator::EffectTreeLayerListIterator(
44 const EffectTreeLayerListIterator& iterator) = default;
45
46 EffectTreeLayerListIterator::~EffectTreeLayerListIterator() {}
47
48 // Finds the lowest common ancestor that has a render surface.
49 static int LowestCommonAncestor(int effect_id_1,
50 int effect_id_2,
51 const EffectTree* effect_tree) {
52 while (effect_id_1 != effect_id_2) {
53 if (effect_id_1 < effect_id_2)
54 effect_id_2 = effect_tree->Node(effect_id_2)->target_id;
55 else
56 effect_id_1 = effect_tree->Node(effect_id_1)->target_id;
57 }
58
59 return effect_id_1;
60 }
61
62 void EffectTreeLayerListIterator::operator++() {
63 switch (state_) {
64 case State::LAYER:
65 // Find the next drawn layer.
66 layer_list_iterator_++;
67 while (layer_list_iterator_ != layer_tree_impl_->rend() &&
68 !(*layer_list_iterator_)
69 ->is_drawn_render_surface_layer_list_member()) {
70 layer_list_iterator_++;
71 }
72 if (layer_list_iterator_ == layer_tree_impl_->rend()) {
73 next_effect_tree_index_ = EffectTree::kInvalidNodeId;
74 lowest_common_effect_tree_ancestor_index_ = EffectTree::kInvalidNodeId;
75 state_ = State::TARGET_SURFACE;
76 break;
jaydasika 2017/03/22 20:49:42 Should current_effect_tree_index_ be set to Effect
ajuma 2017/03/24 17:25:07 Not necessarily, it should (already) be the render
77 }
78
79 next_effect_tree_index_ =
80 (*layer_list_iterator_)->render_target_effect_tree_index();
81
82 // If the next drawn layer has a different target effect tree index, check
83 // for surfaces whose contributors have all been visited.
84 if (next_effect_tree_index_ != current_effect_tree_index_) {
85 lowest_common_effect_tree_ancestor_index_ = LowestCommonAncestor(
86 current_effect_tree_index_, next_effect_tree_index_, effect_tree_);
87 // If the current layer's target effect node is an ancestor of the next
88 // layer's target effect node, then the current effect node still has
89 // more contributors that need to be visited. Otherwise, all
90 // contributors have been visited, so we visit the node's surface next.
91 if (current_effect_tree_index_ ==
92 lowest_common_effect_tree_ancestor_index_) {
93 current_effect_tree_index_ = next_effect_tree_index_;
94 lowest_common_effect_tree_ancestor_index_ = next_effect_tree_index_;
95 } else {
96 state_ = State::TARGET_SURFACE;
97 }
98 }
99 break;
100 case State::TARGET_SURFACE:
101 if (current_effect_tree_index_ == EffectTree::kContentsRootNodeId) {
102 current_effect_tree_index_ = EffectTree::kInvalidNodeId;
103 state_ = State::END;
104 DCHECK(next_effect_tree_index_ == EffectTree::kInvalidNodeId);
105 DCHECK(layer_list_iterator_ == layer_tree_impl_->rend());
106 } else {
107 state_ = State::CONTRIBUTING_SURFACE;
108 }
109 break;
110 case State::CONTRIBUTING_SURFACE:
111 DCHECK(current_effect_tree_index_ !=
112 lowest_common_effect_tree_ancestor_index_);
113 // Step towards the lowest common ancestor.
114 current_effect_tree_index_ =
115 effect_tree_->Node(current_effect_tree_index_)->target_id;
116 if (current_effect_tree_index_ == next_effect_tree_index_) {
117 state_ = State::LAYER;
118 } else if (current_effect_tree_index_ ==
119 lowest_common_effect_tree_ancestor_index_) {
120 // In this case, we know that more content contributes to the current
121 // effect node (since the next effect node is a descendant), so we're
122 // not yet ready to visit it as a target surface. The same holds for all
123 // effect nodes on the path from the current node to the next effect
124 // tree node.
125 state_ = State::LAYER;
126 current_effect_tree_index_ = next_effect_tree_index_;
127 lowest_common_effect_tree_ancestor_index_ = next_effect_tree_index_;
128 } else {
129 state_ = State::TARGET_SURFACE;
jaydasika 2017/03/22 20:49:42 Is there an underlying assumption here that lowest
ajuma 2017/03/24 17:25:07 No, the assumption is only that the lowest_common_
130 }
131 break;
132 case State::END:
133 NOTREACHED();
134 }
135 }
136
137 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698