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

Side by Side Diff: cc/trees/property_tree.cc

Issue 687873004: Introduce Property Trees (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@wip-awoloszyn2
Patch Set: . Created 6 years 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 2014 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 <set>
6
7 #include "base/logging.h"
8 #include "cc/trees/property_tree.h"
9
10 namespace cc {
11
12 template <typename T>
13 PropertyTree<T>::PropertyTree() {
14 nodes_.push_back(T());
15 back()->id = 0;
16 back()->parent_id = -1;
17 }
18
19 template <typename T>
20 PropertyTree<T>::~PropertyTree() {
21 }
22
23 template <typename T>
24 int PropertyTree<T>::Insert(const T& tree_node, int parent_id) {
25 DCHECK_GT(nodes_.size(), 0u);
26 nodes_.push_back(tree_node);
27 T& node = nodes_.back();
28 node.parent_id = parent_id;
29 node.id = static_cast<int>(nodes_.size()) - 1;
30 return node.id;
31 }
32
33 template class PropertyTree<TransformNode>;
34 template class PropertyTree<ClipNode>;
35
36 TransformNodeData::TransformNodeData()
37 : target_id(-1),
38 is_invertible(true),
39 ancestors_are_invertible(true),
40 flattens(false) {
41 }
42
43 TransformNodeData::~TransformNodeData() {
44 }
45
46 ClipNodeData::ClipNodeData() : transform_id(-1), target_id(-1) {
47 }
48
49 bool IsDescendant(const TransformTree& tree, int desc_id, int source_id) {
50 while (desc_id != source_id) {
51 if (desc_id < 0)
52 return false;
53 desc_id = tree.Node(desc_id)->parent_id;
54 }
55 return true;
56 }
57
58 int LowestCommonAncestor(const TransformTree& tree, int a, int b) {
59 std::set<int> chain_a;
60 std::set<int> chain_b;
61 while (a || b) {
62 if (a) {
63 a = tree.Node(a)->parent_id;
64 if (a > -1 && chain_b.find(a) != chain_b.end())
65 return a;
66 chain_a.insert(a);
67 }
68 if (b) {
69 b = tree.Node(b)->parent_id;
70 if (b > -1 && chain_a.find(b) != chain_a.end())
71 return b;
72 chain_b.insert(b);
73 }
74 }
75 NOTREACHED();
76 return 0;
77 }
78
79 bool CombineTransformsBetween(const TransformTree& tree,
80 int source_id,
81 int dest_id,
82 gfx::Transform* transform) {
83 const TransformNode* current = tree.Node(source_id);
84 const TransformNode* dest = tree.Node(dest_id);
85 if (!dest || dest->data.ancestors_are_invertible) {
86 transform->ConcatTransform(current->data.to_screen);
87 if (dest)
88 transform->ConcatTransform(dest->data.from_screen);
89 return true;
90 }
91
92 bool all_are_invertible = true;
93 for (; current && current->id > dest_id; current = tree.parent(current)) {
94 transform->ConcatTransform(current->data.to_parent);
95 if (!current->data.is_invertible)
96 all_are_invertible = false;
97 }
98
99 return all_are_invertible;
100 }
101
102 bool CombineInversesBetween(const TransformTree& tree,
103 int source_id,
104 int dest_id,
105 gfx::Transform* transform) {
106 const TransformNode* current = tree.Node(dest_id);
107 const TransformNode* dest = tree.Node(source_id);
108 if (current->data.ancestors_are_invertible) {
109 transform->PreconcatTransform(current->data.from_screen);
110 if (dest)
111 transform->PreconcatTransform(dest->data.to_screen);
112 return true;
113 }
114
115 bool all_are_invertible = true;
116 for (; current && current->id > source_id; current = tree.parent(current)) {
117 transform->PreconcatTransform(current->data.from_parent);
118 if (!current->data.is_invertible)
119 all_are_invertible = false;
120 }
121
122 return all_are_invertible;
123 }
124
125 bool ComputeTransform(const TransformTree& tree,
enne (OOO) 2014/12/10 23:45:59 This probably needs a note that transform should b
Ian Vollick 2014/12/12 03:01:47 I actually take advantage of the fact that it does
enne (OOO) 2014/12/12 19:05:49 It still looks to me like you're just passing iden
Ian Vollick 2014/12/15 21:45:17 Sorry, I pointed you at the wrong function. But in
126 int source_id,
127 int dest_id,
128 gfx::Transform* transform) {
129 if (source_id == dest_id)
130 return true;
131
132 if (source_id > dest_id && IsDescendant(tree, source_id, dest_id))
133 return CombineTransformsBetween(tree, source_id, dest_id, transform);
134
135 if (dest_id > source_id && IsDescendant(tree, dest_id, source_id))
136 return CombineInversesBetween(tree, source_id, dest_id, transform);
137
138 int lca = LowestCommonAncestor(tree, source_id, dest_id);
139
140 bool no_singular_matrices_to_lca =
141 CombineTransformsBetween(tree, source_id, lca, transform);
142
143 bool no_singular_matrices_from_lca =
144 CombineInversesBetween(tree, lca, dest_id, transform);
145
146 return no_singular_matrices_to_lca && no_singular_matrices_from_lca;
147 }
148
149 bool Are2DAxisAligned(const TransformTree& tree, int source_id, int dest_id) {
150 gfx::Transform transform;
151 return ComputeTransform(tree, source_id, dest_id, &transform) &&
152 transform.Preserves2dAxisAlignment();
153 }
154
155 void UpdateScreenSpaceTransform(TransformTree* tree, int id) {
156 TransformNode* node = tree->Node(id);
157 TransformNode* parent = tree->parent(node);
158 TransformNode* target = tree->Node(node->data.target_id);
159
160 if (!parent) {
161 node->data.to_screen = node->data.to_parent;
162 node->data.ancestors_are_invertible = true;
163 } else if (parent->data.flattens) {
164 // Flattening is tricky. Once a layer is drawn into its render target, it
165 // cannot escape, so we only need to consider transforms between the layer
166 // and its target when flattening (i.e., its draw transform). To compute the
167 // screen space transform when flattening is involved we combine three
168 // transforms, A * B * C, where A is the screen space transform of the
169 // target, B is the flattened draw transform of the layer's parent, and C is
170 // the local transform.
171 node->data.to_screen = target->data.to_screen;
172 gfx::Transform flattened;
173 ComputeTransform(*tree, parent->id, target->id, &flattened);
174 flattened.FlattenTo2d();
175 node->data.to_screen.PreconcatTransform(flattened);
176 node->data.to_screen.PreconcatTransform(node->data.to_parent);
177 node->data.ancestors_are_invertible = parent->data.ancestors_are_invertible;
178 } else {
179 node->data.to_screen = parent->data.to_screen;
180 node->data.to_screen.PreconcatTransform(node->data.to_parent);
181 node->data.ancestors_are_invertible = parent->data.ancestors_are_invertible;
182 }
183 if (!node->data.to_screen.GetInverse(&node->data.from_screen))
184 node->data.ancestors_are_invertible = false;
185 }
186
187 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698