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

Side by Side Diff: cc/trees/draw_property_utils.cc

Issue 2781483006: cc : Compute render surface is_clipped outside property tree building (Closed)
Patch Set: . Created 3 years, 8 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/damage_tracker_unittest.cc ('k') | cc/trees/effect_node.h » ('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 "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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « cc/trees/damage_tracker_unittest.cc ('k') | cc/trees/effect_node.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698