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..8d42ab09bce1e9e23234d2a23e12ebd0fac77439 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_parent()); |
+ 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->SetClipTreeIndex(data_for_children->clip_tree_parent); |
+} |
+ |
+template <typename LayerType> |
static inline bool IsAtBoundaryOf3dRenderingContext(LayerType* layer) { |
return Parent(layer) |
? Parent(layer)->sorting_context_id() != |