Chromium Code Reviews| 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 fb600ab13a691f07035a913c2e55db4e6ebefe88..4d577941d5512571dfe72f3848b1d34c725c7f06 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; |
| OwnPtrWillBePersistent<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 |
| @@ -1183,6 +1181,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,9 @@ PaintLayer* PaintLayer::removeChild(PaintLayer* oldChild) |
| oldChild->setPreviousSibling(0); |
| oldChild->setNextSibling(0); |
| oldChild->m_parent = 0; |
| + if (oldChild->ancestorOverflowLayer()) |
| + oldChild->ancestorOverflowLayer()->getScrollableArea()->invalidateStickyConstraintsFor(oldChild); |
| + oldChild->updateAncestorOverflowLayer(nullptr); |
|
flackr
2016/04/12 14:26:25
In order to ensure we don't have any stale ancesto
|
| dirtyAncestorChainHasSelfPaintingLayerDescendantStatus(); |
| @@ -1285,6 +1289,9 @@ void PaintLayer::removeOnlyThisLayer() |
| removeChild(current); |
| m_parent->addChild(current, nextSib); |
| + // Remove ourselves from descendant overflow layers. |
| + current->removeAncestorOverflowLayer(this); |
| + |
| // FIXME: We should call a specialized version of this function. |
| current->updateLayerPositionsAfterLayout(); |
| current = next; |
| @@ -2664,6 +2671,21 @@ 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; |
| + |
| + updateAncestorOverflowLayer(nullptr); |
| + PaintLayer* current = m_first; |
| + while (current) { |
| + current->removeAncestorOverflowLayer(removedLayer); |
| + current = current->nextSibling(); |
| + } |
| +} |
| + |
| void PaintLayer::updateOrRemoveFilterClients() |
| { |
| const auto& filter = layoutObject()->style()->filter(); |