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; |
| 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 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
760 } | 756 } |
761 | 757 |
762 bool TransformTree::HasNodesAffectedByInnerViewportBoundsDelta() const { | 758 bool TransformTree::HasNodesAffectedByInnerViewportBoundsDelta() const { |
763 return !nodes_affected_by_inner_viewport_bounds_delta_.empty(); | 759 return !nodes_affected_by_inner_viewport_bounds_delta_.empty(); |
764 } | 760 } |
765 | 761 |
766 bool TransformTree::HasNodesAffectedByOuterViewportBoundsDelta() const { | 762 bool TransformTree::HasNodesAffectedByOuterViewportBoundsDelta() const { |
767 return !nodes_affected_by_outer_viewport_bounds_delta_.empty(); | 763 return !nodes_affected_by_outer_viewport_bounds_delta_.empty(); |
768 } | 764 } |
769 | 765 |
770 const gfx::Transform& TransformTree::FromTarget(int node_id, | 766 gfx::Transform TransformTree::FromTarget(int node_id, int effect_id) const { |
771 int effect_id) const { | 767 gfx::Transform from_target; |
772 DCHECK(static_cast<int>(cached_data_.size()) > node_id); | 768 property_trees()->GetFromTarget(node_id, effect_id, &from_target); |
773 if (effect_id != kInvalidNodeId && | 769 return from_target; |
774 property_trees()->verify_transform_tree_calculations) { | |
775 const gfx::Transform& transform = | |
776 property_trees()->GetDrawTransforms(node_id, effect_id).from_target; | |
777 CHECK(transform.ApproximatelyEqual(cached_data_[node_id].from_target)); | |
778 } | |
779 return cached_data_[node_id].from_target; | |
780 } | 770 } |
781 | 771 |
782 void TransformTree::SetFromTarget(int node_id, | 772 void TransformTree::SetFromTarget(int node_id, |
783 const gfx::Transform& transform) { | 773 const gfx::Transform& transform) { |
784 DCHECK(static_cast<int>(cached_data_.size()) > node_id); | 774 DCHECK(static_cast<int>(cached_data_.size()) > node_id); |
785 cached_data_[node_id].from_target = transform; | 775 cached_data_[node_id].from_target = transform; |
786 } | 776 } |
787 | 777 |
788 const gfx::Transform& TransformTree::ToTarget(int node_id, | 778 gfx::Transform TransformTree::ToTarget(int node_id, int effect_id) const { |
789 int effect_id) const { | 779 gfx::Transform to_target; |
790 DCHECK(static_cast<int>(cached_data_.size()) > node_id); | 780 property_trees()->GetToTarget(node_id, effect_id, &to_target); |
791 if (effect_id != kInvalidNodeId && | 781 return to_target; |
792 property_trees()->verify_transform_tree_calculations) { | |
793 const gfx::Transform& transform = | |
794 property_trees()->GetDrawTransforms(node_id, effect_id).to_target; | |
795 if (property_trees()->non_root_surfaces_enabled) | |
796 CHECK(transform.ApproximatelyEqual(cached_data_[node_id].to_target)); | |
797 else | |
798 CHECK(transform.ApproximatelyEqual(cached_data_[node_id].to_screen)); | |
799 } | |
800 return cached_data_[node_id].to_target; | |
801 } | 782 } |
802 | 783 |
803 void TransformTree::SetToTarget(int node_id, const gfx::Transform& transform) { | 784 void TransformTree::SetToTarget(int node_id, const gfx::Transform& transform) { |
804 DCHECK(static_cast<int>(cached_data_.size()) > node_id); | 785 DCHECK(static_cast<int>(cached_data_.size()) > node_id); |
805 cached_data_[node_id].to_target = transform; | 786 cached_data_[node_id].to_target = transform; |
806 } | 787 } |
807 | 788 |
808 const gfx::Transform& TransformTree::FromScreen(int node_id) const { | 789 const gfx::Transform& TransformTree::FromScreen(int node_id) const { |
809 DCHECK(static_cast<int>(cached_data_.size()) > node_id); | 790 DCHECK(static_cast<int>(cached_data_.size()) > node_id); |
810 return cached_data_[node_id].from_screen; | 791 return cached_data_[node_id].from_screen; |
(...skipping 935 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1746 | 1727 |
1747 PropertyTreesCachedData::~PropertyTreesCachedData() {} | 1728 PropertyTreesCachedData::~PropertyTreesCachedData() {} |
1748 | 1729 |
1749 PropertyTrees::PropertyTrees() | 1730 PropertyTrees::PropertyTrees() |
1750 : needs_rebuild(true), | 1731 : needs_rebuild(true), |
1751 non_root_surfaces_enabled(true), | 1732 non_root_surfaces_enabled(true), |
1752 changed(false), | 1733 changed(false), |
1753 full_tree_damaged(false), | 1734 full_tree_damaged(false), |
1754 sequence_number(0), | 1735 sequence_number(0), |
1755 is_main_thread(true), | 1736 is_main_thread(true), |
1756 is_active(false), | 1737 is_active(false) { |
1757 verify_transform_tree_calculations(false) { | |
1758 transform_tree.SetPropertyTrees(this); | 1738 transform_tree.SetPropertyTrees(this); |
1759 effect_tree.SetPropertyTrees(this); | 1739 effect_tree.SetPropertyTrees(this); |
1760 clip_tree.SetPropertyTrees(this); | 1740 clip_tree.SetPropertyTrees(this); |
1761 scroll_tree.SetPropertyTrees(this); | 1741 scroll_tree.SetPropertyTrees(this); |
1762 } | 1742 } |
1763 | 1743 |
1764 PropertyTrees::~PropertyTrees() {} | 1744 PropertyTrees::~PropertyTrees() {} |
1765 | 1745 |
1766 bool PropertyTrees::operator==(const PropertyTrees& other) const { | 1746 bool PropertyTrees::operator==(const PropertyTrees& other) const { |
1767 return transform_tree == other.transform_tree && | 1747 return transform_tree == other.transform_tree && |
(...skipping 24 matching lines...) Expand all Loading... |
1792 from.always_use_active_tree_opacity_effect_ids; | 1772 from.always_use_active_tree_opacity_effect_ids; |
1793 clip_id_to_index_map = from.clip_id_to_index_map; | 1773 clip_id_to_index_map = from.clip_id_to_index_map; |
1794 scroll_id_to_index_map = from.scroll_id_to_index_map; | 1774 scroll_id_to_index_map = from.scroll_id_to_index_map; |
1795 needs_rebuild = from.needs_rebuild; | 1775 needs_rebuild = from.needs_rebuild; |
1796 changed = from.changed; | 1776 changed = from.changed; |
1797 full_tree_damaged = from.full_tree_damaged; | 1777 full_tree_damaged = from.full_tree_damaged; |
1798 non_root_surfaces_enabled = from.non_root_surfaces_enabled; | 1778 non_root_surfaces_enabled = from.non_root_surfaces_enabled; |
1799 sequence_number = from.sequence_number; | 1779 sequence_number = from.sequence_number; |
1800 is_main_thread = from.is_main_thread; | 1780 is_main_thread = from.is_main_thread; |
1801 is_active = from.is_active; | 1781 is_active = from.is_active; |
1802 verify_transform_tree_calculations = from.verify_transform_tree_calculations; | |
1803 inner_viewport_container_bounds_delta_ = | 1782 inner_viewport_container_bounds_delta_ = |
1804 from.inner_viewport_container_bounds_delta(); | 1783 from.inner_viewport_container_bounds_delta(); |
1805 outer_viewport_container_bounds_delta_ = | 1784 outer_viewport_container_bounds_delta_ = |
1806 from.outer_viewport_container_bounds_delta(); | 1785 from.outer_viewport_container_bounds_delta(); |
1807 inner_viewport_scroll_bounds_delta_ = | 1786 inner_viewport_scroll_bounds_delta_ = |
1808 from.inner_viewport_scroll_bounds_delta(); | 1787 from.inner_viewport_scroll_bounds_delta(); |
1809 transform_tree.SetPropertyTrees(this); | 1788 transform_tree.SetPropertyTrees(this); |
1810 effect_tree.SetPropertyTrees(this); | 1789 effect_tree.SetPropertyTrees(this); |
1811 clip_tree.SetPropertyTrees(this); | 1790 clip_tree.SetPropertyTrees(this); |
1812 scroll_tree.SetPropertyTrees(this); | 1791 scroll_tree.SetPropertyTrees(this); |
1813 ResetCachedData(); | 1792 ResetCachedData(); |
1814 return *this; | 1793 return *this; |
1815 } | 1794 } |
1816 | 1795 |
1817 void PropertyTrees::ToProtobuf(proto::PropertyTrees* proto) const { | 1796 void PropertyTrees::ToProtobuf(proto::PropertyTrees* proto) const { |
1818 // TODO(khushalsagar): Add support for sending diffs when serializaing | 1797 // TODO(khushalsagar): Add support for sending diffs when serializaing |
1819 // property trees. See crbug/555370. | 1798 // property trees. See crbug/555370. |
1820 transform_tree.ToProtobuf(proto->mutable_transform_tree()); | 1799 transform_tree.ToProtobuf(proto->mutable_transform_tree()); |
1821 effect_tree.ToProtobuf(proto->mutable_effect_tree()); | 1800 effect_tree.ToProtobuf(proto->mutable_effect_tree()); |
1822 clip_tree.ToProtobuf(proto->mutable_clip_tree()); | 1801 clip_tree.ToProtobuf(proto->mutable_clip_tree()); |
1823 scroll_tree.ToProtobuf(proto->mutable_scroll_tree()); | 1802 scroll_tree.ToProtobuf(proto->mutable_scroll_tree()); |
1824 proto->set_needs_rebuild(needs_rebuild); | 1803 proto->set_needs_rebuild(needs_rebuild); |
1825 proto->set_changed(changed); | 1804 proto->set_changed(changed); |
1826 proto->set_full_tree_damaged(full_tree_damaged); | 1805 proto->set_full_tree_damaged(full_tree_damaged); |
1827 proto->set_non_root_surfaces_enabled(non_root_surfaces_enabled); | 1806 proto->set_non_root_surfaces_enabled(non_root_surfaces_enabled); |
1828 proto->set_is_main_thread(is_main_thread); | 1807 proto->set_is_main_thread(is_main_thread); |
1829 proto->set_is_active(is_active); | 1808 proto->set_is_active(is_active); |
1830 proto->set_verify_transform_tree_calculations( | |
1831 verify_transform_tree_calculations); | |
1832 | 1809 |
1833 // TODO(khushalsagar): Consider using the sequence number to decide if | 1810 // TODO(khushalsagar): Consider using the sequence number to decide if |
1834 // property trees need to be serialized again for a commit. See crbug/555370. | 1811 // property trees need to be serialized again for a commit. See crbug/555370. |
1835 proto->set_sequence_number(sequence_number); | 1812 proto->set_sequence_number(sequence_number); |
1836 | 1813 |
1837 for (auto i : always_use_active_tree_opacity_effect_ids) | 1814 for (auto i : always_use_active_tree_opacity_effect_ids) |
1838 proto->add_always_use_active_tree_opacity_effect_ids(i); | 1815 proto->add_always_use_active_tree_opacity_effect_ids(i); |
1839 } | 1816 } |
1840 | 1817 |
1841 // static | 1818 // static |
1842 void PropertyTrees::FromProtobuf(const proto::PropertyTrees& proto) { | 1819 void PropertyTrees::FromProtobuf(const proto::PropertyTrees& proto) { |
1843 transform_tree.FromProtobuf(proto.transform_tree(), | 1820 transform_tree.FromProtobuf(proto.transform_tree(), |
1844 &transform_id_to_index_map); | 1821 &transform_id_to_index_map); |
1845 effect_tree.FromProtobuf(proto.effect_tree(), &effect_id_to_index_map); | 1822 effect_tree.FromProtobuf(proto.effect_tree(), &effect_id_to_index_map); |
1846 clip_tree.FromProtobuf(proto.clip_tree(), &clip_id_to_index_map); | 1823 clip_tree.FromProtobuf(proto.clip_tree(), &clip_id_to_index_map); |
1847 scroll_tree.FromProtobuf(proto.scroll_tree(), &scroll_id_to_index_map); | 1824 scroll_tree.FromProtobuf(proto.scroll_tree(), &scroll_id_to_index_map); |
1848 | 1825 |
1849 needs_rebuild = proto.needs_rebuild(); | 1826 needs_rebuild = proto.needs_rebuild(); |
1850 changed = proto.changed(); | 1827 changed = proto.changed(); |
1851 full_tree_damaged = proto.full_tree_damaged(); | 1828 full_tree_damaged = proto.full_tree_damaged(); |
1852 non_root_surfaces_enabled = proto.non_root_surfaces_enabled(); | 1829 non_root_surfaces_enabled = proto.non_root_surfaces_enabled(); |
1853 sequence_number = proto.sequence_number(); | 1830 sequence_number = proto.sequence_number(); |
1854 is_main_thread = proto.is_main_thread(); | 1831 is_main_thread = proto.is_main_thread(); |
1855 is_active = proto.is_active(); | 1832 is_active = proto.is_active(); |
1856 verify_transform_tree_calculations = | |
1857 proto.verify_transform_tree_calculations(); | |
1858 | 1833 |
1859 transform_tree.SetPropertyTrees(this); | 1834 transform_tree.SetPropertyTrees(this); |
1860 effect_tree.SetPropertyTrees(this); | 1835 effect_tree.SetPropertyTrees(this); |
1861 clip_tree.SetPropertyTrees(this); | 1836 clip_tree.SetPropertyTrees(this); |
1862 scroll_tree.SetPropertyTrees(this); | 1837 scroll_tree.SetPropertyTrees(this); |
1863 for (auto i : proto.always_use_active_tree_opacity_effect_ids()) | 1838 for (auto i : proto.always_use_active_tree_opacity_effect_ids()) |
1864 always_use_active_tree_opacity_effect_ids.push_back(i); | 1839 always_use_active_tree_opacity_effect_ids.push_back(i); |
1865 } | 1840 } |
1866 | 1841 |
1867 void PropertyTrees::clear() { | 1842 void PropertyTrees::clear() { |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2075 !node->has_only_translation_animations || ancestor_is_animating_scale; | 2050 !node->has_only_translation_animations || ancestor_is_animating_scale; |
2076 | 2051 |
2077 // Once we've failed to compute a maximum animated scale at an ancestor, we | 2052 // Once we've failed to compute a maximum animated scale at an ancestor, we |
2078 // continue to fail. | 2053 // continue to fail. |
2079 bool failed_at_ancestor = | 2054 bool failed_at_ancestor = |
2080 ancestor_is_animating_scale && ancestor_maximum_target_scale == 0.f; | 2055 ancestor_is_animating_scale && ancestor_maximum_target_scale == 0.f; |
2081 | 2056 |
2082 // Computing maximum animated scale in the presence of non-scale/translation | 2057 // Computing maximum animated scale in the presence of non-scale/translation |
2083 // transforms isn't supported. | 2058 // transforms isn't supported. |
2084 bool failed_for_non_scale_or_translation = | 2059 bool failed_for_non_scale_or_translation = |
2085 !transform_tree.Node(transform_node_id) | 2060 !node->to_parent.IsScaleOrTranslation(); |
2086 ->to_parent.IsScaleOrTranslation(); | |
2087 | 2061 |
2088 // We don't attempt to accumulate animation scale from multiple nodes with | 2062 // We don't attempt to accumulate animation scale from multiple nodes with |
2089 // scale animations, because of the risk of significant overestimation. For | 2063 // scale animations, because of the risk of significant overestimation. For |
2090 // example, one node might be increasing scale from 1 to 10 at the same time | 2064 // example, one node might be increasing scale from 1 to 10 at the same time |
2091 // as another node is decreasing scale from 10 to 1. Naively combining these | 2065 // as another node is decreasing scale from 10 to 1. Naively combining these |
2092 // scales would produce a scale of 100. | 2066 // scales would produce a scale of 100. |
2093 bool failed_for_multiple_scale_animations = | 2067 bool failed_for_multiple_scale_animations = |
2094 ancestor_is_animating_scale && !node->has_only_translation_animations; | 2068 ancestor_is_animating_scale && !node->has_only_translation_animations; |
2095 | 2069 |
2096 if (failed_at_ancestor || failed_for_non_scale_or_translation || | 2070 if (failed_at_ancestor || failed_for_non_scale_or_translation || |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2181 float maximum_animation_scale, | 2155 float maximum_animation_scale, |
2182 float starting_animation_scale) { | 2156 float starting_animation_scale) { |
2183 cached_data_.animation_scales[transform_id] | 2157 cached_data_.animation_scales[transform_id] |
2184 .combined_maximum_animation_target_scale = maximum_animation_scale; | 2158 .combined_maximum_animation_target_scale = maximum_animation_scale; |
2185 cached_data_.animation_scales[transform_id] | 2159 cached_data_.animation_scales[transform_id] |
2186 .combined_starting_animation_scale = starting_animation_scale; | 2160 .combined_starting_animation_scale = starting_animation_scale; |
2187 cached_data_.animation_scales[transform_id].update_number = | 2161 cached_data_.animation_scales[transform_id].update_number = |
2188 cached_data_.property_tree_update_number; | 2162 cached_data_.property_tree_update_number; |
2189 } | 2163 } |
2190 | 2164 |
2191 const DrawTransforms& PropertyTrees::GetDrawTransforms(int transform_id, | 2165 bool PropertyTrees::GetToTarget(int transform_id, |
2192 int effect_id) const { | 2166 int effect_id, |
2193 if (cached_data_.draw_transforms[effect_id][transform_id].update_number != | 2167 gfx::Transform* to_target) const { |
2194 cached_data_.property_tree_update_number) { | 2168 DrawTransforms& transforms = GetDrawTransforms(transform_id, effect_id); |
2195 gfx::Transform target_space_transform; | 2169 if (transforms.to_valid) { |
2196 gfx::Transform from_target; | 2170 *to_target = transforms.to_target; |
2197 const TransformNode* transform_node = transform_tree.Node(transform_id); | 2171 return true; |
2198 const EffectNode* effect_node = effect_tree.Node(effect_id); | 2172 } else if (!transforms.might_be_invertible) { |
2199 const TransformNode* dest_node = | 2173 return false; |
2200 transform_tree.Node(effect_node->transform_id); | 2174 } else { |
2201 DCHECK(effect_id == effect_tree.kRootNodeId || | 2175 transforms.might_be_invertible = |
2202 effect_node->has_render_surface); | 2176 transforms.from_target.GetInverse(to_target); |
2203 bool already_computed_inverse = false; | 2177 transforms.to_valid = transforms.might_be_invertible; |
2204 if (transform_id == effect_node->transform_id) { | 2178 transforms.to_target = *to_target; |
2205 target_space_transform.Scale(effect_node->surface_contents_scale.x(), | 2179 return transforms.to_valid; |
2206 effect_node->surface_contents_scale.y()); | 2180 } |
2207 } else if (!dest_node || (dest_node->ancestors_are_invertible && | 2181 } |
2208 dest_node->node_and_ancestors_are_flat)) { | 2182 |
2209 // Compute transform from transform_id to effect_node->transform using | 2183 bool PropertyTrees::GetFromTarget(int transform_id, |
2210 // screen space transforms. | 2184 int effect_id, |
2211 target_space_transform.ConcatTransform( | 2185 gfx::Transform* from_target) const { |
2212 transform_tree.ToScreen(transform_id)); | 2186 DrawTransforms& transforms = GetDrawTransforms(transform_id, effect_id); |
2213 if (dest_node) | 2187 if (transforms.from_valid) { |
2214 target_space_transform.ConcatTransform( | 2188 *from_target = transforms.from_target; |
2215 transform_tree.FromScreen(dest_node->id)); | 2189 return true; |
2216 if (dest_node->needs_surface_contents_scale) | 2190 } else if (!transforms.might_be_invertible) { |
2217 target_space_transform.matrix().postScale( | 2191 return false; |
2218 dest_node->surface_contents_scale.x(), | 2192 } else { |
2219 dest_node->surface_contents_scale.y(), 1.f); | 2193 transforms.might_be_invertible = |
2220 } else if (transform_node->id > dest_node->id) { | 2194 transforms.to_target.GetInverse(from_target); |
2221 target_space_transform = | 2195 transforms.from_valid = transforms.might_be_invertible; |
2222 GetDrawTransforms(transform_node->parent_id, effect_id).to_target; | 2196 transforms.from_target = *from_target; |
2223 if (transform_node->flattens_inherited_transform) | 2197 return transforms.from_valid; |
2224 target_space_transform.FlattenTo2d(); | 2198 } |
2225 target_space_transform.PreconcatTransform(transform_node->to_parent); | 2199 } |
2226 } else { | 2200 |
2227 const TransformNode* current = dest_node; | 2201 DrawTransformData& PropertyTrees::FetchDrawTransformsDataFromCache( |
2228 std::vector<int> source_to_destination; | 2202 int transform_id, |
2229 source_to_destination.push_back(current->id); | 2203 int dest_id) const { |
2230 current = transform_tree.parent(current); | 2204 for (auto& transform_data : cached_data_.draw_transforms[transform_id]) { |
2231 for (; current && current->id > transform_node->id; | 2205 // We initialize draw_transforms with 1 element vectors when |
2232 current = transform_tree.parent(current)) { | 2206 // ResetCachedData, so if we hit a -1 target id, it means it's the first |
2233 source_to_destination.push_back(current->id); | 2207 // time we compute draw transforms after reset. |
2234 } | 2208 if (transform_data.target_id == dest_id || transform_data.target_id == -1) { |
2235 DCHECK_EQ(current, transform_node); | 2209 return transform_data; |
2236 gfx::Transform combined_transform; | |
2237 size_t source_to_destination_size = source_to_destination.size(); | |
2238 for (size_t i = 0; i < source_to_destination_size; ++i) { | |
2239 size_t index = source_to_destination_size - 1 - i; | |
2240 const TransformNode* node = | |
2241 transform_tree.Node(source_to_destination[index]); | |
2242 if (node->flattens_inherited_transform) | |
2243 combined_transform.FlattenTo2d(); | |
2244 combined_transform.PreconcatTransform(node->to_parent); | |
2245 } | |
2246 if (effect_node->surface_contents_scale.x() != 0.f && | |
2247 effect_node->surface_contents_scale.y() != 0.f) | |
2248 combined_transform.Scale( | |
2249 1.0f / effect_node->surface_contents_scale.x(), | |
2250 1.0f / effect_node->surface_contents_scale.y()); | |
2251 cached_data_.draw_transforms[effect_id][transform_id] | |
2252 .transforms.invertible = | |
2253 combined_transform.GetInverse(&target_space_transform); | |
2254 from_target = combined_transform; | |
2255 already_computed_inverse = true; | |
2256 } | 2210 } |
2257 if (!already_computed_inverse) { | |
2258 cached_data_.draw_transforms[effect_id][transform_id] | |
2259 .transforms.invertible = | |
2260 target_space_transform.GetInverse(&from_target); | |
2261 } | |
2262 cached_data_.draw_transforms[effect_id][transform_id].update_number = | |
2263 cached_data_.property_tree_update_number; | |
2264 cached_data_.draw_transforms[effect_id][transform_id] | |
2265 .transforms.from_target = from_target; | |
2266 cached_data_.draw_transforms[effect_id][transform_id].transforms.to_target = | |
2267 target_space_transform; | |
2268 } | 2211 } |
2269 return cached_data_.draw_transforms[effect_id][transform_id].transforms; | 2212 // Add an entry to the cache. |
| 2213 cached_data_.draw_transforms[transform_id].push_back(DrawTransformData()); |
| 2214 DrawTransformData& data = cached_data_.draw_transforms[transform_id].back(); |
| 2215 data.update_number = -1; |
| 2216 data.target_id = dest_id; |
| 2217 return data; |
| 2218 } |
| 2219 |
| 2220 DrawTransforms& PropertyTrees::GetDrawTransforms(int transform_id, |
| 2221 int effect_id) const { |
| 2222 const EffectNode* effect_node = effect_tree.Node(effect_id); |
| 2223 int dest_id = effect_node->transform_id; |
| 2224 |
| 2225 DrawTransformData& data = |
| 2226 FetchDrawTransformsDataFromCache(transform_id, dest_id); |
| 2227 |
| 2228 DCHECK(data.update_number != cached_data_.property_tree_update_number || |
| 2229 data.target_id != -1); |
| 2230 if (data.update_number == cached_data_.property_tree_update_number) |
| 2231 return data.transforms; |
| 2232 |
| 2233 // Cache miss. |
| 2234 gfx::Transform target_space_transform; |
| 2235 gfx::Transform from_target; |
| 2236 bool already_computed_inverse = false; |
| 2237 if (transform_id == dest_id) { |
| 2238 target_space_transform.Scale(effect_node->surface_contents_scale.x(), |
| 2239 effect_node->surface_contents_scale.y()); |
| 2240 data.transforms.to_valid = true; |
| 2241 data.transforms.from_valid = false; |
| 2242 } else if (transform_id > dest_id) { |
| 2243 transform_tree.CombineTransformsBetween(transform_id, dest_id, |
| 2244 &target_space_transform); |
| 2245 if (dest_id != TransformTree::kRootNodeId) |
| 2246 target_space_transform.matrix().postScale( |
| 2247 effect_node->surface_contents_scale.x(), |
| 2248 effect_node->surface_contents_scale.y(), 1.f); |
| 2249 data.transforms.to_valid = true; |
| 2250 data.transforms.from_valid = false; |
| 2251 data.transforms.might_be_invertible = true; |
| 2252 } else { |
| 2253 gfx::Transform combined_transform; |
| 2254 transform_tree.CombineTransformsBetween(dest_id, transform_id, |
| 2255 &combined_transform); |
| 2256 if (effect_node->surface_contents_scale.x() != 0.f && |
| 2257 effect_node->surface_contents_scale.y() != 0.f) |
| 2258 combined_transform.Scale(1.0f / effect_node->surface_contents_scale.x(), |
| 2259 1.0f / effect_node->surface_contents_scale.y()); |
| 2260 bool invertible = combined_transform.GetInverse(&target_space_transform); |
| 2261 data.transforms.might_be_invertible = invertible; |
| 2262 data.transforms.to_valid = invertible; |
| 2263 data.transforms.from_valid = true; |
| 2264 from_target = combined_transform; |
| 2265 already_computed_inverse = true; |
| 2266 } |
| 2267 |
| 2268 if (!already_computed_inverse) |
| 2269 data.transforms.to_valid = true; |
| 2270 data.update_number = cached_data_.property_tree_update_number; |
| 2271 data.target_id = dest_id; |
| 2272 data.transforms.from_target = from_target; |
| 2273 data.transforms.to_target = target_space_transform; |
| 2274 return data.transforms; |
2270 } | 2275 } |
2271 | 2276 |
2272 void PropertyTrees::ResetCachedData() { | 2277 void PropertyTrees::ResetCachedData() { |
2273 cached_data_.property_tree_update_number = 0; | 2278 cached_data_.property_tree_update_number = 0; |
2274 cached_data_.animation_scales = std::vector<AnimationScaleData>( | 2279 cached_data_.animation_scales = std::vector<AnimationScaleData>( |
2275 transform_tree.nodes().size(), AnimationScaleData()); | 2280 transform_tree.nodes().size(), AnimationScaleData()); |
2276 cached_data_.draw_transforms = | 2281 cached_data_.draw_transforms = std::vector<std::vector<DrawTransformData>>( |
2277 std::vector<std::unordered_map<int, DrawTransformData>>( | 2282 transform_tree.nodes().size(), std::vector<DrawTransformData>(1)); |
2278 effect_tree.nodes().size(), | |
2279 std::unordered_map<int, DrawTransformData>()); | |
2280 } | 2283 } |
2281 | 2284 |
2282 void PropertyTrees::UpdateCachedNumber() { | 2285 void PropertyTrees::UpdateCachedNumber() { |
2283 cached_data_.property_tree_update_number++; | 2286 cached_data_.property_tree_update_number++; |
2284 } | 2287 } |
2285 | 2288 |
2286 gfx::Transform PropertyTrees::ToScreenSpaceTransformWithoutSurfaceContentsScale( | 2289 gfx::Transform PropertyTrees::ToScreenSpaceTransformWithoutSurfaceContentsScale( |
2287 int transform_id, | 2290 int transform_id, |
2288 int effect_id) const { | 2291 int effect_id) const { |
2289 DCHECK_GT(transform_id, 0); | 2292 DCHECK_GT(transform_id, 0); |
2290 if (transform_id == 1) { | 2293 if (transform_id == 1) { |
2291 return gfx::Transform(); | 2294 return gfx::Transform(); |
2292 } | 2295 } |
2293 gfx::Transform screen_space_transform = transform_tree.ToScreen(transform_id); | 2296 gfx::Transform screen_space_transform = transform_tree.ToScreen(transform_id); |
2294 const EffectNode* effect_node = effect_tree.Node(effect_id); | 2297 const EffectNode* effect_node = effect_tree.Node(effect_id); |
2295 | 2298 |
2296 if (effect_node->surface_contents_scale.x() != 0.0 && | 2299 if (effect_node->surface_contents_scale.x() != 0.0 && |
2297 effect_node->surface_contents_scale.y() != 0.0) | 2300 effect_node->surface_contents_scale.y() != 0.0) |
2298 screen_space_transform.Scale(1.0 / effect_node->surface_contents_scale.x(), | 2301 screen_space_transform.Scale(1.0 / effect_node->surface_contents_scale.x(), |
2299 1.0 / effect_node->surface_contents_scale.y()); | 2302 1.0 / effect_node->surface_contents_scale.y()); |
2300 return screen_space_transform; | 2303 return screen_space_transform; |
2301 } | 2304 } |
2302 | 2305 |
2303 bool PropertyTrees::ComputeTransformToTarget(int transform_id, | 2306 bool PropertyTrees::ComputeTransformToTarget(int transform_id, |
2304 int effect_id, | 2307 int effect_id, |
2305 gfx::Transform* transform) const { | 2308 gfx::Transform* transform) const { |
2306 transform->MakeIdentity(); | 2309 transform->MakeIdentity(); |
2307 | |
2308 if (transform_id == TransformTree::kInvalidNodeId) | 2310 if (transform_id == TransformTree::kInvalidNodeId) |
2309 return true; | 2311 return true; |
2310 | 2312 |
2311 int target_transform_id; | |
2312 const EffectNode* effect_node = effect_tree.Node(effect_id); | 2313 const EffectNode* effect_node = effect_tree.Node(effect_id); |
2313 if (effect_id == EffectTree::kInvalidNodeId) { | |
2314 // This can happen when PaintArtifactCompositor builds property trees as | |
2315 // it doesn't set effect ids on clip nodes. We want to compute transform | |
2316 // to the root in this case. | |
2317 target_transform_id = TransformTree::kRootNodeId; | |
2318 } else { | |
2319 DCHECK(effect_node->has_render_surface || | |
2320 effect_node->id == EffectTree::kRootNodeId); | |
2321 target_transform_id = effect_node->transform_id; | |
2322 } | |
2323 | 2314 |
2324 bool success = transform_tree.ComputeTransform( | 2315 bool success = true; |
2325 transform_id, target_transform_id, transform); | 2316 success = GetToTarget(transform_id, effect_id, transform); |
2326 if (verify_transform_tree_calculations) { | 2317 if (effect_node->surface_contents_scale.x() != 0.f && |
2327 gfx::Transform to_target; | 2318 effect_node->surface_contents_scale.y() != 0.f) |
2328 to_target.ConcatTransform( | 2319 transform->matrix().postScale( |
2329 GetDrawTransforms(transform_id, effect_id).to_target); | 2320 1.0f / effect_node->surface_contents_scale.x(), |
2330 if (effect_node->surface_contents_scale.x() != 0.f && | 2321 1.0f / effect_node->surface_contents_scale.y(), 1.0f); |
2331 effect_node->surface_contents_scale.y() != 0.f) | |
2332 to_target.matrix().postScale( | |
2333 1.0f / effect_node->surface_contents_scale.x(), | |
2334 1.0f / effect_node->surface_contents_scale.y(), 1.0f); | |
2335 DCHECK(to_target.ApproximatelyEqual(*transform)); | |
2336 } | |
2337 return success; | 2322 return success; |
2338 } | 2323 } |
2339 | 2324 |
2340 bool PropertyTrees::ComputeTransformFromTarget( | 2325 bool PropertyTrees::ComputeTransformFromTarget( |
2341 int transform_id, | 2326 int transform_id, |
2342 int effect_id, | 2327 int effect_id, |
2343 gfx::Transform* transform) const { | 2328 gfx::Transform* transform) const { |
2344 transform->MakeIdentity(); | 2329 transform->MakeIdentity(); |
2345 | |
2346 if (transform_id == TransformTree::kInvalidNodeId) | 2330 if (transform_id == TransformTree::kInvalidNodeId) |
2347 return true; | 2331 return true; |
2348 | 2332 |
2349 int target_transform_id; | |
2350 const EffectNode* effect_node = effect_tree.Node(effect_id); | 2333 const EffectNode* effect_node = effect_tree.Node(effect_id); |
2351 if (effect_id == EffectTree::kInvalidNodeId) { | |
2352 // This can happen when PaintArtifactCompositor builds property trees as | |
2353 // it doesn't set effect ids on clip nodes. We want to compute transform | |
2354 // to the root in this case. | |
2355 target_transform_id = TransformTree::kRootNodeId; | |
2356 } else { | |
2357 DCHECK(effect_node->has_render_surface || | |
2358 effect_node->id == EffectTree::kRootNodeId); | |
2359 target_transform_id = effect_node->transform_id; | |
2360 } | |
2361 | 2334 |
2362 bool success = transform_tree.ComputeTransform(target_transform_id, | 2335 bool success = GetFromTarget(transform_id, effect_id, transform); |
2363 transform_id, transform); | 2336 transform->Scale(effect_node->surface_contents_scale.x(), |
2364 if (verify_transform_tree_calculations) { | 2337 effect_node->surface_contents_scale.y()); |
2365 auto draw_transforms = GetDrawTransforms(transform_id, effect_id); | |
2366 gfx::Transform from_target; | |
2367 from_target.ConcatTransform(draw_transforms.from_target); | |
2368 from_target.Scale(effect_node->surface_contents_scale.x(), | |
2369 effect_node->surface_contents_scale.y()); | |
2370 DCHECK(from_target.ApproximatelyEqual(*transform) || | |
2371 !draw_transforms.invertible); | |
2372 } | |
2373 return success; | 2338 return success; |
2374 } | 2339 } |
2375 | 2340 |
2376 } // namespace cc | 2341 } // namespace cc |
OLD | NEW |