Commit 56d8f0dc authored by wangxianzhu's avatar wangxianzhu Committed by Commit bot

Don't clip contain:paint when requested to ignore clip

This fixes another place that previously forced clip for contain:paint,
causing corrupted painting in nested contain:paint containers.
Other places were fixed in https://codereview.chromium.org/1985933002.

BUG=648091
CQ_INCLUDE_TRYBOTS=master.tryserver.chromium.linux:linux_layout_tests_slimming_paint_v2

Review-Url: https://codereview.chromium.org/2400063002
Cr-Commit-Position: refs/heads/master@{#423788}
parent e3c600aa
...@@ -344,9 +344,7 @@ void PaintLayerClipper::calculateRects( ...@@ -344,9 +344,7 @@ void PaintLayerClipper::calculateRects(
layerBounds = LayoutRect(offset, LayoutSize(m_layer.size())); layerBounds = LayoutRect(offset, LayoutSize(m_layer.size()));
// Update the clip rects that will be passed to child layers. // Update the clip rects that will be passed to child layers.
if ((layoutObject.hasOverflowClip() || if (shouldClipOverflow(context)) {
layoutObject.styleRef().containsPaint()) &&
shouldRespectOverflowClip(context)) {
foregroundRect.intersect( foregroundRect.intersect(
toLayoutBox(layoutObject) toLayoutBox(layoutObject)
.overflowClipRect(offset, context.overlayScrollbarClipBehavior)); .overflowClipRect(offset, context.overlayScrollbarClipBehavior));
...@@ -407,10 +405,9 @@ void PaintLayerClipper::calculateClipRects(const ClipRectsContext& context, ...@@ -407,10 +405,9 @@ void PaintLayerClipper::calculateClipRects(const ClipRectsContext& context,
adjustClipRectsForChildren(layoutObject, clipRects); adjustClipRectsForChildren(layoutObject, clipRects);
if ((layoutObject.hasOverflowClip() && shouldRespectOverflowClip(context)) || if (shouldClipOverflow(context) || layoutObject.hasClip() ||
(layoutObject.isSVGRoot() && (layoutObject.isSVGRoot() &&
toLayoutSVGRoot(&layoutObject)->shouldApplyViewportClip()) || toLayoutSVGRoot(&layoutObject)->shouldApplyViewportClip())) {
layoutObject.hasClip() || layoutObject.styleRef().containsPaint()) {
// This offset cannot use convertToLayerCoords, because sometimes our // This offset cannot use convertToLayerCoords, because sometimes our
// rootLayer may be across some transformed layer boundary, for example, in // rootLayer may be across some transformed layer boundary, for example, in
// the PaintLayerCompositor overlapMap, where clipRects are needed in view // the PaintLayerCompositor overlapMap, where clipRects are needed in view
...@@ -447,13 +444,8 @@ ClipRect PaintLayerClipper::clipRectWithGeometryMapper( ...@@ -447,13 +444,8 @@ ClipRect PaintLayerClipper::clipRectWithGeometryMapper(
if (properties->cssClip()) if (properties->cssClip())
propertyTreeState.setClip(properties->cssClip()); propertyTreeState.setClip(properties->cssClip());
const LayoutObject& layoutObject = *m_layer.layoutObject(); if (isForeground && shouldClipOverflow(context) && properties->overflowClip())
if (shouldRespectOverflowClip(context) && isForeground &&
(layoutObject.hasOverflowClip() ||
layoutObject.styleRef().containsPaint())) {
if (properties->overflowClip())
propertyTreeState.setClip(properties->overflowClip()); propertyTreeState.setClip(properties->overflowClip());
}
const ObjectPaintProperties* ancestorProperties = const ObjectPaintProperties* ancestorProperties =
context.rootLayer->layoutObject()->objectPaintProperties(); context.rootLayer->layoutObject()->objectPaintProperties();
...@@ -476,9 +468,7 @@ ClipRect PaintLayerClipper::applyOverflowClipToBackgroundRectWithGeometryMapper( ...@@ -476,9 +468,7 @@ ClipRect PaintLayerClipper::applyOverflowClipToBackgroundRectWithGeometryMapper(
const ClipRect& clip) const { const ClipRect& clip) const {
const LayoutObject& layoutObject = *m_layer.layoutObject(); const LayoutObject& layoutObject = *m_layer.layoutObject();
FloatRect clipRect(clip.rect()); FloatRect clipRect(clip.rect());
if ((layoutObject.hasOverflowClip() || if (shouldClipOverflow(context)) {
layoutObject.styleRef().containsPaint()) &&
shouldRespectOverflowClip(context)) {
LayoutRect layerBoundsWithVisualOverflow = LayoutRect layerBoundsWithVisualOverflow =
layoutObject.isLayoutView() layoutObject.isLayoutView()
? toLayoutView(layoutObject).viewRect() ? toLayoutView(layoutObject).viewRect()
...@@ -538,6 +528,13 @@ void PaintLayerClipper::getOrCalculateClipRects(const ClipRectsContext& context, ...@@ -538,6 +528,13 @@ void PaintLayerClipper::getOrCalculateClipRects(const ClipRectsContext& context,
calculateClipRects(context, clipRects); calculateClipRects(context, clipRects);
} }
bool PaintLayerClipper::shouldClipOverflow(
const ClipRectsContext& context) const {
return (m_layer.layoutObject()->hasOverflowClip() ||
m_layer.layoutObject()->styleRef().containsPaint()) &&
shouldRespectOverflowClip(context);
}
bool PaintLayerClipper::shouldRespectOverflowClip( bool PaintLayerClipper::shouldRespectOverflowClip(
const ClipRectsContext& context) const { const ClipRectsContext& context) const {
if (&m_layer != context.rootLayer) if (&m_layer != context.rootLayer)
......
...@@ -210,6 +210,7 @@ class CORE_EXPORT PaintLayerClipper { ...@@ -210,6 +210,7 @@ class CORE_EXPORT PaintLayerClipper {
void getOrCalculateClipRects(const ClipRectsContext&, ClipRects&) const; void getOrCalculateClipRects(const ClipRectsContext&, ClipRects&) const;
bool shouldClipOverflow(const ClipRectsContext&) const;
bool shouldRespectOverflowClip(const ClipRectsContext&) const; bool shouldRespectOverflowClip(const ClipRectsContext&) const;
ClipRect clipRectWithGeometryMapper(const ClipRectsContext&, ClipRect clipRectWithGeometryMapper(const ClipRectsContext&,
......
...@@ -61,4 +61,60 @@ TEST_F(PaintLayerClipperTest, LayoutSVGRootChild) { ...@@ -61,4 +61,60 @@ TEST_F(PaintLayerClipperTest, LayoutSVGRootChild) {
EXPECT_EQ(LayoutRect(8, 8, 400, 0), layerBounds); EXPECT_EQ(LayoutRect(8, 8, 400, 0), layerBounds);
} }
TEST_F(PaintLayerClipperTest, ContainPaintClip) {
setBodyInnerHTML(
"<div id='target'"
" style='contain: paint; width: 200px; height: 200px; overflow: auto'>"
" <div style='height: 400px'></div>"
"</div>");
LayoutRect infiniteRect(LayoutRect::infiniteIntRect());
PaintLayer* layer =
toLayoutBoxModelObject(getLayoutObjectByElementId("target"))->layer();
ClipRectsContext context(layer, PaintingClipRectsIgnoringOverflowClip);
LayoutRect layerBounds;
ClipRect backgroundRect, foregroundRect;
layer->clipper().calculateRects(context, infiniteRect, layerBounds,
backgroundRect, foregroundRect);
EXPECT_EQ(infiniteRect, backgroundRect.rect());
EXPECT_EQ(infiniteRect, foregroundRect.rect());
EXPECT_EQ(LayoutRect(0, 0, 200, 200), layerBounds);
ClipRectsContext contextClip(layer, PaintingClipRects);
layer->clipper().calculateRects(contextClip, infiniteRect, layerBounds,
backgroundRect, foregroundRect);
EXPECT_EQ(LayoutRect(0, 0, 200, 200), backgroundRect.rect());
EXPECT_EQ(LayoutRect(0, 0, 200, 200), foregroundRect.rect());
EXPECT_EQ(LayoutRect(0, 0, 200, 200), layerBounds);
}
TEST_F(PaintLayerClipperTest, NestedContainPaintClip) {
setBodyInnerHTML(
"<div style='contain: paint; width: 200px; height: 200px; overflow: "
"auto'>"
" <div id='target' style='contain: paint; height: 400px'>"
" </div>"
"</div>");
LayoutRect infiniteRect(LayoutRect::infiniteIntRect());
PaintLayer* layer =
toLayoutBoxModelObject(getLayoutObjectByElementId("target"))->layer();
ClipRectsContext context(layer->parent(),
PaintingClipRectsIgnoringOverflowClip);
LayoutRect layerBounds;
ClipRect backgroundRect, foregroundRect;
layer->clipper().calculateRects(context, infiniteRect, layerBounds,
backgroundRect, foregroundRect);
EXPECT_EQ(LayoutRect(0, 0, 200, 400), backgroundRect.rect());
EXPECT_EQ(LayoutRect(0, 0, 200, 400), foregroundRect.rect());
EXPECT_EQ(LayoutRect(0, 0, 200, 400), layerBounds);
ClipRectsContext contextClip(layer->parent(), PaintingClipRects);
layer->clipper().calculateRects(contextClip, infiniteRect, layerBounds,
backgroundRect, foregroundRect);
EXPECT_EQ(LayoutRect(0, 0, 200, 200), backgroundRect.rect());
EXPECT_EQ(LayoutRect(0, 0, 200, 200), foregroundRect.rect());
EXPECT_EQ(LayoutRect(0, 0, 200, 400), layerBounds);
}
} // namespace blink } // namespace blink
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment