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 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 251 TransformNode* source_node = Node(node->source_node_id); | 251 TransformNode* source_node = Node(node->source_node_id); |
| 252 property_trees()->UpdateCachedNumber(); | 252 property_trees()->UpdateCachedNumber(); |
| 253 if (node->needs_local_transform_update || NeedsSourceToParentUpdate(node)) | 253 if (node->needs_local_transform_update || NeedsSourceToParentUpdate(node)) |
| 254 UpdateLocalTransform(node); | 254 UpdateLocalTransform(node); |
| 255 else | 255 else |
| 256 UndoSnapping(node); | 256 UndoSnapping(node); |
| 257 UpdateScreenSpaceTransform(node, parent_node, target_node); | 257 UpdateScreenSpaceTransform(node, parent_node, target_node); |
| 258 UpdateSurfaceContentsScale(node); | 258 UpdateSurfaceContentsScale(node); |
| 259 UpdateAnimationProperties(node, parent_node); | 259 UpdateAnimationProperties(node, parent_node); |
| 260 UpdateSnapping(node); | 260 UpdateSnapping(node); |
| 261 UpdateTargetSpaceTransform(node, target_node); | 261 if (!property_trees()->verify_transform_tree_calculations) |
| 262 UpdateTargetSpaceTransform(node, target_node); | |
| 262 UpdateNodeAndAncestorsHaveIntegerTranslations(node, parent_node); | 263 UpdateNodeAndAncestorsHaveIntegerTranslations(node, parent_node); |
| 263 UpdateTransformChanged(node, parent_node, source_node); | 264 UpdateTransformChanged(node, parent_node, source_node); |
| 264 UpdateNodeAndAncestorsAreAnimatedOrInvertible(node, parent_node); | 265 UpdateNodeAndAncestorsAreAnimatedOrInvertible(node, parent_node); |
| 265 } | 266 } |
| 266 | 267 |
| 267 bool TransformTree::IsDescendant(int desc_id, int source_id) const { | 268 bool TransformTree::IsDescendant(int desc_id, int source_id) const { |
| 268 while (desc_id != source_id) { | 269 while (desc_id != source_id) { |
| 269 if (desc_id == kInvalidNodeId) | 270 if (desc_id == kInvalidNodeId) |
| 270 return false; | 271 return false; |
| 271 desc_id = Node(desc_id)->parent_id; | 272 desc_id = Node(desc_id)->parent_id; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 308 // surface contents scale baked in, but we need to compute an unscaled | 309 // surface contents scale baked in, but we need to compute an unscaled |
| 309 // transform. | 310 // transform. |
| 310 std::vector<int> source_to_destination; | 311 std::vector<int> source_to_destination; |
| 311 source_to_destination.push_back(current->id); | 312 source_to_destination.push_back(current->id); |
| 312 current = parent(current); | 313 current = parent(current); |
| 313 bool destination_has_non_zero_surface_contents_scale = | 314 bool destination_has_non_zero_surface_contents_scale = |
| 314 dest->surface_contents_scale.x() != 0.f && | 315 dest->surface_contents_scale.x() != 0.f && |
| 315 dest->surface_contents_scale.y() != 0.f; | 316 dest->surface_contents_scale.y() != 0.f; |
| 316 DCHECK(destination_has_non_zero_surface_contents_scale || | 317 DCHECK(destination_has_non_zero_surface_contents_scale || |
| 317 !dest->ancestors_are_invertible); | 318 !dest->ancestors_are_invertible); |
| 318 for (; current && current->id > dest_id; current = parent(current)) { | 319 for (; current && current->id > dest_id; current = parent(current)) |
| 319 if (destination_has_non_zero_surface_contents_scale && | |
| 320 TargetId(current->id) == dest_id && | |
| 321 ContentTargetId(current->id) == dest_id) | |
| 322 break; | |
| 323 source_to_destination.push_back(current->id); | 320 source_to_destination.push_back(current->id); |
| 324 } | |
| 325 | 321 |
| 326 gfx::Transform combined_transform; | 322 gfx::Transform combined_transform; |
| 327 if (current->id > dest_id) { | 323 if (current->id > dest_id) { |
| 328 // TODO(sunxd): Instead of using target space transform, only use to_parent | |
| 329 // here when we fully implement computing draw transforms on demand. | |
| 330 combined_transform = ToTarget(current->id, kInvalidNodeId); | |
|
jaydasika
2016/09/02 18:10:01
This is not behind a flag. Is it fine to remove it
sunxd
2016/09/02 18:13:10
Removing it does make performance suffer. I can ma
| |
| 331 // The stored target space transform has surface contents scale baked in, | 324 // The stored target space transform has surface contents scale baked in, |
| 332 // but we need the unscaled transform. | 325 // but we need the unscaled transform. |
| 333 combined_transform.matrix().postScale( | 326 combined_transform.matrix().postScale( |
| 334 1.0f / dest->surface_contents_scale.x(), | 327 1.0f / dest->surface_contents_scale.x(), |
| 335 1.0f / dest->surface_contents_scale.y(), 1.0f); | 328 1.0f / dest->surface_contents_scale.y(), 1.0f); |
| 336 } else if (current->id < dest_id) { | 329 } else if (current->id < dest_id) { |
| 337 // We have reached the lowest common ancestor of the source and destination | 330 // We have reached the lowest common ancestor of the source and destination |
| 338 // nodes. This case can occur when we are transforming between a node | 331 // nodes. This case can occur when we are transforming between a node |
| 339 // corresponding to a fixed-position layer (or its descendant) and the node | 332 // corresponding to a fixed-position layer (or its descendant) and the node |
| 340 // corresponding to the layer's render target. For example, consider the | 333 // corresponding to the layer's render target. For example, consider the |
| (...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 663 | 656 |
| 664 bool TransformTree::HasNodesAffectedByOuterViewportBoundsDelta() const { | 657 bool TransformTree::HasNodesAffectedByOuterViewportBoundsDelta() const { |
| 665 return !nodes_affected_by_outer_viewport_bounds_delta_.empty(); | 658 return !nodes_affected_by_outer_viewport_bounds_delta_.empty(); |
| 666 } | 659 } |
| 667 | 660 |
| 668 const gfx::Transform& TransformTree::FromTarget(int node_id, | 661 const gfx::Transform& TransformTree::FromTarget(int node_id, |
| 669 int effect_id) const { | 662 int effect_id) const { |
| 670 DCHECK(static_cast<int>(cached_data_.size()) > node_id); | 663 DCHECK(static_cast<int>(cached_data_.size()) > node_id); |
| 671 if (effect_id != kInvalidNodeId && | 664 if (effect_id != kInvalidNodeId && |
| 672 property_trees()->verify_transform_tree_calculations) { | 665 property_trees()->verify_transform_tree_calculations) { |
| 673 const gfx::Transform& transform = | 666 return property_trees()->GetDrawTransforms(node_id, effect_id).from_target; |
| 674 property_trees()->GetDrawTransforms(node_id, effect_id).from_target; | |
| 675 CHECK(transform.ApproximatelyEqual(cached_data_[node_id].from_target)); | |
| 676 } | 667 } |
| 677 return cached_data_[node_id].from_target; | 668 return cached_data_[node_id].from_target; |
| 678 } | 669 } |
| 679 | 670 |
| 680 void TransformTree::SetFromTarget(int node_id, | 671 void TransformTree::SetFromTarget(int node_id, |
| 681 const gfx::Transform& transform) { | 672 const gfx::Transform& transform) { |
| 682 DCHECK(static_cast<int>(cached_data_.size()) > node_id); | 673 DCHECK(static_cast<int>(cached_data_.size()) > node_id); |
| 683 cached_data_[node_id].from_target = transform; | 674 cached_data_[node_id].from_target = transform; |
| 684 } | 675 } |
| 685 | 676 |
| 686 const gfx::Transform& TransformTree::ToTarget(int node_id, | 677 const gfx::Transform& TransformTree::ToTarget(int node_id, |
| 687 int effect_id) const { | 678 int effect_id) const { |
| 688 DCHECK(static_cast<int>(cached_data_.size()) > node_id); | 679 DCHECK(static_cast<int>(cached_data_.size()) > node_id); |
| 689 if (effect_id != kInvalidNodeId && | 680 if (effect_id != kInvalidNodeId && |
| 690 property_trees()->verify_transform_tree_calculations) { | 681 property_trees()->verify_transform_tree_calculations) { |
| 691 const gfx::Transform& transform = | 682 return property_trees()->GetDrawTransforms(node_id, effect_id).to_target; |
| 692 property_trees()->GetDrawTransforms(node_id, effect_id).to_target; | |
| 693 if (property_trees()->non_root_surfaces_enabled) | |
| 694 CHECK(transform.ApproximatelyEqual(cached_data_[node_id].to_target)); | |
| 695 else | |
| 696 CHECK(transform.ApproximatelyEqual(cached_data_[node_id].to_screen)); | |
| 697 } | 683 } |
| 698 return cached_data_[node_id].to_target; | 684 return cached_data_[node_id].to_target; |
| 699 } | 685 } |
| 700 | 686 |
| 701 void TransformTree::SetToTarget(int node_id, const gfx::Transform& transform) { | 687 void TransformTree::SetToTarget(int node_id, const gfx::Transform& transform) { |
| 702 DCHECK(static_cast<int>(cached_data_.size()) > node_id); | 688 DCHECK(static_cast<int>(cached_data_.size()) > node_id); |
| 703 cached_data_[node_id].to_target = transform; | 689 cached_data_[node_id].to_target = transform; |
| 704 } | 690 } |
| 705 | 691 |
| 706 const gfx::Transform& TransformTree::FromScreen(int node_id) const { | 692 const gfx::Transform& TransformTree::FromScreen(int node_id) const { |
| (...skipping 1232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1939 !node->has_only_translation_animations || ancestor_is_animating_scale; | 1925 !node->has_only_translation_animations || ancestor_is_animating_scale; |
| 1940 | 1926 |
| 1941 // Once we've failed to compute a maximum animated scale at an ancestor, we | 1927 // Once we've failed to compute a maximum animated scale at an ancestor, we |
| 1942 // continue to fail. | 1928 // continue to fail. |
| 1943 bool failed_at_ancestor = | 1929 bool failed_at_ancestor = |
| 1944 ancestor_is_animating_scale && ancestor_maximum_target_scale == 0.f; | 1930 ancestor_is_animating_scale && ancestor_maximum_target_scale == 0.f; |
| 1945 | 1931 |
| 1946 // Computing maximum animated scale in the presence of non-scale/translation | 1932 // Computing maximum animated scale in the presence of non-scale/translation |
| 1947 // transforms isn't supported. | 1933 // transforms isn't supported. |
| 1948 bool failed_for_non_scale_or_translation = | 1934 bool failed_for_non_scale_or_translation = |
| 1949 !transform_tree.Node(transform_node_id) | 1935 !node->to_parent.IsScaleOrTranslation(); |
| 1950 ->to_parent.IsScaleOrTranslation(); | |
| 1951 | 1936 |
| 1952 // We don't attempt to accumulate animation scale from multiple nodes with | 1937 // We don't attempt to accumulate animation scale from multiple nodes with |
| 1953 // scale animations, because of the risk of significant overestimation. For | 1938 // scale animations, because of the risk of significant overestimation. For |
| 1954 // example, one node might be increasing scale from 1 to 10 at the same time | 1939 // example, one node might be increasing scale from 1 to 10 at the same time |
| 1955 // as another node is decreasing scale from 10 to 1. Naively combining these | 1940 // as another node is decreasing scale from 10 to 1. Naively combining these |
| 1956 // scales would produce a scale of 100. | 1941 // scales would produce a scale of 100. |
| 1957 bool failed_for_multiple_scale_animations = | 1942 bool failed_for_multiple_scale_animations = |
| 1958 ancestor_is_animating_scale && !node->has_only_translation_animations; | 1943 ancestor_is_animating_scale && !node->has_only_translation_animations; |
| 1959 | 1944 |
| 1960 if (failed_at_ancestor || failed_for_non_scale_or_translation || | 1945 if (failed_at_ancestor || failed_for_non_scale_or_translation || |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2130 cached_data_.draw_transforms[effect_id][transform_id].transforms.to_target = | 2115 cached_data_.draw_transforms[effect_id][transform_id].transforms.to_target = |
| 2131 target_space_transform; | 2116 target_space_transform; |
| 2132 } | 2117 } |
| 2133 return cached_data_.draw_transforms[effect_id][transform_id].transforms; | 2118 return cached_data_.draw_transforms[effect_id][transform_id].transforms; |
| 2134 } | 2119 } |
| 2135 | 2120 |
| 2136 void PropertyTrees::ResetCachedData() { | 2121 void PropertyTrees::ResetCachedData() { |
| 2137 cached_data_.property_tree_update_number = 0; | 2122 cached_data_.property_tree_update_number = 0; |
| 2138 cached_data_.animation_scales = std::vector<AnimationScaleData>( | 2123 cached_data_.animation_scales = std::vector<AnimationScaleData>( |
| 2139 transform_tree.nodes().size(), AnimationScaleData()); | 2124 transform_tree.nodes().size(), AnimationScaleData()); |
| 2140 cached_data_.draw_transforms = | 2125 cached_data_.draw_transforms = std::vector<std::map<int, DrawTransformData>>( |
| 2141 std::vector<std::unordered_map<int, DrawTransformData>>( | 2126 effect_tree.nodes().size(), std::map<int, DrawTransformData>()); |
| 2142 effect_tree.nodes().size(), | |
| 2143 std::unordered_map<int, DrawTransformData>()); | |
| 2144 } | 2127 } |
| 2145 | 2128 |
| 2146 void PropertyTrees::UpdateCachedNumber() { | 2129 void PropertyTrees::UpdateCachedNumber() { |
| 2147 cached_data_.property_tree_update_number++; | 2130 cached_data_.property_tree_update_number++; |
| 2148 } | 2131 } |
| 2149 | 2132 |
| 2150 gfx::Transform PropertyTrees::ToScreenSpaceTransformWithoutSurfaceContentsScale( | 2133 gfx::Transform PropertyTrees::ToScreenSpaceTransformWithoutSurfaceContentsScale( |
| 2151 int transform_id, | 2134 int transform_id, |
| 2152 int effect_id) const { | 2135 int effect_id) const { |
| 2153 DCHECK_GT(transform_id, 0); | 2136 DCHECK_GT(transform_id, 0); |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 2178 // This can happen when PaintArtifactCompositor builds property trees as | 2161 // This can happen when PaintArtifactCompositor builds property trees as |
| 2179 // it doesn't set effect ids on clip nodes. We want to compute transform | 2162 // it doesn't set effect ids on clip nodes. We want to compute transform |
| 2180 // to the root in this case. | 2163 // to the root in this case. |
| 2181 target_transform_id = TransformTree::kRootNodeId; | 2164 target_transform_id = TransformTree::kRootNodeId; |
| 2182 } else { | 2165 } else { |
| 2183 DCHECK(effect_node->has_render_surface || | 2166 DCHECK(effect_node->has_render_surface || |
| 2184 effect_node->id == EffectTree::kRootNodeId); | 2167 effect_node->id == EffectTree::kRootNodeId); |
| 2185 target_transform_id = effect_node->transform_id; | 2168 target_transform_id = effect_node->transform_id; |
| 2186 } | 2169 } |
| 2187 | 2170 |
| 2188 bool success = transform_tree.ComputeTransform( | 2171 bool success = true; |
| 2189 transform_id, target_transform_id, transform); | |
| 2190 if (verify_transform_tree_calculations) { | 2172 if (verify_transform_tree_calculations) { |
| 2191 gfx::Transform to_target; | 2173 auto draw_transforms = GetDrawTransforms(transform_id, effect_id); |
| 2192 to_target.ConcatTransform( | 2174 success = draw_transforms.invertible; |
| 2193 GetDrawTransforms(transform_id, effect_id).to_target); | 2175 transform->ConcatTransform(draw_transforms.to_target); |
| 2194 if (effect_node->surface_contents_scale.x() != 0.f && | 2176 if (effect_node->surface_contents_scale.x() != 0.f && |
| 2195 effect_node->surface_contents_scale.y() != 0.f) | 2177 effect_node->surface_contents_scale.y() != 0.f) |
| 2196 to_target.matrix().postScale( | 2178 transform->matrix().postScale( |
| 2197 1.0f / effect_node->surface_contents_scale.x(), | 2179 1.0f / effect_node->surface_contents_scale.x(), |
| 2198 1.0f / effect_node->surface_contents_scale.y(), 1.0f); | 2180 1.0f / effect_node->surface_contents_scale.y(), 1.0f); |
| 2199 DCHECK(to_target.ApproximatelyEqual(*transform)); | 2181 } else { |
| 2182 success = transform_tree.ComputeTransform(transform_id, target_transform_id, | |
| 2183 transform); | |
| 2200 } | 2184 } |
| 2201 return success; | 2185 return success; |
| 2202 } | 2186 } |
| 2203 | 2187 |
| 2204 bool PropertyTrees::ComputeTransformFromTarget( | 2188 bool PropertyTrees::ComputeTransformFromTarget( |
| 2205 int transform_id, | 2189 int transform_id, |
| 2206 int effect_id, | 2190 int effect_id, |
| 2207 gfx::Transform* transform) const { | 2191 gfx::Transform* transform) const { |
| 2208 transform->MakeIdentity(); | 2192 transform->MakeIdentity(); |
| 2209 | 2193 |
| 2210 if (transform_id == TransformTree::kInvalidNodeId) | 2194 if (transform_id == TransformTree::kInvalidNodeId) |
| 2211 return true; | 2195 return true; |
| 2212 | 2196 |
| 2213 int target_transform_id; | 2197 int target_transform_id; |
| 2214 const EffectNode* effect_node = effect_tree.Node(effect_id); | 2198 const EffectNode* effect_node = effect_tree.Node(effect_id); |
| 2215 if (effect_id == EffectTree::kInvalidNodeId) { | 2199 if (effect_id == EffectTree::kInvalidNodeId) { |
| 2216 // This can happen when PaintArtifactCompositor builds property trees as | 2200 // This can happen when PaintArtifactCompositor builds property trees as |
| 2217 // it doesn't set effect ids on clip nodes. We want to compute transform | 2201 // it doesn't set effect ids on clip nodes. We want to compute transform |
| 2218 // to the root in this case. | 2202 // to the root in this case. |
| 2219 target_transform_id = TransformTree::kRootNodeId; | 2203 target_transform_id = TransformTree::kRootNodeId; |
| 2220 } else { | 2204 } else { |
| 2221 DCHECK(effect_node->has_render_surface || | 2205 DCHECK(effect_node->has_render_surface || |
| 2222 effect_node->id == EffectTree::kRootNodeId); | 2206 effect_node->id == EffectTree::kRootNodeId); |
| 2223 target_transform_id = effect_node->transform_id; | 2207 target_transform_id = effect_node->transform_id; |
| 2224 } | 2208 } |
| 2225 | 2209 |
| 2226 bool success = transform_tree.ComputeTransform(target_transform_id, | 2210 bool success = true; |
| 2227 transform_id, transform); | |
| 2228 if (verify_transform_tree_calculations) { | 2211 if (verify_transform_tree_calculations) { |
| 2229 auto draw_transforms = GetDrawTransforms(transform_id, effect_id); | 2212 auto draw_transforms = GetDrawTransforms(transform_id, effect_id); |
| 2230 gfx::Transform from_target; | 2213 success = draw_transforms.invertible; |
| 2231 from_target.ConcatTransform(draw_transforms.from_target); | 2214 transform->ConcatTransform(draw_transforms.from_target); |
| 2232 from_target.Scale(effect_node->surface_contents_scale.x(), | 2215 transform->Scale(effect_node->surface_contents_scale.x(), |
| 2233 effect_node->surface_contents_scale.y()); | 2216 effect_node->surface_contents_scale.y()); |
| 2234 DCHECK(from_target.ApproximatelyEqual(*transform) || | 2217 } else { |
| 2235 !draw_transforms.invertible); | 2218 success = transform_tree.ComputeTransform(target_transform_id, transform_id, |
| 2219 transform); | |
| 2236 } | 2220 } |
| 2237 return success; | 2221 return success; |
| 2238 } | 2222 } |
| 2239 | 2223 |
| 2240 } // namespace cc | 2224 } // namespace cc |
| OLD | NEW |