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 |