OLD | NEW |
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 #include <vector> | 6 #include <vector> |
7 | 7 |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "cc/base/math_util.h" | 9 #include "cc/base/math_util.h" |
10 #include "cc/trees/property_tree.h" | 10 #include "cc/trees/property_tree.h" |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
58 } | 58 } |
59 | 59 |
60 bool TransformTree::ComputeTransform(int source_id, | 60 bool TransformTree::ComputeTransform(int source_id, |
61 int dest_id, | 61 int dest_id, |
62 gfx::Transform* transform) const { | 62 gfx::Transform* transform) const { |
63 transform->MakeIdentity(); | 63 transform->MakeIdentity(); |
64 | 64 |
65 if (source_id == dest_id) | 65 if (source_id == dest_id) |
66 return true; | 66 return true; |
67 | 67 |
68 if (source_id > dest_id && IsDescendant(source_id, dest_id)) | 68 if (source_id > dest_id) { |
| 69 DCHECK(IsDescendant(source_id, dest_id)); |
69 return CombineTransformsBetween(source_id, dest_id, transform); | 70 return CombineTransformsBetween(source_id, dest_id, transform); |
| 71 } |
70 | 72 |
71 if (dest_id > source_id && IsDescendant(dest_id, source_id)) | 73 DCHECK(IsDescendant(dest_id, source_id)); |
72 return CombineInversesBetween(source_id, dest_id, transform); | 74 return CombineInversesBetween(source_id, dest_id, transform); |
73 | |
74 int lca = LowestCommonAncestor(source_id, dest_id); | |
75 | |
76 bool no_singular_matrices_to_lca = | |
77 CombineTransformsBetween(source_id, lca, transform); | |
78 | |
79 bool no_singular_matrices_from_lca = | |
80 CombineInversesBetween(lca, dest_id, transform); | |
81 | |
82 return no_singular_matrices_to_lca && no_singular_matrices_from_lca; | |
83 } | 75 } |
84 | 76 |
85 bool TransformTree::Are2DAxisAligned(int source_id, int dest_id) const { | 77 bool TransformTree::Are2DAxisAligned(int source_id, int dest_id) const { |
86 gfx::Transform transform; | 78 gfx::Transform transform; |
87 return ComputeTransform(source_id, dest_id, &transform) && | 79 return ComputeTransform(source_id, dest_id, &transform) && |
88 transform.Preserves2dAxisAlignment(); | 80 transform.Preserves2dAxisAlignment(); |
89 } | 81 } |
90 | 82 |
91 void TransformTree::UpdateTransforms(int id) { | 83 void TransformTree::UpdateTransforms(int id) { |
92 TransformNode* node = Node(id); | 84 TransformNode* node = Node(id); |
(...skipping 10 matching lines...) Expand all Loading... |
103 | 95 |
104 bool TransformTree::IsDescendant(int desc_id, int source_id) const { | 96 bool TransformTree::IsDescendant(int desc_id, int source_id) const { |
105 while (desc_id != source_id) { | 97 while (desc_id != source_id) { |
106 if (desc_id < 0) | 98 if (desc_id < 0) |
107 return false; | 99 return false; |
108 desc_id = Node(desc_id)->parent_id; | 100 desc_id = Node(desc_id)->parent_id; |
109 } | 101 } |
110 return true; | 102 return true; |
111 } | 103 } |
112 | 104 |
113 int TransformTree::LowestCommonAncestor(int a, int b) const { | |
114 std::set<int> chain_a; | |
115 std::set<int> chain_b; | |
116 while (a || b) { | |
117 if (a) { | |
118 a = Node(a)->parent_id; | |
119 if (a > -1 && chain_b.find(a) != chain_b.end()) | |
120 return a; | |
121 chain_a.insert(a); | |
122 } | |
123 if (b) { | |
124 b = Node(b)->parent_id; | |
125 if (b > -1 && chain_a.find(b) != chain_a.end()) | |
126 return b; | |
127 chain_b.insert(b); | |
128 } | |
129 } | |
130 NOTREACHED(); | |
131 return 0; | |
132 } | |
133 | |
134 bool TransformTree::CombineTransformsBetween(int source_id, | 105 bool TransformTree::CombineTransformsBetween(int source_id, |
135 int dest_id, | 106 int dest_id, |
136 gfx::Transform* transform) const { | 107 gfx::Transform* transform) const { |
137 const TransformNode* current = Node(source_id); | 108 const TransformNode* current = Node(source_id); |
138 const TransformNode* dest = Node(dest_id); | 109 const TransformNode* dest = Node(dest_id); |
139 // Combine transforms to and from the screen when possible. Since flattening | 110 // Combine transforms to and from the screen when possible. Since flattening |
140 // is a non-linear operation, we cannot use this approach when there is | 111 // is a non-linear operation, we cannot use this approach when there is |
141 // non-trivial flattening between the source and destination nodes. For | 112 // non-trivial flattening between the source and destination nodes. For |
142 // example, consider the tree R->A->B->C, where B flattens its inherited | 113 // example, consider the tree R->A->B->C, where B flattens its inherited |
143 // transform, and A has a non-flat transform. Suppose C is the source and A is | 114 // transform, and A has a non-flat transform. Suppose C is the source and A is |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
324 node->data.from_target.matrix().postTranslate(-translation.x(), | 295 node->data.from_target.matrix().postTranslate(-translation.x(), |
325 -translation.y(), 0); | 296 -translation.y(), 0); |
326 node->data.to_screen.Translate(translation.x(), translation.y()); | 297 node->data.to_screen.Translate(translation.x(), translation.y()); |
327 node->data.from_screen.matrix().postTranslate(-translation.x(), | 298 node->data.from_screen.matrix().postTranslate(-translation.x(), |
328 -translation.y(), 0); | 299 -translation.y(), 0); |
329 | 300 |
330 node->data.scroll_snap = translation; | 301 node->data.scroll_snap = translation; |
331 } | 302 } |
332 | 303 |
333 } // namespace cc | 304 } // namespace cc |
OLD | NEW |