Index: third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp |
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp |
index 7e8e9e6cad804fd0cf1c6dc74cbaaa5830bdfc0a..71f12726b582f92e931df0fdd910f193c9e9894e 100644 |
--- a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp |
+++ b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp |
@@ -201,7 +201,7 @@ CompositedLayerMapping::~CompositedLayerMapping() |
} |
} |
- updateClippingLayers(false, false); |
+ updateClippingLayers(false, false, false); |
updateOverflowControlsLayers(false, false, false, false); |
updateChildTransformLayer(false); |
updateForegroundLayer(false); |
@@ -243,6 +243,7 @@ void CompositedLayerMapping::destroyGraphicsLayers() |
m_graphicsLayer->removeFromParent(); |
m_ancestorClippingLayer = nullptr; |
+ m_ancestorClippingMaskLayer = nullptr; |
m_graphicsLayer = nullptr; |
m_foregroundLayer = nullptr; |
m_backgroundLayer = nullptr; |
@@ -414,6 +415,29 @@ bool CompositedLayerMapping::owningLayerClippedByLayerNotAboveCompositedAncestor |
return parentClipRect != LayoutRect::infiniteIntRect(); |
} |
+bool CompositedLayerMapping::owningLayerMaskedByLayerNotAboveCompositedAncestor(const PaintLayer* scrollParent) |
+{ |
+ if (!m_owningLayer.parent()) |
+ return false; |
+ |
+ const PaintLayer* compositingAncestor = m_owningLayer.enclosingLayerWithCompositedLayerMapping(ExcludeSelf); |
+ if (!compositingAncestor) |
+ return false; |
+ |
+ const LayoutObject* clippingContainer = m_owningLayer.clippingContainer(); |
+ if (!clippingContainer) |
+ return false; |
+ |
+ if (clippingContainer->enclosingLayer() == scrollParent) |
+ return false; |
+ |
+ if (compositingAncestor->layoutObject()->isDescendantOf(clippingContainer)) |
+ return false; |
+ |
+ DCHECK(clippingContainer->style()); |
+ return clippingContainer->style()->clipPath() || clippingContainer->style()->hasBorderRadius(); |
+} |
+ |
const PaintLayer* CompositedLayerMapping::scrollParent() |
{ |
const PaintLayer* scrollParent = m_owningLayer.scrollParent(); |
@@ -470,8 +494,8 @@ bool CompositedLayerMapping::updateGraphicsLayerConfiguration() |
// clipping layer is necessary to apply the composited clip for this layer. |
bool needsAncestorClip = owningLayerClippedByLayerNotAboveCompositedAncestor(scrollParent) |
&& !m_owningLayer.clippingContainer()->enclosingLayer()->hasRootScrollerAsDescendant(); |
- |
- if (updateClippingLayers(needsAncestorClip, needsDescendantsClippingLayer)) |
+ bool needsAncestorClippingMask = needsAncestorClip && owningLayerMaskedByLayerNotAboveCompositedAncestor(scrollParent); |
+ if (updateClippingLayers(needsAncestorClip, needsAncestorClippingMask, needsDescendantsClippingLayer)) |
layerConfigChanged = true; |
bool scrollingConfigChanged = false; |
@@ -871,6 +895,12 @@ void CompositedLayerMapping::updateAncestorClippingLayerGeometry(const PaintLaye |
// backgroundRect is relative to compositingContainer, so subtract snappedOffsetFromCompositedAncestor.X/snappedOffsetFromCompositedAncestor.Y to get back to local coords. |
m_ancestorClippingLayer->setOffsetFromLayoutObject(parentClipRect.location() - snappedOffsetFromCompositedAncestor); |
+ if (m_ancestorClippingMaskLayer) { |
+ m_ancestorClippingMaskLayer->setPosition(m_ancestorClippingLayer->position()); // TODO(schenney) Don't need this? |
+ m_ancestorClippingMaskLayer->setSize(m_ancestorClippingLayer->size()); |
+ m_ancestorClippingMaskLayer->setNeedsDisplay(); |
+ } |
+ |
// The primary layer is then parented in, and positioned relative to this clipping layer. |
graphicsLayerParentLocation = parentClipRect.location(); |
} |
@@ -1295,6 +1325,9 @@ void CompositedLayerMapping::updateDrawsContent() |
if (m_backgroundLayer) |
m_backgroundLayer->setDrawsContent(hasPaintedContent); |
+ if (m_ancestorClippingMaskLayer) |
+ m_ancestorClippingMaskLayer->setDrawsContent(true); |
+ |
if (m_maskLayer) |
m_maskLayer->setDrawsContent(true); |
@@ -1313,18 +1346,32 @@ void CompositedLayerMapping::updateChildrenTransform() |
} |
// Return true if the layers changed. |
-bool CompositedLayerMapping::updateClippingLayers(bool needsAncestorClip, bool needsDescendantClip) |
+bool CompositedLayerMapping::updateClippingLayers( |
+ bool needsAncestorClip, |
+ bool needsAncestorClippingMask, |
+ bool needsDescendantClip) |
{ |
bool layersChanged = false; |
+ // TODO(schenney) correctly handle change to border radius while still needing ancestor clip |
if (needsAncestorClip) { |
if (!m_ancestorClippingLayer) { |
m_ancestorClippingLayer = createGraphicsLayer(CompositingReasonLayerForAncestorClip); |
m_ancestorClippingLayer->setMasksToBounds(true); |
m_ancestorClippingLayer->setShouldFlattenTransform(false); |
+ if (needsAncestorClippingMask) { |
+ m_ancestorClippingMaskLayer = |
+ createGraphicsLayer(CompositingReasonLayerForAncestorClippingMask); |
+ m_ancestorClippingMaskLayer->setPaintingPhase(GraphicsLayerPaintAncestorClippingMask); |
+ m_ancestorClippingLayer->setMaskLayer(m_ancestorClippingMaskLayer.get()); |
+ } |
layersChanged = true; |
} |
} else if (m_ancestorClippingLayer) { |
+ if (m_ancestorClippingMaskLayer) { |
+ m_ancestorClippingMaskLayer->removeFromParent(); |
+ m_ancestorClippingMaskLayer = nullptr; |
+ } |
m_ancestorClippingLayer->removeFromParent(); |
m_ancestorClippingLayer = nullptr; |
layersChanged = true; |
@@ -2477,6 +2524,8 @@ void CompositedLayerMapping::paintContents(const GraphicsLayer* graphicsLayer, G |
paintLayerFlags |= PaintLayerPaintingCompositingMaskPhase; |
if (graphicsLayerPaintingPhase & GraphicsLayerPaintChildClippingMask) |
paintLayerFlags |= PaintLayerPaintingChildClippingMaskPhase; |
+ if (graphicsLayerPaintingPhase & GraphicsLayerPaintAncestorClippingMask) |
+ paintLayerFlags |= PaintLayerPaintingAncestorClippingMaskPhase; |
if (graphicsLayerPaintingPhase & GraphicsLayerPaintOverflowContents) |
paintLayerFlags |= PaintLayerPaintingOverflowContents; |
if (graphicsLayerPaintingPhase & GraphicsLayerPaintCompositedScroll) |
@@ -2492,7 +2541,8 @@ void CompositedLayerMapping::paintContents(const GraphicsLayer* graphicsLayer, G |
|| graphicsLayer == m_backgroundLayer.get() |
|| graphicsLayer == m_maskLayer.get() |
|| graphicsLayer == m_childClippingMaskLayer.get() |
- || graphicsLayer == m_scrollingContentsLayer.get()) { |
+ || graphicsLayer == m_scrollingContentsLayer.get() |
+ || graphicsLayer == m_ancestorClippingMaskLayer.get()) { |
bool paintRootBackgroundOntoScrollingContentsLayer = m_backgroundPaintsOntoScrollingContentsLayer; |
DCHECK(!paintRootBackgroundOntoScrollingContentsLayer || (!m_backgroundLayer && !m_foregroundLayer)); |
@@ -2687,6 +2737,8 @@ String CompositedLayerMapping::debugName(const GraphicsLayer* graphicsLayer) con |
name = "Squashing Layer (first squashed layer: " + (m_squashedLayers.size() > 0 ? m_squashedLayers[0].paintLayer->debugName() : "") + ")"; |
} else if (graphicsLayer == m_ancestorClippingLayer.get()) { |
name = "Ancestor Clipping Layer"; |
+ } else if (graphicsLayer == m_ancestorClippingMaskLayer.get()) { |
+ name = "Ancestor Clipping Mask Layer"; |
} else if (graphicsLayer == m_foregroundLayer.get()) { |
name = m_owningLayer.debugName() + " (foreground) Layer"; |
} else if (graphicsLayer == m_backgroundLayer.get()) { |