Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(23)

Unified Diff: Source/core/rendering/RenderLayerBacking.cpp

Issue 22419002: Set up clip and scroll parents on the blink side. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: rebase Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: Source/core/rendering/RenderLayerBacking.cpp
diff --git a/Source/core/rendering/RenderLayerBacking.cpp b/Source/core/rendering/RenderLayerBacking.cpp
index 991d529755e2b4362627f51818ffca24254383f2..3073fc89e053cec14522a41be73f95d11236c3dc 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);
@@ -418,7 +419,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()))
@@ -427,6 +430,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();
@@ -543,21 +553,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;
enne (OOO) 2013/08/22 20:54:30 Is this the equivalent of the "scroll buddy" scrol
+ }
+
+ 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();
@@ -749,6 +803,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 +816,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,8 +902,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) {
@@ -868,6 +938,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 +1172,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())
enne (OOO) 2013/08/22 20:54:30 Can you help me understand the containing block lo
+ clipParent = containingBlock->enclosingLayer()->enclosingCompositingLayer(true);
+ }
+
+ scrollingCoordinator->updateClipParentForLayer(m_owningLayer, clipParent);
+}
+
GraphicsLayerPaintingPhase RenderLayerBacking::paintingPhaseForPrimaryLayer() const
{
unsigned phase = 0;
@@ -1105,6 +1215,9 @@ GraphicsLayerPaintingPhase RenderLayerBacking::paintingPhaseForPrimaryLayer() co
phase |= GraphicsLayerPaintCompositedScroll;
}
+ if (m_owningLayer->compositingReasons() & CompositingReasonOverflowScrollingParent)
enne (OOO) 2013/08/22 20:54:30 Use your shiny new unused m_owningLayer->hasScroll
+ phase |= GraphicsLayerPaintCompositedScroll;
+
return static_cast<GraphicsLayerPaintingPhase>(phase);
}
@@ -1442,6 +1555,9 @@ GraphicsLayer* RenderLayerBacking::parentForSublayers() const
GraphicsLayer* RenderLayerBacking::childForSuperlayers() const
{
+ if (m_ancestorScrollClippingLayer)
+ return m_ancestorScrollClippingLayer.get();
+
if (m_ancestorClippingLayer)
return m_ancestorClippingLayer.get();

Powered by Google App Engine
This is Rietveld 408576698