Index: third_party/WebKit/Source/core/paint/PaintLayer.cpp |
diff --git a/third_party/WebKit/Source/core/paint/PaintLayer.cpp b/third_party/WebKit/Source/core/paint/PaintLayer.cpp |
index 25a704b56969c89dc4eeefb4a840f081c2c18e94..dbafbbe174782754ebf591c4bbe814beec98225e 100644 |
--- a/third_party/WebKit/Source/core/paint/PaintLayer.cpp |
+++ b/third_party/WebKit/Source/core/paint/PaintLayer.cpp |
@@ -99,7 +99,7 @@ static CompositingQueryMode gCompositingQueryMode = |
struct SameSizeAsPaintLayer : DisplayItemClient { |
int bitFields; |
- void* pointers[9]; |
+ void* pointers[10]; |
LayoutUnit layoutUnits[4]; |
IntSize size; |
Persistent<PaintLayerScrollableArea> scrollableArea; |
@@ -172,6 +172,7 @@ PaintLayer::PaintLayer(LayoutBoxModelObject* layoutObject, PaintLayerType type) |
, m_last(0) |
, m_staticInlinePosition(0) |
, m_staticBlockPosition(0) |
+ , m_ancestorOverflowLayer(nullptr) |
{ |
updateStackingNode(); |
@@ -349,7 +350,8 @@ void PaintLayer::dirtyAncestorChainHasSelfPaintingLayerDescendantStatus() |
bool PaintLayer::scrollsWithViewport() const |
{ |
- return layoutObject()->style()->position() == FixedPosition && layoutObject()->containerForFixedPosition() == layoutObject()->view(); |
+ return (layoutObject()->style()->position() == FixedPosition && layoutObject()->containerForFixedPosition() == layoutObject()->view()) |
+ || (layoutObject()->style()->position() == StickyPosition && !ancestorScrollingLayer()); |
} |
bool PaintLayer::scrollsWithRespectTo(const PaintLayer* other) const |
@@ -747,7 +749,7 @@ bool PaintLayer::update3DTransformedDescendantStatus() |
return has3DTransform(); |
} |
-bool PaintLayer::updateLayerPosition() |
+void PaintLayer::updateLayerPosition() |
{ |
LayoutPoint localPoint; |
LayoutPoint inlineBoundingBoxOffset; // We don't put this into the Layer x/y for inlines, so we need to subtract it out when done. |
@@ -798,10 +800,8 @@ bool PaintLayer::updateLayerPosition() |
localPoint -= scrollOffset; |
} |
- bool positionOrOffsetChanged = false; |
if (layoutObject()->isInFlowPositioned()) { |
LayoutSize newOffset = layoutObject()->offsetForInFlowPosition(); |
- positionOrOffsetChanged = newOffset != offsetForInFlowPosition(); |
if (m_rareData || !newOffset.isZero()) |
ensureRareData().offsetForInFlowPosition = newOffset; |
localPoint.move(newOffset); |
@@ -813,7 +813,6 @@ bool PaintLayer::updateLayerPosition() |
localPoint.moveBy(-inlineBoundingBoxOffset); |
if (m_location != localPoint) { |
- positionOrOffsetChanged = true; |
setNeedsRepaint(); |
} |
m_location = localPoint; |
@@ -821,7 +820,6 @@ bool PaintLayer::updateLayerPosition() |
#if ENABLE(ASSERT) |
m_needsPositionUpdate = false; |
#endif |
- return positionOrOffsetChanged; |
} |
TransformationMatrix PaintLayer::perspectiveTransform() const |
@@ -1182,6 +1180,9 @@ void PaintLayer::addChild(PaintLayer* child, PaintLayer* beforeChild) |
child->m_parent = this; |
+ // The ancestor overflow layer is calculated during compositing inputs update and should not be set yet. |
+ ASSERT(!child->ancestorOverflowLayer()); |
+ |
setNeedsCompositingInputsUpdate(); |
if (!child->stackingNode()->isStacked() && !layoutObject()->documentBeingDestroyed()) |
@@ -1236,6 +1237,10 @@ PaintLayer* PaintLayer::removeChild(PaintLayer* oldChild) |
oldChild->setNextSibling(0); |
oldChild->m_parent = 0; |
+ // Remove any ancestor overflow layers which descended into the removed child. |
+ if (oldChild->ancestorOverflowLayer()) |
+ oldChild->removeAncestorOverflowLayer(oldChild->ancestorOverflowLayer()); |
+ |
dirtyAncestorChainHasSelfPaintingLayerDescendantStatus(); |
oldChild->updateDescendantDependentFlags(); |
@@ -2686,6 +2691,23 @@ PaintLayerFilterInfo& PaintLayer::ensureFilterInfo() |
return *rareData.filterInfo; |
} |
+void PaintLayer::removeAncestorOverflowLayer(const PaintLayer* removedLayer) |
+{ |
+ // If the current ancestor overflow layer does not match the removed layer |
+ // the ancestor overflow layer has changed so we can stop searching. |
+ if (ancestorOverflowLayer() && ancestorOverflowLayer() != removedLayer) |
+ return; |
+ |
+ if (ancestorOverflowLayer()) |
+ ancestorOverflowLayer()->getScrollableArea()->invalidateStickyConstraintsFor(this); |
+ updateAncestorOverflowLayer(nullptr); |
+ PaintLayer* current = m_first; |
+ while (current) { |
+ current->removeAncestorOverflowLayer(removedLayer); |
+ current = current->nextSibling(); |
+ } |
+} |
+ |
void PaintLayer::updateOrRemoveFilterClients() |
{ |
const auto& filter = layoutObject()->style()->filter(); |