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 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |