| 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 "cc/trees/draw_property_utils.h" | 5 #include "cc/trees/draw_property_utils.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 160 combined_clip_rect_in_target_space = clip_rect_in_target_space; | 160 combined_clip_rect_in_target_space = clip_rect_in_target_space; |
| 161 } | 161 } |
| 162 | 162 |
| 163 if (!clip_rect_in_target_space.IsEmpty()) { | 163 if (!clip_rect_in_target_space.IsEmpty()) { |
| 164 layer->set_clip_rect(clip_rect_in_target_space); | 164 layer->set_clip_rect(clip_rect_in_target_space); |
| 165 } else { | 165 } else { |
| 166 layer->set_clip_rect(gfx::Rect()); | 166 layer->set_clip_rect(gfx::Rect()); |
| 167 } | 167 } |
| 168 | 168 |
| 169 // The clip rect should be intersected with layer rect in target space. | 169 // The clip rect should be intersected with layer rect in target space. |
| 170 gfx::Transform content_to_target = non_root_surfaces_enabled | 170 gfx::Transform content_to_target = |
| 171 ? transform_node->data.to_target | 171 non_root_surfaces_enabled |
| 172 : transform_node->data.to_screen; | 172 ? transform_tree.ToTarget(layer->transform_tree_index()) |
| 173 : transform_tree.ToScreen(layer->transform_tree_index()); |
| 173 | 174 |
| 174 content_to_target.Translate(layer->offset_to_transform_parent().x(), | 175 content_to_target.Translate(layer->offset_to_transform_parent().x(), |
| 175 layer->offset_to_transform_parent().y()); | 176 layer->offset_to_transform_parent().y()); |
| 176 gfx::Rect layer_content_rect = gfx::Rect(layer_bounds); | 177 gfx::Rect layer_content_rect = gfx::Rect(layer_bounds); |
| 177 gfx::Rect layer_content_bounds_in_target_space = | 178 gfx::Rect layer_content_bounds_in_target_space = |
| 178 MathUtil::MapEnclosingClippedRect(content_to_target, | 179 MathUtil::MapEnclosingClippedRect(content_to_target, |
| 179 layer_content_rect); | 180 layer_content_rect); |
| 180 combined_clip_rect_in_target_space.Intersect( | 181 combined_clip_rect_in_target_space.Intersect( |
| 181 layer_content_bounds_in_target_space); | 182 layer_content_bounds_in_target_space); |
| 182 if (combined_clip_rect_in_target_space.IsEmpty()) { | 183 if (combined_clip_rect_in_target_space.IsEmpty()) { |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 245 return layer->id() == node->owner_id ? tree.parent(node)->id : node->id; | 246 return layer->id() == node->owner_id ? tree.parent(node)->id : node->id; |
| 246 } | 247 } |
| 247 | 248 |
| 248 template <typename LayerType> | 249 template <typename LayerType> |
| 249 static bool IsLayerBackFaceVisible(LayerType* layer, | 250 static bool IsLayerBackFaceVisible(LayerType* layer, |
| 250 int transform_tree_index, | 251 int transform_tree_index, |
| 251 const TransformTree& tree) { | 252 const TransformTree& tree) { |
| 252 const TransformNode* node = tree.Node(transform_tree_index); | 253 const TransformNode* node = tree.Node(transform_tree_index); |
| 253 return layer->use_local_transform_for_backface_visibility() | 254 return layer->use_local_transform_for_backface_visibility() |
| 254 ? node->data.local.IsBackFaceVisible() | 255 ? node->data.local.IsBackFaceVisible() |
| 255 : node->data.to_target.IsBackFaceVisible(); | 256 : tree.ToTarget(transform_tree_index).IsBackFaceVisible(); |
| 256 } | 257 } |
| 257 | 258 |
| 258 static inline bool TransformToScreenIsKnown(Layer* layer, | 259 static inline bool TransformToScreenIsKnown(Layer* layer, |
| 259 int transform_tree_index, | 260 int transform_tree_index, |
| 260 const TransformTree& tree) { | 261 const TransformTree& tree) { |
| 261 const TransformNode* node = tree.Node(transform_tree_index); | 262 const TransformNode* node = tree.Node(transform_tree_index); |
| 262 return !node->data.to_screen_is_potentially_animated; | 263 return !node->data.to_screen_is_potentially_animated; |
| 263 } | 264 } |
| 264 | 265 |
| 265 static inline bool TransformToScreenIsKnown(LayerImpl* layer, | 266 static inline bool TransformToScreenIsKnown(LayerImpl* layer, |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 478 parent_to_current, parent_clip_node->data.clip_in_target_space); | 479 parent_to_current, parent_clip_node->data.clip_in_target_space); |
| 479 } | 480 } |
| 480 // Only nodes affected by ancestor clips will have their clip adjusted due | 481 // Only nodes affected by ancestor clips will have their clip adjusted due |
| 481 // to intersecting with an ancestor clip. But, we still need to propagate | 482 // to intersecting with an ancestor clip. But, we still need to propagate |
| 482 // the combined clip to our children because if they are clipped, they may | 483 // the combined clip to our children because if they are clipped, they may |
| 483 // need to clip using our parent clip and if we don't propagate it here, | 484 // need to clip using our parent clip and if we don't propagate it here, |
| 484 // it will be lost. | 485 // it will be lost. |
| 485 if (clip_node->data.resets_clip && non_root_surfaces_enabled) { | 486 if (clip_node->data.resets_clip && non_root_surfaces_enabled) { |
| 486 if (clip_node->data.applies_local_clip) { | 487 if (clip_node->data.applies_local_clip) { |
| 487 clip_node->data.clip_in_target_space = MathUtil::MapClippedRect( | 488 clip_node->data.clip_in_target_space = MathUtil::MapClippedRect( |
| 488 transform_node->data.to_target, clip_node->data.clip); | 489 transform_tree.ToTarget(clip_node->data.transform_id), |
| 490 clip_node->data.clip); |
| 489 ResetIfHasNanCoordinate(&clip_node->data.clip_in_target_space); | 491 ResetIfHasNanCoordinate(&clip_node->data.clip_in_target_space); |
| 490 clip_node->data.combined_clip_in_target_space = | 492 clip_node->data.combined_clip_in_target_space = |
| 491 gfx::IntersectRects(clip_node->data.clip_in_target_space, | 493 gfx::IntersectRects(clip_node->data.clip_in_target_space, |
| 492 parent_combined_clip_in_target_space); | 494 parent_combined_clip_in_target_space); |
| 493 } else { | 495 } else { |
| 494 DCHECK(!clip_node->data.target_is_clipped); | 496 DCHECK(!clip_node->data.target_is_clipped); |
| 495 DCHECK(!clip_node->data.layers_are_clipped); | 497 DCHECK(!clip_node->data.layers_are_clipped); |
| 496 clip_node->data.combined_clip_in_target_space = | 498 clip_node->data.combined_clip_in_target_space = |
| 497 parent_combined_clip_in_target_space; | 499 parent_combined_clip_in_target_space; |
| 498 } | 500 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 511 } else { | 513 } else { |
| 512 // Render Surface applies clip and the owning layer itself applies | 514 // Render Surface applies clip and the owning layer itself applies |
| 513 // no clip. So, clip_in_target_space is not used and hence we can set | 515 // no clip. So, clip_in_target_space is not used and hence we can set |
| 514 // it to an empty rect. | 516 // it to an empty rect. |
| 515 clip_node->data.clip_in_target_space = gfx::RectF(); | 517 clip_node->data.clip_in_target_space = gfx::RectF(); |
| 516 } | 518 } |
| 517 } else { | 519 } else { |
| 518 gfx::Transform source_to_target; | 520 gfx::Transform source_to_target; |
| 519 | 521 |
| 520 if (!non_root_surfaces_enabled) { | 522 if (!non_root_surfaces_enabled) { |
| 521 source_to_target = transform_node->data.to_screen; | 523 source_to_target = |
| 524 transform_tree.ToScreen(clip_node->data.transform_id); |
| 522 } else if (transform_node->data.content_target_id == | 525 } else if (transform_node->data.content_target_id == |
| 523 clip_node->data.target_id) { | 526 clip_node->data.target_id) { |
| 524 source_to_target = transform_node->data.to_target; | 527 source_to_target = |
| 528 transform_tree.ToTarget(clip_node->data.transform_id); |
| 525 } else { | 529 } else { |
| 526 success = transform_tree.ComputeTransformWithDestinationSublayerScale( | 530 success = transform_tree.ComputeTransformWithDestinationSublayerScale( |
| 527 transform_node->id, clip_node->data.target_id, &source_to_target); | 531 transform_node->id, clip_node->data.target_id, &source_to_target); |
| 528 // source_to_target computation should be successful as target is an | 532 // source_to_target computation should be successful as target is an |
| 529 // ancestor of the transform node. | 533 // ancestor of the transform node. |
| 530 DCHECK(success); | 534 DCHECK(success); |
| 531 } | 535 } |
| 532 | 536 |
| 533 gfx::RectF source_clip_in_target_space = | 537 gfx::RectF source_clip_in_target_space = |
| 534 MathUtil::MapClippedRect(source_to_target, clip_node->data.clip); | 538 MathUtil::MapClippedRect(source_to_target, clip_node->data.clip); |
| (...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 869 | 873 |
| 870 gfx::Transform DrawTransform(const LayerImpl* layer, | 874 gfx::Transform DrawTransform(const LayerImpl* layer, |
| 871 const TransformTree& tree) { | 875 const TransformTree& tree) { |
| 872 const TransformNode* node = tree.Node(layer->transform_tree_index()); | 876 const TransformNode* node = tree.Node(layer->transform_tree_index()); |
| 873 gfx::Transform xform; | 877 gfx::Transform xform; |
| 874 const bool owns_non_root_surface = | 878 const bool owns_non_root_surface = |
| 875 !IsRootLayer(layer) && layer->has_render_surface(); | 879 !IsRootLayer(layer) && layer->has_render_surface(); |
| 876 if (!owns_non_root_surface) { | 880 if (!owns_non_root_surface) { |
| 877 // If you're not the root, or you don't own a surface, you need to apply | 881 // If you're not the root, or you don't own a surface, you need to apply |
| 878 // your local offset. | 882 // your local offset. |
| 879 xform = node->data.to_target; | 883 xform = tree.ToTarget(layer->transform_tree_index()); |
| 880 if (layer->should_flatten_transform_from_property_tree()) | 884 if (layer->should_flatten_transform_from_property_tree()) |
| 881 xform.FlattenTo2d(); | 885 xform.FlattenTo2d(); |
| 882 xform.Translate(layer->offset_to_transform_parent().x(), | 886 xform.Translate(layer->offset_to_transform_parent().x(), |
| 883 layer->offset_to_transform_parent().y()); | 887 layer->offset_to_transform_parent().y()); |
| 884 } else { | 888 } else { |
| 885 // Surfaces need to apply their sublayer scale. | 889 // Surfaces need to apply their sublayer scale. |
| 886 xform.Scale(node->data.sublayer_scale.x(), node->data.sublayer_scale.y()); | 890 xform.Scale(node->data.sublayer_scale.x(), node->data.sublayer_scale.y()); |
| 887 } | 891 } |
| 888 return xform; | 892 return xform; |
| 889 } | 893 } |
| 890 | 894 |
| 891 static void SetSurfaceDrawTransform(const TransformTree& tree, | 895 static void SetSurfaceDrawTransform(const TransformTree& tree, |
| 892 RenderSurfaceImpl* render_surface) { | 896 RenderSurfaceImpl* render_surface) { |
| 893 const TransformNode* node = tree.Node(render_surface->TransformTreeIndex()); | 897 const TransformNode* node = tree.Node(render_surface->TransformTreeIndex()); |
| 894 // The draw transform of root render surface is identity tranform. | 898 // The draw transform of root render surface is identity tranform. |
| 895 if (node->id == 1) { | 899 if (node->id == 1) { |
| 896 render_surface->SetDrawTransform(gfx::Transform()); | 900 render_surface->SetDrawTransform(gfx::Transform()); |
| 897 return; | 901 return; |
| 898 } | 902 } |
| 899 | 903 |
| 900 gfx::Transform render_surface_transform; | 904 gfx::Transform render_surface_transform; |
| 901 const TransformNode* target_node = tree.Node(node->data.target_id); | 905 const TransformNode* target_node = tree.Node(tree.TargetId(node->id)); |
| 902 tree.ComputeTransformWithDestinationSublayerScale(node->id, target_node->id, | 906 tree.ComputeTransformWithDestinationSublayerScale(node->id, target_node->id, |
| 903 &render_surface_transform); | 907 &render_surface_transform); |
| 904 if (node->data.sublayer_scale.x() != 0.0 && | 908 if (node->data.sublayer_scale.x() != 0.0 && |
| 905 node->data.sublayer_scale.y() != 0.0) | 909 node->data.sublayer_scale.y() != 0.0) |
| 906 render_surface_transform.Scale(1.0 / node->data.sublayer_scale.x(), | 910 render_surface_transform.Scale(1.0 / node->data.sublayer_scale.x(), |
| 907 1.0 / node->data.sublayer_scale.y()); | 911 1.0 / node->data.sublayer_scale.y()); |
| 908 render_surface->SetDrawTransform(render_surface_transform); | 912 render_surface->SetDrawTransform(render_surface_transform); |
| 909 } | 913 } |
| 910 | 914 |
| 911 static void SetSurfaceIsClipped(const ClipNode* clip_node, | 915 static void SetSurfaceIsClipped(const ClipNode* clip_node, |
| 912 RenderSurfaceImpl* render_surface) { | 916 RenderSurfaceImpl* render_surface) { |
| 913 DCHECK(render_surface->OwningLayerId() == clip_node->owner_id) | 917 DCHECK(render_surface->OwningLayerId() == clip_node->owner_id) |
| 914 << "we now create clip node for every render surface"; | 918 << "we now create clip node for every render surface"; |
| 915 | 919 |
| 916 render_surface->SetIsClipped(clip_node->data.target_is_clipped); | 920 render_surface->SetIsClipped(clip_node->data.target_is_clipped); |
| 917 } | 921 } |
| 918 | 922 |
| 919 static void SetSurfaceClipRect(const ClipNode* parent_clip_node, | 923 static void SetSurfaceClipRect(const ClipNode* parent_clip_node, |
| 920 const TransformTree& transform_tree, | 924 const TransformTree& transform_tree, |
| 921 RenderSurfaceImpl* render_surface) { | 925 RenderSurfaceImpl* render_surface) { |
| 922 if (!render_surface->is_clipped()) { | 926 if (!render_surface->is_clipped()) { |
| 923 render_surface->SetClipRect(gfx::Rect()); | 927 render_surface->SetClipRect(gfx::Rect()); |
| 924 return; | 928 return; |
| 925 } | 929 } |
| 926 | 930 |
| 927 const TransformNode* transform_node = | 931 const TransformNode* transform_node = |
| 928 transform_tree.Node(render_surface->TransformTreeIndex()); | 932 transform_tree.Node(render_surface->TransformTreeIndex()); |
| 929 if (transform_node->data.target_id == parent_clip_node->data.target_id) { | 933 if (transform_tree.TargetId(transform_node->id) == |
| 934 parent_clip_node->data.target_id) { |
| 930 render_surface->SetClipRect( | 935 render_surface->SetClipRect( |
| 931 gfx::ToEnclosingRect(parent_clip_node->data.clip_in_target_space)); | 936 gfx::ToEnclosingRect(parent_clip_node->data.clip_in_target_space)); |
| 932 return; | 937 return; |
| 933 } | 938 } |
| 934 | 939 |
| 935 // In this case, the clip child has reset the clip node for subtree and hence | 940 // In this case, the clip child has reset the clip node for subtree and hence |
| 936 // the parent clip node's clip rect is in clip parent's target space and not | 941 // the parent clip node's clip rect is in clip parent's target space and not |
| 937 // our target space. We need to transform it to our target space. | 942 // our target space. We need to transform it to our target space. |
| 938 gfx::Transform clip_parent_target_to_target; | 943 gfx::Transform clip_parent_target_to_target; |
| 939 const bool success = | 944 const bool success = |
| 940 transform_tree.ComputeTransformWithDestinationSublayerScale( | 945 transform_tree.ComputeTransformWithDestinationSublayerScale( |
| 941 parent_clip_node->data.target_id, transform_node->data.target_id, | 946 parent_clip_node->data.target_id, |
| 947 transform_tree.TargetId(transform_node->id), |
| 942 &clip_parent_target_to_target); | 948 &clip_parent_target_to_target); |
| 943 | 949 |
| 944 if (!success) { | 950 if (!success) { |
| 945 render_surface->SetClipRect(gfx::Rect()); | 951 render_surface->SetClipRect(gfx::Rect()); |
| 946 return; | 952 return; |
| 947 } | 953 } |
| 948 | 954 |
| 949 DCHECK_LT(parent_clip_node->data.target_id, transform_node->data.target_id); | 955 DCHECK_LT(parent_clip_node->data.target_id, |
| 956 transform_tree.TargetId(transform_node->id)); |
| 950 render_surface->SetClipRect(gfx::ToEnclosingRect(MathUtil::ProjectClippedRect( | 957 render_surface->SetClipRect(gfx::ToEnclosingRect(MathUtil::ProjectClippedRect( |
| 951 clip_parent_target_to_target, | 958 clip_parent_target_to_target, |
| 952 parent_clip_node->data.clip_in_target_space))); | 959 parent_clip_node->data.clip_in_target_space))); |
| 953 } | 960 } |
| 954 | 961 |
| 955 template <typename LayerType> | 962 template <typename LayerType> |
| 956 static gfx::Transform ScreenSpaceTransformInternal(LayerType* layer, | 963 static gfx::Transform ScreenSpaceTransformInternal(LayerType* layer, |
| 957 const TransformNode* node) { | 964 const TransformTree& tree) { |
| 958 gfx::Transform xform(1, 0, 0, 1, layer->offset_to_transform_parent().x(), | 965 gfx::Transform xform(1, 0, 0, 1, layer->offset_to_transform_parent().x(), |
| 959 layer->offset_to_transform_parent().y()); | 966 layer->offset_to_transform_parent().y()); |
| 960 gfx::Transform ssxform = node->data.to_screen; | 967 gfx::Transform ssxform = tree.ToScreen(layer->transform_tree_index()); |
| 961 xform.ConcatTransform(ssxform); | 968 xform.ConcatTransform(ssxform); |
| 962 if (layer->should_flatten_transform_from_property_tree()) | 969 if (layer->should_flatten_transform_from_property_tree()) |
| 963 xform.FlattenTo2d(); | 970 xform.FlattenTo2d(); |
| 964 return xform; | 971 return xform; |
| 965 } | 972 } |
| 966 | 973 |
| 967 gfx::Transform ScreenSpaceTransform(const Layer* layer, | 974 gfx::Transform ScreenSpaceTransform(const Layer* layer, |
| 968 const TransformTree& tree) { | 975 const TransformTree& tree) { |
| 969 return ScreenSpaceTransformInternal(layer, | 976 return ScreenSpaceTransformInternal(layer, tree); |
| 970 tree.Node(layer->transform_tree_index())); | |
| 971 } | 977 } |
| 972 | 978 |
| 973 gfx::Transform ScreenSpaceTransform(const LayerImpl* layer, | 979 gfx::Transform ScreenSpaceTransform(const LayerImpl* layer, |
| 974 const TransformTree& tree) { | 980 const TransformTree& tree) { |
| 975 return ScreenSpaceTransformInternal(layer, | 981 return ScreenSpaceTransformInternal(layer, tree); |
| 976 tree.Node(layer->transform_tree_index())); | |
| 977 } | 982 } |
| 978 | 983 |
| 979 static float LayerDrawOpacity(const LayerImpl* layer, const EffectTree& tree) { | 984 static float LayerDrawOpacity(const LayerImpl* layer, const EffectTree& tree) { |
| 980 if (!layer->render_target()) | 985 if (!layer->render_target()) |
| 981 return 0.f; | 986 return 0.f; |
| 982 | 987 |
| 983 const EffectNode* target_node = | 988 const EffectNode* target_node = |
| 984 tree.Node(layer->render_target()->EffectTreeIndex()); | 989 tree.Node(layer->render_target()->EffectTreeIndex()); |
| 985 const EffectNode* node = tree.Node(layer->effect_tree_index()); | 990 const EffectNode* node = tree.Node(layer->effect_tree_index()); |
| 986 if (node == target_node) | 991 if (node == target_node) |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1074 bool layers_always_allowed_lcd_text, | 1079 bool layers_always_allowed_lcd_text, |
| 1075 bool can_use_lcd_text) { | 1080 bool can_use_lcd_text) { |
| 1076 const TransformNode* transform_node = | 1081 const TransformNode* transform_node = |
| 1077 property_trees->transform_tree.Node(layer->transform_tree_index()); | 1082 property_trees->transform_tree.Node(layer->transform_tree_index()); |
| 1078 const EffectNode* effect_node = | 1083 const EffectNode* effect_node = |
| 1079 property_trees->effect_tree.Node(layer->effect_tree_index()); | 1084 property_trees->effect_tree.Node(layer->effect_tree_index()); |
| 1080 const ClipNode* clip_node = | 1085 const ClipNode* clip_node = |
| 1081 property_trees->clip_tree.Node(layer->clip_tree_index()); | 1086 property_trees->clip_tree.Node(layer->clip_tree_index()); |
| 1082 | 1087 |
| 1083 layer->draw_properties().screen_space_transform = | 1088 layer->draw_properties().screen_space_transform = |
| 1084 ScreenSpaceTransformInternal(layer, transform_node); | 1089 ScreenSpaceTransformInternal(layer, property_trees->transform_tree); |
| 1085 if (property_trees->non_root_surfaces_enabled) { | 1090 if (property_trees->non_root_surfaces_enabled) { |
| 1086 layer->draw_properties().target_space_transform = | 1091 layer->draw_properties().target_space_transform = |
| 1087 DrawTransform(layer, property_trees->transform_tree); | 1092 DrawTransform(layer, property_trees->transform_tree); |
| 1088 } else { | 1093 } else { |
| 1089 layer->draw_properties().target_space_transform = | 1094 layer->draw_properties().target_space_transform = |
| 1090 layer->draw_properties().screen_space_transform; | 1095 layer->draw_properties().screen_space_transform; |
| 1091 } | 1096 } |
| 1092 layer->draw_properties().screen_space_transform_is_animating = | 1097 layer->draw_properties().screen_space_transform_is_animating = |
| 1093 transform_node->data.to_screen_is_potentially_animated; | 1098 transform_node->data.to_screen_is_potentially_animated; |
| 1094 if (layer->layer_tree_impl() | 1099 if (layer->layer_tree_impl() |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1246 void UpdateElasticOverscroll(PropertyTrees* property_trees, | 1251 void UpdateElasticOverscroll(PropertyTrees* property_trees, |
| 1247 const Layer* overscroll_elasticity_layer, | 1252 const Layer* overscroll_elasticity_layer, |
| 1248 const gfx::Vector2dF& elastic_overscroll) { | 1253 const gfx::Vector2dF& elastic_overscroll) { |
| 1249 UpdateElasticOverscrollInternal(property_trees, overscroll_elasticity_layer, | 1254 UpdateElasticOverscrollInternal(property_trees, overscroll_elasticity_layer, |
| 1250 elastic_overscroll); | 1255 elastic_overscroll); |
| 1251 } | 1256 } |
| 1252 | 1257 |
| 1253 } // namespace draw_property_utils | 1258 } // namespace draw_property_utils |
| 1254 | 1259 |
| 1255 } // namespace cc | 1260 } // namespace cc |
| OLD | NEW |