Skip to content

Commit

Permalink
Check subtree paint invalidation when overflow clip status changes
Browse files Browse the repository at this point in the history
Before https://crrev.com/392652 because we included descendant overflow
into container overflow and the paint invalidation rect covered the
changed part of descendants.

Call setNeedsPaintInvalidationSubtree() to force checking of paint
invalidation of descendants when overflow clip status changes.

The other changes are needed because we need to move
clearPaintInvalidationFlags() after
newPaintInvalidationState.updateForChildren().

Several overriding invalidateTreeIfNeeded() methods in subclasses are
removed because they have been the same as inherited ones after we
changed the paint invalidation tree walk order.

BUG=613475
TEST=paint/invalidation/overflow-hidden-to-visible.html
TEST=paint/invalidation/overflow-visible-to-hidden.html

Review-Url: https://codereview.chromium.org/2000763003
Cr-Commit-Position: refs/heads/master@{#395491}

Review URL: https://codereview.chromium.org/2007003003 .

Cr-Commit-Position: refs/branch-heads/2743@{crosswalk-project#44}
Cr-Branched-From: 2b3ae3b-refs/heads/master@{#394939}
  • Loading branch information
wangxianzhu committed May 25, 2016
1 parent 9aae238 commit 3104da0
Show file tree
Hide file tree
Showing 13 changed files with 71 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
"object": "LayoutBlockFlow DIV id='target' class='square'",
"rect": [8, 8, 100, 100],
"reason": "style change"
},
{
"object": "LayoutBlockFlow DIV class='square'",
"reason": "none"
}
]
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<!DOCTYPE html>
Tests paint invalidation of overflowing contents when the container's overflow changes from hidden to visible.
Passes if there is no red.
<div id="green" style="width: 200px; height: 400px; background-color: green"></div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!DOCTYPE html>
Tests paint invalidation of overflowing contents when the container's overflow changes from hidden to visible.
Passes if there is no red.
<div id="indicator" style="position: absolute; z-index: -1; width: 200px; height: 400px; background-color: red"></div>
<div id="container" style="width: 200px; height: 200px; overflow: hidden">
<div style="width: 0; height: 0">
<div id="green" style="width: 200px; height: 400px; background-color: green"></div>
</div>
</div>
<script src="../../resources/run-after-layout-and-paint.js"></script>
<script>
runAfterLayoutAndPaint(function() {
container.style.overflow = 'visible';
}, true);
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<!DOCTYPE html>
Tests paint invalidation of overflowing contents when the container's overflow changes from visible to hidden.
Passes if there is no red.
<div id="green" style="width: 200px; height: 200px; background-color: green"></div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!DOCTYPE html>
Tests paint invalidation of overflowing contents when the container's overflow changes from visible to hidden.
Passes if there is no red.
<div id="container" style="width: 200px; height: 200px; overflow: visible">
<div style="width: 0; height: 0">
<div id="green" style="width: 200px; height: 200px; background-color: green"></div>
<div id="red" style="width: 200px; height: 200px; background-color: red"></div>
</div>
</div>
<script src="../../resources/run-after-layout-and-paint.js"></script>
<script>
runAfterLayoutAndPaint(function() {
container.style.overflow = 'hidden';
}, true);
</script>
3 changes: 1 addition & 2 deletions third_party/WebKit/Source/core/layout/LayoutBlock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,8 +245,7 @@ void LayoutBlock::updateFromStyle()
if (shouldClipOverflow != hasOverflowClip()) {
if (!shouldClipOverflow)
getScrollableArea()->invalidateAllStickyConstraints();
for (LayoutObject* child = firstChild(); child; child = child->nextSibling())
child->setMayNeedPaintInvalidation();
setMayNeedPaintInvalidationSubtree();
}
setHasOverflowClip(shouldClipOverflow);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,9 @@ void LayoutBoxModelObject::invalidateTreeIfNeeded(const PaintInvalidationState&
if (!shouldCheckForPaintInvalidation(newPaintInvalidationState))
return;

if (mayNeedPaintInvalidationSubtree())
newPaintInvalidationState.setForceSubtreeInvalidationCheckingWithinContainer();

LayoutRect previousPaintInvalidationRect = this->previousPaintInvalidationRect();
LayoutPoint previousPosition = previousPositionFromPaintInvalidationBacking();
PaintInvalidationReason reason = invalidatePaintIfNeeded(newPaintInvalidationState);
Expand Down
13 changes: 13 additions & 0 deletions third_party/WebKit/Source/core/layout/LayoutObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1313,6 +1313,10 @@ void LayoutObject::invalidateTreeIfNeeded(const PaintInvalidationState& paintInv
return;

PaintInvalidationState newPaintInvalidationState(paintInvalidationState, *this);

if (mayNeedPaintInvalidationSubtree())
newPaintInvalidationState.setForceSubtreeInvalidationCheckingWithinContainer();

PaintInvalidationReason reason = invalidatePaintIfNeeded(newPaintInvalidationState);
clearPaintInvalidationFlags(newPaintInvalidationState);

Expand Down Expand Up @@ -3454,6 +3458,14 @@ void LayoutObject::setMayNeedPaintInvalidation()
frameView()->scheduleVisualUpdateForPaintInvalidationIfNeeded();
}

void LayoutObject::setMayNeedPaintInvalidationSubtree()
{
if (mayNeedPaintInvalidationSubtree())
return;
m_bitfields.setMayNeedPaintInvalidationSubtree(true);
setMayNeedPaintInvalidation();
}

void LayoutObject::clearPaintInvalidationFlags(const PaintInvalidationState& paintInvalidationState)
{
// paintInvalidationStateIsDirty should be kept in sync with the
Expand All @@ -3464,6 +3476,7 @@ void LayoutObject::clearPaintInvalidationFlags(const PaintInvalidationState& pai
m_bitfields.setNeededLayoutBecauseOfChildren(false);
m_bitfields.setShouldInvalidateOverflowForPaint(false);
m_bitfields.setMayNeedPaintInvalidation(false);
m_bitfields.setMayNeedPaintInvalidationSubtree(false);
m_bitfields.setShouldInvalidateSelection(false);
}

Expand Down
7 changes: 6 additions & 1 deletion third_party/WebKit/Source/core/layout/LayoutObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -1361,6 +1361,9 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver, public DisplayIte
bool mayNeedPaintInvalidation() const { return m_bitfields.mayNeedPaintInvalidation(); }
void setMayNeedPaintInvalidation();

bool mayNeedPaintInvalidationSubtree() const { return m_bitfields.mayNeedPaintInvalidationSubtree(); }
void setMayNeedPaintInvalidationSubtree();

bool shouldInvalidateSelection() const { return m_bitfields.shouldInvalidateSelection(); }
void setShouldInvalidateSelection();

Expand Down Expand Up @@ -1722,6 +1725,7 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver, public DisplayIte
, m_shouldInvalidateOverflowForPaint(false)
, m_childShouldCheckForPaintInvalidation(false)
, m_mayNeedPaintInvalidation(false)
, m_mayNeedPaintInvalidationSubtree(false)
, m_shouldInvalidateSelection(false)
, m_neededLayoutBecauseOfChildren(false)
, m_floating(false)
Expand Down Expand Up @@ -1757,7 +1761,7 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver, public DisplayIte
{
}

// 32 bits have been used in the first word, and 17 in the second.
// 32 bits have been used in the first word, and 18 in the second.

// Self needs layout means that this layout object is marked for a full layout.
// This is the default layout but it is expensive as it recomputes everything.
Expand Down Expand Up @@ -1808,6 +1812,7 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver, public DisplayIte
ADD_BOOLEAN_BITFIELD(shouldInvalidateOverflowForPaint, ShouldInvalidateOverflowForPaint); // TODO(wangxianzhu): Remove for slimming paint v2.
ADD_BOOLEAN_BITFIELD(childShouldCheckForPaintInvalidation, ChildShouldCheckForPaintInvalidation);
ADD_BOOLEAN_BITFIELD(mayNeedPaintInvalidation, MayNeedPaintInvalidation);
ADD_BOOLEAN_BITFIELD(mayNeedPaintInvalidationSubtree, MayNeedPaintInvalidationSubtree);
ADD_BOOLEAN_BITFIELD(shouldInvalidateSelection, ShouldInvalidateSelection); // TODO(wangxianzhu): Remove for slimming paint v2.
ADD_BOOLEAN_BITFIELD(neededLayoutBecauseOfChildren, NeededLayoutBecauseOfChildren); // TODO(wangxianzhu): Remove for slimming paint v2.

Expand Down
14 changes: 3 additions & 11 deletions third_party/WebKit/Source/core/layout/svg/LayoutSVGInline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,17 +145,9 @@ void LayoutSVGInline::removeChild(LayoutObject* child)

void LayoutSVGInline::invalidateTreeIfNeeded(const PaintInvalidationState& paintInvalidationState)
{
ASSERT(!needsLayout());

if (!shouldCheckForPaintInvalidation(paintInvalidationState))
return;

PaintInvalidationState newPaintInvalidationState(paintInvalidationState, *this);
PaintInvalidationReason reason = invalidatePaintIfNeeded(newPaintInvalidationState);
clearPaintInvalidationFlags(newPaintInvalidationState);

newPaintInvalidationState.updateForChildren(reason);
invalidatePaintOfSubtreesIfNeeded(newPaintInvalidationState);
// TODO(wangxianzhu): Verify if the inherited LayoutBoxModelObject::invalidateTreeIfNeeded()
// is applicable here. If yes, remove this overriding method.
LayoutObject::invalidateTreeIfNeeded(paintInvalidationState);
}

} // namespace blink
17 changes: 0 additions & 17 deletions third_party/WebKit/Source/core/layout/svg/LayoutSVGModelObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,21 +130,4 @@ IntRect LayoutSVGModelObject::absoluteElementBoundingBoxRect() const
return localToAbsoluteQuad(FloatQuad(paintInvalidationRectInLocalSVGCoordinates())).enclosingBoundingBox();
}

void LayoutSVGModelObject::invalidateTreeIfNeeded(const PaintInvalidationState& paintInvalidationState)
{
ASSERT(!needsLayout());

// If we didn't need paint invalidation then our children don't need as well.
// Skip walking down the tree as everything should be fine below us.
if (!shouldCheckForPaintInvalidation(paintInvalidationState))
return;

PaintInvalidationState newPaintInvalidationState(paintInvalidationState, *this);
PaintInvalidationReason reason = invalidatePaintIfNeeded(newPaintInvalidationState);
clearPaintInvalidationFlags(newPaintInvalidationState);

newPaintInvalidationState.updateForChildren(reason);
invalidatePaintOfSubtreesIfNeeded(newPaintInvalidationState);
}

} // namespace blink
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,6 @@ class LayoutSVGModelObject : public LayoutObject {
bool nodeAtPoint(HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) final;
IntRect absoluteElementBoundingBoxRect() const final;

void invalidateTreeIfNeeded(const PaintInvalidationState&) final;

protected:
FloatRect m_paintInvalidationBoundingBox;
};
Expand Down
14 changes: 3 additions & 11 deletions third_party/WebKit/Source/core/layout/svg/LayoutSVGText.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -396,17 +396,9 @@ void LayoutSVGText::removeChild(LayoutObject* child)

void LayoutSVGText::invalidateTreeIfNeeded(const PaintInvalidationState& paintInvalidationState)
{
ASSERT(!needsLayout());

if (!shouldCheckForPaintInvalidation(paintInvalidationState))
return;

PaintInvalidationState newPaintInvalidationState(paintInvalidationState, *this);
PaintInvalidationReason reason = invalidatePaintIfNeeded(newPaintInvalidationState);
clearPaintInvalidationFlags(newPaintInvalidationState);

newPaintInvalidationState.updateForChildren(reason);
invalidatePaintOfSubtreesIfNeeded(newPaintInvalidationState);
// TODO(wangxianzhu): Verify if the inherited LayoutBoxModelObject::invalidateTreeIfNeeded()
// is applicable here. If yes, remove this overriding method.
LayoutObject::invalidateTreeIfNeeded(paintInvalidationState);
}

} // namespace blink

0 comments on commit 3104da0

Please sign in to comment.