Chromium Code Reviews| 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 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 217 int target_transform_id = target_node->transform_id; | 217 int target_transform_id = target_node->transform_id; |
| 218 | 218 |
| 219 bool cache_hit = false; | 219 bool cache_hit = false; |
| 220 ConditionalClip cached_clip = ConditionalClip{false, gfx::RectF()}; | 220 ConditionalClip cached_clip = ConditionalClip{false, gfx::RectF()}; |
| 221 ConditionalClip unclipped = ConditionalClip{false, gfx::RectF()}; | 221 ConditionalClip unclipped = ConditionalClip{false, gfx::RectF()}; |
| 222 | 222 |
| 223 // Collect all the clips that need to be accumulated. | 223 // Collect all the clips that need to be accumulated. |
| 224 std::stack<const ClipNode*, std::vector<const ClipNode*>> parent_chain; | 224 std::stack<const ClipNode*, std::vector<const ClipNode*>> parent_chain; |
| 225 | 225 |
| 226 // If target is not direct ancestor of clip, this will find least common | 226 // If target is not direct ancestor of clip, this will find least common |
| 227 // ancestor between the target and the clip. | 227 // ancestor between the target and the clip. Or, if the target has a |
| 228 // contributing layer that escapes clip, this will find the nearest ancestor | |
| 229 // that doesn't. | |
| 228 while (target_node->clip_id > clip_node->id || | 230 while (target_node->clip_id > clip_node->id || |
| 229 target_node->has_unclipped_descendants) { | 231 effect_tree.GetRenderSurface(target_node->id) |
| 232 ->has_contributing_layer_that_escapes_clip()) { | |
| 230 target_node = effect_tree.Node(target_node->target_id); | 233 target_node = effect_tree.Node(target_node->target_id); |
| 231 } | 234 } |
| 232 | 235 |
| 233 // Collect clip nodes up to the least common ancestor or till we get a cache | 236 // Collect clip nodes up to the least common ancestor or till we get a cache |
| 234 // hit. | 237 // hit. |
| 235 while (target_node->clip_id < clip_node->id) { | 238 while (target_node->clip_id < clip_node->id) { |
| 236 if (parent_chain.size() > 0) { | 239 if (parent_chain.size() > 0) { |
| 237 // Search the cache. | 240 // Search the cache. |
| 238 for (auto& data : clip_node->cached_clip_rects) { | 241 for (auto& data : clip_node->cached_clip_rects) { |
| 239 if (data.target_id == target_id) { | 242 if (data.target_id == target_id) { |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 311 cached_data->clip = clip; | 314 cached_data->clip = clip; |
| 312 return clip; | 315 return clip; |
| 313 } | 316 } |
| 314 | 317 |
| 315 static bool HasSingularTransform(int transform_tree_index, | 318 static bool HasSingularTransform(int transform_tree_index, |
| 316 const TransformTree& tree) { | 319 const TransformTree& tree) { |
| 317 const TransformNode* node = tree.Node(transform_tree_index); | 320 const TransformNode* node = tree.Node(transform_tree_index); |
| 318 return !node->is_invertible || !node->ancestors_are_invertible; | 321 return !node->is_invertible || !node->ancestors_are_invertible; |
| 319 } | 322 } |
| 320 | 323 |
| 324 static int LowestCommonAncestor(int clip_id_1, | |
| 325 int clip_id_2, | |
| 326 const ClipTree* clip_tree) { | |
| 327 const ClipNode* clip_node_1 = clip_tree->Node(clip_id_1); | |
| 328 const ClipNode* clip_node_2 = clip_tree->Node(clip_id_2); | |
| 329 while (clip_node_1->id != clip_node_2->id) { | |
| 330 if (clip_node_1->id < clip_node_2->id) | |
| 331 clip_node_2 = clip_tree->parent(clip_node_2); | |
| 332 else | |
| 333 clip_node_1 = clip_tree->parent(clip_node_1); | |
| 334 } | |
| 335 return clip_node_1->id; | |
| 336 } | |
| 337 | |
| 338 static void SetHasContributingLayerThatEscapesClip(int lca_clip_id, | |
| 339 int target_effect_id, | |
| 340 EffectTree* effect_tree) { | |
| 341 const EffectNode* effect_node = effect_tree->Node(target_effect_id); | |
| 342 // Find all ancestor targets starting from effect_node who are clipped by | |
| 343 // a descendant of lowest ancestor clip and set their | |
| 344 // has_contributing_layer_that_escapes_clip to true. | |
| 345 while (effect_node->clip_id > lca_clip_id) { | |
| 346 RenderSurfaceImpl* render_surface = | |
| 347 effect_tree->GetRenderSurface(effect_node->id); | |
| 348 DCHECK(render_surface); | |
| 349 render_surface->set_has_contributing_layer_that_escapes_clip(true); | |
| 350 effect_node = effect_tree->Node(effect_node->target_id); | |
| 351 } | |
| 352 } | |
| 353 | |
| 321 template <typename LayerType> | 354 template <typename LayerType> |
| 322 static int TransformTreeIndexForBackfaceVisibility(LayerType* layer, | 355 static int TransformTreeIndexForBackfaceVisibility(LayerType* layer, |
| 323 const TransformTree& tree) { | 356 const TransformTree& tree) { |
| 324 if (!layer->use_parent_backface_visibility()) | 357 if (!layer->use_parent_backface_visibility()) |
| 325 return layer->transform_tree_index(); | 358 return layer->transform_tree_index(); |
| 326 const TransformNode* node = tree.Node(layer->transform_tree_index()); | 359 const TransformNode* node = tree.Node(layer->transform_tree_index()); |
| 327 return layer->id() == node->owning_layer_id ? tree.parent(node)->id | 360 return layer->id() == node->owning_layer_id ? tree.parent(node)->id |
| 328 : node->id; | 361 : node->id; |
| 329 } | 362 } |
| 330 | 363 |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 505 static gfx::Rect LayerDrawableContentRect( | 538 static gfx::Rect LayerDrawableContentRect( |
| 506 const LayerImpl* layer, | 539 const LayerImpl* layer, |
| 507 const gfx::Rect& layer_bounds_in_target_space, | 540 const gfx::Rect& layer_bounds_in_target_space, |
| 508 const gfx::Rect& clip_rect) { | 541 const gfx::Rect& clip_rect) { |
| 509 if (layer->is_clipped()) | 542 if (layer->is_clipped()) |
| 510 return IntersectRects(layer_bounds_in_target_space, clip_rect); | 543 return IntersectRects(layer_bounds_in_target_space, clip_rect); |
| 511 | 544 |
| 512 return layer_bounds_in_target_space; | 545 return layer_bounds_in_target_space; |
| 513 } | 546 } |
| 514 | 547 |
| 548 static void SetSurfaceIsClipped(const ClipTree& clip_tree, | |
| 549 RenderSurfaceImpl* render_surface) { | |
| 550 bool is_clipped; | |
| 551 if (render_surface->EffectTreeIndex() == EffectTree::kContentsRootNodeId) { | |
| 552 // Root render surface is always clipped. | |
| 553 is_clipped = true; | |
| 554 } else if (render_surface->has_contributing_layer_that_escapes_clip()) { | |
| 555 // We cannot clip a surface that has a contribuitng layer which escapes the | |
| 556 // clip. | |
| 557 is_clipped = false; | |
| 558 } else if (render_surface->ClipTreeIndex() == | |
| 559 render_surface->render_target()->ClipTreeIndex()) { | |
| 560 // There is no clip between between the render surface and its target, so | |
| 561 // the surface need not be clipped. | |
| 562 is_clipped = false; | |
|
weiliangc
2017/03/30 19:02:17
I also think it's ok to clip here too. It will jus
jaydasika
2017/04/03 19:06:31
Acknowledged. Will do in a follow-up.
| |
| 563 } else { | |
| 564 // If the clips between the render surface and its target only expand the | |
| 565 // clips and do not apply any new clip, we need not clip the render surface. | |
| 566 const ClipNode* clip_node = clip_tree.Node(render_surface->ClipTreeIndex()); | |
| 567 is_clipped = clip_node->clip_type != ClipNode::ClipType::EXPANDS_CLIP; | |
|
weiliangc
2017/03/30 19:02:17
I think even with expansion this should still be i
jaydasika
2017/04/03 19:06:31
For this to happen, we need the other change (that
weiliangc
2017/04/04 20:56:38
Yeah sounds good to have a follow up.
| |
| 568 } | |
| 569 render_surface->SetIsClipped(is_clipped); | |
| 570 } | |
| 571 | |
| 515 static void SetSurfaceDrawOpacity(const EffectTree& tree, | 572 static void SetSurfaceDrawOpacity(const EffectTree& tree, |
| 516 RenderSurfaceImpl* render_surface) { | 573 RenderSurfaceImpl* render_surface) { |
| 517 // Draw opacity of a surface is the product of opacities between the surface | 574 // Draw opacity of a surface is the product of opacities between the surface |
| 518 // (included) and its target surface (excluded). | 575 // (included) and its target surface (excluded). |
| 519 const EffectNode* node = tree.Node(render_surface->EffectTreeIndex()); | 576 const EffectNode* node = tree.Node(render_surface->EffectTreeIndex()); |
| 520 float draw_opacity = tree.EffectiveOpacity(node); | 577 float draw_opacity = tree.EffectiveOpacity(node); |
| 521 for (node = tree.parent(node); node && !node->has_render_surface; | 578 for (node = tree.parent(node); node && !node->has_render_surface; |
| 522 node = tree.parent(node)) { | 579 node = tree.parent(node)) { |
| 523 draw_opacity *= tree.EffectiveOpacity(node); | 580 draw_opacity *= tree.EffectiveOpacity(node); |
| 524 } | 581 } |
| (...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 919 property_trees->transform_tree.Node(layer->transform_tree_index()); | 976 property_trees->transform_tree.Node(layer->transform_tree_index()); |
| 920 | 977 |
| 921 layer->draw_properties().screen_space_transform = | 978 layer->draw_properties().screen_space_transform = |
| 922 ScreenSpaceTransformInternal(layer, property_trees->transform_tree); | 979 ScreenSpaceTransformInternal(layer, property_trees->transform_tree); |
| 923 layer->draw_properties().target_space_transform = DrawTransform( | 980 layer->draw_properties().target_space_transform = DrawTransform( |
| 924 layer, property_trees->transform_tree, property_trees->effect_tree); | 981 layer, property_trees->transform_tree, property_trees->effect_tree); |
| 925 layer->draw_properties().screen_space_transform_is_animating = | 982 layer->draw_properties().screen_space_transform_is_animating = |
| 926 transform_node->to_screen_is_potentially_animated; | 983 transform_node->to_screen_is_potentially_animated; |
| 927 } | 984 } |
| 928 | 985 |
| 929 // Compute draw opacities | 986 // Compute effects and determine if render surfaces have contributing layers |
| 987 // that escape clip. | |
| 930 for (LayerImpl* layer : *layer_list) { | 988 for (LayerImpl* layer : *layer_list) { |
| 931 layer->draw_properties().opacity = | 989 layer->draw_properties().opacity = |
| 932 LayerDrawOpacity(layer, property_trees->effect_tree); | 990 LayerDrawOpacity(layer, property_trees->effect_tree); |
| 991 RenderSurfaceImpl* render_target = layer->render_target(); | |
| 992 int lca_clip_id = LowestCommonAncestor(layer->clip_tree_index(), | |
| 993 render_target->ClipTreeIndex(), | |
| 994 &property_trees->clip_tree); | |
| 995 if (lca_clip_id != render_target->ClipTreeIndex()) { | |
| 996 SetHasContributingLayerThatEscapesClip(lca_clip_id, | |
| 997 render_target->EffectTreeIndex(), | |
| 998 &property_trees->effect_tree); | |
| 999 } | |
| 933 } | 1000 } |
| 934 | 1001 |
| 935 // Compute clips and viisble rects | 1002 // Compute clips and visible rects |
| 936 for (LayerImpl* layer : *layer_list) { | 1003 for (LayerImpl* layer : *layer_list) { |
| 937 ConditionalClip clip = LayerClipRect(property_trees, layer); | 1004 ConditionalClip clip = LayerClipRect(property_trees, layer); |
| 938 // is_clipped should be set before visible rect computation as it is used | 1005 // is_clipped should be set before visible rect computation as it is used |
| 939 // there. | 1006 // there. |
| 940 layer->draw_properties().is_clipped = clip.is_clipped; | 1007 layer->draw_properties().is_clipped = clip.is_clipped; |
| 941 layer->draw_properties().clip_rect = gfx::ToEnclosingRect(clip.clip_rect); | 1008 layer->draw_properties().clip_rect = gfx::ToEnclosingRect(clip.clip_rect); |
| 942 layer->draw_properties().visible_layer_rect = | 1009 layer->draw_properties().visible_layer_rect = |
| 943 LayerVisibleRect(property_trees, layer); | 1010 LayerVisibleRect(property_trees, layer); |
| 944 } | 1011 } |
| 945 | 1012 |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 960 mask_layer->draw_properties().screen_space_transform = | 1027 mask_layer->draw_properties().screen_space_transform = |
| 961 ScreenSpaceTransformInternal(mask_layer, | 1028 ScreenSpaceTransformInternal(mask_layer, |
| 962 property_trees->transform_tree); | 1029 property_trees->transform_tree); |
| 963 mask_layer->draw_properties().visible_layer_rect = | 1030 mask_layer->draw_properties().visible_layer_rect = |
| 964 gfx::Rect(mask_layer->bounds()); | 1031 gfx::Rect(mask_layer->bounds()); |
| 965 } | 1032 } |
| 966 | 1033 |
| 967 void ComputeSurfaceDrawProperties(PropertyTrees* property_trees, | 1034 void ComputeSurfaceDrawProperties(PropertyTrees* property_trees, |
| 968 RenderSurfaceImpl* render_surface, | 1035 RenderSurfaceImpl* render_surface, |
| 969 const bool use_layer_lists) { | 1036 const bool use_layer_lists) { |
| 970 const EffectNode* effect_node = | 1037 SetSurfaceIsClipped(property_trees->clip_tree, render_surface); |
| 971 property_trees->effect_tree.Node(render_surface->EffectTreeIndex()); | |
| 972 if (use_layer_lists) { | |
| 973 // TODO(crbug.com/702010) : Calculate surface's is_clipped value outside | |
| 974 // cc property tree building. This is a temporary hack to make SPv2 layout | |
| 975 // tests pass. | |
| 976 bool is_clipped = effect_node->id == EffectTree::kContentsRootNodeId || | |
| 977 (render_surface->render_target()->ClipTreeIndex() != | |
| 978 render_surface->ClipTreeIndex()); | |
| 979 render_surface->SetIsClipped(is_clipped); | |
| 980 } else { | |
| 981 render_surface->SetIsClipped(effect_node->surface_is_clipped); | |
| 982 } | |
| 983 SetSurfaceDrawOpacity(property_trees->effect_tree, render_surface); | 1038 SetSurfaceDrawOpacity(property_trees->effect_tree, render_surface); |
| 984 SetSurfaceDrawTransform(property_trees, render_surface); | 1039 SetSurfaceDrawTransform(property_trees, render_surface); |
| 985 render_surface->SetScreenSpaceTransform( | 1040 render_surface->SetScreenSpaceTransform( |
| 986 property_trees->ToScreenSpaceTransformWithoutSurfaceContentsScale( | 1041 property_trees->ToScreenSpaceTransformWithoutSurfaceContentsScale( |
| 987 render_surface->TransformTreeIndex(), | 1042 render_surface->TransformTreeIndex(), |
| 988 render_surface->EffectTreeIndex())); | 1043 render_surface->EffectTreeIndex())); |
| 989 | 1044 |
| 990 const ClipNode* clip_node = | 1045 const ClipNode* clip_node = |
| 991 property_trees->clip_tree.Node(render_surface->ClipTreeIndex()); | 1046 property_trees->clip_tree.Node(render_surface->ClipTreeIndex()); |
| 992 SetSurfaceClipRect(clip_node, property_trees, render_surface); | 1047 SetSurfaceClipRect(clip_node, property_trees, render_surface); |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 1022 void UpdateElasticOverscroll(PropertyTrees* property_trees, | 1077 void UpdateElasticOverscroll(PropertyTrees* property_trees, |
| 1023 const Layer* overscroll_elasticity_layer, | 1078 const Layer* overscroll_elasticity_layer, |
| 1024 const gfx::Vector2dF& elastic_overscroll) { | 1079 const gfx::Vector2dF& elastic_overscroll) { |
| 1025 UpdateElasticOverscrollInternal(property_trees, overscroll_elasticity_layer, | 1080 UpdateElasticOverscrollInternal(property_trees, overscroll_elasticity_layer, |
| 1026 elastic_overscroll); | 1081 elastic_overscroll); |
| 1027 } | 1082 } |
| 1028 | 1083 |
| 1029 } // namespace draw_property_utils | 1084 } // namespace draw_property_utils |
| 1030 | 1085 |
| 1031 } // namespace cc | 1086 } // namespace cc |
| OLD | NEW |