Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (237116 => 237117)
--- trunk/Source/WebCore/rendering/RenderLayer.cpp 2018-10-15 16:02:35 UTC (rev 237116)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp 2018-10-15 16:12:37 UTC (rev 237117)
@@ -271,9 +271,10 @@
RenderLayer::RenderLayer(RenderLayerModelObject& rendererLayerModelObject)
: m_isRenderViewLayer(rendererLayerModelObject.isRenderView())
, m_forcedStackingContext(rendererLayerModelObject.isMedia())
+ , m_zOrderListsDirty(false)
+ , m_normalFlowListDirty(true)
, m_inResizeMode(false)
, m_scrollDimensionsDirty(true)
- , m_normalFlowListDirty(true)
, m_hasSelfPaintingLayerDescendant(false)
, m_hasSelfPaintingLayerDescendantDirty(false)
, m_usedTransparency(false)
@@ -315,13 +316,11 @@
#endif
, m_renderer(rendererLayerModelObject)
{
- m_isNormalFlowOnly = shouldBeNormalFlowOnly();
+ setIsNormalFlowOnly(shouldBeNormalFlowOnly());
+ setIsStackingContext(shouldBeStackingContext());
+
m_isSelfPaintingLayer = shouldBeSelfPaintingLayer();
- // Non-stacking containers should have empty z-order lists. As this is already the case,
- // there is no need to dirty / recompute these lists.
- m_zOrderListsDirty = isStackingContext();
-
if (!renderer().firstChild()) {
m_visibleContentStatusDirty = false;
m_hasVisibleContent = renderer().style().visibility() == Visibility::Visible;
@@ -376,6 +375,350 @@
RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(renderer().renderTreeBeingDestroyed() || !m_first);
}
+void RenderLayer::addChild(RenderLayer* child, RenderLayer* beforeChild)
+{
+ RenderLayer* prevSibling = beforeChild ? beforeChild->previousSibling() : lastChild();
+ if (prevSibling) {
+ child->setPreviousSibling(prevSibling);
+ prevSibling->setNextSibling(child);
+ ASSERT(prevSibling != child);
+ } else
+ setFirstChild(child);
+
+ if (beforeChild) {
+ beforeChild->setPreviousSibling(child);
+ child->setNextSibling(beforeChild);
+ ASSERT(beforeChild != child);
+ } else
+ setLastChild(child);
+
+ child->setParent(this);
+
+ if (child->isNormalFlowOnly())
+ dirtyNormalFlowList();
+
+ if (!child->isNormalFlowOnly() || child->firstChild()) {
+ // Dirty the z-order list in which we are contained. The stackingContext() can be null in the
+ // case where we're building up generated content layers. This is ok, since the lists will start
+ // off dirty in that case anyway.
+ child->dirtyStackingContextZOrderLists();
+ }
+
+ child->updateDescendantDependentFlags();
+ if (child->m_hasVisibleContent || child->m_hasVisibleDescendant)
+ setAncestorChainHasVisibleDescendant();
+
+ if (child->isSelfPaintingLayer() || child->hasSelfPaintingLayerDescendant())
+ setAncestorChainHasSelfPaintingLayerDescendant();
+
+#if ENABLE(CSS_COMPOSITING)
+ if (child->hasBlendMode() || (child->hasNotIsolatedBlendingDescendants() && !child->isolatesBlending()))
+ updateAncestorChainHasBlendingDescendants();
+#endif
+
+ compositor().layerWasAdded(*this, *child);
+}
+
+RenderLayer* RenderLayer::removeChild(RenderLayer* oldChild)
+{
+ if (!renderer().renderTreeBeingDestroyed())
+ compositor().layerWillBeRemoved(*this, *oldChild);
+
+ // remove the child
+ if (oldChild->previousSibling())
+ oldChild->previousSibling()->setNextSibling(oldChild->nextSibling());
+ if (oldChild->nextSibling())
+ oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling());
+
+ if (m_first == oldChild)
+ m_first = oldChild->nextSibling();
+ if (m_last == oldChild)
+ m_last = oldChild->previousSibling();
+
+ if (oldChild->isNormalFlowOnly())
+ dirtyNormalFlowList();
+ if (!oldChild->isNormalFlowOnly() || oldChild->firstChild()) {
+ // Dirty the z-order list in which we are contained. When called via the
+ // reattachment process in removeOnlyThisLayer, the layer may already be disconnected
+ // from the main layer tree, so we need to null-check the |stackingContext| value.
+ oldChild->dirtyStackingContextZOrderLists();
+ }
+
+ oldChild->setPreviousSibling(nullptr);
+ oldChild->setNextSibling(nullptr);
+ oldChild->setParent(nullptr);
+
+ oldChild->updateDescendantDependentFlags();
+ if (oldChild->m_hasVisibleContent || oldChild->m_hasVisibleDescendant)
+ dirtyAncestorChainVisibleDescendantStatus();
+
+ if (oldChild->isSelfPaintingLayer() || oldChild->hasSelfPaintingLayerDescendant())
+ dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
+
+#if ENABLE(CSS_COMPOSITING)
+ if (oldChild->hasBlendMode() || (oldChild->hasNotIsolatedBlendingDescendants() && !oldChild->isolatesBlending()))
+ dirtyAncestorChainHasBlendingDescendants();
+#endif
+
+ return oldChild;
+}
+
+void RenderLayer::insertOnlyThisLayer()
+{
+ if (!m_parent && renderer().parent()) {
+ // We need to connect ourselves when our renderer() has a parent.
+ // Find our enclosingLayer and add ourselves.
+ RenderLayer* parentLayer = renderer().parent()->enclosingLayer();
+ ASSERT(parentLayer);
+ RenderLayer* beforeChild = parentLayer->reflectionLayer() != this ? renderer().parent()->findNextLayer(parentLayer, &renderer()) : nullptr;
+ parentLayer->addChild(this, beforeChild);
+ }
+
+ // Remove all descendant layers from the hierarchy and add them to the new position.
+ for (auto& child : childrenOfType<RenderElement>(renderer()))
+ child.moveLayers(m_parent, this);
+
+ // Clear out all the clip rects.
+ clearClipRectsIncludingDescendants();
+}
+
+void RenderLayer::removeOnlyThisLayer()
+{
+ if (!m_parent)
+ return;
+
+ // Mark that we are about to lose our layer. This makes render tree
+ // walks ignore this layer while we're removing it.
+ renderer().setHasLayer(false);
+
+ compositor().layerWillBeRemoved(*m_parent, *this);
+
+ // Dirty the clip rects.
+ clearClipRectsIncludingDescendants();
+
+ RenderLayer* nextSib = nextSibling();
+
+ // Remove the child reflection layer before moving other child layers.
+ // The reflection layer should not be moved to the parent.
+ if (reflection())
+ removeChild(reflectionLayer());
+
+ // Now walk our kids and reattach them to our parent.
+ RenderLayer* current = m_first;
+ while (current) {
+ RenderLayer* next = current->nextSibling();
+ removeChild(current);
+ m_parent->addChild(current, nextSib);
+ current->setRepaintStatus(NeedsFullRepaint);
+ current = next;
+ }
+
+ // Remove us from the parent.
+ m_parent->removeChild(this);
+ renderer().destroyLayer();
+}
+
+static bool canCreateStackingContext(const RenderLayer& layer)
+{
+ auto& renderer = layer.renderer();
+ return renderer.hasTransformRelatedProperty()
+ || renderer.hasClipPath()
+ || renderer.hasFilter()
+ || renderer.hasMask()
+ || renderer.hasBackdropFilter()
+#if ENABLE(CSS_COMPOSITING)
+ || renderer.hasBlendMode()
+#endif
+ || renderer.isTransparent()
+ || renderer.isPositioned() // Note that this only creates stacking context in conjunction with explicit z-index.
+ || renderer.hasReflection()
+ || renderer.style().hasIsolation()
+#if PLATFORM(IOS)
+ || layer.canUseAcceleratedTouchScrolling()
+#endif
+ || (renderer.style().willChange() && renderer.style().willChange()->canCreateStackingContext());
+}
+
+bool RenderLayer::shouldBeNormalFlowOnly() const
+{
+ if (canCreateStackingContext(*this))
+ return false;
+
+ return renderer().hasOverflowClip()
+ || renderer().isCanvas()
+ || renderer().isVideo()
+ || renderer().isEmbeddedObject()
+ || renderer().isRenderIFrame()
+ || (renderer().style().specifiesColumns() && !isRenderViewLayer())
+ || renderer().isInFlowRenderFragmentedFlow();
+}
+
+bool RenderLayer::shouldBeStackingContext() const
+{
+ // Non-auto z-index always implies stacking context here, because StyleResolver::adjustRenderStyle already adjusts z-index
+ // based on positioning and other criteria.
+ return !renderer().style().hasAutoZIndex() || isRenderViewLayer() || isForcedStackingContext();
+}
+
+bool RenderLayer::setIsNormalFlowOnly(bool isNormalFlowOnly)
+{
+ if (isNormalFlowOnly == m_isNormalFlowOnly)
+ return false;
+
+ m_isNormalFlowOnly = isNormalFlowOnly;
+
+ if (auto* p = parent())
+ p->dirtyNormalFlowList();
+ dirtyStackingContextZOrderLists();
+ return true;
+}
+
+bool RenderLayer::setIsStackingContext(bool isStackingContext)
+{
+ if (isStackingContext == m_isStackingContext)
+ return false;
+
+ m_isStackingContext = isStackingContext;
+
+ dirtyStackingContextZOrderLists();
+ if (isStackingContext)
+ dirtyZOrderLists();
+ else
+ clearZOrderLists();
+
+ return true;
+}
+
+void RenderLayer::setParent(RenderLayer* parent)
+{
+ if (parent == m_parent)
+ return;
+
+ if (m_parent && !renderer().renderTreeBeingDestroyed())
+ compositor().layerWillBeRemoved(*m_parent, *this);
+
+ m_parent = parent;
+
+ if (m_parent && !renderer().renderTreeBeingDestroyed())
+ compositor().layerWasAdded(*m_parent, *this);
+}
+
+void RenderLayer::dirtyZOrderLists()
+{
+ ASSERT(m_layerListMutationAllowed);
+ ASSERT(isStackingContext());
+
+ if (m_posZOrderList)
+ m_posZOrderList->clear();
+ if (m_negZOrderList)
+ m_negZOrderList->clear();
+ m_zOrderListsDirty = true;
+
+ if (!renderer().renderTreeBeingDestroyed())
+ compositor().setCompositingLayersNeedRebuild();
+}
+
+void RenderLayer::dirtyStackingContextZOrderLists()
+{
+ if (auto* sc = stackingContext())
+ sc->dirtyZOrderLists();
+}
+
+void RenderLayer::dirtyNormalFlowList()
+{
+ ASSERT(m_layerListMutationAllowed);
+
+ if (m_normalFlowList)
+ m_normalFlowList->clear();
+ m_normalFlowListDirty = true;
+
+ if (!renderer().renderTreeBeingDestroyed())
+ compositor().setCompositingLayersNeedRebuild();
+}
+
+void RenderLayer::updateNormalFlowList()
+{
+ if (!m_normalFlowListDirty)
+ return;
+
+ ASSERT(m_layerListMutationAllowed);
+
+ for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
+ // Ignore non-overflow layers and reflections.
+ if (child->isNormalFlowOnly() && (!m_reflection || reflectionLayer() != child)) {
+ if (!m_normalFlowList)
+ m_normalFlowList = std::make_unique<Vector<RenderLayer*>>();
+ m_normalFlowList->append(child);
+ }
+ }
+
+ m_normalFlowListDirty = false;
+}
+
+void RenderLayer::rebuildZOrderLists()
+{
+ ASSERT(m_layerListMutationAllowed);
+ ASSERT(isDirtyStackingContext());
+ rebuildZOrderLists(m_posZOrderList, m_negZOrderList);
+ m_zOrderListsDirty = false;
+}
+
+void RenderLayer::rebuildZOrderLists(std::unique_ptr<Vector<RenderLayer*>>& posZOrderList, std::unique_ptr<Vector<RenderLayer*>>& negZOrderList)
+{
+ bool includeHiddenLayers = compositor().inCompositingMode();
+ for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
+ if (!m_reflection || reflectionLayer() != child)
+ child->collectLayers(includeHiddenLayers, posZOrderList, negZOrderList);
+ }
+
+ auto compareZIndex = [] (const RenderLayer* first, const RenderLayer* second) -> bool {
+ return first->zIndex() < second->zIndex();
+ };
+
+ // Sort the two lists.
+ if (posZOrderList)
+ std::stable_sort(posZOrderList->begin(), posZOrderList->end(), compareZIndex);
+
+ if (negZOrderList)
+ std::stable_sort(negZOrderList->begin(), negZOrderList->end(), compareZIndex);
+}
+
+void RenderLayer::collectLayers(bool includeHiddenLayers, std::unique_ptr<Vector<RenderLayer*>>& positiveZOrderList, std::unique_ptr<Vector<RenderLayer*>>& negativeZOrderList)
+{
+ updateDescendantDependentFlags();
+
+ bool isStacking = isStackingContext();
+ // Overflow layers are just painted by their enclosing layers, so they don't get put in zorder lists.
+ bool includeHiddenLayer = includeHiddenLayers || (m_hasVisibleContent || (m_hasVisibleDescendant && isStacking));
+ if (includeHiddenLayer && !isNormalFlowOnly()) {
+ auto& layerList = (zIndex() >= 0) ? positiveZOrderList : negativeZOrderList;
+ if (!layerList)
+ layerList = std::make_unique<Vector<RenderLayer*>>();
+ layerList->append(this);
+ }
+
+ // Recur into our children to collect more layers, but only if we don't establish
+ // a stacking context/container.
+ if ((includeHiddenLayers || m_hasVisibleDescendant) && !isStacking) {
+ for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
+ // Ignore reflections.
+ if (!m_reflection || reflectionLayer() != child)
+ child->collectLayers(includeHiddenLayers, positiveZOrderList, negativeZOrderList);
+ }
+ }
+}
+
+void RenderLayer::updateLayerListsIfNeeded()
+{
+ updateZOrderLists();
+ updateNormalFlowList();
+
+ if (RenderLayer* reflectionLayer = this->reflectionLayer()) {
+ reflectionLayer->updateZOrderLists();
+ reflectionLayer->updateNormalFlowList();
+ }
+}
+
String RenderLayer::name() const
{
StringBuilder name;
@@ -1631,149 +1974,6 @@
return false;
}
-void RenderLayer::addChild(RenderLayer* child, RenderLayer* beforeChild)
-{
- RenderLayer* prevSibling = beforeChild ? beforeChild->previousSibling() : lastChild();
- if (prevSibling) {
- child->setPreviousSibling(prevSibling);
- prevSibling->setNextSibling(child);
- ASSERT(prevSibling != child);
- } else
- setFirstChild(child);
-
- if (beforeChild) {
- beforeChild->setPreviousSibling(child);
- child->setNextSibling(beforeChild);
- ASSERT(beforeChild != child);
- } else
- setLastChild(child);
-
- child->setParent(this);
-
- if (child->isNormalFlowOnly())
- dirtyNormalFlowList();
-
- if (!child->isNormalFlowOnly() || child->firstChild()) {
- // Dirty the z-order list in which we are contained. The stackingContext() can be null in the
- // case where we're building up generated content layers. This is ok, since the lists will start
- // off dirty in that case anyway.
- child->dirtyStackingContextZOrderLists();
- }
-
- child->updateDescendantDependentFlags();
- if (child->m_hasVisibleContent || child->m_hasVisibleDescendant)
- setAncestorChainHasVisibleDescendant();
-
- if (child->isSelfPaintingLayer() || child->hasSelfPaintingLayerDescendant())
- setAncestorChainHasSelfPaintingLayerDescendant();
-
-#if ENABLE(CSS_COMPOSITING)
- if (child->hasBlendMode() || (child->hasNotIsolatedBlendingDescendants() && !child->isolatesBlending()))
- updateAncestorChainHasBlendingDescendants();
-#endif
-
- compositor().layerWasAdded(*this, *child);
-}
-
-RenderLayer* RenderLayer::removeChild(RenderLayer* oldChild)
-{
- if (!renderer().renderTreeBeingDestroyed())
- compositor().layerWillBeRemoved(*this, *oldChild);
-
- // remove the child
- if (oldChild->previousSibling())
- oldChild->previousSibling()->setNextSibling(oldChild->nextSibling());
- if (oldChild->nextSibling())
- oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling());
-
- if (m_first == oldChild)
- m_first = oldChild->nextSibling();
- if (m_last == oldChild)
- m_last = oldChild->previousSibling();
-
- if (oldChild->isNormalFlowOnly())
- dirtyNormalFlowList();
- if (!oldChild->isNormalFlowOnly() || oldChild->firstChild()) {
- // Dirty the z-order list in which we are contained. When called via the
- // reattachment process in removeOnlyThisLayer, the layer may already be disconnected
- // from the main layer tree, so we need to null-check the |stackingContext| value.
- oldChild->dirtyStackingContextZOrderLists();
- }
-
- oldChild->setPreviousSibling(nullptr);
- oldChild->setNextSibling(nullptr);
- oldChild->setParent(nullptr);
-
- oldChild->updateDescendantDependentFlags();
- if (oldChild->m_hasVisibleContent || oldChild->m_hasVisibleDescendant)
- dirtyAncestorChainVisibleDescendantStatus();
-
- if (oldChild->isSelfPaintingLayer() || oldChild->hasSelfPaintingLayerDescendant())
- dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
-
-#if ENABLE(CSS_COMPOSITING)
- if (oldChild->hasBlendMode() || (oldChild->hasNotIsolatedBlendingDescendants() && !oldChild->isolatesBlending()))
- dirtyAncestorChainHasBlendingDescendants();
-#endif
-
- return oldChild;
-}
-
-void RenderLayer::removeOnlyThisLayer()
-{
- if (!m_parent)
- return;
-
- // Mark that we are about to lose our layer. This makes render tree
- // walks ignore this layer while we're removing it.
- renderer().setHasLayer(false);
-
- compositor().layerWillBeRemoved(*m_parent, *this);
-
- // Dirty the clip rects.
- clearClipRectsIncludingDescendants();
-
- RenderLayer* nextSib = nextSibling();
-
- // Remove the child reflection layer before moving other child layers.
- // The reflection layer should not be moved to the parent.
- if (reflection())
- removeChild(reflectionLayer());
-
- // Now walk our kids and reattach them to our parent.
- RenderLayer* current = m_first;
- while (current) {
- RenderLayer* next = current->nextSibling();
- removeChild(current);
- m_parent->addChild(current, nextSib);
- current->setRepaintStatus(NeedsFullRepaint);
- current = next;
- }
-
- // Remove us from the parent.
- m_parent->removeChild(this);
- renderer().destroyLayer();
-}
-
-void RenderLayer::insertOnlyThisLayer()
-{
- if (!m_parent && renderer().parent()) {
- // We need to connect ourselves when our renderer() has a parent.
- // Find our enclosingLayer and add ourselves.
- RenderLayer* parentLayer = renderer().parent()->enclosingLayer();
- ASSERT(parentLayer);
- RenderLayer* beforeChild = parentLayer->reflectionLayer() != this ? renderer().parent()->findNextLayer(parentLayer, &renderer()) : nullptr;
- parentLayer->addChild(this, beforeChild);
- }
-
- // Remove all descendant layers from the hierarchy and add them to the new position.
- for (auto& child : childrenOfType<RenderElement>(renderer()))
- child.moveLayers(m_parent, this);
-
- // Clear out all the clip rects.
- clearClipRectsIncludingDescendants();
-}
-
void RenderLayer::convertToPixelSnappedLayerCoords(const RenderLayer* ancestorLayer, IntPoint& roundedLocation, ColumnOffsetAdjustment adjustForColumns) const
{
LayoutPoint location = convertToLayerCoords(ancestorLayer, roundedLocation, adjustForColumns);
@@ -3976,12 +4176,6 @@
restoreClip(originalContext, paintingInfo, backgroundRect);
}
-// Helper for the sorting of layers by z-index.
-static inline bool compareZIndex(RenderLayer* first, RenderLayer* second)
-{
- return first->zIndex() < second->zIndex();
-}
-
void RenderLayer::paintLayerContents(GraphicsContext& context, const LayerPaintingInfo& paintingInfo, OptionSet<PaintLayerFlag> paintFlags)
{
ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant());
@@ -5810,137 +6004,6 @@
return false;
}
-void RenderLayer::setParent(RenderLayer* parent)
-{
- if (parent == m_parent)
- return;
-
- if (m_parent && !renderer().renderTreeBeingDestroyed())
- compositor().layerWillBeRemoved(*m_parent, *this);
-
- m_parent = parent;
-
- if (m_parent && !renderer().renderTreeBeingDestroyed())
- compositor().layerWasAdded(*m_parent, *this);
-}
-
-void RenderLayer::dirtyZOrderLists()
-{
- ASSERT(m_layerListMutationAllowed);
- ASSERT(isStackingContext());
-
- if (m_posZOrderList)
- m_posZOrderList->clear();
- if (m_negZOrderList)
- m_negZOrderList->clear();
- m_zOrderListsDirty = true;
-
- if (!renderer().renderTreeBeingDestroyed())
- compositor().setCompositingLayersNeedRebuild();
-}
-
-void RenderLayer::dirtyStackingContextZOrderLists()
-{
- RenderLayer* sc = stackingContext();
- if (sc)
- sc->dirtyZOrderLists();
-}
-
-void RenderLayer::dirtyNormalFlowList()
-{
- ASSERT(m_layerListMutationAllowed);
-
- if (m_normalFlowList)
- m_normalFlowList->clear();
- m_normalFlowListDirty = true;
-
- if (!renderer().renderTreeBeingDestroyed())
- compositor().setCompositingLayersNeedRebuild();
-}
-
-void RenderLayer::rebuildZOrderLists()
-{
- ASSERT(m_layerListMutationAllowed);
- ASSERT(isDirtyStackingContext());
- rebuildZOrderLists(m_posZOrderList, m_negZOrderList);
- m_zOrderListsDirty = false;
-}
-
-void RenderLayer::rebuildZOrderLists(std::unique_ptr<Vector<RenderLayer*>>& posZOrderList, std::unique_ptr<Vector<RenderLayer*>>& negZOrderList)
-{
- bool includeHiddenLayers = compositor().inCompositingMode();
- for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
- if (!m_reflection || reflectionLayer() != child)
- child->collectLayers(includeHiddenLayers, posZOrderList, negZOrderList);
-
- // Sort the two lists.
- if (posZOrderList)
- std::stable_sort(posZOrderList->begin(), posZOrderList->end(), compareZIndex);
-
- if (negZOrderList)
- std::stable_sort(negZOrderList->begin(), negZOrderList->end(), compareZIndex);
-}
-
-void RenderLayer::updateNormalFlowList()
-{
- if (!m_normalFlowListDirty)
- return;
-
- ASSERT(m_layerListMutationAllowed);
-
- for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
- // Ignore non-overflow layers and reflections.
- if (child->isNormalFlowOnly() && (!m_reflection || reflectionLayer() != child)) {
- if (!m_normalFlowList)
- m_normalFlowList = std::make_unique<Vector<RenderLayer*>>();
- m_normalFlowList->append(child);
- }
- }
-
- m_normalFlowListDirty = false;
-}
-
-void RenderLayer::collectLayers(bool includeHiddenLayers, std::unique_ptr<Vector<RenderLayer*>>& posBuffer, std::unique_ptr<Vector<RenderLayer*>>& negBuffer)
-{
- updateDescendantDependentFlags();
-
- bool isStacking = isStackingContext();
- // Overflow layers are just painted by their enclosing layers, so they don't get put in zorder lists.
- bool includeHiddenLayer = includeHiddenLayers || (m_hasVisibleContent || (m_hasVisibleDescendant && isStacking));
- if (includeHiddenLayer && !isNormalFlowOnly()) {
- // Determine which buffer the child should be in.
- std::unique_ptr<Vector<RenderLayer*>>& buffer = (zIndex() >= 0) ? posBuffer : negBuffer;
-
- // Create the buffer if it doesn't exist yet.
- if (!buffer)
- buffer = std::make_unique<Vector<RenderLayer*>>();
-
- // Append ourselves at the end of the appropriate buffer.
- buffer->append(this);
- }
-
- // Recur into our children to collect more layers, but only if we don't establish
- // a stacking context/container.
- if ((includeHiddenLayers || m_hasVisibleDescendant) && !isStacking) {
- for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
- // Ignore reflections.
- if (!m_reflection || reflectionLayer() != child)
- child->collectLayers(includeHiddenLayers, posBuffer, negBuffer);
- }
- }
-}
-
-void RenderLayer::updateLayerListsIfNeeded()
-{
- updateZOrderLists();
- updateNormalFlowList();
-
- if (RenderLayer* reflectionLayer = this->reflectionLayer()) {
- reflectionLayer->updateZOrderLists();
- reflectionLayer->updateNormalFlowList();
- }
-}
-
void RenderLayer::updateCompositingAndLayerListsIfNeeded()
{
if (compositor().inCompositingMode()) {
@@ -5997,41 +6060,6 @@
}
}
-static bool createsStackingContext(const RenderLayer& layer)
-{
- auto& renderer = layer.renderer();
- return renderer.hasTransformRelatedProperty()
- || renderer.hasClipPath()
- || renderer.hasFilter()
- || renderer.hasMask()
- || renderer.hasBackdropFilter()
-#if ENABLE(CSS_COMPOSITING)
- || renderer.hasBlendMode()
-#endif
- || renderer.isTransparent()
- || renderer.isPositioned()
- || renderer.hasReflection()
- || renderer.style().hasIsolation()
-#if PLATFORM(IOS)
- || layer.canUseAcceleratedTouchScrolling()
-#endif
- || (renderer.style().willChange() && renderer.style().willChange()->canCreateStackingContext());
-}
-
-bool RenderLayer::shouldBeNormalFlowOnly() const
-{
- if (createsStackingContext(*this))
- return false;
-
- return renderer().hasOverflowClip()
- || renderer().isCanvas()
- || renderer().isVideo()
- || renderer().isEmbeddedObject()
- || renderer().isRenderIFrame()
- || (renderer().style().specifiesColumns() && !isRenderViewLayer())
- || renderer().isInFlowRenderFragmentedFlow();
-}
-
bool RenderLayer::shouldBeSelfPaintingLayer() const
{
if (!isNormalFlowOnly())
@@ -6184,49 +6212,10 @@
PaintedContentRequest localRequest;
if (!request)
request = &localRequest;
+
return hasNonEmptyChildRenderers(*request);
}
-void RenderLayer::updateStackingContextsAfterStyleChange(const RenderStyle* oldStyle)
-{
- if (!oldStyle)
- return;
-
- bool wasStackingContext = isStackingContext(oldStyle);
- bool isStackingContext = this->isStackingContext();
- if (isStackingContext != wasStackingContext) {
- dirtyStackingContextZOrderLists();
- if (isStackingContext)
- dirtyZOrderLists();
- else
- clearZOrderLists();
-
-#if ENABLE(CSS_COMPOSITING)
- if (parent()) {
- if (isStackingContext) {
- if (!hasNotIsolatedBlendingDescendantsStatusDirty() && hasNotIsolatedBlendingDescendants())
- parent()->dirtyAncestorChainHasBlendingDescendants();
- } else {
- if (hasNotIsolatedBlendingDescendantsStatusDirty())
- parent()->dirtyAncestorChainHasBlendingDescendants();
- else if (hasNotIsolatedBlendingDescendants())
- parent()->updateAncestorChainHasBlendingDescendants();
- }
- }
-#endif
-
- return;
- }
-
- // FIXME: RenderLayer already handles visibility changes through our visiblity dirty bits. This logic could
- // likely be folded along with the rest.
- if (oldStyle->zIndex() != renderer().style().zIndex() || oldStyle->visibility() != renderer().style().visibility()) {
- dirtyStackingContextZOrderLists();
- if (isStackingContext)
- dirtyZOrderLists();
- }
-}
-
void RenderLayer::updateScrollbarsAfterStyleChange(const RenderStyle* oldStyle)
{
// Overflow are a box concept.
@@ -6261,26 +6250,42 @@
void RenderLayer::styleChanged(StyleDifference diff, const RenderStyle* oldStyle)
{
- bool isNormalFlowOnly = shouldBeNormalFlowOnly();
- if (isNormalFlowOnly != m_isNormalFlowOnly) {
- m_isNormalFlowOnly = isNormalFlowOnly;
- RenderLayer* p = parent();
- if (p)
- p->dirtyNormalFlowList();
- dirtyStackingContextZOrderLists();
+ setIsNormalFlowOnly(shouldBeNormalFlowOnly());
+
+ if (setIsStackingContext(shouldBeStackingContext())) {
+#if ENABLE(CSS_COMPOSITING)
+ if (parent()) {
+ if (isStackingContext()) {
+ if (!hasNotIsolatedBlendingDescendantsStatusDirty() && hasNotIsolatedBlendingDescendants())
+ parent()->dirtyAncestorChainHasBlendingDescendants();
+ } else {
+ if (hasNotIsolatedBlendingDescendantsStatusDirty())
+ parent()->dirtyAncestorChainHasBlendingDescendants();
+ else if (hasNotIsolatedBlendingDescendants())
+ parent()->updateAncestorChainHasBlendingDescendants();
+ }
+ }
+#endif
}
+ // FIXME: RenderLayer already handles visibility changes through our visiblity dirty bits. This logic could
+ // likely be folded along with the rest.
+ if (oldStyle) {
+ if (oldStyle->zIndex() != renderer().style().zIndex() || oldStyle->visibility() != renderer().style().visibility()) {
+ dirtyStackingContextZOrderLists();
+ if (isStackingContext())
+ dirtyZOrderLists();
+ }
+ }
+
if (renderer().isHTMLMarquee() && renderer().style().marqueeBehavior() != MarqueeBehavior::None && renderer().isBox()) {
if (!m_marquee)
m_marquee = std::make_unique<RenderMarquee>(this);
m_marquee->updateMarqueeStyle();
- }
- else if (m_marquee) {
+ } else if (m_marquee)
m_marquee = nullptr;
- }
updateScrollbarsAfterStyleChange(oldStyle);
- updateStackingContextsAfterStyleChange(oldStyle);
// Overlay scrollbars can make this layer self-painting so we need
// to recompute the bit once scrollbars have been updated.
updateSelfPaintingLayer();
Modified: trunk/Source/WebCore/rendering/RenderLayer.h (237116 => 237117)
--- trunk/Source/WebCore/rendering/RenderLayer.h 2018-10-15 16:02:35 UTC (rev 237116)
+++ trunk/Source/WebCore/rendering/RenderLayer.h 2018-10-15 16:12:37 UTC (rev 237117)
@@ -142,8 +142,10 @@
#endif
String name() const;
+ Page& page() const { return renderer().page(); }
RenderLayerModelObject& renderer() const { return m_renderer; }
RenderBox* renderBox() const { return is<RenderBox>(renderer()) ? &downcast<RenderBox>(renderer()) : nullptr; }
+
RenderLayer* parent() const { return m_parent; }
RenderLayer* previousSibling() const { return m_previous; }
RenderLayer* nextSibling() const { return m_next; }
@@ -151,14 +153,94 @@
RenderLayer* lastChild() const { return m_last; }
bool isDescendantOf(const RenderLayer&) const;
+ // This does an ancestor tree walk. Avoid it!
+ const RenderLayer* root() const
+ {
+ const RenderLayer* curr = this;
+ while (curr->parent())
+ curr = curr->parent();
+ return curr;
+ }
+
void addChild(RenderLayer* newChild, RenderLayer* beforeChild = nullptr);
RenderLayer* removeChild(RenderLayer*);
- Page& page() const { return renderer().page(); }
-
+ void insertOnlyThisLayer();
void removeOnlyThisLayer();
- void insertOnlyThisLayer();
+ bool isNormalFlowOnly() const { return m_isNormalFlowOnly; }
+ bool isStackingContext() const { return m_isStackingContext; }
+
+ // Gets the enclosing stacking context for this layer, excluding this layer itself.
+ RenderLayer* stackingContext() const;
+
+ // Gets the enclosing stacking container for this layer, possibly the layer
+ // itself, if it is a stacking container.
+ RenderLayer* enclosingStackingContext() { return isStackingContext() ? this : stackingContext(); }
+
+ void dirtyNormalFlowList();
+ void dirtyZOrderLists();
+ void dirtyStackingContextZOrderLists();
+
+ class LayerList {
+ friend class RenderLayer;
+ public:
+ using iterator = RenderLayer**;
+ using const_iterator = RenderLayer * const *;
+ using reverse_iterator = std::reverse_iterator<iterator>;
+ using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+
+ iterator begin() { return m_layerList ? m_layerList->begin() : nullptr; }
+ iterator end() { return m_layerList ? m_layerList->end() : nullptr; }
+
+ reverse_iterator rbegin() { return reverse_iterator(end()); }
+ reverse_iterator rend() { return reverse_iterator(begin()); }
+
+ const_iterator begin() const { return m_layerList ? m_layerList->begin() : nullptr; }
+ const_iterator end() const { return m_layerList ? m_layerList->end() : nullptr; }
+
+ const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
+ const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
+
+ size_t size() const { return m_layerList ? m_layerList->size() : 0; }
+
+ private:
+ LayerList(Vector<RenderLayer*>* layerList)
+ : m_layerList(layerList)
+ {
+ }
+
+ Vector<RenderLayer*>* m_layerList;
+ };
+
+ LayerList normalFlowLayers() const
+ {
+ ASSERT(!m_normalFlowListDirty);
+ return LayerList(m_normalFlowList.get());
+ }
+
+ LayerList positiveZOrderLayers() const
+ {
+ ASSERT(!m_zOrderListsDirty);
+ ASSERT(isStackingContext() || !m_posZOrderList);
+ return LayerList(m_posZOrderList.get());
+ }
+
+ bool hasNegativeZOrderLayers() const
+ {
+ return m_negZOrderList && m_negZOrderList->size();
+ }
+
+ LayerList negativeZOrderLayers() const
+ {
+ ASSERT(!m_zOrderListsDirty);
+ ASSERT(isStackingContext() || !m_negZOrderList);
+ return LayerList(m_negZOrderList.get());
+ }
+
+ // Update our normal and z-index lists.
+ void updateLayerListsIfNeeded();
+
void repaintIncludingDescendants();
// Indicate that the layer contents need to be repainted. Only has an effect
@@ -173,7 +255,6 @@
RenderMarquee* marquee() const { return m_marquee.get(); }
- bool isNormalFlowOnly() const { return m_isNormalFlowOnly; }
bool isSelfPaintingLayer() const { return m_isSelfPaintingLayer; }
bool cannotBlitToWindow() const;
@@ -185,14 +266,6 @@
RenderReplica* reflection() const { return m_reflection.get(); }
RenderLayer* reflectionLayer() const;
- const RenderLayer* root() const
- {
- const RenderLayer* curr = this;
- while (curr->parent())
- curr = curr->parent();
- return curr;
- }
-
const LayoutPoint& location() const { return m_topLeft; }
void setLocation(const LayoutPoint& p) { m_topLeft = p; }
@@ -294,6 +367,7 @@
void setInResizeMode(bool b) { m_inResizeMode = b; }
bool isRenderViewLayer() const { return m_isRenderViewLayer; }
+ bool isForcedStackingContext() const { return m_forcedStackingContext; }
RenderLayerCompositor& compositor() const;
@@ -304,13 +378,13 @@
bool canRender3DTransforms() const;
enum UpdateLayerPositionsFlag {
- CheckForRepaint = 1 << 0,
- NeedsFullRepaintInBacking = 1 << 1,
- IsCompositingUpdateRoot = 1 << 2,
- UpdateCompositingLayers = 1 << 3,
- UpdatePagination = 1 << 4,
- SeenTransformedLayer = 1 << 5,
- Seen3DTransformedLayer = 1 << 6
+ CheckForRepaint = 1 << 0,
+ NeedsFullRepaintInBacking = 1 << 1,
+ IsCompositingUpdateRoot = 1 << 2,
+ UpdateCompositingLayers = 1 << 3,
+ UpdatePagination = 1 << 4,
+ SeenTransformedLayer = 1 << 5,
+ Seen3DTransformedLayer = 1 << 6,
};
static constexpr OptionSet<UpdateLayerPositionsFlag> updateLayerPositionsDefaultFlags() { return { CheckForRepaint, IsCompositingUpdateRoot, UpdateCompositingLayers }; }
@@ -343,80 +417,6 @@
void clearBlockSelectionGapsBounds();
void repaintBlockSelectionGaps();
- // A stacking context is a layer that has a non-auto z-index.
- bool isStackingContext() const { return isStackingContext(&renderer().style()); }
-
- // Gets the enclosing stacking context for this layer, excluding this layer itself.
- RenderLayer* stackingContext() const;
-
- // Gets the enclosing stacking container for this layer, possibly the layer
- // itself, if it is a stacking container.
- RenderLayer* enclosingStackingContext() { return isStackingContext() ? this : stackingContext(); }
-
- void dirtyNormalFlowList();
-
- void dirtyZOrderLists();
- void dirtyStackingContextZOrderLists();
-
- class LayerList {
- friend class RenderLayer;
- public:
- using iterator = RenderLayer**;
- using const_iterator = RenderLayer * const *;
- using reverse_iterator = std::reverse_iterator<iterator>;
- using const_reverse_iterator = std::reverse_iterator<const_iterator>;
-
- iterator begin() { return m_layerList ? m_layerList->begin() : nullptr; }
- iterator end() { return m_layerList ? m_layerList->end() : nullptr; }
-
- reverse_iterator rbegin() { return reverse_iterator(end()); }
- reverse_iterator rend() { return reverse_iterator(begin()); }
-
- const_iterator begin() const { return m_layerList ? m_layerList->begin() : nullptr; }
- const_iterator end() const { return m_layerList ? m_layerList->end() : nullptr; }
-
- const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
- const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
-
- size_t size() const { return m_layerList ? m_layerList->size() : 0; }
-
- private:
- LayerList(Vector<RenderLayer*>* layerList)
- : m_layerList(layerList)
- {
- }
-
- Vector<RenderLayer*>* m_layerList;
- };
-
- LayerList normalFlowLayers() const
- {
- ASSERT(!m_normalFlowListDirty);
- return LayerList(m_normalFlowList.get());
- }
-
- LayerList positiveZOrderLayers() const
- {
- ASSERT(!m_zOrderListsDirty);
- ASSERT(isStackingContext() || !m_posZOrderList);
- return LayerList(m_posZOrderList.get());
- }
-
- bool hasNegativeZOrderLayers() const
- {
- return m_negZOrderList && m_negZOrderList->size();
- }
-
- LayerList negativeZOrderLayers() const
- {
- ASSERT(!m_zOrderListsDirty);
- ASSERT(isStackingContext() || !m_negZOrderList);
- return LayerList(m_negZOrderList.get());
- }
-
- // Update our normal and z-index lists.
- void updateLayerListsIfNeeded();
-
// FIXME: We should ASSERT(!m_visibleContentStatusDirty) here, but see https://bugs.webkit.org/show_bug.cgi?id=71044
// ditto for hasVisibleDescendant(), see https://bugs.webkit.org/show_bug.cgi?id=71277
bool hasVisibleContent() const { return m_hasVisibleContent; }
@@ -738,6 +738,30 @@
bool paintingFrequently() const { return m_paintFrequencyTracker.paintingFrequently(); }
private:
+
+ void setNextSibling(RenderLayer* next) { m_next = next; }
+ void setPreviousSibling(RenderLayer* prev) { m_previous = prev; }
+ void setParent(RenderLayer*);
+ void setFirstChild(RenderLayer* first) { m_first = first; }
+ void setLastChild(RenderLayer* last) { m_last = last; }
+
+ bool shouldBeNormalFlowOnly() const;
+ bool shouldBeStackingContext() const;
+
+ // Return true if changed.
+ bool setIsNormalFlowOnly(bool);
+ bool setIsStackingContext(bool);
+
+ bool isDirtyStackingContext() const { return m_zOrderListsDirty && isStackingContext(); }
+
+ void updateZOrderLists();
+ void rebuildZOrderLists();
+ void rebuildZOrderLists(std::unique_ptr<Vector<RenderLayer*>>&, std::unique_ptr<Vector<RenderLayer*>>&);
+ void collectLayers(bool includeHiddenLayers, std::unique_ptr<Vector<RenderLayer*>>&, std::unique_ptr<Vector<RenderLayer*>>&);
+ void clearZOrderLists();
+
+ void updateNormalFlowList();
+
struct LayerPaintingInfo {
LayerPaintingInfo(RenderLayer* inRootLayer, const LayoutRect& inDirtyRect, OptionSet<PaintBehavior> inPaintBehavior, const LayoutSize& inSubpixelOffset, RenderObject* inSubtreePaintRoot = nullptr, OverlapTestRequestMap* inOverlapTestRequests = nullptr, bool inRequireSecurityOriginAccessForWidgets = false)
: rootLayer(inRootLayer)
@@ -766,20 +790,7 @@
void calculateClipRects(const ClipRectsContext&, ClipRects&) const;
ClipRects* clipRects(const ClipRectsContext&) const;
- void updateZOrderLists();
- void rebuildZOrderLists();
- void rebuildZOrderLists(std::unique_ptr<Vector<RenderLayer*>>&, std::unique_ptr<Vector<RenderLayer*>>&);
- void collectLayers(bool includeHiddenLayers, std::unique_ptr<Vector<RenderLayer*>>&, std::unique_ptr<Vector<RenderLayer*>>&);
- void clearZOrderLists();
- void updateNormalFlowList();
-
- // Non-auto z-index always implies stacking context here, because StyleResolver::adjustRenderStyle already adjusts z-index
- // based on positioning and other criteria.
- bool isStackingContext(const RenderStyle* style) const { return !style->hasAutoZIndex() || isRenderViewLayer() || m_forcedStackingContext; }
-
- bool isDirtyStackingContext() const { return m_zOrderListsDirty && isStackingContext(); }
-
void setAncestorChainHasSelfPaintingLayerDescendant();
void dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
@@ -795,7 +806,6 @@
bool shouldRepaintAfterLayout() const;
void updateSelfPaintingLayer();
- void updateStackingContextsAfterStyleChange(const RenderStyle* oldStyle);
void updateScrollbarsAfterStyleChange(const RenderStyle* oldStyle);
void updateScrollbarsAfterLayout();
@@ -806,10 +816,10 @@
void updateLayerPositions(RenderGeometryMap* = nullptr, OptionSet<UpdateLayerPositionsFlag> = updateLayerPositionsDefaultFlags());
enum UpdateLayerPositionsAfterScrollFlag {
- IsOverflowScroll = 1 << 0,
- HasSeenViewportConstrainedAncestor = 1 << 1,
- HasSeenAncestorWithOverflowClip = 1 << 2,
- HasChangedAncestor = 1 << 3
+ IsOverflowScroll = 1 << 0,
+ HasSeenViewportConstrainedAncestor = 1 << 1,
+ HasSeenAncestorWithOverflowClip = 1 << 2,
+ HasChangedAncestor = 1 << 3,
};
void updateLayerPositionsAfterScroll(RenderGeometryMap*, OptionSet<UpdateLayerPositionsAfterScrollFlag> = { });
@@ -817,12 +827,6 @@
RenderLayer* enclosingPaginationLayerInSubtree(const RenderLayer* rootLayer, PaginationInclusionMode) const;
- void setNextSibling(RenderLayer* next) { m_next = next; }
- void setPreviousSibling(RenderLayer* prev) { m_previous = prev; }
- void setParent(RenderLayer* parent);
- void setFirstChild(RenderLayer* first) { m_first = first; }
- void setLastChild(RenderLayer* last) { m_last = last; }
-
LayoutPoint renderBoxLocation() const { return is<RenderBox>(renderer()) ? downcast<RenderBox>(renderer()).location() : LayoutPoint(); }
void updateCompositingAndLayerListsIfNeeded();
@@ -893,7 +897,6 @@
bool showsOverflowControls() const;
- bool shouldBeNormalFlowOnly() const;
bool shouldBeSelfPaintingLayer() const;
int scrollOffset(ScrollbarOrientation) const override;
@@ -1032,14 +1035,16 @@
const bool m_isRenderViewLayer : 1;
const bool m_forcedStackingContext : 1;
+ bool m_isNormalFlowOnly : 1;
+ bool m_isStackingContext : 1;
+
+ bool m_zOrderListsDirty : 1;
+ bool m_normalFlowListDirty: 1;
+
// Keeps track of whether the layer is currently resizing, so events can cause resizing to start and stop.
bool m_inResizeMode : 1;
bool m_scrollDimensionsDirty : 1;
- bool m_zOrderListsDirty : 1;
- bool m_normalFlowListDirty: 1;
- bool m_isNormalFlowOnly : 1;
-
bool m_isSelfPaintingLayer : 1;
// If have no self-painting descendants, we don't have to walk our children during painting. This can lead to
@@ -1102,6 +1107,16 @@
RenderLayer* m_first { nullptr };
RenderLayer* m_last { nullptr };
+ // For layers that establish stacking contexts, m_posZOrderList holds a sorted list of all the
+ // descendant layers within the stacking context that have z-indices of 0 or greater
+ // (auto will count as 0). m_negZOrderList holds descendants within our stacking context with negative
+ // z-indices.
+ std::unique_ptr<Vector<RenderLayer*>> m_posZOrderList;
+ std::unique_ptr<Vector<RenderLayer*>> m_negZOrderList;
+
+ // This list contains child layers that cannot create stacking contexts and appear in normal flow order.
+ std::unique_ptr<Vector<RenderLayer*>> m_normalFlowList;
+
// Our current relative position offset.
LayoutSize m_offsetForInFlowPosition;
@@ -1121,17 +1136,6 @@
RefPtr<Scrollbar> m_hBar;
RefPtr<Scrollbar> m_vBar;
- // For layers that establish stacking contexts, m_posZOrderList holds a sorted list of all the
- // descendant layers within the stacking context that have z-indices of 0 or greater
- // (auto will count as 0). m_negZOrderList holds descendants within our stacking context with negative
- // z-indices.
- std::unique_ptr<Vector<RenderLayer*>> m_posZOrderList;
- std::unique_ptr<Vector<RenderLayer*>> m_negZOrderList;
-
- // This list contains child layers that cannot create stacking contexts. For now it is just
- // overflow layers, but that may change in the future.
- std::unique_ptr<Vector<RenderLayer*>> m_normalFlowList;
-
std::unique_ptr<ClipRectsCache> m_clipRectsCache;
IntPoint m_cachedOverlayScrollbarOffset;