| Index: Source/core/rendering/RenderLayerBacking.cpp
|
| diff --git a/Source/core/rendering/RenderLayerBacking.cpp b/Source/core/rendering/RenderLayerBacking.cpp
|
| index 938cf70beb81d0779674b2ebd2e68fca14c16284..03649be11cec590ae2a3bdf8448d2a8530b82e10 100644
|
| --- a/Source/core/rendering/RenderLayerBacking.cpp
|
| +++ b/Source/core/rendering/RenderLayerBacking.cpp
|
| @@ -40,6 +40,7 @@
|
| #include "core/page/Settings.h"
|
| #include "core/page/animation/AnimationController.h"
|
| #include "core/page/scrolling/ScrollingCoordinator.h"
|
| +#include "core/platform/chromium/TraceEvent.h"
|
| #include "core/platform/graphics/FontCache.h"
|
| #include "core/platform/graphics/GraphicsContext.h"
|
| #include "core/platform/graphics/GraphicsLayer.h"
|
| @@ -171,7 +172,7 @@ RenderLayerBacking::RenderLayerBacking(RenderLayer* layer)
|
|
|
| RenderLayerBacking::~RenderLayerBacking()
|
| {
|
| - updateClippingLayers(false, false);
|
| + updateClippingLayers(false, false, false);
|
| updateOverflowControlsLayers(false, false, false);
|
| updateForegroundLayer(false);
|
| updateBackgroundLayer(false);
|
| @@ -429,7 +430,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 = compositor->clippedByScrollingAncestor(m_owningLayer);
|
| + if (updateClippingLayers(needsAncestorClip, needsDescendentsClippingLayer, needsScrollClip))
|
| layerConfigChanged = true;
|
|
|
| if (updateOverflowControlsLayers(requiresHorizontalScrollbarLayer(), requiresVerticalScrollbarLayer(), requiresScrollCornerLayer()))
|
| @@ -438,6 +441,13 @@ bool RenderLayerBacking::updateGraphicsLayerConfiguration()
|
| if (updateScrollingLayers(m_owningLayer->needsCompositedScrolling()))
|
| layerConfigChanged = true;
|
|
|
| + updateScrollParent();
|
| +
|
| + // 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.
|
| + if (!needsAncestorClip)
|
| + updateClipParent();
|
| +
|
| if (layerConfigChanged)
|
| updateInternalHierarchy();
|
|
|
| @@ -554,21 +564,65 @@ void RenderLayerBacking::updateGraphicsLayerGeometry()
|
| graphicsLayerParentLocation = scrollOrigin - scrollOffset;
|
| }
|
|
|
| + RenderLayer* scrollAncestor = 0;
|
| + if (compAncestor && m_ancestorScrollClippingLayer) {
|
| + scrollAncestor = m_owningLayer->ancestorScrollingLayer();
|
| + ASSERT(scrollAncestor);
|
| + RenderLayer::ClipRectsContext clipRectsContext(compAncestor, 0, TemporaryClipRects, IgnoreOverlayScrollbarSize, IgnoreOverflowClip, scrollAncestor);
|
| + IntRect parentClipRect = pixelSnappedIntRect(m_owningLayer->backgroundClipRect(clipRectsContext).rect()); // FIXME: Incorrect for CSS regions.
|
| + ASSERT(parentClipRect != PaintInfo::infiniteRect());
|
| +
|
| + m_ancestorScrollClippingLayer->setPosition(FloatPoint(parentClipRect.location() - graphicsLayerParentLocation));
|
| + m_ancestorScrollClippingLayer->setSize(parentClipRect.size());
|
| +
|
| + // backgroundRect is relative to compAncestor, so subtract deltaX/deltaY to get back to local coords.
|
| + m_ancestorScrollClippingLayer->setOffsetFromRenderer(parentClipRect.location() - delta);
|
| +
|
| + graphicsLayerParentLocation = parentClipRect.location();
|
| + }
|
| +
|
| 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
|
| - // for a compositing layer, rootLayer is the layer itself.
|
| - RenderLayer::ClipRectsContext clipRectsContext(compAncestor, 0, TemporaryClipRects, IgnoreOverlayScrollbarSize, IgnoreOverflowClip);
|
| + // for a compositing layer, rootLayer is the layer itself. Also note that if we have an ancestor clipping
|
| + // layer, then we have a scroll parent. As such, we consider ourself unclipped with respect to that
|
| + // scroll parent -- it's as if we are contained within a large, unclipped scrolling layer that moves
|
| + // beneath the clip established by our scroll parent. If we did not do this, we would be completely
|
| + // clipped and ignored when we slid outside our scroll parent's clip, preventing us from being
|
| + // prepainted, etc.
|
| + RenderLayer* clipRoot = compAncestor;
|
| + IntPoint scrollToCompAncestorOffset;
|
| + IntPoint compToScrollAncestorOffset;
|
| + if (m_ancestorScrollClippingLayer) {
|
| + ASSERT(m_owningLayer->renderer()->containingBlock()->enclosingLayer() != scrollAncestor);
|
| + ASSERT(scrollAncestor && scrollAncestor->hasAncestor(compAncestor));
|
| + clipRoot = scrollAncestor;
|
| + scrollAncestor->convertToPixelSnappedLayerCoords(compAncestor, compToScrollAncestorOffset);
|
| + scrollToCompAncestorOffset = -compToScrollAncestorOffset;
|
| + }
|
| +
|
| + RenderLayer::ClipRectsContext clipRectsContext(clipRoot, 0, TemporaryClipRects, IgnoreOverlayScrollbarSize, IgnoreOverflowClip);
|
| IntRect parentClipRect = pixelSnappedIntRect(m_owningLayer->backgroundClipRect(clipRectsContext).rect()); // FIXME: Incorrect for CSS regions.
|
| +
|
| ASSERT(parentClipRect != PaintInfo::infiniteRect());
|
| - m_ancestorClippingLayer->setPosition(FloatPoint(parentClipRect.location() - graphicsLayerParentLocation));
|
| +
|
| + // If we have an ancestor scroll clipping layer, then our clip rects will already be in our scroll
|
| + // parent's space (it would be the clip root), so there is no need to adjust the position of the
|
| + // ancestor clip's graphics layer. Otherwise, our clip is with respect to compAncestor, so we must
|
| + // adjust here.
|
| + IntPoint positionOffset;
|
| + if (!m_ancestorScrollClippingLayer)
|
| + positionOffset = graphicsLayerParentLocation;
|
| +
|
| + m_ancestorClippingLayer->setPosition(FloatPoint(parentClipRect.location() - positionOffset));
|
| m_ancestorClippingLayer->setSize(parentClipRect.size());
|
|
|
| - // backgroundRect is relative to compAncestor, so subtract deltaX/deltaY to get back to local coords.
|
| - m_ancestorClippingLayer->setOffsetFromRenderer(parentClipRect.location() - delta);
|
| + // backgroundRect is relative to clipRoot, so subtract deltaX/deltaY and the scrollToCompAncestorOffset to get back to local coords.
|
| + IntPoint clipToLocalOffset = delta + scrollToCompAncestorOffset;
|
| + m_ancestorClippingLayer->setOffsetFromRenderer(parentClipRect.location() - clipToLocalOffset);
|
|
|
| // The primary layer is then parented in, and positioned relative to this clipping layer.
|
| - graphicsLayerParentLocation = parentClipRect.location();
|
| + graphicsLayerParentLocation = parentClipRect.location() + compToScrollAncestorOffset;
|
| }
|
|
|
| FloatSize contentsSize = relativeCompositingBounds.size();
|
| @@ -760,6 +814,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)
|
| @@ -770,6 +827,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());
|
| @@ -849,8 +913,14 @@ 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)
|
| {
|
| + TRACE_EVENT_INSTANT2(
|
| + "comp-scroll",
|
| + "RenderLayerBacking::updateClippingLayers",
|
| + "needsAncestorClip", needsAncestorClip,
|
| + "needsScrollClip", needsScrollClip);
|
| +
|
| bool layersChanged = false;
|
|
|
| if (needsAncestorClip) {
|
| @@ -879,6 +949,18 @@ bool RenderLayerBacking::updateClippingLayers(bool needsAncestorClip, bool needs
|
| layersChanged = true;
|
| }
|
|
|
| + if (needsScrollClip) {
|
| + if (!m_ancestorScrollClippingLayer) {
|
| + m_ancestorScrollClippingLayer = createGraphicsLayer("Ancestor scroll clipping Layer", CompositingReasonLayerForClip);
|
| + m_ancestorScrollClippingLayer->setMasksToBounds(true);
|
| + layersChanged = true;
|
| + }
|
| + } else if (m_ancestorScrollClippingLayer) {
|
| + m_ancestorScrollClippingLayer->removeFromParent();
|
| + m_ancestorScrollClippingLayer = nullptr;
|
| + layersChanged = true;
|
| + }
|
| +
|
| return layersChanged;
|
| }
|
|
|
| @@ -1109,6 +1191,34 @@ bool RenderLayerBacking::updateScrollingLayers(bool needsScrollingLayers)
|
| return layerChanged;
|
| }
|
|
|
| +void RenderLayerBacking::updateScrollParent()
|
| +{
|
| + ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer);
|
| + if (!scrollingCoordinator)
|
| + return;
|
| +
|
| + RenderLayer* scrollParent = 0;
|
| + if (m_owningLayer->compositingReasons() & CompositingReasonOverflowScrollingParent)
|
| + scrollParent = m_owningLayer->ancestorScrollingLayer();
|
| +
|
| + scrollingCoordinator->updateScrollParentForLayer(m_owningLayer, scrollParent);
|
| +}
|
| +
|
| +void RenderLayerBacking::updateClipParent()
|
| +{
|
| + ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer);
|
| + if (!scrollingCoordinator)
|
| + return;
|
| +
|
| + RenderLayer* clipParent = 0;
|
| + if (m_owningLayer->compositingReasons() & CompositingReasonOutOfFlowClipping) {
|
| + if (RenderObject* containingBlock = m_owningLayer->renderer()->containingBlock())
|
| + clipParent = containingBlock->enclosingLayer()->enclosingCompositingLayer(true);
|
| + }
|
| +
|
| + scrollingCoordinator->updateClipParentForLayer(m_owningLayer, clipParent);
|
| +}
|
| +
|
| GraphicsLayerPaintingPhase RenderLayerBacking::paintingPhaseForPrimaryLayer() const
|
| {
|
| unsigned phase = 0;
|
| @@ -1124,6 +1234,9 @@ GraphicsLayerPaintingPhase RenderLayerBacking::paintingPhaseForPrimaryLayer() co
|
| phase |= GraphicsLayerPaintCompositedScroll;
|
| }
|
|
|
| + if (m_owningLayer->compositingReasons() & CompositingReasonOverflowScrollingParent)
|
| + phase |= GraphicsLayerPaintCompositedScroll;
|
| +
|
| return static_cast<GraphicsLayerPaintingPhase>(phase);
|
| }
|
|
|
| @@ -1461,6 +1574,9 @@ GraphicsLayer* RenderLayerBacking::parentForSublayers() const
|
|
|
| GraphicsLayer* RenderLayerBacking::childForSuperlayers() const
|
| {
|
| + if (m_ancestorScrollClippingLayer)
|
| + return m_ancestorScrollClippingLayer.get();
|
| +
|
| if (m_ancestorClippingLayer)
|
| return m_ancestorClippingLayer.get();
|
|
|
|
|