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

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

Issue 935333002: Update from https://crrev.com/316786 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 10 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
« no previous file with comments | « cc/trees/property_tree.h ('k') | cc/trees/property_tree_builder.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <set> 5 #include <set>
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "cc/base/math_util.h"
8 #include "cc/trees/property_tree.h" 9 #include "cc/trees/property_tree.h"
9 10
10 namespace cc { 11 namespace cc {
11 12
12 template <typename T> 13 template <typename T>
13 PropertyTree<T>::PropertyTree() { 14 PropertyTree<T>::PropertyTree() {
14 nodes_.push_back(T()); 15 nodes_.push_back(T());
15 back()->id = 0; 16 back()->id = 0;
16 back()->parent_id = -1; 17 back()->parent_id = -1;
17 } 18 }
(...skipping 10 matching lines...) Expand all
28 node.parent_id = parent_id; 29 node.parent_id = parent_id;
29 node.id = static_cast<int>(nodes_.size()) - 1; 30 node.id = static_cast<int>(nodes_.size()) - 1;
30 return node.id; 31 return node.id;
31 } 32 }
32 33
33 template class PropertyTree<TransformNode>; 34 template class PropertyTree<TransformNode>;
34 template class PropertyTree<ClipNode>; 35 template class PropertyTree<ClipNode>;
35 36
36 TransformNodeData::TransformNodeData() 37 TransformNodeData::TransformNodeData()
37 : target_id(-1), 38 : target_id(-1),
39 content_target_id(-1),
40 needs_local_transform_update(true),
38 is_invertible(true), 41 is_invertible(true),
39 ancestors_are_invertible(true), 42 ancestors_are_invertible(true),
40 is_animated(false), 43 is_animated(false),
41 to_screen_is_animated(false), 44 to_screen_is_animated(false),
42 flattens(false) { 45 flattens(false),
46 scrolls(false),
47 needs_sublayer_scale(false),
48 layer_scale_factor(1.0f) {
43 } 49 }
44 50
45 TransformNodeData::~TransformNodeData() { 51 TransformNodeData::~TransformNodeData() {
46 } 52 }
47 53
48 ClipNodeData::ClipNodeData() : transform_id(-1), target_id(-1) { 54 ClipNodeData::ClipNodeData() : transform_id(-1), target_id(-1) {
49 } 55 }
50 56
51 bool TransformTree::ComputeTransform(int source_id, 57 bool TransformTree::ComputeTransform(int source_id,
52 int dest_id, 58 int dest_id,
(...skipping 19 matching lines...) Expand all
72 78
73 return no_singular_matrices_to_lca && no_singular_matrices_from_lca; 79 return no_singular_matrices_to_lca && no_singular_matrices_from_lca;
74 } 80 }
75 81
76 bool TransformTree::Are2DAxisAligned(int source_id, int dest_id) const { 82 bool TransformTree::Are2DAxisAligned(int source_id, int dest_id) const {
77 gfx::Transform transform; 83 gfx::Transform transform;
78 return ComputeTransform(source_id, dest_id, &transform) && 84 return ComputeTransform(source_id, dest_id, &transform) &&
79 transform.Preserves2dAxisAlignment(); 85 transform.Preserves2dAxisAlignment();
80 } 86 }
81 87
82 void TransformTree::UpdateScreenSpaceTransform(int id) { 88 void TransformTree::UpdateTransforms(int id) {
83 TransformNode* current_node = Node(id); 89 TransformNode* node = Node(id);
84 TransformNode* parent_node = parent(current_node); 90 TransformNode* parent_node = parent(node);
85 TransformNode* target_node = Node(current_node->data.target_id); 91 TransformNode* target_node = Node(node->data.target_id);
86 92 if (node->data.needs_local_transform_update)
87 if (!parent_node) { 93 UpdateLocalTransform(node);
88 current_node->data.to_screen = current_node->data.to_parent; 94 UpdateLocalTransform(node);
89 current_node->data.ancestors_are_invertible = true; 95 UpdateScreenSpaceTransform(node, parent_node, target_node);
90 current_node->data.to_screen_is_animated = false; 96 UpdateSublayerScale(node);
91 } else if (parent_node->data.flattens) { 97 UpdateTargetSpaceTransform(node, target_node);
92 // Flattening is tricky. Once a layer is drawn into its render target, it 98 UpdateIsAnimated(node, parent_node);
93 // cannot escape, so we only need to consider transforms between the layer 99 UpdateSnapping(node);
94 // and its target when flattening (i.e., its draw transform). To compute the
95 // screen space transform when flattening is involved we combine three
96 // transforms, A * B * C, where A is the screen space transform of the
97 // target, B is the flattened draw transform of the layer's parent, and C is
98 // the local transform.
99 current_node->data.to_screen = target_node->data.to_screen;
100 gfx::Transform flattened;
101 ComputeTransform(parent_node->id, target_node->id, &flattened);
102 flattened.FlattenTo2d();
103 current_node->data.to_screen.PreconcatTransform(flattened);
104 current_node->data.to_screen.PreconcatTransform(
105 current_node->data.to_parent);
106 current_node->data.ancestors_are_invertible =
107 parent_node->data.ancestors_are_invertible;
108 } else {
109 current_node->data.to_screen = parent_node->data.to_screen;
110 current_node->data.to_screen.PreconcatTransform(
111 current_node->data.to_parent);
112 current_node->data.ancestors_are_invertible =
113 parent_node->data.ancestors_are_invertible;
114 }
115 if (!current_node->data.to_screen.GetInverse(&current_node->data.from_screen))
116 current_node->data.ancestors_are_invertible = false;
117
118 if (parent_node) {
119 current_node->data.to_screen_is_animated =
120 current_node->data.is_animated ||
121 parent_node->data.to_screen_is_animated;
122 }
123 } 100 }
124 101
125 bool TransformTree::IsDescendant(int desc_id, int source_id) const { 102 bool TransformTree::IsDescendant(int desc_id, int source_id) const {
126 while (desc_id != source_id) { 103 while (desc_id != source_id) {
127 if (desc_id < 0) 104 if (desc_id < 0)
128 return false; 105 return false;
129 desc_id = Node(desc_id)->parent_id; 106 desc_id = Node(desc_id)->parent_id;
130 } 107 }
131 return true; 108 return true;
132 } 109 }
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 bool all_are_invertible = true; 166 bool all_are_invertible = true;
190 for (; current && current->id > source_id; current = parent(current)) { 167 for (; current && current->id > source_id; current = parent(current)) {
191 transform->PreconcatTransform(current->data.from_parent); 168 transform->PreconcatTransform(current->data.from_parent);
192 if (!current->data.is_invertible) 169 if (!current->data.is_invertible)
193 all_are_invertible = false; 170 all_are_invertible = false;
194 } 171 }
195 172
196 return all_are_invertible; 173 return all_are_invertible;
197 } 174 }
198 175
176 void TransformTree::UpdateLocalTransform(TransformNode* node) {
177 gfx::Transform transform = node->data.post_local;
178 transform.Translate(-node->data.scroll_offset.x(),
179 -node->data.scroll_offset.y());
180 transform.PreconcatTransform(node->data.local);
181 transform.PreconcatTransform(node->data.pre_local);
182 node->data.set_to_parent(transform);
183 node->data.needs_local_transform_update = false;
184 }
185
186 void TransformTree::UpdateScreenSpaceTransform(TransformNode* node,
187 TransformNode* parent_node,
188 TransformNode* target_node) {
189 if (!parent_node) {
190 node->data.to_screen = node->data.to_parent;
191 node->data.ancestors_are_invertible = true;
192 node->data.to_screen_is_animated = false;
193 } else if (parent_node->data.flattens) {
194 // Flattening is tricky. Once a layer is drawn into its render target, it
195 // cannot escape, so we only need to consider transforms between the layer
196 // and its target when flattening (i.e., its draw transform). To compute the
197 // screen space transform when flattening is involved we combine three
198 // transforms, A * B * C, where A is the screen space transform of the
199 // target, B is the flattened draw transform of the layer's parent, and C is
200 // the local transform.
201 node->data.to_screen = target_node->data.to_screen;
202 gfx::Transform flattened;
203 ComputeTransform(parent_node->id, target_node->id, &flattened);
204 flattened.FlattenTo2d();
205 node->data.to_screen.PreconcatTransform(flattened);
206 node->data.to_screen.PreconcatTransform(node->data.to_parent);
207 node->data.ancestors_are_invertible =
208 parent_node->data.ancestors_are_invertible;
209 } else {
210 node->data.to_screen = parent_node->data.to_screen;
211 node->data.to_screen.PreconcatTransform(node->data.to_parent);
212 node->data.ancestors_are_invertible =
213 parent_node->data.ancestors_are_invertible;
214 }
215
216 if (!node->data.to_screen.GetInverse(&node->data.from_screen))
217 node->data.ancestors_are_invertible = false;
218 }
219
220 void TransformTree::UpdateSublayerScale(TransformNode* node) {
221 // The sublayer scale depends on the screen space transform, so update it too.
222 node->data.sublayer_scale =
223 node->data.needs_sublayer_scale
224 ? MathUtil::ComputeTransform2dScaleComponents(
225 node->data.to_screen, node->data.layer_scale_factor)
226 : gfx::Vector2dF(1.0f, 1.0f);
227 }
228
229 void TransformTree::UpdateTargetSpaceTransform(TransformNode* node,
230 TransformNode* target_node) {
231 node->data.to_target.MakeIdentity();
232 if (node->data.needs_sublayer_scale) {
233 node->data.to_target.Scale(node->data.sublayer_scale.x(),
234 node->data.sublayer_scale.y());
235 } else {
236 const bool target_is_root_surface = target_node->id == 1;
237 // In order to include the root transform for the root surface, we walk up
238 // to the root of the transform tree in ComputeTransform.
239 int target_id = target_is_root_surface ? 0 : target_node->id;
240 if (target_node) {
241 node->data.to_target.Scale(target_node->data.sublayer_scale.x(),
242 target_node->data.sublayer_scale.y());
243 }
244
245 gfx::Transform unscaled_target_transform;
246 ComputeTransform(node->id, target_id, &unscaled_target_transform);
247 node->data.to_target.PreconcatTransform(unscaled_target_transform);
248 }
249
250 if (!node->data.to_target.GetInverse(&node->data.from_target))
251 node->data.ancestors_are_invertible = false;
252 }
253
254 void TransformTree::UpdateIsAnimated(TransformNode* node,
255 TransformNode* parent_node) {
256 if (parent_node) {
257 node->data.to_screen_is_animated =
258 node->data.is_animated || parent_node->data.to_screen_is_animated;
259 }
260 }
261
262 void TransformTree::UpdateSnapping(TransformNode* node) {
263 if (!node->data.scrolls || node->data.to_screen_is_animated ||
264 !node->data.to_target.IsScaleOrTranslation()) {
265 return;
266 }
267
268 // Scroll snapping must be done in target space (the pixels we care about).
269 // This means we effectively snap the target space transform. If TT is the
270 // target space transform and TT' is TT with its translation components
271 // rounded, then what we're after is the scroll delta X, where TT * X = TT'.
272 // I.e., we want a transform that will realize our scroll snap. It follows
273 // that X = TT^-1 * TT'. We cache TT and TT^-1 to make this more efficient.
274 gfx::Transform rounded = node->data.to_target;
275 rounded.RoundTranslationComponents();
276 gfx::Transform delta = node->data.from_target;
277 delta *= rounded;
278 gfx::Transform inverse_delta(gfx::Transform::kSkipInitialization);
279 bool invertible_delta = delta.GetInverse(&inverse_delta);
280
281 // The delta should be a translation, modulo floating point error, and should
282 // therefore be invertible.
283 DCHECK(invertible_delta);
284
285 // Now that we have our scroll delta, we must apply it to each of our
286 // combined, to/from matrices.
287 node->data.to_parent.PreconcatTransform(delta);
288 node->data.from_parent.ConcatTransform(inverse_delta);
289 node->data.to_target.PreconcatTransform(delta);
290 node->data.from_target.ConcatTransform(inverse_delta);
291 node->data.to_screen.PreconcatTransform(delta);
292 node->data.from_screen.ConcatTransform(inverse_delta);
293 }
294
199 } // namespace cc 295 } // namespace cc
OLDNEW
« no previous file with comments | « cc/trees/property_tree.h ('k') | cc/trees/property_tree_builder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698