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

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: Rebase! 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
« no previous file with comments | « cc/trees/property_tree.h ('k') | cc/trees/property_tree_builder.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <stddef.h> 5 #include <stddef.h>
6 6
7 #include <set> 7 #include <set>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 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;
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 401 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
OLDNEW
« no previous file with comments | « cc/trees/property_tree.h ('k') | cc/trees/property_tree_builder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698