Chromium Code Reviews| Index: Source/core/rendering/CompositedLayerMapping.cpp |
| diff --git a/Source/core/rendering/CompositedLayerMapping.cpp b/Source/core/rendering/CompositedLayerMapping.cpp |
| index d60ab34e3c0bb51be192e48ea32396eba3ce5ab7..14a8bd202db5ca81d1db0179ec5eaa1be7a077d9 100644 |
| --- a/Source/core/rendering/CompositedLayerMapping.cpp |
| +++ b/Source/core/rendering/CompositedLayerMapping.cpp |
| @@ -175,6 +175,12 @@ CompositedLayerMapping::CompositedLayerMapping(RenderLayer* layer) |
| CompositedLayerMapping::~CompositedLayerMapping() |
| { |
| + // Do not leave the destroyed pointer dangling on any RenderLayers that painted to this mapping's squashing layer. |
| + for (size_t i = 0; i < m_squashedLayers.size(); ++i) { |
| + if (m_squashedLayers[i].renderLayer->groupedMapping() == this) |
| + m_squashedLayers[i].renderLayer->setGroupedMapping(0); |
| + } |
| + |
| updateClippingLayers(false, false); |
| updateOverflowControlsLayers(false, false, false); |
| updateForegroundLayer(false); |
| @@ -182,6 +188,7 @@ CompositedLayerMapping::~CompositedLayerMapping() |
| updateMaskLayer(false); |
| updateClippingMaskLayers(false); |
| updateScrollingLayers(false); |
| + updateSquashingLayers(false); |
| destroyGraphicsLayers(); |
| } |
| @@ -470,6 +477,9 @@ bool CompositedLayerMapping::updateGraphicsLayerConfiguration() |
| updateScrollParent(scrollParent); |
| updateClipParent(m_owningLayer->clipParent()); |
| + if (updateSquashingLayers(!m_squashedLayers.isEmpty())) |
| + layerConfigChanged = true; |
| + |
| if (layerConfigChanged) |
| updateInternalHierarchy(); |
| @@ -790,6 +800,45 @@ void CompositedLayerMapping::updateGraphicsLayerGeometry() |
| } |
| } |
| + if (m_squashingLayer) { |
| + ASSERT(compositor()->isLayerSquashingEnabled()); |
| + |
| + IntRect totalSquashBounds; |
| + for (size_t i = 0; i < m_squashedLayers.size(); ++i) { |
| + IntRect squashedBounds = compositor()->calculateCompositedBounds(m_squashedLayers[i].renderLayer, m_squashedLayers[i].renderLayer); |
| + |
| + // Store the composited bounds before applying the offset. |
| + // FIXME: consider whether it is more efficient or clarifies the math to store the compositedBounds after applying the offset. |
| + m_squashedLayers[i].compositedBounds = squashedBounds; |
| + |
| + squashedBounds.move(m_squashedLayers[i].offsetFromBackingRoot); |
| + totalSquashBounds.unite(squashedBounds); |
| + } |
| + |
| + IntPoint squashLayerPosition; |
| + // FIXME: this logic needs to update depending on what "containment" layers are added to CompositedLayerMapping due to other changes |
| + if (m_ancestorClippingLayer) { |
| + squashLayerPosition = IntPoint(m_ancestorClippingLayer->position().x() + totalSquashBounds.location().x(), |
| + m_ancestorClippingLayer->position().y() + totalSquashBounds.location().y()); |
| + } else { |
| + squashLayerPosition = IntPoint(m_graphicsLayer->position().x() + totalSquashBounds.location().x(), |
| + m_graphicsLayer->position().y() + totalSquashBounds.location().y()); |
| + } |
| + |
| + m_squashingLayer->setPosition(squashLayerPosition); |
| + m_squashingLayer->setSize(totalSquashBounds.size()); |
| + |
| + // Now that the position of the squashing layer is known, update the offsets for each squashed RenderLayer. |
| + for (size_t i = 0; i < m_squashedLayers.size(); ++i) { |
| + m_squashedLayers[i].offsetFromRenderer = IntSize(-m_squashedLayers[i].offsetFromBackingRoot.width() - m_graphicsLayer->position().x() + m_squashingLayer->position().x(), |
| + -m_squashedLayers[i].offsetFromBackingRoot.height() - m_graphicsLayer->position().y() + m_squashingLayer->position().y()); |
| + |
| + // FIXME: find a better design to avoid this redundant value - most likely it will make |
| + // sense to move the paint task info into RenderLayer's m_compositingProperties. |
| + m_squashedLayers[i].renderLayer->setOffsetFromSquashingLayerOrigin(m_squashedLayers[i].offsetFromRenderer); |
| + } |
| + } |
| + |
| if (m_owningLayer->scrollableArea()) |
| m_owningLayer->scrollableArea()->positionOverflowControls(); |
| @@ -868,6 +917,21 @@ void CompositedLayerMapping::updateInternalHierarchy() |
| m_layerForScrollCorner->removeFromParent(); |
| m_graphicsLayer->addChild(m_layerForScrollCorner.get()); |
| } |
| + |
| + // The squashing containment layer, if it exists, becomes a no-op parent. |
| + if (m_squashingLayer) { |
| + ASSERT(compositor()->isLayerSquashingEnabled()); |
| + ASSERT(m_squashingContainmentLayer); |
| + |
| + m_squashingContainmentLayer->removeAllChildren(); |
| + |
| + if (m_ancestorClippingLayer) |
| + m_squashingContainmentLayer->addChild(m_ancestorClippingLayer.get()); |
| + else |
| + m_squashingContainmentLayer->addChild(m_graphicsLayer.get()); |
| + |
| + m_squashingContainmentLayer->addChild(m_squashingLayer.get()); |
| + } |
| } |
| void CompositedLayerMapping::updateContentsRect(bool isSimpleContainer) |
| @@ -1194,8 +1258,16 @@ bool CompositedLayerMapping::updateScrollingLayers(bool needsScrollingLayers) |
| void CompositedLayerMapping::updateScrollParent(RenderLayer* scrollParent) |
| { |
| + |
| if (ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer)) { |
| - if (m_ancestorClippingLayer) { |
| + // FIXME: not 100% certain if this scrollParent code adjustment for squashing is correct?. |
|
Ian Vollick
2013/12/06 21:11:30
Looks correct, but would you mind doing a minor cl
Ian Vollick
2013/12/07 02:44:42
On second thought, I'm pretty confident this is co
shawnsingh
2013/12/11 18:50:34
Your cleanup landed anyway, and the latest patch i
|
| + if (m_squashingContainmentLayer) { |
| + ASSERT(childForSuperlayers() == m_squashingContainmentLayer.get()); |
| + scrollingCoordinator->updateScrollParentForGraphicsLayer(m_squashingContainmentLayer.get(), scrollParent); |
| + if (m_ancestorClippingLayer) |
| + scrollingCoordinator->updateScrollParentForGraphicsLayer(m_ancestorClippingLayer.get(), 0); |
| + scrollingCoordinator->updateScrollParentForGraphicsLayer(m_graphicsLayer.get(), 0); |
| + } else if (m_ancestorClippingLayer) { |
| ASSERT(childForSuperlayers() == m_ancestorClippingLayer.get()); |
| // If we have an ancestor clipping layer, it is the scroll child. The other layer that may have |
| // been the scroll child is the graphics layer. We will ensure that we clear its association |
| @@ -1215,6 +1287,49 @@ void CompositedLayerMapping::updateClipParent(RenderLayer* clipParent) |
| scrollingCoordinator->updateClipParentForGraphicsLayer(m_graphicsLayer.get(), clipParent); |
| } |
| +bool CompositedLayerMapping::updateSquashingLayers(bool needsSquashingLayers) |
| +{ |
| + bool layersChanged = false; |
| + |
| + if (needsSquashingLayers) { |
| + ASSERT(compositor()->isLayerSquashingEnabled()); |
| + |
| + if (!m_squashingLayer) { |
| + ASSERT(!m_squashingContainmentLayer); |
| + |
| + m_squashingLayer = createGraphicsLayer(CompositingReasonOverlap); |
| + m_squashingLayer->setDrawsContent(true); |
| + m_squashingLayer->setNeedsDisplay(); |
| + layersChanged = true; |
| + |
| + // FIXME: containment layer needs a new CompositingReason, CompositingReasonOverlap is not appropriate. |
| + m_squashingContainmentLayer = createGraphicsLayer(CompositingReasonOverlap); |
| + // FIXME: reflections should force transform-style to be flat in the style: https://bugs.webkit.org/show_bug.cgi?id=106959 |
| + bool preserves3D = renderer()->style()->transformStyle3D() == TransformStyle3DPreserve3D && !renderer()->hasReflection(); |
| + m_squashingContainmentLayer->setPreserves3D(preserves3D); |
| + layersChanged = true; |
| + } |
| + |
| + ASSERT(m_squashingLayer && m_squashingContainmentLayer); |
| + } else { |
| + if (m_squashingLayer) { |
| + m_squashingLayer->removeFromParent(); |
| + m_squashingLayer = nullptr; |
| + layersChanged = true; |
| + // FIXME: do we need to invalidate something here? |
| + |
| + ASSERT(m_squashingContainmentLayer); |
| + m_squashingContainmentLayer->removeFromParent(); |
| + m_squashingContainmentLayer = nullptr; |
| + layersChanged = true; |
| + } |
| + |
| + ASSERT(!m_squashingLayer && !m_squashingContainmentLayer); |
| + } |
| + |
| + return layersChanged; |
| +} |
| + |
| GraphicsLayerPaintingPhase CompositedLayerMapping::paintingPhaseForPrimaryLayer() const |
| { |
| unsigned phase = 0; |
| @@ -1556,6 +1671,9 @@ GraphicsLayer* CompositedLayerMapping::parentForSublayers() const |
| GraphicsLayer* CompositedLayerMapping::childForSuperlayers() const |
| { |
| + if (m_squashingContainmentLayer) |
| + return m_squashingContainmentLayer.get(); |
| + |
| if (m_ancestorClippingLayer) |
| return m_ancestorClippingLayer.get(); |
| @@ -1730,14 +1848,20 @@ void CompositedLayerMapping::doPaintTask(GraphicsLayerPaintInfo& paintInfo, Grap |
| paintInfo.renderLayer->renderer()->assertSubtreeIsLaidOut(); |
| #endif |
| - // FIXME: GraphicsLayers need a way to split for RenderRegions. |
| - LayerPaintingInfo paintingInfo(paintInfo.renderLayer, dirtyRect, PaintBehaviorNormal, LayoutSize()); |
| - paintInfo.renderLayer->paintLayerContents(context, paintingInfo, paintFlags); |
| + if (paintInfo.renderLayer->compositingState() != PaintsIntoGroupedBacking) { |
| + // FIXME: GraphicsLayers need a way to split for RenderRegions. |
| + LayerPaintingInfo paintingInfo(paintInfo.renderLayer, dirtyRect, PaintBehaviorNormal, LayoutSize()); |
| + paintInfo.renderLayer->paintLayerContents(context, paintingInfo, paintFlags); |
| - ASSERT(!paintInfo.isBackgroundLayer || paintFlags & PaintLayerPaintingRootBackgroundOnly); |
| + ASSERT(!paintInfo.isBackgroundLayer || paintFlags & PaintLayerPaintingRootBackgroundOnly); |
| - if (paintInfo.renderLayer->containsDirtyOverlayScrollbars()) |
| - paintInfo.renderLayer->paintLayerContents(context, paintingInfo, paintFlags | PaintLayerPaintingOverlayScrollbars); |
| + if (paintInfo.renderLayer->containsDirtyOverlayScrollbars()) |
| + paintInfo.renderLayer->paintLayerContents(context, paintingInfo, paintFlags | PaintLayerPaintingOverlayScrollbars); |
| + } else { |
| + ASSERT(compositor()->isLayerSquashingEnabled()); |
| + LayerPaintingInfo paintingInfo(paintInfo.renderLayer, dirtyRect, PaintBehaviorNormal, LayoutSize()); |
| + paintInfo.renderLayer->paintLayer(context, paintingInfo, paintFlags); |
| + } |
| ASSERT(!paintInfo.renderLayer->m_usedTransparency); |
| @@ -1784,6 +1908,10 @@ void CompositedLayerMapping::paintContents(const GraphicsLayer* graphicsLayer, G |
| // We have to use the same root as for hit testing, because both methods can compute and cache clipRects. |
| doPaintTask(paintInfo, &context, clip); |
| + } else if (graphicsLayer == m_squashingLayer.get()) { |
| + ASSERT(compositor()->isLayerSquashingEnabled()); |
| + for (size_t i = 0; i < m_squashedLayers.size(); ++i) |
| + doPaintTask(m_squashedLayers[i], &context, clip); |
| } else if (graphicsLayer == layerForHorizontalScrollbar()) { |
| paintScrollbar(m_owningLayer->scrollableArea()->horizontalScrollbar(), context, clip); |
| } else if (graphicsLayer == layerForVerticalScrollbar()) { |
| @@ -1979,6 +2107,46 @@ void CompositedLayerMapping::setCompositedBounds(const IntRect& bounds) |
| m_compositedBounds = bounds; |
| } |
| +void CompositedLayerMapping::addRenderLayerToSquashingGraphicsLayer(RenderLayer* layer, IntSize offsetFromTargetBacking, size_t nextSquashedLayerIndex) |
| +{ |
| + ASSERT(compositor()->isLayerSquashingEnabled()); |
| + |
| + GraphicsLayerPaintInfo paintInfo; |
| + paintInfo.renderLayer = layer; |
| + // NOTE: composited bounds are updated elsewhere |
| + // NOTE: offsetFromRenderer is updated elsewhere |
| + paintInfo.offsetFromBackingRoot = offsetFromTargetBacking; |
| + paintInfo.paintingPhase = GraphicsLayerPaintAllWithOverflowClip; |
| + paintInfo.isBackgroundLayer = false; |
| + |
| + // Change tracking on squashing layers: at the first sign of something changed, just invalidate the layer. |
| + // FIXME: Perhaps we can find a tighter more clever mechanism later. |
| + if (nextSquashedLayerIndex < m_squashedLayers.size()) { |
| + if (m_squashedLayers[nextSquashedLayerIndex].renderLayer != layer) { |
| + m_squashedLayers[nextSquashedLayerIndex] = paintInfo; |
| + if (m_squashingLayer) |
| + m_squashingLayer->setNeedsDisplay(); |
| + } |
| + } else { |
| + m_squashedLayers.append(paintInfo); |
| + if (m_squashingLayer) |
| + m_squashingLayer->setNeedsDisplay(); |
| + } |
| + layer->setGroupedMapping(this); |
| +} |
| + |
| +void CompositedLayerMapping::finishAccumulatingSquashingLayers(size_t nextSquashedLayerIndex) |
| +{ |
| + ASSERT(compositor()->isLayerSquashingEnabled()); |
| + |
| + // Any additional squashed RenderLayers in the array no longer exist, and removing invalidates the squashingLayer contents. |
| + if (nextSquashedLayerIndex < m_squashedLayers.size()) { |
| + m_squashedLayers.remove(nextSquashedLayerIndex, m_squashedLayers.size() - nextSquashedLayerIndex); |
| + if (m_squashingLayer) |
| + m_squashingLayer->setNeedsDisplay(); |
| + } |
| +} |
| + |
| CompositingLayerType CompositedLayerMapping::compositingLayerType() const |
| { |
| if (m_graphicsLayer->hasContentsLayer()) |