Index: third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp |
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp b/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp |
index da24d7aaabd5bd373b245de256182977fb82bc7a..cbd9264a48d3326a3b15a24597f45b8479e01b09 100644 |
--- a/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp |
+++ b/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp |
@@ -53,6 +53,25 @@ |
namespace blink { |
+static bool HasOverflowClip( |
+ const PaintLayer& layer) { |
+ if (!layer.GetLayoutObject().IsBox()) |
+ return false; |
+ const LayoutBox& box = ToLayoutBox(layer.GetLayoutObject()); |
+ return box.ShouldClipOverflow(); |
+} |
+ |
+bool ClipRectsContext::ShouldRespectRootLayerClip() const { |
+ if (respect_overflow_clip == kIgnoreOverflowClip) |
+ return false; |
+ |
+ if (root_layer->IsRootLayer() && |
+ respect_overflow_clip_for_viewport == kIgnoreOverflowClip) |
+ return false; |
+ |
+ return true; |
+} |
+ |
static void AdjustClipRectsForChildren( |
const LayoutBoxModelObject& layout_object, |
ClipRects& clip_rects) { |
@@ -386,6 +405,13 @@ void PaintLayerClipper::CalculateClipRects(const ClipRectsContext& context, |
bool is_clipping_root = &layer_ == context.root_layer; |
+ if (is_clipping_root && !context.ShouldRespectRootLayerClip()) { |
+ clip_rects.Reset(LayoutRect(LayoutRect::InfiniteIntRect())); |
+ if (layout_object.StyleRef().GetPosition() == EPosition::kFixed) |
+ clip_rects.SetFixed(true); |
+ return; |
+ } |
+ |
// For transformed layers, the root layer was shifted to be us, so there is no |
// need to examine the parent. We want to cache clip rects with us as the |
// root. |
@@ -401,7 +427,9 @@ void PaintLayerClipper::CalculateClipRects(const ClipRectsContext& context, |
AdjustClipRectsForChildren(layout_object, clip_rects); |
- if (ShouldClipOverflow(context) || layout_object.HasClip()) { |
+ // Computing paint offset is expensive, skip the computation if the object |
+ // is known to have no clip. This check is redundant otherwise. |
+ if (HasOverflowClip(layer_) || layout_object.HasClip()) { |
// This offset cannot use convertToLayerCoords, because sometimes our |
// rootLayer may be across some transformed layer boundary, for example, in |
// the PaintLayerCompositor overlapMap, where clipRects are needed in view |
@@ -428,23 +456,18 @@ void PaintLayerClipper::CalculateBackgroundClipRectWithGeometryMapper( |
const ClipRectsContext& context, |
ClipRect& output) const { |
DCHECK(use_geometry_mapper_); |
+ |
+ bool is_clipping_root = &layer_ == context.root_layer; |
+ if (is_clipping_root && !context.ShouldRespectRootLayerClip()) { |
+ output.SetRect(FloatClipRect()); |
+ return; |
+ } |
+ |
PropertyTreeState source_property_tree_state(nullptr, nullptr, nullptr); |
PropertyTreeState destination_property_tree_state(nullptr, nullptr, nullptr); |
InitializeCommonClipRectState(context, source_property_tree_state, |
destination_property_tree_state); |
- if (&layer_ != context.root_layer) { |
- auto* ancestor_properties = |
- context.root_layer->GetLayoutObject().PaintProperties(); |
- const auto* ancestor_overflow_clip = |
- ancestor_properties ? ancestor_properties->OverflowClip() : nullptr; |
- // Set the clip of |destinationPropertyTreeState| to be inside the |
- // ancestor's overflow clip, so that that clip is not applied. |
- if (context.respect_overflow_clip == kIgnoreOverflowClip && |
- ancestor_overflow_clip) |
- destination_property_tree_state.SetClip(ancestor_overflow_clip); |
- } |
- |
// The background rect applies all clips *above* m_layer, but not the overflow |
// clip of m_layer. It also applies a clip to the total painting bounds |
// of m_layer, because nothing in m_layer or its children within the clip can |
@@ -457,7 +480,7 @@ void PaintLayerClipper::CalculateBackgroundClipRectWithGeometryMapper( |
// of transforms. Tight results are required for most use cases of these |
// rects, so we should add methods to GeometryMapper that guarantee there |
// are tight results, or else signal an error. |
- if (ShouldClipOverflow(context)) { |
+ if (HasOverflowClip(layer_)) { |
FloatClipRect clip_rect((FloatRect(LocalVisualRect()))); |
clip_rect.MoveBy(FloatPoint(layer_.GetLayoutObject().PaintOffset())); |
GeometryMapper::SourceToDestinationVisualRect( |
@@ -478,23 +501,34 @@ void PaintLayerClipper::InitializeCommonClipRectState( |
PropertyTreeState& source_property_tree_state, |
PropertyTreeState& destination_property_tree_state) const { |
DCHECK(use_geometry_mapper_); |
- DCHECK(layer_.GetLayoutObject().LocalBorderBoxProperties()); |
+ DCHECK(layer_.GetLayoutObject().LocalBorderBoxProperties()); |
source_property_tree_state = |
*layer_.GetLayoutObject().LocalBorderBoxProperties(); |
+ |
DCHECK(context.root_layer->GetLayoutObject().LocalBorderBoxProperties()); |
destination_property_tree_state = |
*context.root_layer->GetLayoutObject().LocalBorderBoxProperties(); |
auto* ancestor_properties = |
context.root_layer->GetLayoutObject().PaintProperties(); |
- const auto* ancestor_css_clip = |
- ancestor_properties ? ancestor_properties->CssClip() : nullptr; |
- // CSS clip of the root is always applied. |
- if (ancestor_css_clip) { |
- DCHECK(destination_property_tree_state.Clip() == |
- ancestor_properties->CssClip()); |
- destination_property_tree_state.SetClip(ancestor_css_clip->Parent()); |
+ if (!ancestor_properties) |
+ return; |
+ |
+ if (context.ShouldRespectRootLayerClip()) { |
+ const auto* ancestor_css_clip = ancestor_properties->CssClip(); |
+ if (ancestor_css_clip) { |
+ DCHECK_EQ(destination_property_tree_state.Clip(), |
+ ancestor_css_clip); |
+ destination_property_tree_state.SetClip(ancestor_css_clip->Parent()); |
+ } |
+ } else { |
+ const auto* ancestor_overflow_clip = ancestor_properties->OverflowClip(); |
+ if (ancestor_overflow_clip) { |
+ DCHECK_EQ(destination_property_tree_state.Clip(), |
+ ancestor_overflow_clip->Parent()); |
+ destination_property_tree_state.SetClip(ancestor_overflow_clip); |
+ } |
} |
} |
@@ -572,29 +606,9 @@ void PaintLayerClipper::GetOrCalculateClipRects(const ClipRectsContext& context, |
bool PaintLayerClipper::ShouldClipOverflow( |
const ClipRectsContext& context) const { |
- if (!layer_.GetLayoutObject().IsBox()) |
- return false; |
- const LayoutBox& box = ToLayoutBox(layer_.GetLayoutObject()); |
- |
- if (!ShouldRespectOverflowClip(context)) |
+ if (&layer_ == context.root_layer && !context.ShouldRespectRootLayerClip()) |
return false; |
- |
- return box.ShouldClipOverflow(); |
-} |
- |
-bool PaintLayerClipper::ShouldRespectOverflowClip( |
- const ClipRectsContext& context) const { |
- if (&layer_ != context.root_layer) |
- return true; |
- |
- if (context.respect_overflow_clip == kIgnoreOverflowClip) |
- return false; |
- |
- if (layer_.IsRootLayer() && |
- context.respect_overflow_clip_for_viewport == kIgnoreOverflowClip) |
- return false; |
- |
- return true; |
+ return HasOverflowClip(layer_); |
} |
ClipRects& PaintLayerClipper::PaintingClipRects( |