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

Unified Diff: third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp

Issue 2817053002: [blink] Refactor PaintLayerClipper::CalculateClipRects
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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 6aa997cb1f083039c7f65042cb7cfb7409366aa0..de6d4262a4f3fc3d520601a687dfc1247572b662 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp
@@ -53,66 +53,66 @@
namespace blink {
-static void AdjustClipRectsForChildren(
- const LayoutBoxModelObject& layout_object,
- ClipRects& clip_rects) {
- EPosition position = layout_object.StyleRef().GetPosition();
- // A fixed object is essentially the root of its containing block hierarchy,
- // so when we encounter such an object, we reset our clip rects to the
- // fixedClipRect.
- if (position == EPosition::kFixed) {
- clip_rects.SetPosClipRect(clip_rects.FixedClipRect());
+// Match the SPv2 counterpart PaintPropertyTreeBuilder::UpdatePaintOffset.
+static void InheritAncestorClipByPosition(EPosition position,
+ ClipRects& clip_rects) {
+ if (position == EPosition::kAbsolute) {
+ clip_rects.SetOverflowClipRect(clip_rects.PosClipRect());
+ } else if (position == EPosition::kFixed) {
clip_rects.SetOverflowClipRect(clip_rects.FixedClipRect());
clip_rects.SetFixed(true);
- } else if (position == EPosition::kRelative) {
- clip_rects.SetPosClipRect(clip_rects.OverflowClipRect());
- } else if (position == EPosition::kAbsolute) {
- clip_rects.SetOverflowClipRect(clip_rects.PosClipRect());
}
}
-static void ApplyClipRects(const ClipRectsContext& context,
- const LayoutBoxModelObject& layout_object,
- LayoutPoint offset,
- ClipRects& clip_rects) {
- DCHECK(layout_object.IsBox());
- const LayoutBox& box = *ToLayoutBox(&layout_object);
-
- DCHECK(box.ShouldClipOverflow() || box.HasClip());
- LayoutView* view = box.View();
- DCHECK(view);
- if (clip_rects.Fixed() && &context.root_layer->GetLayoutObject() == view)
- offset -= LayoutSize(view->GetFrameView()->GetScrollOffset());
-
- if (box.ShouldClipOverflow()) {
- ClipRect new_overflow_clip =
- box.OverflowClipRect(offset, context.overlay_scrollbar_clip_behavior);
- new_overflow_clip.SetHasRadius(box.StyleRef().HasBorderRadius());
- clip_rects.SetOverflowClipRect(
- Intersection(new_overflow_clip, clip_rects.OverflowClipRect()));
- if (box.IsPositioned())
- clip_rects.SetPosClipRect(
- Intersection(new_overflow_clip, clip_rects.PosClipRect()));
- if (box.CanContainFixedPositionObjects())
- clip_rects.SetFixedClipRect(
- Intersection(new_overflow_clip, clip_rects.FixedClipRect()));
- if (box.StyleRef().ContainsPaint())
- clip_rects.SetPosClipRect(
- Intersection(new_overflow_clip, clip_rects.PosClipRect()));
- }
- if (box.HasClip()) {
- LayoutRect new_clip = box.ClipRect(offset);
- clip_rects.SetPosClipRect(Intersection(new_clip, clip_rects.PosClipRect()));
- clip_rects.SetOverflowClipRect(
- Intersection(new_clip, clip_rects.OverflowClipRect()));
- clip_rects.SetFixedClipRect(
- Intersection(new_clip, clip_rects.FixedClipRect()));
- }
+// Match the SPv2 counterpart PaintPropertyTreeBuilder::UpdateCssClip.
+static void ApplyCssClip(const ClipRectsContext& context,
+ const LayoutBoxModelObject& object,
+ LayoutPoint offset,
+ ClipRects& clip_rects) {
+ if (!object.HasClip())
+ return;
+
+ const LayoutBox& box = ToLayoutBox(object);
+ LayoutRect new_clip = box.ClipRect(offset);
+ clip_rects.SetOverflowClipRect(
+ Intersection(new_clip, clip_rects.OverflowClipRect()));
+ clip_rects.SetFixedClipRect(
+ Intersection(new_clip, clip_rects.FixedClipRect()));
+ // Skip SetPosClipRect because CSS clip requires non-static position,
+ // thus absolute position children always inherit in-flow clips.
+}
+
+// Match the SPv2 counterpart PaintPropertyTreeBuilder::UpdateOverflowClip.
+static void ApplyOverflowClip(const ClipRectsContext& context,
+ const LayoutBoxModelObject& object,
+ LayoutPoint offset,
+ ClipRects& clip_rects) {
+ if (!object.IsBox())
+ return;
+ const LayoutBox& box = ToLayoutBox(object);
+ if (!box.ShouldClipOverflow())
+ return;
+
+ ClipRect new_overflow_clip =
+ box.OverflowClipRect(offset, context.overlay_scrollbar_clip_behavior);
+ new_overflow_clip.SetHasRadius(box.StyleRef().HasBorderRadius());
+
+ clip_rects.SetOverflowClipRect(
+ Intersection(new_overflow_clip, clip_rects.OverflowClipRect()));
+}
+
+// Match the SPv2 counterpart PaintPropertyTreeBuilder::UpdateOutOfFlowContext.
+static void AdjustClipRectsForChildren(const LayoutBoxModelObject& object,
+ ClipRects& clip_rects) {
+ if (object.CanContainAbsolutePositionObjects())
+ clip_rects.SetPosClipRect(clip_rects.OverflowClipRect());
+ if (object.CanContainFixedPositionObjects())
+ clip_rects.SetFixedClipRect(clip_rects.OverflowClipRect());
}
PaintLayerClipper::PaintLayerClipper(const PaintLayer& layer,
- bool usegeometry_mapper)
- : layer_(layer), use_geometry_mapper_(usegeometry_mapper) {}
+ bool use_geometry_mapper)
+ : layer_(layer), use_geometry_mapper_(use_geometry_mapper) {}
ClipRects* PaintLayerClipper::ClipRectsIfCached(
const ClipRectsContext& context) const {
@@ -125,7 +125,7 @@ ClipRects* PaintLayerClipper::ClipRectsIfCached(
// We should add a test that has an inconsistent root. See
// http://crbug.com/366118 for an example.
if (context.root_layer != entry.root)
- return 0;
+ return nullptr;
#if DCHECK_IS_ON()
DCHECK(entry.overlay_scrollbar_clip_behavior ==
context.overlay_scrollbar_clip_behavior);
@@ -371,33 +371,44 @@ void PaintLayerClipper::CalculateClipRects(const ClipRectsContext& context,
return;
}
- bool is_clipping_root = &layer_ == context.root_layer;
+ if (!ShouldRespectOverflowClip(context)) {
+ clip_rects.Reset(LayoutRect(LayoutRect::InfiniteIntRect()));
+ 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.
- PaintLayer* parent_layer = !is_clipping_root ? layer_.Parent() : nullptr;
- // Ensure that our parent's clip has been calculated so that we can examine
- // the values.
- if (parent_layer) {
- PaintLayerClipper(*parent_layer, use_geometry_mapper_)
+ bool is_clipping_root = &layer_ == context.root_layer;
+ if (!is_clipping_root && layer_.Parent()) {
+ PaintLayerClipper(*layer_.Parent(), use_geometry_mapper_)
.GetOrCalculateClipRects(context, clip_rects);
+ InheritAncestorClipByPosition(layout_object.StyleRef().GetPosition(),
+ clip_rects);
} else {
clip_rects.Reset(LayoutRect(LayoutRect::InfiniteIntRect()));
}
- 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 (layout_object.HasClip() ||
+ (layout_object.IsBox() &&
+ ToLayoutBox(layout_object).ShouldClipOverflow())) {
// 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
// space.
- ApplyClipRects(context, layout_object,
- LayoutPoint(layout_object.LocalToAncestorPoint(
- FloatPoint(), &context.root_layer->GetLayoutObject())),
- clip_rects);
+ LayoutPoint paint_offset(layout_object.LocalToAncestorPoint(
+ FloatPoint(), &context.root_layer->GetLayoutObject()));
+ LayoutView* view = layout_object.View();
+ DCHECK(view);
+ if (clip_rects.Fixed() && &context.root_layer->GetLayoutObject() == view)
+ paint_offset -= LayoutSize(view->GetFrameView()->GetScrollOffset());
+
+ ApplyCssClip(context, layout_object, paint_offset, clip_rects);
+ ApplyOverflowClip(context, layout_object, paint_offset, clip_rects);
}
+ AdjustClipRectsForChildren(layout_object, clip_rects);
}
static ClipRect BackgroundClipRectForPosition(const ClipRects& parent_rects,
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698