Index: Source/core/rendering/RenderLayerBacking.cpp |
diff --git a/Source/core/rendering/RenderLayerBacking.cpp b/Source/core/rendering/RenderLayerBacking.cpp |
index 100f82d56d3e49ad7e59cf5d006a69f0c719477d..9f7c6f8e557211dd2067507ed55218829bf212a9 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,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())) |
@@ -427,6 +430,9 @@ bool RenderLayerBacking::updateGraphicsLayerConfiguration() |
if (updateScrollingLayers(m_owningLayer->needsCompositedScrolling())) |
layerConfigChanged = true; |
+ updateScrollParent(scrollParent); |
+ updateClipParent(m_owningLayer->clipParent()); |
+ |
if (layerConfigChanged) |
updateInternalHierarchy(); |
@@ -543,6 +549,29 @@ void RenderLayerBacking::updateGraphicsLayerGeometry() |
graphicsLayerParentLocation = scrollOrigin - scrollOffset; |
} |
+ if (compAncestor && m_ancestorScrollClippingLayer) { |
enne (OOO)
2013/09/10 23:45:01
Just as a sanity check, the ancestor scroll clippi
Ian Vollick
2013/09/11 17:57:52
I've added a detailed description of all layers in
|
+ // 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()) { |
+ position = position + toFloatSize(scrollAncestor->position()); |
enne (OOO)
2013/09/10 23:45:01
Maybe also ASSERT that there's no transform applie
Ian Vollick
2013/09/11 17:57:52
Done.
|
+ 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 +778,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 +791,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 +876,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 +906,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 +1140,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; |
@@ -1104,6 +1167,9 @@ GraphicsLayerPaintingPhase RenderLayerBacking::paintingPhaseForPrimaryLayer() co |
phase |= GraphicsLayerPaintCompositedScroll; |
} |
+ if (m_owningLayer->compositingReasons() & CompositingReasonOverflowScrollingParent) |
+ phase |= GraphicsLayerPaintCompositedScroll; |
+ |
return static_cast<GraphicsLayerPaintingPhase>(phase); |
} |
@@ -1441,6 +1507,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 +1976,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()) { |