| Index: Source/core/rendering/CompositedLayerMapping.cpp
|
| diff --git a/Source/core/rendering/CompositedLayerMapping.cpp b/Source/core/rendering/CompositedLayerMapping.cpp
|
| index 8d940b8ff2036435a42a8f77f37dc2b4d2a93877..fd291fd26470125364fe11dd41d30324cc110e74 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();
|
|
|
| @@ -827,6 +876,7 @@ void CompositedLayerMapping::registerScrollingLayers()
|
| // layer is further up in the hierarchy, we need to avoid marking the root render view
|
| // layer as a container.
|
| bool isContainer = m_owningLayer->hasTransform() && !m_owningLayer->isRootLayer();
|
| + // FIXME: we should make certain that childForSuperLayers will never be the m_squashingContainmentLayer here
|
| scrollingCoordinator->setLayerIsContainerForFixedPositionLayers(childForSuperlayers(), isContainer);
|
| }
|
|
|
| @@ -868,6 +918,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)
|
| @@ -1206,8 +1271,10 @@ static void updateScrollParentForGraphicsLayer(GraphicsLayer* layer, GraphicsLay
|
|
|
| void CompositedLayerMapping::updateScrollParent(RenderLayer* scrollParent)
|
| {
|
| +
|
| if (ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer)) {
|
| GraphicsLayer* topmostLayer = childForSuperlayers();
|
| + updateScrollParentForGraphicsLayer(m_squashingContainmentLayer.get(), topmostLayer, scrollParent, scrollingCoordinator);
|
| updateScrollParentForGraphicsLayer(m_ancestorClippingLayer.get(), topmostLayer, scrollParent, scrollingCoordinator);
|
| updateScrollParentForGraphicsLayer(m_graphicsLayer.get(), topmostLayer, scrollParent, scrollingCoordinator);
|
| }
|
| @@ -1219,6 +1286,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;
|
| @@ -1560,6 +1670,9 @@ GraphicsLayer* CompositedLayerMapping::parentForSublayers() const
|
|
|
| GraphicsLayer* CompositedLayerMapping::childForSuperlayers() const
|
| {
|
| + if (m_squashingContainmentLayer)
|
| + return m_squashingContainmentLayer.get();
|
| +
|
| if (m_ancestorClippingLayer)
|
| return m_ancestorClippingLayer.get();
|
|
|
| @@ -1611,12 +1724,11 @@ void CompositedLayerMapping::paintsIntoCompositedAncestorChanged()
|
| void CompositedLayerMapping::setBlendMode(blink::WebBlendMode blendMode)
|
| {
|
| if (m_ancestorClippingLayer) {
|
| - ASSERT(childForSuperlayers() == m_ancestorClippingLayer.get());
|
| + m_ancestorClippingLayer->setBlendMode(blendMode);
|
| m_graphicsLayer->setBlendMode(blink::WebBlendModeNormal);
|
| } else {
|
| - ASSERT(childForSuperlayers() == m_graphicsLayer.get());
|
| + m_graphicsLayer->setBlendMode(blendMode);
|
| }
|
| - childForSuperlayers()->setBlendMode(blendMode);
|
| }
|
|
|
| void CompositedLayerMapping::setContentsNeedDisplay()
|
| @@ -1734,14 +1846,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);
|
|
|
| @@ -1788,6 +1906,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()) {
|
| @@ -1983,6 +2105,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())
|
|
|