Index: cc/trees/property_tree_builder.cc |
diff --git a/cc/trees/property_tree_builder.cc b/cc/trees/property_tree_builder.cc |
index d99262f84e268156ac925bafd5a8b9ef5092d462..c2f67ad3b087a68a42b8f8d361910a16f5452d71 100644 |
--- a/cc/trees/property_tree_builder.cc |
+++ b/cc/trees/property_tree_builder.cc |
@@ -456,6 +456,81 @@ void AddClipNodeIfNeeded(const DataForRecursion<LayerType>& data_from_ancestor, |
} |
template <typename LayerType> |
+void AddClipNodeOnlyIfLayerClipsSubtree( |
+ const DataForRecursion<LayerType>& data_from_ancestor, |
+ LayerType* layer, |
+ bool created_render_surface, |
+ bool created_transform_node, |
+ DataForRecursion<LayerType>* data_for_children) { |
+ const bool inherits_clip = !ClipParent(layer); |
+ const int parent_id = inherits_clip ? data_from_ancestor.clip_tree_parent |
+ : ClipParent(layer)->clip_tree_index(); |
+ ClipNode* parent = |
+ data_from_ancestor.property_trees->clip_tree.Node(parent_id); |
+ |
+ bool apply_ancestor_clip = false; |
+ if (inherits_clip) { |
+ apply_ancestor_clip = data_from_ancestor.apply_ancestor_clip; |
+ } else { |
+ const EffectNode* parent_effect_node = |
+ data_from_ancestor.property_trees->effect_tree.Node( |
+ ClipParent(layer)->effect_tree_index()); |
+ if (parent_effect_node->clip_id == parent->id) { |
+ if (parent_effect_node->surface_is_clipped) { |
+ // In this case, there is no clipping layer between the clip parent and |
+ // its target and the target has applied the clip. |
+ apply_ancestor_clip = false; |
+ } else { |
+ // In this case, there is no clipping layer between the clip parent and |
+ // its target and the target has not applied the clip. There are two |
+ // cases when a target doesn't apply clip. First, there is no ancestor |
+ // clip to apply, in this case apply_ancestor_clip should be false. |
+ // Second, there is a clip to apply but there are unclipped descendants, |
+ // so the target cannot apply the clip. In this case, |
+ // apply_ancestor_clip should be true. |
+ apply_ancestor_clip = parent_effect_node->has_unclipped_descendants; |
+ } |
+ } else { |
+ // In this case, there is a clipping layer between the clip parent and |
+ // its target. |
+ apply_ancestor_clip = true; |
+ } |
+ } |
+ if (created_render_surface) |
+ SetSurfaceIsClipped(data_for_children, apply_ancestor_clip, layer); |
+ |
+ bool layer_clips_subtree = LayerClipsSubtree(layer); |
+ if (layer_clips_subtree) { |
+ data_for_children->apply_ancestor_clip = true; |
+ } |
+ |
+ if (!layer_clips_subtree) { |
+ data_for_children->clip_tree_parent = parent_id; |
+ } else { |
+ LayerType* transform_parent = data_for_children->transform_tree_parent; |
+ if (PositionConstraint(layer).is_fixed_position() && |
+ !created_transform_node) { |
+ transform_parent = data_for_children->transform_fixed_parent; |
+ } |
+ ClipNode node; |
+ node.clip = gfx::RectF(gfx::PointF() + layer->offset_to_transform_parent(), |
+ gfx::SizeF(layer->bounds())); |
+ node.transform_id = transform_parent->transform_tree_index(); |
+ node.owner_id = layer->id(); |
+ if (layer_clips_subtree) |
+ node.clip_type = ClipNode::ClipType::APPLIES_LOCAL_CLIP; |
+ else |
+ node.clip_type = ClipNode::ClipType::NONE; |
+ data_for_children->clip_tree_parent = |
+ data_for_children->property_trees->clip_tree.Insert(node, parent_id); |
+ data_for_children->property_trees->clip_id_to_index_map[layer->id()] = |
+ data_for_children->clip_tree_parent; |
+ } |
+ |
+ layer->SetNewClipTreeIndex(data_for_children->clip_tree_parent); |
+} |
+ |
+template <typename LayerType> |
static inline bool IsAtBoundaryOf3dRenderingContext(LayerType* layer) { |
return Parent(layer) |
? Parent(layer)->sorting_context_id() != |
@@ -1239,7 +1314,8 @@ template <typename LayerType> |
void BuildPropertyTreesInternal( |
LayerType* layer, |
const DataForRecursion<LayerType>& data_from_parent, |
- DataForRecursionFromChild<LayerType>* data_to_parent) { |
+ DataForRecursionFromChild<LayerType>* data_to_parent, |
+ bool build_new_clip_tree) { |
layer->set_property_tree_sequence_number( |
data_from_parent.property_trees->sequence_number); |
@@ -1257,8 +1333,12 @@ void BuildPropertyTreesInternal( |
bool created_transform_node = AddTransformNodeIfNeeded( |
data_from_parent, layer, created_render_surface, &data_for_children); |
- AddClipNodeIfNeeded(data_from_parent, layer, created_render_surface, |
- created_transform_node, &data_for_children); |
+ if (build_new_clip_tree) |
+ AddClipNodeOnlyIfLayerClipsSubtree(data_from_parent, layer, created_render_surface, |
+ created_transform_node, &data_for_children); |
+ else |
+ AddClipNodeIfNeeded(data_from_parent, layer, created_render_surface, |
+ created_transform_node, &data_for_children); |
AddScrollNodeIfNeeded(data_from_parent, layer, &data_for_children); |
@@ -1271,7 +1351,7 @@ void BuildPropertyTreesInternal( |
if (!ScrollParent(current_child)) { |
DataForRecursionFromChild<LayerType> data_from_child; |
BuildPropertyTreesInternal(current_child, data_for_children, |
- &data_from_child); |
+ &data_from_child, build_new_clip_tree); |
data_to_parent->Merge(data_from_child); |
} else { |
// The child should be included in its scroll parent's list of scroll |
@@ -1290,7 +1370,7 @@ void BuildPropertyTreesInternal( |
data_for_children.render_target = |
Parent(scroll_child)->effect_tree_index(); |
BuildPropertyTreesInternal(scroll_child, data_for_children, |
- &data_from_child); |
+ &data_from_child, build_new_clip_tree); |
data_to_parent->Merge(data_from_child); |
} |
} |
@@ -1360,7 +1440,8 @@ void BuildPropertyTreesTopLevelInternal( |
const gfx::Rect& viewport, |
const gfx::Transform& device_transform, |
PropertyTrees* property_trees, |
- SkColor color) { |
+ SkColor color, |
+ bool build_new_clip_tree) { |
if (!property_trees->needs_rebuild) { |
draw_property_utils::UpdatePageScaleFactor( |
property_trees, page_scale_layer, page_scale_factor, |
@@ -1423,7 +1504,8 @@ void BuildPropertyTreesTopLevelInternal( |
root_clip, kRootPropertyTreeNodeId); |
DataForRecursionFromChild<LayerType> data_from_child; |
- BuildPropertyTreesInternal(root_layer, data_for_recursion, &data_from_child); |
+ BuildPropertyTreesInternal(root_layer, data_for_recursion, &data_from_child, |
+ build_new_clip_tree); |
property_trees->needs_rebuild = false; |
// The transform tree is kept up to date as it is built, but the |
@@ -1467,7 +1549,8 @@ void PropertyTreeBuilder::BuildPropertyTrees( |
float device_scale_factor, |
const gfx::Rect& viewport, |
const gfx::Transform& device_transform, |
- PropertyTrees* property_trees) { |
+ PropertyTrees* property_trees, |
+ bool build_new_clip_tree) { |
property_trees->is_main_thread = true; |
property_trees->is_active = false; |
SkColor color = root_layer->GetLayerTree()->background_color(); |
@@ -1477,7 +1560,7 @@ void PropertyTreeBuilder::BuildPropertyTrees( |
root_layer, page_scale_layer, inner_viewport_scroll_layer, |
outer_viewport_scroll_layer, overscroll_elasticity_layer, |
elastic_overscroll, page_scale_factor, device_scale_factor, viewport, |
- device_transform, property_trees, color); |
+ device_transform, property_trees, color, build_new_clip_tree); |
#if DCHECK_IS_ON() |
for (auto* layer : *root_layer->GetLayerTree()) |
CheckScrollAndClipPointersForLayer(layer); |
@@ -1496,7 +1579,8 @@ void PropertyTreeBuilder::BuildPropertyTrees( |
float device_scale_factor, |
const gfx::Rect& viewport, |
const gfx::Transform& device_transform, |
- PropertyTrees* property_trees) { |
+ PropertyTrees* property_trees, |
+ bool build_new_clip_tree) { |
property_trees->is_main_thread = false; |
property_trees->is_active = root_layer->IsActive(); |
SkColor color = root_layer->layer_tree_impl()->background_color(); |
@@ -1506,7 +1590,7 @@ void PropertyTreeBuilder::BuildPropertyTrees( |
root_layer, page_scale_layer, inner_viewport_scroll_layer, |
outer_viewport_scroll_layer, overscroll_elasticity_layer, |
elastic_overscroll, page_scale_factor, device_scale_factor, viewport, |
- device_transform, property_trees, color); |
+ device_transform, property_trees, color, build_new_clip_tree); |
property_trees->ResetCachedData(); |
} |