Chromium Code Reviews| 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 <stddef.h> | 5 #include <stddef.h> |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 144 | 144 |
| 145 bool TransformTree::ComputeTransform(int source_id, | 145 bool TransformTree::ComputeTransform(int source_id, |
| 146 int dest_id, | 146 int dest_id, |
| 147 gfx::Transform* transform) const { | 147 gfx::Transform* transform) const { |
| 148 transform->MakeIdentity(); | 148 transform->MakeIdentity(); |
| 149 | 149 |
| 150 if (source_id == dest_id) | 150 if (source_id == dest_id) |
| 151 return true; | 151 return true; |
| 152 | 152 |
| 153 if (source_id > dest_id) { | 153 if (source_id > dest_id) { |
| 154 return CombineTransformsBetween(source_id, dest_id, transform); | 154 CombineTransformsBetween(source_id, dest_id, transform); |
| 155 return true; | |
| 155 } | 156 } |
| 156 | 157 |
| 157 return CombineInversesBetween(source_id, dest_id, transform); | 158 return CombineInversesBetween(source_id, dest_id, transform); |
| 158 } | 159 } |
| 159 | 160 |
| 161 bool TransformTree::ComputeTranslation(int source_id, | |
| 162 int dest_id, | |
| 163 gfx::Transform* transform) const { | |
| 164 bool success = ComputeTransform(source_id, dest_id, transform); | |
| 165 DCHECK( | |
| 166 transform->IsApproximatelyIdentityOrTranslation(SkDoubleToMScalar(1e-4))); | |
|
jaydasika
2016/07/28 02:18:04
Had to change this as some browser tests are faili
| |
| 167 return success; | |
| 168 } | |
| 169 | |
| 160 bool TransformTree::NeedsSourceToParentUpdate(TransformNode* node) { | 170 bool TransformTree::NeedsSourceToParentUpdate(TransformNode* node) { |
| 161 return (source_to_parent_updates_allowed() && | 171 return (source_to_parent_updates_allowed() && |
| 162 node->parent_id != node->source_node_id); | 172 node->parent_id != node->source_node_id); |
| 163 } | 173 } |
| 164 | 174 |
| 165 void TransformTree::ResetChangeTracking() { | 175 void TransformTree::ResetChangeTracking() { |
| 166 for (int id = 1; id < static_cast<int>(size()); ++id) { | 176 for (int id = 1; id < static_cast<int>(size()); ++id) { |
| 167 TransformNode* node = Node(id); | 177 TransformNode* node = Node(id); |
| 168 node->transform_changed = false; | 178 node->transform_changed = false; |
| 169 } | 179 } |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 191 | 201 |
| 192 bool TransformTree::IsDescendant(int desc_id, int source_id) const { | 202 bool TransformTree::IsDescendant(int desc_id, int source_id) const { |
| 193 while (desc_id != source_id) { | 203 while (desc_id != source_id) { |
| 194 if (desc_id == kInvalidNodeId) | 204 if (desc_id == kInvalidNodeId) |
| 195 return false; | 205 return false; |
| 196 desc_id = Node(desc_id)->parent_id; | 206 desc_id = Node(desc_id)->parent_id; |
| 197 } | 207 } |
| 198 return true; | 208 return true; |
| 199 } | 209 } |
| 200 | 210 |
| 201 bool TransformTree::CombineTransformsBetween(int source_id, | 211 void TransformTree::CombineTransformsBetween(int source_id, |
| 202 int dest_id, | 212 int dest_id, |
| 203 gfx::Transform* transform) const { | 213 gfx::Transform* transform) const { |
| 204 DCHECK(source_id > dest_id); | 214 DCHECK(source_id > dest_id); |
| 205 const TransformNode* current = Node(source_id); | 215 const TransformNode* current = Node(source_id); |
| 206 const TransformNode* dest = Node(dest_id); | 216 const TransformNode* dest = Node(dest_id); |
| 207 // Combine transforms to and from the screen when possible. Since flattening | 217 // Combine transforms to and from the screen when possible. Since flattening |
| 208 // is a non-linear operation, we cannot use this approach when there is | 218 // is a non-linear operation, we cannot use this approach when there is |
| 209 // non-trivial flattening between the source and destination nodes. For | 219 // non-trivial flattening between the source and destination nodes. For |
| 210 // example, consider the tree R->A->B->C, where B flattens its inherited | 220 // example, consider the tree R->A->B->C, where B flattens its inherited |
| 211 // transform, and A has a non-flat transform. Suppose C is the source and A is | 221 // transform, and A has a non-flat transform. Suppose C is the source and A is |
| 212 // the destination. The expected result is C * B. But C's to_screen | 222 // the destination. The expected result is C * B. But C's to_screen |
| 213 // transform is C * B * flattened(A * R), and A's from_screen transform is | 223 // transform is C * B * flattened(A * R), and A's from_screen transform is |
| 214 // R^{-1} * A^{-1}. If at least one of A and R isn't flat, the inverse of | 224 // R^{-1} * A^{-1}. If at least one of A and R isn't flat, the inverse of |
| 215 // flattened(A * R) won't be R^{-1} * A{-1}, so multiplying C's to_screen and | 225 // flattened(A * R) won't be R^{-1} * A{-1}, so multiplying C's to_screen and |
| 216 // A's from_screen will not produce the correct result. | 226 // A's from_screen will not produce the correct result. |
| 217 if (!dest || | 227 if (!dest || |
| 218 (dest->ancestors_are_invertible && dest->node_and_ancestors_are_flat)) { | 228 (dest->ancestors_are_invertible && dest->node_and_ancestors_are_flat)) { |
| 219 transform->ConcatTransform(ToScreen(current->id)); | 229 transform->ConcatTransform(ToScreen(current->id)); |
| 220 if (dest) | 230 if (dest) |
| 221 transform->ConcatTransform(FromScreen(dest->id)); | 231 transform->ConcatTransform(FromScreen(dest->id)); |
| 222 return true; | 232 return; |
| 223 } | 233 } |
| 224 | 234 |
| 225 // Flattening is defined in a way that requires it to be applied while | 235 // Flattening is defined in a way that requires it to be applied while |
| 226 // traversing downward in the tree. We first identify nodes that are on the | 236 // traversing downward in the tree. We first identify nodes that are on the |
| 227 // path from the source to the destination (this is traversing upward), and | 237 // path from the source to the destination (this is traversing upward), and |
| 228 // then we visit these nodes in reverse order, flattening as needed. We | 238 // then we visit these nodes in reverse order, flattening as needed. We |
| 229 // early-out if we get to a node whose target node is the destination, since | 239 // early-out if we get to a node whose target node is the destination, since |
| 230 // we can then re-use the target space transform stored at that node. However, | 240 // we can then re-use the target space transform stored at that node. However, |
| 231 // we cannot re-use a stored target space transform if the destination has a | 241 // we cannot re-use a stored target space transform if the destination has a |
| 232 // zero surface contents scale, since stored target space transforms have | 242 // zero surface contents scale, since stored target space transforms have |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 283 size_t source_to_destination_size = source_to_destination.size(); | 293 size_t source_to_destination_size = source_to_destination.size(); |
| 284 for (size_t i = 0; i < source_to_destination_size; ++i) { | 294 for (size_t i = 0; i < source_to_destination_size; ++i) { |
| 285 size_t index = source_to_destination_size - 1 - i; | 295 size_t index = source_to_destination_size - 1 - i; |
| 286 const TransformNode* node = Node(source_to_destination[index]); | 296 const TransformNode* node = Node(source_to_destination[index]); |
| 287 if (node->flattens_inherited_transform) | 297 if (node->flattens_inherited_transform) |
| 288 combined_transform.FlattenTo2d(); | 298 combined_transform.FlattenTo2d(); |
| 289 combined_transform.PreconcatTransform(node->to_parent); | 299 combined_transform.PreconcatTransform(node->to_parent); |
| 290 } | 300 } |
| 291 | 301 |
| 292 transform->ConcatTransform(combined_transform); | 302 transform->ConcatTransform(combined_transform); |
| 293 return true; | |
| 294 } | 303 } |
| 295 | 304 |
| 296 bool TransformTree::CombineInversesBetween(int source_id, | 305 bool TransformTree::CombineInversesBetween(int source_id, |
| 297 int dest_id, | 306 int dest_id, |
| 298 gfx::Transform* transform) const { | 307 gfx::Transform* transform) const { |
| 299 DCHECK(source_id < dest_id); | 308 DCHECK(source_id < dest_id); |
| 300 const TransformNode* current = Node(dest_id); | 309 const TransformNode* current = Node(dest_id); |
| 301 const TransformNode* dest = Node(source_id); | 310 const TransformNode* dest = Node(source_id); |
| 302 // Just as in CombineTransformsBetween, we can use screen space transforms in | 311 // Just as in CombineTransformsBetween, we can use screen space transforms in |
| 303 // this computation only when there isn't any non-trivial flattening | 312 // this computation only when there isn't any non-trivial flattening |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 320 gfx::Transform source_to_dest; | 329 gfx::Transform source_to_dest; |
| 321 bool all_are_invertible = dest_to_source.GetInverse(&source_to_dest); | 330 bool all_are_invertible = dest_to_source.GetInverse(&source_to_dest); |
| 322 transform->PreconcatTransform(source_to_dest); | 331 transform->PreconcatTransform(source_to_dest); |
| 323 return all_are_invertible; | 332 return all_are_invertible; |
| 324 } | 333 } |
| 325 | 334 |
| 326 void TransformTree::UpdateLocalTransform(TransformNode* node) { | 335 void TransformTree::UpdateLocalTransform(TransformNode* node) { |
| 327 gfx::Transform transform = node->post_local; | 336 gfx::Transform transform = node->post_local; |
| 328 if (NeedsSourceToParentUpdate(node)) { | 337 if (NeedsSourceToParentUpdate(node)) { |
| 329 gfx::Transform to_parent; | 338 gfx::Transform to_parent; |
| 330 ComputeTransform(node->source_node_id, node->parent_id, &to_parent); | 339 ComputeTranslation(node->source_node_id, node->parent_id, &to_parent); |
| 331 node->source_to_parent = to_parent.To2dTranslation(); | 340 node->source_to_parent = to_parent.To2dTranslation(); |
| 332 } | 341 } |
| 333 | 342 |
| 334 gfx::Vector2dF fixed_position_adjustment; | 343 gfx::Vector2dF fixed_position_adjustment; |
| 335 gfx::Vector2dF inner_viewport_bounds_delta = | 344 gfx::Vector2dF inner_viewport_bounds_delta = |
| 336 property_trees()->inner_viewport_container_bounds_delta(); | 345 property_trees()->inner_viewport_container_bounds_delta(); |
| 337 gfx::Vector2dF outer_viewport_bounds_delta = | 346 gfx::Vector2dF outer_viewport_bounds_delta = |
| 338 property_trees()->outer_viewport_container_bounds_delta(); | 347 property_trees()->outer_viewport_container_bounds_delta(); |
| 339 if (node->affected_by_inner_viewport_bounds_delta_x) | 348 if (node->affected_by_inner_viewport_bounds_delta_x) |
| 340 fixed_position_adjustment.set_x(inner_viewport_bounds_delta.x()); | 349 fixed_position_adjustment.set_x(inner_viewport_bounds_delta.x()); |
| (...skipping 1613 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1954 screen_space_transform.Scale(1.0 / effect_node->surface_contents_scale.x(), | 1963 screen_space_transform.Scale(1.0 / effect_node->surface_contents_scale.x(), |
| 1955 1.0 / effect_node->surface_contents_scale.y()); | 1964 1.0 / effect_node->surface_contents_scale.y()); |
| 1956 return screen_space_transform; | 1965 return screen_space_transform; |
| 1957 } | 1966 } |
| 1958 | 1967 |
| 1959 bool PropertyTrees::ComputeTransformToTarget(int transform_id, | 1968 bool PropertyTrees::ComputeTransformToTarget(int transform_id, |
| 1960 int effect_id, | 1969 int effect_id, |
| 1961 gfx::Transform* transform) const { | 1970 gfx::Transform* transform) const { |
| 1962 transform->MakeIdentity(); | 1971 transform->MakeIdentity(); |
| 1963 | 1972 |
| 1964 int destination_transform_id; | 1973 int target_transform_id; |
| 1965 if (effect_id == EffectTree::kInvalidNodeId) { | 1974 if (effect_id == EffectTree::kInvalidNodeId) { |
| 1966 // This can happen when PaintArtifactCompositor builds property trees as | 1975 // This can happen when PaintArtifactCompositor builds property trees as |
| 1967 // it doesn't set effect ids on clip nodes. We want to compute transform | 1976 // it doesn't set effect ids on clip nodes. We want to compute transform |
| 1968 // to the root in this case. | 1977 // to the root in this case. |
| 1969 destination_transform_id = TransformTree::kRootNodeId; | 1978 target_transform_id = TransformTree::kRootNodeId; |
| 1970 } else { | 1979 } else { |
| 1971 const EffectNode* effect_node = effect_tree.Node(effect_id); | 1980 const EffectNode* effect_node = effect_tree.Node(effect_id); |
| 1972 DCHECK(effect_node->has_render_surface || | 1981 DCHECK(effect_node->has_render_surface || |
| 1973 effect_node->id == EffectTree::kRootNodeId); | 1982 effect_node->id == EffectTree::kRootNodeId); |
| 1974 destination_transform_id = effect_node->transform_id; | 1983 target_transform_id = effect_node->transform_id; |
| 1975 } | 1984 } |
| 1976 | 1985 |
| 1977 if (transform_id == destination_transform_id) | 1986 return transform_tree.ComputeTransform(transform_id, target_transform_id, |
| 1978 return true; | 1987 transform); |
| 1988 } | |
| 1979 | 1989 |
| 1980 if (transform_id > destination_transform_id) { | 1990 bool PropertyTrees::ComputeTransformFromTarget( |
| 1981 return transform_tree.CombineTransformsBetween( | 1991 int transform_id, |
| 1982 transform_id, destination_transform_id, transform); | 1992 int effect_id, |
| 1993 gfx::Transform* transform) const { | |
| 1994 transform->MakeIdentity(); | |
| 1995 | |
| 1996 int target_transform_id; | |
| 1997 if (effect_id == EffectTree::kInvalidNodeId) { | |
| 1998 // This can happen when PaintArtifactCompositor builds property trees as | |
| 1999 // it doesn't set effect ids on clip nodes. We want to compute transform | |
| 2000 // to the root in this case. | |
| 2001 target_transform_id = TransformTree::kRootNodeId; | |
| 2002 } else { | |
| 2003 const EffectNode* effect_node = effect_tree.Node(effect_id); | |
| 2004 DCHECK(effect_node->has_render_surface || | |
| 2005 effect_node->id == EffectTree::kRootNodeId); | |
| 2006 target_transform_id = effect_node->transform_id; | |
| 1983 } | 2007 } |
| 1984 | 2008 |
| 1985 return transform_tree.CombineInversesBetween( | 2009 return transform_tree.ComputeTransform(target_transform_id, transform_id, |
| 1986 transform_id, destination_transform_id, transform); | 2010 transform); |
| 1987 } | 2011 } |
| 1988 | 2012 |
| 1989 } // namespace cc | 2013 } // namespace cc |
| OLD | NEW |