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

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

Issue 2266223002: cc: Compute draw transforms dynamically. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix build error Created 4 years, 3 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') | tools/perf/benchmarks/draw_properties.py » ('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 <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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « cc/trees/property_tree.h ('k') | tools/perf/benchmarks/draw_properties.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698