Index: Source/core/rendering/RenderLayerBacking.cpp |
diff --git a/Source/core/rendering/RenderLayerBacking.cpp b/Source/core/rendering/RenderLayerBacking.cpp |
index 100f82d56d3e49ad7e59cf5d006a69f0c719477d..f568515a858907be9e08b6345f5ce327962d3fc4 100644 |
--- a/Source/core/rendering/RenderLayerBacking.cpp |
+++ b/Source/core/rendering/RenderLayerBacking.cpp |
@@ -171,7 +171,7 @@ RenderLayerBacking::RenderLayerBacking(RenderLayer* layer) |
RenderLayerBacking::~RenderLayerBacking() |
{ |
- updateClippingLayers(false, false); |
+ updateClippingLayers(false, false, false); |
updateOverflowControlsLayers(false, false, false); |
updateForegroundLayer(false); |
updateBackgroundLayer(false); |
@@ -418,7 +418,9 @@ bool RenderLayerBacking::updateGraphicsLayerConfiguration() |
if (m_owningLayer->needsCompositedScrolling()) |
needsDescendentsClippingLayer = false; |
- if (updateClippingLayers(compositor->clippedByAncestor(m_owningLayer), needsDescendentsClippingLayer)) |
+ bool needsAncestorClip = compositor->clippedByAncestor(m_owningLayer); |
+ bool needsScrollClip = m_owningLayer->hasScrollParent(); |
+ if (updateClippingLayers(needsAncestorClip, needsDescendentsClippingLayer, needsScrollClip)) |
layerConfigChanged = true; |
if (updateOverflowControlsLayers(requiresHorizontalScrollbarLayer(), requiresVerticalScrollbarLayer(), requiresScrollCornerLayer())) |
@@ -427,6 +429,10 @@ bool RenderLayerBacking::updateGraphicsLayerConfiguration() |
if (updateScrollingLayers(m_owningLayer->needsCompositedScrolling())) |
layerConfigChanged = true; |
+ updateScrollParent(needsScrollClip); |
+ |
+ updateClipParent(needsAncestorClip); |
+ |
if (layerConfigChanged) |
updateInternalHierarchy(); |
@@ -543,6 +549,28 @@ void RenderLayerBacking::updateGraphicsLayerGeometry() |
graphicsLayerParentLocation = scrollOrigin - scrollOffset; |
} |
+ if (compAncestor && m_ancestorScrollClippingLayer) { |
+ // Our scroll parent must have been processed before us. |
+ 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()) { |
+ 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 |
@@ -749,6 +777,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) |
@@ -759,6 +790,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()); |
@@ -837,7 +875,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; |
@@ -867,6 +905,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; |
} |
@@ -1089,6 +1139,36 @@ bool RenderLayerBacking::updateScrollingLayers(bool needsScrollingLayers) |
return layerChanged; |
} |
+void RenderLayerBacking::updateScrollParent(bool needsScrollParent) |
+{ |
+ ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer); |
+ if (!scrollingCoordinator) |
+ return; |
+ |
+ RenderLayer* scrollParent = 0; |
+ if (needsScrollParent) |
+ scrollParent = m_owningLayer->ancestorScrollingLayer(); |
+ |
+ scrollingCoordinator->updateScrollParentForLayer(m_owningLayer, scrollParent); |
+} |
+ |
+void RenderLayerBacking::updateClipParent(bool needsAncestorClip) |
+{ |
+ ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer); |
+ if (!scrollingCoordinator) |
+ return; |
+ |
+ // If the clip we want to ignore is established by a stacking sibling, it won't affect us. |
+ // We've already made sure that we don't get a troublesome m_ancestorClippingLayer in this case. |
+ RenderLayer* clipParent = 0; |
+ if ((m_owningLayer->compositingReasons() & CompositingReasonOutOfFlowClipping) && !needsAncestorClip) { |
+ if (RenderObject* containingBlock = m_owningLayer->renderer()->containingBlock()) |
+ clipParent = containingBlock->enclosingLayer()->enclosingCompositingLayer(true); |
+ } |
+ |
+ scrollingCoordinator->updateClipParentForLayer(m_owningLayer, clipParent); |
+} |
+ |
GraphicsLayerPaintingPhase RenderLayerBacking::paintingPhaseForPrimaryLayer() const |
{ |
unsigned phase = 0; |
@@ -1104,6 +1184,9 @@ GraphicsLayerPaintingPhase RenderLayerBacking::paintingPhaseForPrimaryLayer() co |
phase |= GraphicsLayerPaintCompositedScroll; |
} |
+ if (m_owningLayer->compositingReasons() & CompositingReasonOverflowScrollingParent) |
+ phase |= GraphicsLayerPaintCompositedScroll; |
+ |
return static_cast<GraphicsLayerPaintingPhase>(phase); |
} |
@@ -1441,6 +1524,9 @@ GraphicsLayer* RenderLayerBacking::parentForSublayers() const |
GraphicsLayer* RenderLayerBacking::childForSuperlayers() const |
{ |
+ if (m_ancestorScrollClippingLayer) |
+ return m_ancestorScrollClippingLayer.get(); |
+ |
if (m_ancestorClippingLayer) |
return m_ancestorClippingLayer.get(); |
@@ -1907,6 +1993,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()) { |