Commit a6c054a6 authored by wangxianzhu's avatar wangxianzhu Committed by Commit bot

PaintInvalidationState::enclosingSelfPaintingLayer()

It was PaintInvalidationState::enclosingLayer(), but we actually need
the enclosing self painting layer to set repaint flags. Later changes
to optimize empty paint phases also need enclosing self painting layer.

We don't need to specially handle multicol spanner in the new function
because our paint invalidation of multicol spanner follows the true
layer painting order. Instead we need to special handle multicol
spanner in the assertion to check if the repaint flags are properly
set on layers.

This has been reviewed by mstensho@opera.com and chrishtr@chromium.org
as part of https://codereview.chromium.org/1584493002/.

TBR=mstensho@opera.com,chrishtr@chromium.org
BUG=574938

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

Cr-Commit-Position: refs/heads/master@{#371475}
parent 12973847
......@@ -1231,8 +1231,6 @@ void LayoutObject::invalidatePaintUsingContainer(const LayoutBoxModelObject& pai
void LayoutObject::invalidateDisplayItemClient(const DisplayItemClient& displayItemClient) const
{
// TODO(wangxianzhu): Ensure correct bounds for the client will be or has been passed to PaintController. crbug.com/547119.
// Not using enclosingCompositedContainer() directly because this object may be in an orphaned subtree.
if (PaintLayer* enclosingLayer = this->enclosingLayer()) {
// This is valid because we want to invalidate the client in the display item list of the current backing.
DisableCompositingQueryAsserts disabler;
......@@ -1242,19 +1240,38 @@ void LayoutObject::invalidateDisplayItemClient(const DisplayItemClient& displayI
}
}
#if ENABLE(ASSERT)
static void assertEnclosingSelfPaintingLayerHasSetNeedsRepaint(const LayoutObject& layoutObject)
{
PaintLayer* enclosingSelfPaintingLayer = nullptr;
const LayoutObject* curr = &layoutObject;
while (curr) {
if (curr->hasLayer() && toLayoutBoxModelObject(curr)->hasSelfPaintingLayer()) {
enclosingSelfPaintingLayer = toLayoutBoxModelObject(curr)->layer();
break;
}
// Multi-column spanner is painted by the layer of the multi-column container instead of
// its enclosing layer (the layer of the multi-column flow thread).
curr = curr->isColumnSpanAll() ? curr->containingBlock() : curr->parent();
}
ASSERT(!enclosingSelfPaintingLayer || enclosingSelfPaintingLayer->needsRepaint());
}
#endif
void LayoutObject::invalidateDisplayItemClients(const LayoutBoxModelObject& paintInvalidationContainer, PaintInvalidationReason invalidationReason) const
{
// It's caller's responsibility to ensure enclosingLayer's needsRepaint is set.
// Don't set the flag here because enclosingLayer() has cost and the caller can use
// various ways (e.g. PaintInvalidatinState::enclosingLayer()) to reduce the cost.
ASSERT(!enclosingLayer() || enclosingLayer()->needsRepaint());
// It's caller's responsibility to ensure enclosingSelfPaintingLayer's needsRepaint is set.
// Don't set the flag here because getting enclosingSelfPaintLayer has cost and the caller can use
// various ways (e.g. PaintInvalidatinState::enclosingSelfPaintingLayer()) to reduce the cost.
#if ENABLE(ASSERT)
assertEnclosingSelfPaintingLayerHasSetNeedsRepaint(*this);
#endif
paintInvalidationContainer.invalidateDisplayItemClientOnBacking(*this, invalidationReason);
}
void LayoutObject::invalidateDisplayItemClientsWithPaintInvalidationState(const LayoutBoxModelObject& paintInvalidationContainer, const PaintInvalidationState& paintInvalidationState, PaintInvalidationReason invalidationReason) const
{
ASSERT(&paintInvalidationState.enclosingLayer(*this) == enclosingLayer());
paintInvalidationState.enclosingLayer(*this).setNeedsRepaint();
paintInvalidationState.enclosingSelfPaintingLayer(*this).setNeedsRepaint();
invalidateDisplayItemClients(paintInvalidationContainer, invalidationReason);
}
......@@ -3418,10 +3435,12 @@ void LayoutObject::invalidateDisplayItemClientsIncludingNonCompositingDescendant
void LayoutObject::invalidatePaintOfPreviousPaintInvalidationRect(const LayoutBoxModelObject& paintInvalidationContainer, PaintInvalidationReason reason)
{
// It's caller's responsibility to ensure enclosingLayer's needsRepaint is set.
// Don't set the flag here because enclosingLayer() has cost and the caller can use
// various ways (e.g. PaintInvalidatinState::enclosingLayer()) to reduce the cost.
ASSERT(!enclosingLayer() || enclosingLayer()->needsRepaint());
// It's caller's responsibility to ensure enclosingSelfPaintingLayer's needsRepaint is set.
// Don't set the flag here because getting enclosingSelfPaintLayer has cost and the caller can use
// various ways (e.g. PaintInvalidatinState::enclosingSelfPaintingLayer()) to reduce the cost.
#if ENABLE(ASSERT)
assertEnclosingSelfPaintingLayerHasSetNeedsRepaint(*this);
#endif
// These disablers are valid because we want to use the current compositing/invalidation status.
DisablePaintInvalidationStateAsserts invalidationDisabler;
......
......@@ -20,7 +20,7 @@ PaintInvalidationState::PaintInvalidationState(const LayoutView& layoutView, Vec
, m_viewClippingAndScrollOffsetDisabled(false)
, m_paintInvalidationContainer(layoutView.containerForPaintInvalidation())
, m_pendingDelayedPaintInvalidations(pendingDelayedPaintInvalidations)
, m_enclosingLayer(*layoutView.layer())
, m_enclosingSelfPaintingLayer(*layoutView.layer())
{
bool establishesPaintInvalidationContainer = layoutView == m_paintInvalidationContainer;
if (!establishesPaintInvalidationContainer) {
......@@ -47,7 +47,7 @@ PaintInvalidationState::PaintInvalidationState(PaintInvalidationState& next, Lay
, m_viewClippingAndScrollOffsetDisabled(false)
, m_paintInvalidationContainer(paintInvalidationContainer)
, m_pendingDelayedPaintInvalidations(next.pendingDelayedPaintInvalidationTargets())
, m_enclosingLayer(next.enclosingLayer(layoutObject))
, m_enclosingSelfPaintingLayer(next.enclosingSelfPaintingLayer(layoutObject))
{
// FIXME: SVG could probably benefit from a stack-based optimization like html does. crbug.com/391054
bool establishesPaintInvalidationContainer = layoutObject == m_paintInvalidationContainer;
......@@ -109,7 +109,7 @@ PaintInvalidationState::PaintInvalidationState(PaintInvalidationState& next, con
, m_paintOffset(next.m_paintOffset)
, m_paintInvalidationContainer(next.m_paintInvalidationContainer)
, m_pendingDelayedPaintInvalidations(next.pendingDelayedPaintInvalidationTargets())
, m_enclosingLayer(next.enclosingLayer(layoutObject))
, m_enclosingSelfPaintingLayer(next.enclosingSelfPaintingLayer(layoutObject))
{
ASSERT(layoutObject != m_paintInvalidationContainer);
......@@ -145,19 +145,12 @@ void PaintInvalidationState::applyClipIfNeeded(const LayoutObject& layoutObject)
m_paintOffset -= box.scrolledContentOffset();
}
PaintLayer& PaintInvalidationState::enclosingLayer(const LayoutObject& layoutObject) const
PaintLayer& PaintInvalidationState::enclosingSelfPaintingLayer(const LayoutObject& layoutObject) const
{
if (layoutObject.hasLayer())
if (layoutObject.hasLayer() && toLayoutBoxModelObject(layoutObject).hasSelfPaintingLayer())
return *toLayoutBoxModelObject(layoutObject).layer();
// During paint invalidation, a multi-column spanner place holder invokes paint invalidation of
// its layoutObjectInFlowThread (which has a non-null spannerPlaceHolder) directly, skipping the
// parent of its layoutObjectInFlowThread which has a PaintLayer.
if (layoutObject.spannerPlaceholder())
return *layoutObject.enclosingLayer();
ASSERT(layoutObject.enclosingLayer() == &m_enclosingLayer);
return m_enclosingLayer;
return m_enclosingSelfPaintingLayer;
}
} // namespace blink
......@@ -68,7 +68,7 @@ public:
bool viewClippingAndScrollOffsetDisabled() const { return m_viewClippingAndScrollOffsetDisabled; }
void setViewClippingAndScrollOffsetDisabled(bool b) { m_viewClippingAndScrollOffsetDisabled = b; }
PaintLayer& enclosingLayer(const LayoutObject&) const;
PaintLayer& enclosingSelfPaintingLayer(const LayoutObject&) const;
private:
PaintInvalidationState(const LayoutView&, Vector<LayoutObject*>& pendingDelayedPaintInvalidations, PaintInvalidationState* ownerPaintInvalidationState);
......@@ -101,7 +101,7 @@ private:
Vector<LayoutObject*>& m_pendingDelayedPaintInvalidations;
PaintLayer& m_enclosingLayer;
PaintLayer& m_enclosingSelfPaintingLayer;
};
} // 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