Index: Source/core/rendering/RenderLayerBacking.cpp |
diff --git a/Source/core/rendering/RenderLayerBacking.cpp b/Source/core/rendering/RenderLayerBacking.cpp |
index 0bdbeee8dcee8da880d2c8410ae031bce4b44b50..9cddc32a2e08ed5a812e5b0844c9f0f59d21809d 100644 |
--- a/Source/core/rendering/RenderLayerBacking.cpp |
+++ b/Source/core/rendering/RenderLayerBacking.cpp |
@@ -172,7 +172,7 @@ RenderLayerBacking::RenderLayerBacking(RenderLayer* layer) |
RenderLayerBacking::~RenderLayerBacking() |
{ |
- updateClippingLayers(false, false); |
+ updateClippingLayers(false, false, false); |
updateOverflowControlsLayers(false, false, false); |
updateForegroundLayer(false); |
updateBackgroundLayer(false); |
@@ -380,14 +380,16 @@ void RenderLayerBacking::updateAfterLayout(UpdateAfterLayoutFlags flags) |
// The solution is to update compositing children of this layer here, |
// via updateCompositingChildrenGeometry(). |
updateCompositedBounds(); |
- layerCompositor->updateCompositingDescendantGeometry(m_owningLayer, m_owningLayer, flags & CompositingChildrenOnly); |
+ HashSet<RenderLayer*> visited; |
+ layerCompositor->updateCompositingDescendantGeometry(m_owningLayer, m_owningLayer, visited, flags & CompositingChildrenOnly); |
+ visited.clear(); |
if (flags & IsUpdateRoot) { |
updateGraphicsLayerGeometry(); |
layerCompositor->updateRootLayerPosition(); |
RenderLayer* stackingContainer = m_owningLayer->enclosingStackingContainer(); |
if (!layerCompositor->compositingLayersNeedRebuild() && stackingContainer && (stackingContainer != m_owningLayer)) |
- layerCompositor->updateCompositingDescendantGeometry(stackingContainer, stackingContainer, flags & CompositingChildrenOnly); |
+ layerCompositor->updateCompositingDescendantGeometry(stackingContainer, stackingContainer, visited, flags & CompositingChildrenOnly); |
} |
} |
@@ -419,7 +421,10 @@ bool RenderLayerBacking::updateGraphicsLayerConfiguration() |
if (m_owningLayer->needsCompositedScrolling()) |
needsDescendentsClippingLayer = false; |
- if (updateClippingLayers(compositor->clippedByAncestor(m_owningLayer), needsDescendentsClippingLayer)) |
+ RenderLayer* scrollParent = m_owningLayer->scrollParent(); |
+ bool needsAncestorClip = compositor->clippedByAncestor(m_owningLayer); |
+ bool needsScrollClip = !!scrollParent; |
+ if (updateClippingLayers(needsAncestorClip, needsDescendentsClippingLayer, needsScrollClip)) |
layerConfigChanged = true; |
if (updateOverflowControlsLayers(requiresHorizontalScrollbarLayer(), requiresVerticalScrollbarLayer(), requiresScrollCornerLayer())) |
@@ -428,6 +433,9 @@ bool RenderLayerBacking::updateGraphicsLayerConfiguration() |
if (updateScrollingLayers(m_owningLayer->needsCompositedScrolling())) |
layerConfigChanged = true; |
+ updateScrollParent(scrollParent); |
+ updateClipParent(m_owningLayer->clipParent()); |
+ |
if (layerConfigChanged) |
updateInternalHierarchy(); |
@@ -544,6 +552,30 @@ void RenderLayerBacking::updateGraphicsLayerGeometry() |
graphicsLayerParentLocation = scrollOrigin - scrollOffset; |
} |
+ if (compAncestor && m_ancestorScrollClippingLayer && m_owningLayer->ancestorScrollingLayer()) { |
+ // Our scroll parent must have been processed before us. The code in RenderLayerCompositor |
+ // that coordinates updating graphics layer geometry has been set up to guarantee that this is the case. |
+ RenderLayer* scrollParent = m_owningLayer->ancestorScrollingLayer(); |
+ GraphicsLayer* scrollParentClippingLayer = scrollParent->backing()->scrollingLayer(); |
+ |
+ // Not relative to our parent graphics layer. |
+ FloatPoint position; |
+ GraphicsLayer* scrollParentChildForSuperlayers = scrollParent->backing()->childForSuperlayers(); |
+ |
+ for (GraphicsLayer* scrollAncestor = scrollParentClippingLayer; scrollAncestor; scrollAncestor = scrollAncestor->parent()) { |
+ ASSERT(scrollAncestor->transform().isIdentity()); |
+ position = position + toFloatSize(scrollAncestor->position()); |
+ if (scrollAncestor == scrollParentChildForSuperlayers) |
+ break; |
+ } |
+ |
+ m_ancestorScrollClippingLayer->setPosition(position); |
+ m_ancestorScrollClippingLayer->setSize(scrollParentClippingLayer->size()); |
+ m_ancestorScrollClippingLayer->setOffsetFromRenderer(toIntSize(roundedIntPoint(-position))); |
+ |
+ graphicsLayerParentLocation = roundedIntPoint(position); |
+ } |
+ |
if (compAncestor && m_ancestorClippingLayer) { |
// Call calculateRects to get the backgroundRect which is what is used to clip the contents of this |
// layer. Note that we call it with temporaryClipRects = true because normally when computing clip rects |
@@ -750,6 +782,9 @@ void RenderLayerBacking::registerScrollingLayers() |
void RenderLayerBacking::updateInternalHierarchy() |
{ |
+ if (m_ancestorScrollClippingLayer) |
+ m_ancestorScrollClippingLayer->removeAllChildren(); |
+ |
// m_foregroundLayer has to be inserted in the correct order with child layers, |
// so it's not inserted here. |
if (m_ancestorClippingLayer) |
@@ -760,6 +795,13 @@ void RenderLayerBacking::updateInternalHierarchy() |
if (m_ancestorClippingLayer) |
m_ancestorClippingLayer->addChild(m_graphicsLayer.get()); |
+ if (m_ancestorScrollClippingLayer) { |
+ if (m_ancestorClippingLayer) |
+ m_ancestorScrollClippingLayer->addChild(m_ancestorClippingLayer.get()); |
+ else |
+ m_ancestorScrollClippingLayer->addChild(m_graphicsLayer.get()); |
+ } |
+ |
if (m_childContainmentLayer) { |
m_childContainmentLayer->removeFromParent(); |
m_graphicsLayer->addChild(m_childContainmentLayer.get()); |
@@ -838,7 +880,7 @@ void RenderLayerBacking::updateDrawsContent(bool isSimpleContainer) |
} |
// Return true if the layers changed. |
-bool RenderLayerBacking::updateClippingLayers(bool needsAncestorClip, bool needsDescendantClip) |
+bool RenderLayerBacking::updateClippingLayers(bool needsAncestorClip, bool needsDescendantClip, bool needsScrollClip) |
{ |
bool layersChanged = false; |
@@ -868,6 +910,18 @@ bool RenderLayerBacking::updateClippingLayers(bool needsAncestorClip, bool needs |
layersChanged = true; |
} |
+ if (needsScrollClip) { |
+ if (!m_ancestorScrollClippingLayer) { |
+ m_ancestorScrollClippingLayer = createGraphicsLayer(CompositingReasonLayerForClip); |
+ m_ancestorScrollClippingLayer->setMasksToBounds(true); |
+ layersChanged = true; |
+ } |
+ } else if (m_ancestorScrollClippingLayer) { |
+ m_ancestorScrollClippingLayer->removeFromParent(); |
+ m_ancestorScrollClippingLayer = nullptr; |
+ layersChanged = true; |
+ } |
+ |
return layersChanged; |
} |
@@ -1090,6 +1144,18 @@ bool RenderLayerBacking::updateScrollingLayers(bool needsScrollingLayers) |
return layerChanged; |
} |
+void RenderLayerBacking::updateScrollParent(RenderLayer* scrollParent) |
+{ |
+ if (ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer)) |
+ scrollingCoordinator->updateScrollParentForLayer(m_owningLayer, scrollParent); |
+} |
+ |
+void RenderLayerBacking::updateClipParent(RenderLayer* clipParent) |
+{ |
+ if (ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer)) |
+ scrollingCoordinator->updateClipParentForLayer(m_owningLayer, clipParent); |
+} |
+ |
GraphicsLayerPaintingPhase RenderLayerBacking::paintingPhaseForPrimaryLayer() const |
{ |
unsigned phase = 0; |
@@ -1105,6 +1171,9 @@ GraphicsLayerPaintingPhase RenderLayerBacking::paintingPhaseForPrimaryLayer() co |
phase |= GraphicsLayerPaintCompositedScroll; |
} |
+ if (m_owningLayer->compositingReasons() & CompositingReasonOverflowScrollingParent) |
+ phase |= GraphicsLayerPaintCompositedScroll; |
+ |
return static_cast<GraphicsLayerPaintingPhase>(phase); |
} |
@@ -1442,6 +1511,9 @@ GraphicsLayer* RenderLayerBacking::parentForSublayers() const |
GraphicsLayer* RenderLayerBacking::childForSuperlayers() const |
{ |
+ if (m_ancestorScrollClippingLayer) |
+ return m_ancestorScrollClippingLayer.get(); |
+ |
if (m_ancestorClippingLayer) |
return m_ancestorClippingLayer.get(); |
@@ -1908,6 +1980,8 @@ String RenderLayerBacking::debugName(const GraphicsLayer* graphicsLayer) |
String name; |
if (graphicsLayer == m_graphicsLayer.get()) { |
name = m_owningLayer->debugName(); |
+ } else if (graphicsLayer == m_ancestorScrollClippingLayer.get()) { |
+ name = "Ancestor Scroll Clipping Layer"; |
} else if (graphicsLayer == m_ancestorClippingLayer.get()) { |
name = "Ancestor Clipping Layer"; |
} else if (graphicsLayer == m_foregroundLayer.get()) { |