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

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: Nit Created 4 years, 2 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
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 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 167
168 #if DCHECK_IS_ON() 168 #if DCHECK_IS_ON()
169 TransformTree tree; 169 TransformTree tree;
170 // TODO(jaydasika) : Move tests that expect source_to_parent_updates_allowed 170 // TODO(jaydasika) : Move tests that expect source_to_parent_updates_allowed
171 // to be true on impl thread to main thread and set it to is_main_thread here. 171 // to be true on impl thread to main thread and set it to is_main_thread here.
172 tree.source_to_parent_updates_allowed_ = source_to_parent_updates_allowed_; 172 tree.source_to_parent_updates_allowed_ = source_to_parent_updates_allowed_;
173 DCHECK(tree == *this); 173 DCHECK(tree == *this);
174 #endif 174 #endif
175 } 175 }
176 176
177 void TransformTree::set_needs_update(bool needs_update) {
178 if (needs_update && !needs_update_)
179 property_trees()->UpdateCachedNumber();
180 needs_update_ = needs_update;
ajuma 2016/10/12 20:08:47 Can we make needs_update_ private to make sure it'
sunxd 2016/10/12 21:08:19 I think needs_update_ is already private. Transfor
181 }
182
177 bool TransformTree::ComputeTransform(int source_id, 183 bool TransformTree::ComputeTransform(int source_id,
178 int dest_id, 184 int dest_id,
179 gfx::Transform* transform) const { 185 gfx::Transform* transform) const {
180 transform->MakeIdentity(); 186 transform->MakeIdentity();
181 187
182 if (source_id == dest_id) 188 if (source_id == dest_id)
183 return true; 189 return true;
184 190
185 if (source_id > dest_id) { 191 if (source_id > dest_id) {
186 CombineTransformsBetween(source_id, dest_id, transform); 192 CombineTransformsBetween(source_id, dest_id, transform);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 TransformNode* node = Node(id); 263 TransformNode* node = Node(id);
258 node->transform_changed = false; 264 node->transform_changed = false;
259 } 265 }
260 } 266 }
261 267
262 void TransformTree::UpdateTransforms(int id) { 268 void TransformTree::UpdateTransforms(int id) {
263 TransformNode* node = Node(id); 269 TransformNode* node = Node(id);
264 TransformNode* parent_node = parent(node); 270 TransformNode* parent_node = parent(node);
265 TransformNode* target_node = Node(TargetId(id)); 271 TransformNode* target_node = Node(TargetId(id));
266 TransformNode* source_node = Node(node->source_node_id); 272 TransformNode* source_node = Node(node->source_node_id);
267 property_trees()->UpdateCachedNumber();
268 // TODO(flackr): Only dirty when scroll offset changes. 273 // TODO(flackr): Only dirty when scroll offset changes.
269 if (node->sticky_position_constraint_id >= 0 || 274 if (node->sticky_position_constraint_id >= 0 ||
270 node->needs_local_transform_update || NeedsSourceToParentUpdate(node)) { 275 node->needs_local_transform_update || NeedsSourceToParentUpdate(node)) {
271 UpdateLocalTransform(node); 276 UpdateLocalTransform(node);
272 } else { 277 } else {
273 UndoSnapping(node); 278 UndoSnapping(node);
274 } 279 }
275 UpdateScreenSpaceTransform(node, parent_node, target_node); 280 UpdateScreenSpaceTransform(node, parent_node, target_node);
276 UpdateSurfaceContentsScale(node); 281 UpdateSurfaceContentsScale(node);
277 UpdateAnimationProperties(node, parent_node); 282 UpdateAnimationProperties(node, parent_node);
278 UpdateSnapping(node); 283 UpdateSnapping(node);
279 UpdateTargetSpaceTransform(node, target_node);
280 UpdateNodeAndAncestorsHaveIntegerTranslations(node, parent_node); 284 UpdateNodeAndAncestorsHaveIntegerTranslations(node, parent_node);
281 UpdateTransformChanged(node, parent_node, source_node); 285 UpdateTransformChanged(node, parent_node, source_node);
282 UpdateNodeAndAncestorsAreAnimatedOrInvertible(node, parent_node); 286 UpdateNodeAndAncestorsAreAnimatedOrInvertible(node, parent_node);
283 } 287 }
284 288
285 bool TransformTree::IsDescendant(int desc_id, int source_id) const { 289 bool TransformTree::IsDescendant(int desc_id, int source_id) const {
286 while (desc_id != source_id) { 290 while (desc_id != source_id) {
287 if (desc_id == kInvalidNodeId) 291 if (desc_id == kInvalidNodeId)
288 return false; 292 return false;
289 desc_id = Node(desc_id)->parent_id; 293 desc_id = Node(desc_id)->parent_id;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
326 // surface contents scale baked in, but we need to compute an unscaled 330 // surface contents scale baked in, but we need to compute an unscaled
327 // transform. 331 // transform.
328 std::vector<int> source_to_destination; 332 std::vector<int> source_to_destination;
329 source_to_destination.push_back(current->id); 333 source_to_destination.push_back(current->id);
330 current = parent(current); 334 current = parent(current);
331 bool destination_has_non_zero_surface_contents_scale = 335 bool destination_has_non_zero_surface_contents_scale =
332 dest->surface_contents_scale.x() != 0.f && 336 dest->surface_contents_scale.x() != 0.f &&
333 dest->surface_contents_scale.y() != 0.f; 337 dest->surface_contents_scale.y() != 0.f;
334 DCHECK(destination_has_non_zero_surface_contents_scale || 338 DCHECK(destination_has_non_zero_surface_contents_scale ||
335 !dest->ancestors_are_invertible); 339 !dest->ancestors_are_invertible);
336 for (; current && current->id > dest_id; current = parent(current)) { 340 for (; current && current->id > dest_id; current = parent(current))
337 if (destination_has_non_zero_surface_contents_scale &&
338 TargetId(current->id) == dest_id &&
339 ContentTargetId(current->id) == dest_id)
340 break;
341 source_to_destination.push_back(current->id); 341 source_to_destination.push_back(current->id);
342 }
343 342
344 gfx::Transform combined_transform; 343 gfx::Transform combined_transform;
345 if (current->id > dest_id) { 344 if (current->id > dest_id) {
346 // TODO(sunxd): Instead of using target space transform, only use to_parent
347 // here when we fully implement computing draw transforms on demand.
348 combined_transform = ToTarget(current->id, kInvalidNodeId);
349 // The stored target space transform has surface contents scale baked in, 345 // The stored target space transform has surface contents scale baked in,
350 // but we need the unscaled transform. 346 // but we need the unscaled transform.
351 combined_transform.matrix().postScale( 347 combined_transform.matrix().postScale(
352 1.0f / dest->surface_contents_scale.x(), 348 1.0f / dest->surface_contents_scale.x(),
353 1.0f / dest->surface_contents_scale.y(), 1.0f); 349 1.0f / dest->surface_contents_scale.y(), 1.0f);
354 } else if (current->id < dest_id) { 350 } else if (current->id < dest_id) {
355 // We have reached the lowest common ancestor of the source and destination 351 // We have reached the lowest common ancestor of the source and destination
356 // nodes. This case can occur when we are transforming between a node 352 // nodes. This case can occur when we are transforming between a node
357 // corresponding to a fixed-position layer (or its descendant) and the node 353 // corresponding to a fixed-position layer (or its descendant) and the node
358 // corresponding to the layer's render target. For example, consider the 354 // corresponding to the layer's render target. For example, consider the
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after
758 } 754 }
759 755
760 bool TransformTree::HasNodesAffectedByInnerViewportBoundsDelta() const { 756 bool TransformTree::HasNodesAffectedByInnerViewportBoundsDelta() const {
761 return !nodes_affected_by_inner_viewport_bounds_delta_.empty(); 757 return !nodes_affected_by_inner_viewport_bounds_delta_.empty();
762 } 758 }
763 759
764 bool TransformTree::HasNodesAffectedByOuterViewportBoundsDelta() const { 760 bool TransformTree::HasNodesAffectedByOuterViewportBoundsDelta() const {
765 return !nodes_affected_by_outer_viewport_bounds_delta_.empty(); 761 return !nodes_affected_by_outer_viewport_bounds_delta_.empty();
766 } 762 }
767 763
768 const gfx::Transform& TransformTree::FromTarget(int node_id, 764 gfx::Transform TransformTree::FromTarget(int node_id, int effect_id) const {
769 int effect_id) const { 765 gfx::Transform from_target;
770 DCHECK(static_cast<int>(cached_data_.size()) > node_id); 766 property_trees()->GetFromTarget(node_id, effect_id, &from_target);
771 if (effect_id != kInvalidNodeId && 767 return from_target;
772 property_trees()->verify_transform_tree_calculations) {
773 const gfx::Transform& transform =
774 property_trees()->GetDrawTransforms(node_id, effect_id).from_target;
775 CHECK(transform.ApproximatelyEqual(cached_data_[node_id].from_target));
776 }
777 return cached_data_[node_id].from_target;
778 } 768 }
779 769
780 void TransformTree::SetFromTarget(int node_id, 770 void TransformTree::SetFromTarget(int node_id,
781 const gfx::Transform& transform) { 771 const gfx::Transform& transform) {
782 DCHECK(static_cast<int>(cached_data_.size()) > node_id); 772 DCHECK(static_cast<int>(cached_data_.size()) > node_id);
783 cached_data_[node_id].from_target = transform; 773 cached_data_[node_id].from_target = transform;
784 } 774 }
785 775
786 const gfx::Transform& TransformTree::ToTarget(int node_id, 776 gfx::Transform TransformTree::ToTarget(int node_id, int effect_id) const {
787 int effect_id) const { 777 gfx::Transform to_target;
788 DCHECK(static_cast<int>(cached_data_.size()) > node_id); 778 property_trees()->GetToTarget(node_id, effect_id, &to_target);
789 if (effect_id != kInvalidNodeId && 779 return to_target;
790 property_trees()->verify_transform_tree_calculations) {
791 const gfx::Transform& transform =
792 property_trees()->GetDrawTransforms(node_id, effect_id).to_target;
793 if (property_trees()->non_root_surfaces_enabled)
794 CHECK(transform.ApproximatelyEqual(cached_data_[node_id].to_target));
795 else
796 CHECK(transform.ApproximatelyEqual(cached_data_[node_id].to_screen));
797 }
798 return cached_data_[node_id].to_target;
799 } 780 }
800 781
801 void TransformTree::SetToTarget(int node_id, const gfx::Transform& transform) { 782 void TransformTree::SetToTarget(int node_id, const gfx::Transform& transform) {
802 DCHECK(static_cast<int>(cached_data_.size()) > node_id); 783 DCHECK(static_cast<int>(cached_data_.size()) > node_id);
803 cached_data_[node_id].to_target = transform; 784 cached_data_[node_id].to_target = transform;
804 } 785 }
805 786
806 const gfx::Transform& TransformTree::FromScreen(int node_id) const { 787 const gfx::Transform& TransformTree::FromScreen(int node_id) const {
807 DCHECK(static_cast<int>(cached_data_.size()) > node_id); 788 DCHECK(static_cast<int>(cached_data_.size()) > node_id);
808 return cached_data_[node_id].from_screen; 789 return cached_data_[node_id].from_screen;
(...skipping 935 matching lines...) Expand 10 before | Expand all | Expand 10 after
1744 1725
1745 PropertyTreesCachedData::~PropertyTreesCachedData() {} 1726 PropertyTreesCachedData::~PropertyTreesCachedData() {}
1746 1727
1747 PropertyTrees::PropertyTrees() 1728 PropertyTrees::PropertyTrees()
1748 : needs_rebuild(true), 1729 : needs_rebuild(true),
1749 non_root_surfaces_enabled(true), 1730 non_root_surfaces_enabled(true),
1750 changed(false), 1731 changed(false),
1751 full_tree_damaged(false), 1732 full_tree_damaged(false),
1752 sequence_number(0), 1733 sequence_number(0),
1753 is_main_thread(true), 1734 is_main_thread(true),
1754 is_active(false), 1735 is_active(false) {
1755 verify_transform_tree_calculations(false) {
1756 transform_tree.SetPropertyTrees(this); 1736 transform_tree.SetPropertyTrees(this);
1757 effect_tree.SetPropertyTrees(this); 1737 effect_tree.SetPropertyTrees(this);
1758 clip_tree.SetPropertyTrees(this); 1738 clip_tree.SetPropertyTrees(this);
1759 scroll_tree.SetPropertyTrees(this); 1739 scroll_tree.SetPropertyTrees(this);
1760 } 1740 }
1761 1741
1762 PropertyTrees::~PropertyTrees() {} 1742 PropertyTrees::~PropertyTrees() {}
1763 1743
1764 bool PropertyTrees::operator==(const PropertyTrees& other) const { 1744 bool PropertyTrees::operator==(const PropertyTrees& other) const {
1765 return transform_tree == other.transform_tree && 1745 return transform_tree == other.transform_tree &&
(...skipping 24 matching lines...) Expand all
1790 from.always_use_active_tree_opacity_effect_ids; 1770 from.always_use_active_tree_opacity_effect_ids;
1791 clip_id_to_index_map = from.clip_id_to_index_map; 1771 clip_id_to_index_map = from.clip_id_to_index_map;
1792 scroll_id_to_index_map = from.scroll_id_to_index_map; 1772 scroll_id_to_index_map = from.scroll_id_to_index_map;
1793 needs_rebuild = from.needs_rebuild; 1773 needs_rebuild = from.needs_rebuild;
1794 changed = from.changed; 1774 changed = from.changed;
1795 full_tree_damaged = from.full_tree_damaged; 1775 full_tree_damaged = from.full_tree_damaged;
1796 non_root_surfaces_enabled = from.non_root_surfaces_enabled; 1776 non_root_surfaces_enabled = from.non_root_surfaces_enabled;
1797 sequence_number = from.sequence_number; 1777 sequence_number = from.sequence_number;
1798 is_main_thread = from.is_main_thread; 1778 is_main_thread = from.is_main_thread;
1799 is_active = from.is_active; 1779 is_active = from.is_active;
1800 verify_transform_tree_calculations = from.verify_transform_tree_calculations;
1801 inner_viewport_container_bounds_delta_ = 1780 inner_viewport_container_bounds_delta_ =
1802 from.inner_viewport_container_bounds_delta(); 1781 from.inner_viewport_container_bounds_delta();
1803 outer_viewport_container_bounds_delta_ = 1782 outer_viewport_container_bounds_delta_ =
1804 from.outer_viewport_container_bounds_delta(); 1783 from.outer_viewport_container_bounds_delta();
1805 inner_viewport_scroll_bounds_delta_ = 1784 inner_viewport_scroll_bounds_delta_ =
1806 from.inner_viewport_scroll_bounds_delta(); 1785 from.inner_viewport_scroll_bounds_delta();
1807 transform_tree.SetPropertyTrees(this); 1786 transform_tree.SetPropertyTrees(this);
1808 effect_tree.SetPropertyTrees(this); 1787 effect_tree.SetPropertyTrees(this);
1809 clip_tree.SetPropertyTrees(this); 1788 clip_tree.SetPropertyTrees(this);
1810 scroll_tree.SetPropertyTrees(this); 1789 scroll_tree.SetPropertyTrees(this);
1811 ResetCachedData(); 1790 ResetCachedData();
1812 return *this; 1791 return *this;
1813 } 1792 }
1814 1793
1815 void PropertyTrees::ToProtobuf(proto::PropertyTrees* proto) const { 1794 void PropertyTrees::ToProtobuf(proto::PropertyTrees* proto) const {
1816 // TODO(khushalsagar): Add support for sending diffs when serializaing 1795 // TODO(khushalsagar): Add support for sending diffs when serializaing
1817 // property trees. See crbug/555370. 1796 // property trees. See crbug/555370.
1818 transform_tree.ToProtobuf(proto->mutable_transform_tree()); 1797 transform_tree.ToProtobuf(proto->mutable_transform_tree());
1819 effect_tree.ToProtobuf(proto->mutable_effect_tree()); 1798 effect_tree.ToProtobuf(proto->mutable_effect_tree());
1820 clip_tree.ToProtobuf(proto->mutable_clip_tree()); 1799 clip_tree.ToProtobuf(proto->mutable_clip_tree());
1821 scroll_tree.ToProtobuf(proto->mutable_scroll_tree()); 1800 scroll_tree.ToProtobuf(proto->mutable_scroll_tree());
1822 proto->set_needs_rebuild(needs_rebuild); 1801 proto->set_needs_rebuild(needs_rebuild);
1823 proto->set_changed(changed); 1802 proto->set_changed(changed);
1824 proto->set_full_tree_damaged(full_tree_damaged); 1803 proto->set_full_tree_damaged(full_tree_damaged);
1825 proto->set_non_root_surfaces_enabled(non_root_surfaces_enabled); 1804 proto->set_non_root_surfaces_enabled(non_root_surfaces_enabled);
1826 proto->set_is_main_thread(is_main_thread); 1805 proto->set_is_main_thread(is_main_thread);
1827 proto->set_is_active(is_active); 1806 proto->set_is_active(is_active);
1828 proto->set_verify_transform_tree_calculations(
1829 verify_transform_tree_calculations);
1830 1807
1831 // TODO(khushalsagar): Consider using the sequence number to decide if 1808 // TODO(khushalsagar): Consider using the sequence number to decide if
1832 // property trees need to be serialized again for a commit. See crbug/555370. 1809 // property trees need to be serialized again for a commit. See crbug/555370.
1833 proto->set_sequence_number(sequence_number); 1810 proto->set_sequence_number(sequence_number);
1834 1811
1835 for (auto i : always_use_active_tree_opacity_effect_ids) 1812 for (auto i : always_use_active_tree_opacity_effect_ids)
1836 proto->add_always_use_active_tree_opacity_effect_ids(i); 1813 proto->add_always_use_active_tree_opacity_effect_ids(i);
1837 } 1814 }
1838 1815
1839 // static 1816 // static
1840 void PropertyTrees::FromProtobuf(const proto::PropertyTrees& proto) { 1817 void PropertyTrees::FromProtobuf(const proto::PropertyTrees& proto) {
1841 transform_tree.FromProtobuf(proto.transform_tree(), 1818 transform_tree.FromProtobuf(proto.transform_tree(),
1842 &transform_id_to_index_map); 1819 &transform_id_to_index_map);
1843 effect_tree.FromProtobuf(proto.effect_tree(), &effect_id_to_index_map); 1820 effect_tree.FromProtobuf(proto.effect_tree(), &effect_id_to_index_map);
1844 clip_tree.FromProtobuf(proto.clip_tree(), &clip_id_to_index_map); 1821 clip_tree.FromProtobuf(proto.clip_tree(), &clip_id_to_index_map);
1845 scroll_tree.FromProtobuf(proto.scroll_tree(), &scroll_id_to_index_map); 1822 scroll_tree.FromProtobuf(proto.scroll_tree(), &scroll_id_to_index_map);
1846 1823
1847 needs_rebuild = proto.needs_rebuild(); 1824 needs_rebuild = proto.needs_rebuild();
1848 changed = proto.changed(); 1825 changed = proto.changed();
1849 full_tree_damaged = proto.full_tree_damaged(); 1826 full_tree_damaged = proto.full_tree_damaged();
1850 non_root_surfaces_enabled = proto.non_root_surfaces_enabled(); 1827 non_root_surfaces_enabled = proto.non_root_surfaces_enabled();
1851 sequence_number = proto.sequence_number(); 1828 sequence_number = proto.sequence_number();
1852 is_main_thread = proto.is_main_thread(); 1829 is_main_thread = proto.is_main_thread();
1853 is_active = proto.is_active(); 1830 is_active = proto.is_active();
1854 verify_transform_tree_calculations =
1855 proto.verify_transform_tree_calculations();
1856 1831
1857 transform_tree.SetPropertyTrees(this); 1832 transform_tree.SetPropertyTrees(this);
1858 effect_tree.SetPropertyTrees(this); 1833 effect_tree.SetPropertyTrees(this);
1859 clip_tree.SetPropertyTrees(this); 1834 clip_tree.SetPropertyTrees(this);
1860 scroll_tree.SetPropertyTrees(this); 1835 scroll_tree.SetPropertyTrees(this);
1861 for (auto i : proto.always_use_active_tree_opacity_effect_ids()) 1836 for (auto i : proto.always_use_active_tree_opacity_effect_ids())
1862 always_use_active_tree_opacity_effect_ids.push_back(i); 1837 always_use_active_tree_opacity_effect_ids.push_back(i);
1863 } 1838 }
1864 1839
1865 void PropertyTrees::clear() { 1840 void PropertyTrees::clear() {
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
2073 !node->has_only_translation_animations || ancestor_is_animating_scale; 2048 !node->has_only_translation_animations || ancestor_is_animating_scale;
2074 2049
2075 // Once we've failed to compute a maximum animated scale at an ancestor, we 2050 // Once we've failed to compute a maximum animated scale at an ancestor, we
2076 // continue to fail. 2051 // continue to fail.
2077 bool failed_at_ancestor = 2052 bool failed_at_ancestor =
2078 ancestor_is_animating_scale && ancestor_maximum_target_scale == 0.f; 2053 ancestor_is_animating_scale && ancestor_maximum_target_scale == 0.f;
2079 2054
2080 // Computing maximum animated scale in the presence of non-scale/translation 2055 // Computing maximum animated scale in the presence of non-scale/translation
2081 // transforms isn't supported. 2056 // transforms isn't supported.
2082 bool failed_for_non_scale_or_translation = 2057 bool failed_for_non_scale_or_translation =
2083 !transform_tree.Node(transform_node_id) 2058 !node->to_parent.IsScaleOrTranslation();
2084 ->to_parent.IsScaleOrTranslation();
2085 2059
2086 // We don't attempt to accumulate animation scale from multiple nodes with 2060 // We don't attempt to accumulate animation scale from multiple nodes with
2087 // scale animations, because of the risk of significant overestimation. For 2061 // scale animations, because of the risk of significant overestimation. For
2088 // example, one node might be increasing scale from 1 to 10 at the same time 2062 // example, one node might be increasing scale from 1 to 10 at the same time
2089 // as another node is decreasing scale from 10 to 1. Naively combining these 2063 // as another node is decreasing scale from 10 to 1. Naively combining these
2090 // scales would produce a scale of 100. 2064 // scales would produce a scale of 100.
2091 bool failed_for_multiple_scale_animations = 2065 bool failed_for_multiple_scale_animations =
2092 ancestor_is_animating_scale && !node->has_only_translation_animations; 2066 ancestor_is_animating_scale && !node->has_only_translation_animations;
2093 2067
2094 if (failed_at_ancestor || failed_for_non_scale_or_translation || 2068 if (failed_at_ancestor || failed_for_non_scale_or_translation ||
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
2179 float maximum_animation_scale, 2153 float maximum_animation_scale,
2180 float starting_animation_scale) { 2154 float starting_animation_scale) {
2181 cached_data_.animation_scales[transform_id] 2155 cached_data_.animation_scales[transform_id]
2182 .combined_maximum_animation_target_scale = maximum_animation_scale; 2156 .combined_maximum_animation_target_scale = maximum_animation_scale;
2183 cached_data_.animation_scales[transform_id] 2157 cached_data_.animation_scales[transform_id]
2184 .combined_starting_animation_scale = starting_animation_scale; 2158 .combined_starting_animation_scale = starting_animation_scale;
2185 cached_data_.animation_scales[transform_id].update_number = 2159 cached_data_.animation_scales[transform_id].update_number =
2186 cached_data_.property_tree_update_number; 2160 cached_data_.property_tree_update_number;
2187 } 2161 }
2188 2162
2189 const DrawTransforms& PropertyTrees::GetDrawTransforms(int transform_id, 2163 bool PropertyTrees::GetToTarget(int transform_id,
2190 int effect_id) const { 2164 int effect_id,
2191 if (cached_data_.draw_transforms[effect_id][transform_id].update_number != 2165 gfx::Transform* to_target) const {
2192 cached_data_.property_tree_update_number) { 2166 DrawTransforms& transforms = GetDrawTransforms(transform_id, effect_id);
2193 gfx::Transform target_space_transform; 2167 if (transforms.to_valid) {
2194 gfx::Transform from_target; 2168 *to_target = transforms.to_target;
2195 const TransformNode* transform_node = transform_tree.Node(transform_id); 2169 return true;
2196 const EffectNode* effect_node = effect_tree.Node(effect_id); 2170 } else if (!transforms.invertible) {
2197 const TransformNode* dest_node = 2171 return false;
2198 transform_tree.Node(effect_node->transform_id); 2172 } else {
2199 DCHECK(effect_id == effect_tree.kRootNodeId || 2173 transforms.invertible = transforms.from_target.GetInverse(to_target);
2200 effect_node->has_render_surface); 2174 transforms.to_valid = transforms.invertible;
2201 bool already_computed_inverse = false; 2175 transforms.to_target = *to_target;
2202 if (transform_id == effect_node->transform_id) { 2176 return transforms.to_valid;
2203 target_space_transform.Scale(effect_node->surface_contents_scale.x(), 2177 }
2204 effect_node->surface_contents_scale.y()); 2178 }
2205 } else if (!dest_node || (dest_node->ancestors_are_invertible && 2179
2206 dest_node->node_and_ancestors_are_flat)) { 2180 bool PropertyTrees::GetFromTarget(int transform_id,
2207 // Compute transform from transform_id to effect_node->transform using 2181 int effect_id,
2208 // screen space transforms. 2182 gfx::Transform* from_target) const {
2209 target_space_transform.ConcatTransform( 2183 DrawTransforms& transforms = GetDrawTransforms(transform_id, effect_id);
2210 transform_tree.ToScreen(transform_id)); 2184 if (transforms.from_valid) {
2211 if (dest_node) 2185 *from_target = transforms.from_target;
2212 target_space_transform.ConcatTransform( 2186 return true;
2213 transform_tree.FromScreen(dest_node->id)); 2187 } else if (!transforms.invertible) {
2214 if (dest_node->needs_surface_contents_scale) 2188 return false;
2215 target_space_transform.matrix().postScale( 2189 } else {
2216 dest_node->surface_contents_scale.x(), 2190 transforms.invertible = transforms.to_target.GetInverse(from_target);
2217 dest_node->surface_contents_scale.y(), 1.f); 2191 transforms.from_valid = transforms.invertible;
2218 } else if (transform_node->id > dest_node->id) { 2192 transforms.from_target = *from_target;
2219 target_space_transform = 2193 return transforms.from_valid;
2220 GetDrawTransforms(transform_node->parent_id, effect_id).to_target; 2194 }
2221 if (transform_node->flattens_inherited_transform) 2195 }
2222 target_space_transform.FlattenTo2d(); 2196
2223 target_space_transform.PreconcatTransform(transform_node->to_parent); 2197 DrawTransformData& PropertyTrees::FetchDrawTransformsDataFromCache(
2224 } else { 2198 int transform_id,
2225 const TransformNode* current = dest_node; 2199 int dest_id) const {
2226 std::vector<int> source_to_destination; 2200 int cnt = 0;
2227 source_to_destination.push_back(current->id); 2201 for (const auto& transform_data :
2228 current = transform_tree.parent(current); 2202 cached_data_.draw_transforms[transform_id]) {
2229 for (; current && current->id > transform_node->id; 2203 if (transform_data.target_id == dest_id || transform_data.target_id == -1) {
ajuma 2016/10/12 20:08:47 Which cases is the "-1" check supposed to handle?
sunxd 2016/10/12 21:08:19 In PropertyTrees::ResetCachedData, we initialize d
ajuma 2016/10/12 21:37:41 Ah! Please add a comment about this.
2230 current = transform_tree.parent(current)) { 2204 return cached_data_.draw_transforms[transform_id][cnt];
ajuma 2016/10/12 20:08:47 Would it work to return |transform_data| here (so
sunxd 2016/10/12 21:08:19 Done.
2231 source_to_destination.push_back(current->id);
2232 }
2233 DCHECK_EQ(current, transform_node);
2234 gfx::Transform combined_transform;
2235 size_t source_to_destination_size = source_to_destination.size();
2236 for (size_t i = 0; i < source_to_destination_size; ++i) {
2237 size_t index = source_to_destination_size - 1 - i;
2238 const TransformNode* node =
2239 transform_tree.Node(source_to_destination[index]);
2240 if (node->flattens_inherited_transform)
2241 combined_transform.FlattenTo2d();
2242 combined_transform.PreconcatTransform(node->to_parent);
2243 }
2244 if (effect_node->surface_contents_scale.x() != 0.f &&
2245 effect_node->surface_contents_scale.y() != 0.f)
2246 combined_transform.Scale(
2247 1.0f / effect_node->surface_contents_scale.x(),
2248 1.0f / effect_node->surface_contents_scale.y());
2249 cached_data_.draw_transforms[effect_id][transform_id]
2250 .transforms.invertible =
2251 combined_transform.GetInverse(&target_space_transform);
2252 from_target = combined_transform;
2253 already_computed_inverse = true;
2254 } 2205 }
2255 if (!already_computed_inverse) { 2206 cnt++;
2256 cached_data_.draw_transforms[effect_id][transform_id]
2257 .transforms.invertible =
2258 target_space_transform.GetInverse(&from_target);
2259 }
2260 cached_data_.draw_transforms[effect_id][transform_id].update_number =
2261 cached_data_.property_tree_update_number;
2262 cached_data_.draw_transforms[effect_id][transform_id]
2263 .transforms.from_target = from_target;
2264 cached_data_.draw_transforms[effect_id][transform_id].transforms.to_target =
2265 target_space_transform;
2266 } 2207 }
2267 return cached_data_.draw_transforms[effect_id][transform_id].transforms; 2208 // Add an entry to the cache.
2209 cached_data_.draw_transforms[transform_id].push_back(DrawTransformData());
2210 DrawTransformData& data = cached_data_.draw_transforms[transform_id][cnt];
2211 data.update_number = -1;
2212 data.target_id = dest_id;
2213 return data;
2214 }
2215
2216 DrawTransforms& PropertyTrees::GetDrawTransforms(int transform_id,
2217 int effect_id) const {
2218 const EffectNode* effect_node = effect_tree.Node(effect_id);
2219 int dest_id = effect_node->transform_id;
2220
2221 DrawTransformData& data =
2222 FetchDrawTransformsDataFromCache(transform_id, dest_id);
2223
2224 DCHECK(data.update_number != cached_data_.property_tree_update_number ||
2225 data.target_id != -1);
ajuma 2016/10/12 20:08:47 In what situations do we have target_id -1 (and wh
sunxd 2016/10/12 21:08:19 As stated in the comments in Fetch function, it is
2226 if (data.update_number == cached_data_.property_tree_update_number)
2227 return data.transforms;
2228
2229 // Cache miss.
2230 gfx::Transform target_space_transform;
2231 gfx::Transform from_target;
2232 bool already_computed_inverse = false;
2233 if (transform_id == dest_id) {
2234 target_space_transform.Scale(effect_node->surface_contents_scale.x(),
2235 effect_node->surface_contents_scale.y());
2236 data.transforms.to_valid = true;
2237 data.transforms.from_valid = false;
2238 } else if (transform_id > dest_id) {
2239 transform_tree.CombineTransformsBetween(transform_id, dest_id,
2240 &target_space_transform);
2241 if (dest_id != TransformTree::kRootNodeId)
ajuma 2016/10/12 20:08:47 https://codereview.chromium.org/2408243002/ might
sunxd 2016/10/12 21:08:19 Is it safe that we do not apply root surface conte
2242 target_space_transform.matrix().postScale(
2243 effect_node->surface_contents_scale.x(),
2244 effect_node->surface_contents_scale.y(), 1.f);
2245 data.transforms.to_valid = true;
2246 data.transforms.from_valid = false;
2247 data.transforms.invertible = true;
2248 } else {
2249 gfx::Transform combined_transform;
2250 transform_tree.CombineTransformsBetween(dest_id, transform_id,
2251 &combined_transform);
2252 if (effect_node->surface_contents_scale.x() != 0.f &&
2253 effect_node->surface_contents_scale.y() != 0.f)
2254 combined_transform.Scale(1.0f / effect_node->surface_contents_scale.x(),
2255 1.0f / effect_node->surface_contents_scale.y());
2256 bool invertible = combined_transform.GetInverse(&target_space_transform);
2257 data.transforms.invertible = invertible;
2258 data.transforms.to_valid = invertible;
2259 data.transforms.from_valid = true;
2260 from_target = combined_transform;
2261 already_computed_inverse = true;
2262 }
2263
2264 if (!already_computed_inverse)
2265 data.transforms.to_valid = true;
2266 data.update_number = cached_data_.property_tree_update_number;
2267 data.target_id = dest_id;
2268 data.transforms.from_target = from_target;
2269 data.transforms.to_target = target_space_transform;
2270 return data.transforms;
2268 } 2271 }
2269 2272
2270 void PropertyTrees::ResetCachedData() { 2273 void PropertyTrees::ResetCachedData() {
2271 cached_data_.property_tree_update_number = 0; 2274 cached_data_.property_tree_update_number = 0;
2272 cached_data_.animation_scales = std::vector<AnimationScaleData>( 2275 cached_data_.animation_scales = std::vector<AnimationScaleData>(
2273 transform_tree.nodes().size(), AnimationScaleData()); 2276 transform_tree.nodes().size(), AnimationScaleData());
2274 cached_data_.draw_transforms = 2277 cached_data_.draw_transforms = std::vector<std::vector<DrawTransformData>>(
2275 std::vector<std::unordered_map<int, DrawTransformData>>( 2278 transform_tree.nodes().size(), std::vector<DrawTransformData>(1));
2276 effect_tree.nodes().size(),
2277 std::unordered_map<int, DrawTransformData>());
2278 } 2279 }
2279 2280
2280 void PropertyTrees::UpdateCachedNumber() { 2281 void PropertyTrees::UpdateCachedNumber() {
2281 cached_data_.property_tree_update_number++; 2282 cached_data_.property_tree_update_number++;
2282 } 2283 }
2283 2284
2284 gfx::Transform PropertyTrees::ToScreenSpaceTransformWithoutSurfaceContentsScale( 2285 gfx::Transform PropertyTrees::ToScreenSpaceTransformWithoutSurfaceContentsScale(
2285 int transform_id, 2286 int transform_id,
2286 int effect_id) const { 2287 int effect_id) const {
2287 DCHECK_GT(transform_id, 0); 2288 DCHECK_GT(transform_id, 0);
2288 if (transform_id == 1) { 2289 if (transform_id == 1) {
2289 return gfx::Transform(); 2290 return gfx::Transform();
2290 } 2291 }
2291 gfx::Transform screen_space_transform = transform_tree.ToScreen(transform_id); 2292 gfx::Transform screen_space_transform = transform_tree.ToScreen(transform_id);
2292 const EffectNode* effect_node = effect_tree.Node(effect_id); 2293 const EffectNode* effect_node = effect_tree.Node(effect_id);
2293 2294
2294 if (effect_node->surface_contents_scale.x() != 0.0 && 2295 if (effect_node->surface_contents_scale.x() != 0.0 &&
2295 effect_node->surface_contents_scale.y() != 0.0) 2296 effect_node->surface_contents_scale.y() != 0.0)
2296 screen_space_transform.Scale(1.0 / effect_node->surface_contents_scale.x(), 2297 screen_space_transform.Scale(1.0 / effect_node->surface_contents_scale.x(),
2297 1.0 / effect_node->surface_contents_scale.y()); 2298 1.0 / effect_node->surface_contents_scale.y());
2298 return screen_space_transform; 2299 return screen_space_transform;
2299 } 2300 }
2300 2301
2301 bool PropertyTrees::ComputeTransformToTarget(int transform_id, 2302 bool PropertyTrees::ComputeTransformToTarget(int transform_id,
2302 int effect_id, 2303 int effect_id,
2303 gfx::Transform* transform) const { 2304 gfx::Transform* transform) const {
2304 transform->MakeIdentity(); 2305 transform->MakeIdentity();
2305
2306 if (transform_id == TransformTree::kInvalidNodeId) 2306 if (transform_id == TransformTree::kInvalidNodeId)
2307 return true; 2307 return true;
2308 2308
2309 int target_transform_id;
2310 const EffectNode* effect_node = effect_tree.Node(effect_id); 2309 const EffectNode* effect_node = effect_tree.Node(effect_id);
2311 if (effect_id == EffectTree::kInvalidNodeId) {
2312 // This can happen when PaintArtifactCompositor builds property trees as
2313 // it doesn't set effect ids on clip nodes. We want to compute transform
2314 // to the root in this case.
2315 target_transform_id = TransformTree::kRootNodeId;
2316 } else {
2317 DCHECK(effect_node->has_render_surface ||
2318 effect_node->id == EffectTree::kRootNodeId);
2319 target_transform_id = effect_node->transform_id;
2320 }
2321 2310
2322 bool success = transform_tree.ComputeTransform( 2311 bool success = GetToTarget(transform_id, effect_id, transform);
2323 transform_id, target_transform_id, transform); 2312 if (effect_node->surface_contents_scale.x() != 0.f &&
2324 if (verify_transform_tree_calculations) { 2313 effect_node->surface_contents_scale.y() != 0.f)
2325 gfx::Transform to_target; 2314 transform->matrix().postScale(
2326 to_target.ConcatTransform( 2315 1.0f / effect_node->surface_contents_scale.x(),
2327 GetDrawTransforms(transform_id, effect_id).to_target); 2316 1.0f / effect_node->surface_contents_scale.y(), 1.0f);
2328 if (effect_node->surface_contents_scale.x() != 0.f &&
2329 effect_node->surface_contents_scale.y() != 0.f)
2330 to_target.matrix().postScale(
2331 1.0f / effect_node->surface_contents_scale.x(),
2332 1.0f / effect_node->surface_contents_scale.y(), 1.0f);
2333 DCHECK(to_target.ApproximatelyEqual(*transform));
2334 }
2335 return success; 2317 return success;
2336 } 2318 }
2337 2319
2338 bool PropertyTrees::ComputeTransformFromTarget( 2320 bool PropertyTrees::ComputeTransformFromTarget(
2339 int transform_id, 2321 int transform_id,
2340 int effect_id, 2322 int effect_id,
2341 gfx::Transform* transform) const { 2323 gfx::Transform* transform) const {
2342 transform->MakeIdentity(); 2324 transform->MakeIdentity();
2343
2344 if (transform_id == TransformTree::kInvalidNodeId) 2325 if (transform_id == TransformTree::kInvalidNodeId)
2345 return true; 2326 return true;
2346 2327
2347 int target_transform_id;
2348 const EffectNode* effect_node = effect_tree.Node(effect_id); 2328 const EffectNode* effect_node = effect_tree.Node(effect_id);
2349 if (effect_id == EffectTree::kInvalidNodeId) {
2350 // This can happen when PaintArtifactCompositor builds property trees as
2351 // it doesn't set effect ids on clip nodes. We want to compute transform
2352 // to the root in this case.
2353 target_transform_id = TransformTree::kRootNodeId;
2354 } else {
2355 DCHECK(effect_node->has_render_surface ||
2356 effect_node->id == EffectTree::kRootNodeId);
2357 target_transform_id = effect_node->transform_id;
2358 }
2359 2329
2360 bool success = transform_tree.ComputeTransform(target_transform_id, 2330 bool success = GetFromTarget(transform_id, effect_id, transform);
2361 transform_id, transform); 2331 transform->Scale(effect_node->surface_contents_scale.x(),
2362 if (verify_transform_tree_calculations) { 2332 effect_node->surface_contents_scale.y());
2363 auto draw_transforms = GetDrawTransforms(transform_id, effect_id);
2364 gfx::Transform from_target;
2365 from_target.ConcatTransform(draw_transforms.from_target);
2366 from_target.Scale(effect_node->surface_contents_scale.x(),
2367 effect_node->surface_contents_scale.y());
2368 DCHECK(from_target.ApproximatelyEqual(*transform) ||
2369 !draw_transforms.invertible);
2370 }
2371 return success; 2333 return success;
2372 } 2334 }
2373 2335
2374 } // namespace cc 2336 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698