Hide RenderLayer z-order and normal flow lists behind iterators
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 12 Oct 2018 00:23:08 +0000 (00:23 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 12 Oct 2018 00:23:08 +0000 (00:23 +0000)
https://bugs.webkit.org/show_bug.cgi?id=190457

Source/WebCore:

Reviewed by Zalan Bujtas.

Expose the positive z-order, negative z-order and normal flow lists
from RenderLayer as iterators rather than vectors of raw pointers.

This hides the fact that the vectors can be null, and allows for easier casting in future.

* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::update3DTransformedDescendantStatus):
(WebCore::RenderLayer::paintLayerContents):
(WebCore::RenderLayer::paintList):
(WebCore::RenderLayer::hitTestLayer):
(WebCore::RenderLayer::hitTestList):
(WebCore::RenderLayer::calculateClipRects const):
* rendering/RenderLayer.h:
* rendering/RenderLayerBacking.cpp:
(WebCore::traverseVisibleNonCompositedDescendantLayers):
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::addToOverlapMapRecursive):
(WebCore::RenderLayerCompositor::computeCompositingRequirements):
(WebCore::RenderLayerCompositor::rebuildCompositingLayerTree):
(WebCore::RenderLayerCompositor::updateLayerTreeGeometry):
(WebCore::RenderLayerCompositor::updateCompositingDescendantGeometry):
(WebCore::RenderLayerCompositor::recursiveRepaintLayer):
(WebCore::RenderLayerCompositor::needsContentsCompositingLayer const):
(WebCore::RenderLayerCompositor::layerHas3DContent const):
* rendering/RenderTreeAsText.cpp:
(WebCore::writeLayers):

Source/WebKit:

Reviewed by Zalan Bujtas.

Expose the positive z-order, negative z-order and normal flow lists
from RenderLayer as iterators rather than vectors of raw pointers.

Use a lambda function to get access to the private constructor, while not having
to refer to the nested RenderLayer::LayerIterator class in the header.

* Shared/WebRenderLayer.cpp:
(WebKit::WebRenderLayer::WebRenderLayer):
(WebKit::WebRenderLayer::createArrayFromLayerList): Deleted.
* Shared/WebRenderLayer.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@237058 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderLayer.cpp
Source/WebCore/rendering/RenderLayer.h
Source/WebCore/rendering/RenderLayerBacking.cpp
Source/WebCore/rendering/RenderLayerCompositor.cpp
Source/WebCore/rendering/RenderTreeAsText.cpp
Source/WebKit/ChangeLog
Source/WebKit/Shared/WebRenderLayer.cpp
Source/WebKit/Shared/WebRenderLayer.h

index 3589a5d..1291d46 100644 (file)
@@ -1,3 +1,37 @@
+2018-10-10  Simon Fraser  <simon.fraser@apple.com>
+
+        Hide RenderLayer z-order and normal flow lists behind iterators
+        https://bugs.webkit.org/show_bug.cgi?id=190457
+
+        Reviewed by Zalan Bujtas.
+
+        Expose the positive z-order, negative z-order and normal flow lists
+        from RenderLayer as iterators rather than vectors of raw pointers.
+        
+        This hides the fact that the vectors can be null, and allows for easier casting in future.
+
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::update3DTransformedDescendantStatus):
+        (WebCore::RenderLayer::paintLayerContents):
+        (WebCore::RenderLayer::paintList):
+        (WebCore::RenderLayer::hitTestLayer):
+        (WebCore::RenderLayer::hitTestList):
+        (WebCore::RenderLayer::calculateClipRects const):
+        * rendering/RenderLayer.h:
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::traverseVisibleNonCompositedDescendantLayers):
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::addToOverlapMapRecursive):
+        (WebCore::RenderLayerCompositor::computeCompositingRequirements):
+        (WebCore::RenderLayerCompositor::rebuildCompositingLayerTree):
+        (WebCore::RenderLayerCompositor::updateLayerTreeGeometry):
+        (WebCore::RenderLayerCompositor::updateCompositingDescendantGeometry):
+        (WebCore::RenderLayerCompositor::recursiveRepaintLayer):
+        (WebCore::RenderLayerCompositor::needsContentsCompositingLayer const):
+        (WebCore::RenderLayerCompositor::layerHas3DContent const):
+        * rendering/RenderTreeAsText.cpp:
+        (WebCore::writeLayers):
+
 2018-10-11  Don Olmstead  <don.olmstead@sony.com>
 
         Add Houdini specs to features.json
index 1d63713..c8e677d 100644 (file)
@@ -1100,16 +1100,12 @@ bool RenderLayer::update3DTransformedDescendantStatus()
 
         // Transformed or preserve-3d descendants can only be in the z-order lists, not
         // in the normal flow list, so we only need to check those.
-        if (auto* positiveZOrderList = posZOrderList()) {
-            for (auto* layer : *positiveZOrderList)
-                m_has3DTransformedDescendant |= layer->update3DTransformedDescendantStatus();
-        }
+        for (auto* layer : positiveZOrderLayers())
+            m_has3DTransformedDescendant |= layer->update3DTransformedDescendantStatus();
 
         // Now check our negative z-index children.
-        if (auto* negativeZOrderList = negZOrderList()) {
-            for (auto* layer : *negativeZOrderList)
-                m_has3DTransformedDescendant |= layer->update3DTransformedDescendantStatus();
-        }
+        for (auto* layer : negativeZOrderLayers())
+            m_has3DTransformedDescendant |= layer->update3DTransformedDescendantStatus();
         
         m_3DTransformedDescendantStatusDirty = false;
     }
@@ -4104,7 +4100,7 @@ void RenderLayer::paintLayerContents(GraphicsContext& context, const LayerPainti
 
         // Now walk the sorted list of children with negative z-indices.
         if ((isPaintingScrollingContent && isPaintingOverflowContents) || (!isPaintingScrollingContent && isPaintingCompositedBackground))
-            paintList(negZOrderList(), currentContext, localPaintingInfo, localPaintFlags);
+            paintList(negativeZOrderLayers(), currentContext, localPaintingInfo, localPaintFlags);
         
         if (isPaintingCompositedForeground) {
             if (shouldPaintContent) {
@@ -4118,10 +4114,10 @@ void RenderLayer::paintLayerContents(GraphicsContext& context, const LayerPainti
 
         if (isPaintingCompositedForeground) {
             // Paint any child layers that have overflow.
-            paintList(m_normalFlowList.get(), currentContext, localPaintingInfo, localPaintFlags);
+            paintList(normalFlowLayers(), currentContext, localPaintingInfo, localPaintFlags);
         
             // Now walk the sorted list of children with positive z-indices.
-            paintList(posZOrderList(), currentContext, localPaintingInfo, localPaintFlags);
+            paintList(positiveZOrderLayers(), currentContext, localPaintingInfo, localPaintFlags);
         }
 
         if (isPaintingOverlayScrollbars && hasScrollbars())
@@ -4212,9 +4208,9 @@ void RenderLayer::paintLayerByApplyingTransform(GraphicsContext& context, const
     context.setCTM(oldTransfrom);
 }
 
-void RenderLayer::paintList(Vector<RenderLayer*>* list, GraphicsContext& context, const LayerPaintingInfo& paintingInfo, OptionSet<PaintLayerFlag> paintFlags)
+void RenderLayer::paintList(LayerList layerIterator, GraphicsContext& context, const LayerPaintingInfo& paintingInfo, OptionSet<PaintLayerFlag> paintFlags)
 {
-    if (!list)
+    if (layerIterator.begin() == layerIterator.end())
         return;
 
     if (!hasSelfPaintingLayerDescendant())
@@ -4224,7 +4220,7 @@ void RenderLayer::paintList(Vector<RenderLayer*>* list, GraphicsContext& context
     LayerListMutationDetector mutationChecker(this);
 #endif
 
-    for (auto* childLayer : *list)
+    for (auto* childLayer : layerIterator)
         childLayer->paintLayer(context, paintingInfo, paintFlags);
 }
 
@@ -4826,7 +4822,7 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont
 #endif
 
     // Begin by walking our list of positive layers from highest z-index down to the lowest z-index.
-    auto* hitLayer = hitTestList(posZOrderList(), rootLayer, request, result, hitTestRect, hitTestLocation,
+    auto* hitLayer = hitTestList(positiveZOrderLayers(), rootLayer, request, result, hitTestRect, hitTestLocation,
                                         localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants);
     if (hitLayer) {
         if (!depthSortDescendants)
@@ -4835,7 +4831,7 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont
     }
 
     // Now check our overflow objects.
-    hitLayer = hitTestList(m_normalFlowList.get(), rootLayer, request, result, hitTestRect, hitTestLocation,
+    hitLayer = hitTestList(normalFlowLayers(), rootLayer, request, result, hitTestRect, hitTestLocation,
                            localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants);
     if (hitLayer) {
         if (!depthSortDescendants)
@@ -4874,7 +4870,7 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont
     }
 
     // Now check our negative z-index children.
-    hitLayer = hitTestList(negZOrderList(), rootLayer, request, result, hitTestRect, hitTestLocation,
+    hitLayer = hitTestList(negativeZOrderLayers(), rootLayer, request, result, hitTestRect, hitTestLocation,
         localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants);
     if (hitLayer) {
         if (!depthSortDescendants)
@@ -5039,7 +5035,7 @@ bool RenderLayer::hitTestContents(const HitTestRequest& request, HitTestResult&
     return true;
 }
 
-RenderLayer* RenderLayer::hitTestList(Vector<RenderLayer*>* list, RenderLayer* rootLayer,
+RenderLayer* RenderLayer::hitTestList(LayerList layerIterator, RenderLayer* rootLayer,
                                       const HitTestRequest& request, HitTestResult& result,
                                       const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation,
                                       const HitTestingTransformState* transformState, 
@@ -5047,18 +5043,19 @@ RenderLayer* RenderLayer::hitTestList(Vector<RenderLayer*>* list, RenderLayer* r
                                       const HitTestingTransformState* unflattenedTransformState,
                                       bool depthSortDescendants)
 {
-    if (!list)
+    if (layerIterator.begin() == layerIterator.end())
         return nullptr;
 
     if (!hasSelfPaintingLayerDescendant())
         return nullptr;
 
     RenderLayer* resultLayer = nullptr;
-    for (size_t i = list->size(); i > 0; --i) {
-        RenderLayer* childLayer = list->at(i - 1);
-        RenderLayer* hitLayer = nullptr;
+
+    for (auto iter = layerIterator.rbegin(); iter != layerIterator.rend(); ++iter) {
+        auto* childLayer = *iter;
+
         HitTestResult tempResult(result.hitTestLocation());
-        hitLayer = childLayer->hitTestLayer(rootLayer, this, request, tempResult, hitTestRect, hitTestLocation, false, transformState, zOffsetForDescendants);
+        auto* hitLayer = childLayer->hitTestLayer(rootLayer, this, request, tempResult, hitTestRect, hitTestLocation, false, transformState, zOffsetForDescendants);
 
         // If it is a list-based test, we can safely append the temporary result since it might had hit
         // nodes but not necesserily had hitLayer set.
@@ -5597,7 +5594,7 @@ LayoutRect RenderLayer::calculateLayerBounds(const RenderLayer* ancestorLayer, c
         }
     }
     
-    ASSERT(isStackingContext() || (!posZOrderList() || !posZOrderList()->size()));
+    ASSERT(isStackingContext() || !positiveZOrderLayers().size());
 
 #if !ASSERT_DISABLED
     LayerListMutationDetector mutationChecker(const_cast<RenderLayer*>(this));
@@ -5612,20 +5609,14 @@ LayoutRect RenderLayer::calculateLayerBounds(const RenderLayer* ancestorLayer, c
         unionBounds.checkedUnite(childBounds);
     };
 
-    if (auto* negZOrderList = this->negZOrderList()) {
-        for (auto* childLayer : *negZOrderList)
-            computeLayersUnion(*childLayer);
-    }
+    for (auto* childLayer : negativeZOrderLayers())
+        computeLayersUnion(*childLayer);
 
-    if (auto* posZOrderList = this->posZOrderList()) {
-        for (auto* childLayer : *posZOrderList)
-            computeLayersUnion(*childLayer);
-    }
+    for (auto* childLayer : positiveZOrderLayers())
+        computeLayersUnion(*childLayer);
 
-    if (auto* normalFlowList = this->normalFlowList()) {
-        for (auto* childLayer : *normalFlowList)
-            computeLayersUnion(*childLayer);
-    }
+    for (auto* childLayer : normalFlowLayers())
+        computeLayersUnion(*childLayer);
 
     // FIXME: We can optimize the size of the composited layers, by not enlarging
     // filtered areas with the outsets if we know that the filter is going to render in hardware.
@@ -5792,18 +5783,18 @@ bool RenderLayer::backgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect)
     if (renderer().hasOverflowClip())
         return false;
     
-    return listBackgroundIsKnownToBeOpaqueInRect(posZOrderList(), localRect)
-        || listBackgroundIsKnownToBeOpaqueInRect(negZOrderList(), localRect)
-        || listBackgroundIsKnownToBeOpaqueInRect(normalFlowList(), localRect);
+    return listBackgroundIsKnownToBeOpaqueInRect(positiveZOrderLayers(), localRect)
+        || listBackgroundIsKnownToBeOpaqueInRect(negativeZOrderLayers(), localRect)
+        || listBackgroundIsKnownToBeOpaqueInRect(normalFlowLayers(), localRect);
 }
 
-bool RenderLayer::listBackgroundIsKnownToBeOpaqueInRect(const Vector<RenderLayer*>* list, const LayoutRect& localRect) const
+bool RenderLayer::listBackgroundIsKnownToBeOpaqueInRect(const LayerList& list, const LayoutRect& localRect) const
 {
-    if (!list || list->isEmpty())
+    if (list.begin() == list.end())
         return false;
 
-    for (auto iter = list->rbegin(); iter != list->rend(); ++iter) {
-        const RenderLayer* childLayer = *iter;
+    for (auto iter = list.rbegin(); iter != list.rend(); ++iter) {
+        const auto* childLayer = *iter;
         if (childLayer->isComposited())
             continue;
 
index 27e935b..e6a944e 100644 (file)
@@ -353,28 +353,67 @@ public:
     // 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; }
 
-    Vector<RenderLayer*>* posZOrderList() const
+        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 m_posZOrderList.get();
+        return LayerList(m_posZOrderList.get());
     }
 
-    bool hasNegativeZOrderList() const { return negZOrderList() && negZOrderList()->size(); }
+    bool hasNegativeZOrderLayers() const
+    {
+        return m_negZOrderList && m_negZOrderList->size();
+    }
 
-    Vector<RenderLayer*>* negZOrderList() const
+    LayerList negativeZOrderLayers() const
     {
         ASSERT(!m_zOrderListsDirty);
         ASSERT(isStackingContext() || !m_negZOrderList);
-        return m_negZOrderList.get();
+        return LayerList(m_negZOrderList.get());
     }
 
-    void dirtyNormalFlowList();
-    Vector<RenderLayer*>* normalFlowList() const { ASSERT(!m_normalFlowListDirty); return m_normalFlowList.get(); }
-
     // Update our normal and z-index lists.
     void updateLayerListsIfNeeded();
 
@@ -730,6 +769,7 @@ private:
     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();
@@ -785,8 +825,6 @@ private:
 
     LayoutPoint renderBoxLocation() const { return is<RenderBox>(renderer()) ? downcast<RenderBox>(renderer()).location() : LayoutPoint(); }
 
-    void collectLayers(bool includeHiddenLayers, std::unique_ptr<Vector<RenderLayer*>>&, std::unique_ptr<Vector<RenderLayer*>>&);
-
     void updateCompositingAndLayerListsIfNeeded();
 
     bool setupFontSubpixelQuantization(GraphicsContext&, bool& didQuantizeFonts);
@@ -806,7 +844,7 @@ private:
     void paintLayerContentsAndReflection(GraphicsContext&, const LayerPaintingInfo&, OptionSet<PaintLayerFlag>);
     void paintLayerByApplyingTransform(GraphicsContext&, const LayerPaintingInfo&, OptionSet<PaintLayerFlag>, const LayoutSize& translationOffset = LayoutSize());
     void paintLayerContents(GraphicsContext&, const LayerPaintingInfo&, OptionSet<PaintLayerFlag>);
-    void paintList(Vector<RenderLayer*>*, GraphicsContext&, const LayerPaintingInfo&, OptionSet<PaintLayerFlag>);
+    void paintList(LayerList, GraphicsContext&, const LayerPaintingInfo&, OptionSet<PaintLayerFlag>);
 
     void updatePaintingInfoForFragments(LayerFragments&, const LayerPaintingInfo&, OptionSet<PaintLayerFlag>, bool shouldPaintContent, const LayoutSize& offsetFromRoot);
     void paintBackgroundForFragments(const LayerFragments&, GraphicsContext&, GraphicsContext& transparencyLayerContext,
@@ -823,13 +861,13 @@ private:
     RenderLayer* transparentPaintingAncestor();
     void beginTransparencyLayers(GraphicsContext&, const LayerPaintingInfo&, const LayoutRect& dirtyRect);
 
-    RenderLayer* hitTestLayer(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest& request, HitTestResult& result,
+    RenderLayer* hitTestLayer(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest&, HitTestResult&,
         const LayoutRect& hitTestRect, const HitTestLocation&, bool appliedTransform,
         const HitTestingTransformState* = nullptr, double* zOffset = nullptr);
     RenderLayer* hitTestLayerByApplyingTransform(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest&, HitTestResult&,
         const LayoutRect& hitTestRect, const HitTestLocation&, const HitTestingTransformState* = nullptr, double* zOffset = nullptr,
         const LayoutSize& translationOffset = LayoutSize());
-    RenderLayer* hitTestList(Vector<RenderLayer*>*, RenderLayer* rootLayer, const HitTestRequest& request, HitTestResult& result,
+    RenderLayer* hitTestList(LayerList, RenderLayer* rootLayer, const HitTestRequest&, HitTestResult&,
         const LayoutRect& hitTestRect, const HitTestLocation&,
         const HitTestingTransformState*, double* zOffsetForDescendants, double* zOffset,
         const HitTestingTransformState* unflattenedTransformState, bool depthSortDescendants);
@@ -845,7 +883,7 @@ private:
     RenderLayer* hitTestTransformedLayerInFragments(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest&, HitTestResult&,
         const LayoutRect& hitTestRect, const HitTestLocation&, const HitTestingTransformState* = nullptr, double* zOffset = nullptr);
 
-    bool listBackgroundIsKnownToBeOpaqueInRect(const Vector<RenderLayer*>*, const LayoutRect&) const;
+    bool listBackgroundIsKnownToBeOpaqueInRect(const LayerList&, const LayoutRect&) const;
 
     void computeScrollDimensions();
     bool hasHorizontalOverflow() const;
index e5c7342..7cff87b 100644 (file)
@@ -2083,47 +2083,41 @@ static LayerTraversal traverseVisibleNonCompositedDescendantLayers(RenderLayer&
     LayerListMutationDetector mutationChecker(&parent);
 #endif
 
-    if (auto* normalFlowList = parent.normalFlowList()) {
-        for (auto* childLayer : *normalFlowList) {
-            if (compositedWithOwnBackingStore(*childLayer))
-                continue;
+    for (auto* childLayer : parent.normalFlowLayers()) {
+        if (compositedWithOwnBackingStore(*childLayer))
+            continue;
 
-            if (layerFunc(*childLayer) == LayerTraversal::Stop)
-                return LayerTraversal::Stop;
-            
-            if (traverseVisibleNonCompositedDescendantLayers(*childLayer, layerFunc) == LayerTraversal::Stop)
-                return LayerTraversal::Stop;
-        }
+        if (layerFunc(*childLayer) == LayerTraversal::Stop)
+            return LayerTraversal::Stop;
+        
+        if (traverseVisibleNonCompositedDescendantLayers(*childLayer, layerFunc) == LayerTraversal::Stop)
+            return LayerTraversal::Stop;
     }
 
     if (parent.isStackingContext() && !parent.hasVisibleDescendant())
         return LayerTraversal::Continue;
 
     // Use the m_hasCompositingDescendant bit to optimize?
-    if (auto* negZOrderList = parent.negZOrderList()) {
-        for (auto* childLayer : *negZOrderList) {
-            if (compositedWithOwnBackingStore(*childLayer))
-                continue;
+    for (auto* childLayer : parent.negativeZOrderLayers()) {
+        if (compositedWithOwnBackingStore(*childLayer))
+            continue;
 
-            if (layerFunc(*childLayer) == LayerTraversal::Stop)
-                return LayerTraversal::Stop;
+        if (layerFunc(*childLayer) == LayerTraversal::Stop)
+            return LayerTraversal::Stop;
 
-            if (traverseVisibleNonCompositedDescendantLayers(*childLayer, layerFunc) == LayerTraversal::Stop)
-                return LayerTraversal::Stop;
-        }
+        if (traverseVisibleNonCompositedDescendantLayers(*childLayer, layerFunc) == LayerTraversal::Stop)
+            return LayerTraversal::Stop;
     }
 
-    if (auto* posZOrderList = parent.posZOrderList()) {
-        for (auto* childLayer : *posZOrderList) {
-            if (compositedWithOwnBackingStore(*childLayer))
-                continue;
+    for (auto* childLayer : parent.positiveZOrderLayers()) {
+        if (compositedWithOwnBackingStore(*childLayer))
+            continue;
 
-            if (layerFunc(*childLayer) == LayerTraversal::Stop)
-                return LayerTraversal::Stop;
+        if (layerFunc(*childLayer) == LayerTraversal::Stop)
+            return LayerTraversal::Stop;
 
-            if (traverseVisibleNonCompositedDescendantLayers(*childLayer, layerFunc) == LayerTraversal::Stop)
-                return LayerTraversal::Stop;
-        }
+        if (traverseVisibleNonCompositedDescendantLayers(*childLayer, layerFunc) == LayerTraversal::Stop)
+            return LayerTraversal::Stop;
     }
 
     return LayerTraversal::Continue;
index d26fabe..fab7ca1 100644 (file)
@@ -1268,20 +1268,14 @@ void RenderLayerCompositor::addToOverlapMapRecursive(OverlapMap& overlapMap, con
     LayerListMutationDetector mutationChecker(const_cast<RenderLayer*>(&layer));
 #endif
 
-    if (auto* negZOrderList = layer.negZOrderList()) {
-        for (auto* renderLayer : *negZOrderList)
-            addToOverlapMapRecursive(overlapMap, *renderLayer, &layer);
-    }
+    for (auto* renderLayer : layer.negativeZOrderLayers())
+        addToOverlapMapRecursive(overlapMap, *renderLayer, &layer);
 
-    if (auto* normalFlowList = layer.normalFlowList()) {
-        for (auto* renderLayer : *normalFlowList)
-            addToOverlapMapRecursive(overlapMap, *renderLayer, &layer);
-    }
+    for (auto* renderLayer : layer.normalFlowLayers())
+        addToOverlapMapRecursive(overlapMap, *renderLayer, &layer);
 
-    if (auto* posZOrderList = layer.posZOrderList()) {
-        for (auto* renderLayer : *posZOrderList)
-            addToOverlapMapRecursive(overlapMap, *renderLayer, &layer);
-    }
+    for (auto* renderLayer : layer.positiveZOrderLayers())
+        addToOverlapMapRecursive(overlapMap, *renderLayer, &layer);
     
     if (ancestorLayer)
         overlapMap.geometryMap().popMappingsToAncestor(ancestorLayer);
@@ -1374,35 +1368,28 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestor
 
     bool anyDescendantHas3DTransform = false;
 
-    if (auto* negZOrderList = layer.negZOrderList()) {
-        for (auto* renderLayer : *negZOrderList) {
-            computeCompositingRequirements(&layer, *renderLayer, overlapMap, childState, layersChanged, anyDescendantHas3DTransform);
-
-            // If we have to make a layer for this child, make one now so we can have a contents layer
-            // (since we need to ensure that the -ve z-order child renders underneath our contents).
-            if (!willBeComposited && childState.subtreeIsCompositing) {
-                // make layer compositing
-                layer.setIndirectCompositingReason(RenderLayer::IndirectCompositingReason::BackgroundLayer);
-                childState.compositingAncestor = &layer;
-                overlapMap.pushCompositingContainer();
-                // This layer is going to be composited, so children can safely ignore the fact that there's an
-                // animation running behind this layer, meaning they can rely on the overlap map testing again
-                childState.testingOverlap = true;
-                willBeComposited = true;
-            }
+    for (auto* renderLayer : layer.negativeZOrderLayers()) {
+        computeCompositingRequirements(&layer, *renderLayer, overlapMap, childState, layersChanged, anyDescendantHas3DTransform);
+
+        // If we have to make a layer for this child, make one now so we can have a contents layer
+        // (since we need to ensure that the -ve z-order child renders underneath our contents).
+        if (!willBeComposited && childState.subtreeIsCompositing) {
+            // make layer compositing
+            layer.setIndirectCompositingReason(RenderLayer::IndirectCompositingReason::BackgroundLayer);
+            childState.compositingAncestor = &layer;
+            overlapMap.pushCompositingContainer();
+            // This layer is going to be composited, so children can safely ignore the fact that there's an
+            // animation running behind this layer, meaning they can rely on the overlap map testing again
+            childState.testingOverlap = true;
+            willBeComposited = true;
         }
     }
     
-    if (auto* normalFlowList = layer.normalFlowList()) {
-        for (auto* renderLayer : *normalFlowList)
-            computeCompositingRequirements(&layer, *renderLayer, overlapMap, childState, layersChanged, anyDescendantHas3DTransform);
-    }
+    for (auto* renderLayer : layer.normalFlowLayers())
+        computeCompositingRequirements(&layer, *renderLayer, overlapMap, childState, layersChanged, anyDescendantHas3DTransform);
 
-    if (auto* posZOrderList = layer.posZOrderList()) {
-        ASSERT(layer.isStackingContext());
-        for (auto* renderLayer : *posZOrderList)
-            computeCompositingRequirements(&layer, *renderLayer, overlapMap, childState, layersChanged, anyDescendantHas3DTransform);
-    }
+    for (auto* renderLayer : layer.positiveZOrderLayers())
+        computeCompositingRequirements(&layer, *renderLayer, overlapMap, childState, layersChanged, anyDescendantHas3DTransform);
 
     // If we just entered compositing mode, the root will have become composited (as long as accelerated compositing is enabled).
     if (layer.isRenderViewLayer()) {
@@ -1578,24 +1565,20 @@ void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer& layer, Vect
     LayerListMutationDetector mutationChecker(&layer);
 #endif
 
-    if (auto* negZOrderList = layer.negZOrderList()) {
-        for (auto* renderLayer : *negZOrderList)
-            rebuildCompositingLayerTree(*renderLayer, childList, depth + 1);
+    for (auto* renderLayer : layer.negativeZOrderLayers())
+        rebuildCompositingLayerTree(*renderLayer, childList, depth + 1);
 
-        // If a negative z-order child is compositing, we get a foreground layer which needs to get parented.
+    // If a negative z-order child is compositing, we get a foreground layer which needs to get parented.
+    if (layer.negativeZOrderLayers().size()) {
         if (layerBacking && layerBacking->foregroundLayer())
             childList.append(*layerBacking->foregroundLayer());
     }
-
-    if (auto* normalFlowList = layer.normalFlowList()) {
-        for (auto* renderLayer : *normalFlowList)
-            rebuildCompositingLayerTree(*renderLayer, childList, depth + 1);
-    }
     
-    if (auto* posZOrderList = layer.posZOrderList()) {
-        for (auto* renderLayer : *posZOrderList)
-            rebuildCompositingLayerTree(*renderLayer, childList, depth + 1);
-    }
+    for (auto* renderLayer : layer.normalFlowLayers())
+        rebuildCompositingLayerTree(*renderLayer, childList, depth + 1);
+    
+    for (auto* renderLayer : layer.positiveZOrderLayers())
+        rebuildCompositingLayerTree(*renderLayer, childList, depth + 1);
 
     if (layerBacking) {
         bool parented = false;
@@ -1830,20 +1813,14 @@ void RenderLayerCompositor::updateLayerTreeGeometry(RenderLayer& layer, int dept
     LayerListMutationDetector mutationChecker(&layer);
 #endif
 
-    if (auto* negZOrderList = layer.negZOrderList()) {
-        for (auto* renderLayer : *negZOrderList)
-            updateLayerTreeGeometry(*renderLayer, depth + 1);
-    }
+    for (auto* renderLayer : layer.negativeZOrderLayers())
+        updateLayerTreeGeometry(*renderLayer, depth + 1);
 
-    if (auto* normalFlowList = layer.normalFlowList()) {
-        for (auto* renderLayer : *normalFlowList)
-            updateLayerTreeGeometry(*renderLayer, depth + 1);
-    }
+    for (auto* renderLayer : layer.normalFlowLayers())
+        updateLayerTreeGeometry(*renderLayer, depth + 1);
     
-    if (auto* posZOrderList = layer.posZOrderList()) {
-        for (auto* renderLayer : *posZOrderList)
-            updateLayerTreeGeometry(*renderLayer, depth + 1);
-    }
+    for (auto* renderLayer : layer.positiveZOrderLayers())
+        updateLayerTreeGeometry(*renderLayer, depth + 1);
 
     if (auto* layerBacking = layer.backing())
         layerBacking->updateAfterDescendants();
@@ -1877,20 +1854,14 @@ void RenderLayerCompositor::updateCompositingDescendantGeometry(RenderLayer& com
     LayerListMutationDetector mutationChecker(&layer);
 #endif
     
-    if (auto* negZOrderList = layer.negZOrderList()) {
-        for (auto* renderLayer : *negZOrderList)
-            updateCompositingDescendantGeometry(compositingAncestor, *renderLayer);
-    }
+    for (auto* renderLayer : layer.negativeZOrderLayers())
+        updateCompositingDescendantGeometry(compositingAncestor, *renderLayer);
 
-    if (auto* normalFlowList = layer.normalFlowList()) {
-        for (auto* renderLayer : *normalFlowList)
-            updateCompositingDescendantGeometry(compositingAncestor, *renderLayer);
-    }
+    for (auto* renderLayer : layer.normalFlowLayers())
+        updateCompositingDescendantGeometry(compositingAncestor, *renderLayer);
     
-    if (auto* posZOrderList = layer.posZOrderList()) {
-        for (auto* renderLayer : *posZOrderList)
-            updateCompositingDescendantGeometry(compositingAncestor, *renderLayer);
-    }
+    for (auto* renderLayer : layer.positiveZOrderLayers())
+        updateCompositingDescendantGeometry(compositingAncestor, *renderLayer);
     
     if (&layer != &compositingAncestor) {
         if (auto* layerBacking = layer.backing())
@@ -1914,20 +1885,15 @@ void RenderLayerCompositor::recursiveRepaintLayer(RenderLayer& layer)
 #endif
 
     if (layer.hasCompositingDescendant()) {
-        if (auto* negZOrderList = layer.negZOrderList()) {
-            for (auto* renderLayer : *negZOrderList)
-                recursiveRepaintLayer(*renderLayer);
-        }
+        for (auto* renderLayer : layer.negativeZOrderLayers())
+            recursiveRepaintLayer(*renderLayer);
 
-        if (auto* posZOrderList = layer.posZOrderList()) {
-            for (auto* renderLayer : *posZOrderList)
-                recursiveRepaintLayer(*renderLayer);
-        }
-    }
-    if (auto* normalFlowList = layer.normalFlowList()) {
-        for (auto* renderLayer : *normalFlowList)
+        for (auto* renderLayer : layer.positiveZOrderLayers())
             recursiveRepaintLayer(*renderLayer);
     }
+
+    for (auto* renderLayer : layer.normalFlowLayers())
+        recursiveRepaintLayer(*renderLayer);
 }
 
 RenderLayer& RenderLayerCompositor::rootRenderLayer() const
@@ -2783,7 +2749,7 @@ bool RenderLayerCompositor::isRunningTransformAnimation(RenderLayerModelObject&
 // object.
 bool RenderLayerCompositor::needsContentsCompositingLayer(const RenderLayer& layer) const
 {
-    return layer.hasNegativeZOrderList();
+    return layer.hasNegativeZOrderLayers();
 }
 
 bool RenderLayerCompositor::requiresScrollLayer(RootLayerAttachment attachment) const
@@ -3535,25 +3501,19 @@ bool RenderLayerCompositor::layerHas3DContent(const RenderLayer& layer) const
     LayerListMutationDetector mutationChecker(const_cast<RenderLayer*>(&layer));
 #endif
 
-    if (auto* negZOrderList = layer.negZOrderList()) {
-        for (auto* renderLayer : *negZOrderList) {
-            if (layerHas3DContent(*renderLayer))
-                return true;
-        }
+    for (auto* renderLayer : layer.negativeZOrderLayers()) {
+        if (layerHas3DContent(*renderLayer))
+            return true;
     }
 
-    if (auto* posZOrderList = layer.posZOrderList()) {
-        for (auto* renderLayer : *posZOrderList) {
-            if (layerHas3DContent(*renderLayer))
-                return true;
-        }
+    for (auto* renderLayer : layer.positiveZOrderLayers()) {
+        if (layerHas3DContent(*renderLayer))
+            return true;
     }
 
-    if (auto* normalFlowList = layer.normalFlowList()) {
-        for (auto* renderLayer : *normalFlowList) {
-            if (layerHas3DContent(*renderLayer))
-                return true;
-        }
+    for (auto* renderLayer : layer.normalFlowLayers()) {
+        if (layerHas3DContent(*renderLayer))
+            return true;
     }
 
     return false;
index f822a84..234236a 100644 (file)
@@ -706,20 +706,20 @@ static void writeLayers(TextStream& ts, const RenderLayer& rootLayer, RenderLaye
     layer.updateLayerListsIfNeeded();
 
     bool shouldPaint = (behavior & RenderAsTextShowAllLayers) ? true : layer.intersectsDamageRect(layerBounds, damageRect.rect(), &rootLayer, layer.offsetFromAncestor(&rootLayer));
-    auto* negativeZOrderList = layer.negZOrderList();
-    bool paintsBackgroundSeparately = negativeZOrderList && negativeZOrderList->size() > 0;
+    auto negativeZOrderLayers = layer.negativeZOrderLayers();
+    bool paintsBackgroundSeparately = negativeZOrderLayers.size() > 0;
     if (shouldPaint && paintsBackgroundSeparately) {
         writeLayer(ts, layer, layerBounds, damageRect.rect(), clipRectToApply.rect(), LayerPaintPhaseBackground, behavior);
         writeLayerRenderers(ts, layer, LayerPaintPhaseBackground, behavior);
     }
         
-    if (negativeZOrderList) {
+    if (negativeZOrderLayers.size()) {
         if (behavior & RenderAsTextShowLayerNesting) {
-            ts << indent << " negative z-order list(" << negativeZOrderList->size() << ")\n";
+            ts << indent << " negative z-order list(" << negativeZOrderLayers.size() << ")\n";
             ts.increaseIndent();
         }
         
-        for (auto* currLayer : *negativeZOrderList)
+        for (auto* currLayer : negativeZOrderLayers)
             writeLayers(ts, rootLayer, *currLayer, paintDirtyRect, behavior);
 
         if (behavior & RenderAsTextShowLayerNesting)
@@ -745,29 +745,31 @@ static void writeLayers(TextStream& ts, const RenderLayer& rootLayer, RenderLaye
         writeLayerRenderers(ts, layer, paintsBackgroundSeparately ? LayerPaintPhaseForeground : LayerPaintPhaseAll, behavior);
     }
     
-    if (auto* normalFlowList = layer.normalFlowList()) {
+    auto normalFlowLayers = layer.normalFlowLayers();
+    if (normalFlowLayers.size()) {
         if (behavior & RenderAsTextShowLayerNesting) {
-            ts << indent << " normal flow list(" << normalFlowList->size() << ")\n";
+            ts << indent << " normal flow list(" << normalFlowLayers.size() << ")\n";
             ts.increaseIndent();
         }
         
-        for (auto* currLayer : *normalFlowList)
+        for (auto* currLayer : normalFlowLayers)
             writeLayers(ts, rootLayer, *currLayer, paintDirtyRect, behavior);
 
         if (behavior & RenderAsTextShowLayerNesting)
             ts.decreaseIndent();
     }
 
-    if (auto* positiveZOrderList = layer.posZOrderList()) {
-        size_t layerCount = positiveZOrderList->size();
+    auto positiveZOrderLayers = layer.positiveZOrderLayers();
+    if (positiveZOrderLayers.size()) {
+        size_t layerCount = positiveZOrderLayers.size();
 
         if (layerCount) {
             if (behavior & RenderAsTextShowLayerNesting) {
-                ts << indent << " positive z-order list(" << positiveZOrderList->size() << ")\n";
+                ts << indent << " positive z-order list(" << layerCount << ")\n";
                 ts.increaseIndent();
             }
 
-            for (auto* currLayer : *positiveZOrderList)
+            for (auto* currLayer : positiveZOrderLayers)
                 writeLayers(ts, rootLayer, *currLayer, paintDirtyRect, behavior);
 
             if (behavior & RenderAsTextShowLayerNesting)
index 566e634..fbe2153 100644 (file)
@@ -1,3 +1,21 @@
+2018-10-10  Simon Fraser  <simon.fraser@apple.com>
+
+        Hide RenderLayer z-order and normal flow lists behind iterators
+        https://bugs.webkit.org/show_bug.cgi?id=190457
+
+        Reviewed by Zalan Bujtas.
+
+        Expose the positive z-order, negative z-order and normal flow lists
+        from RenderLayer as iterators rather than vectors of raw pointers.
+        
+        Use a lambda function to get access to the private constructor, while not having
+        to refer to the nested RenderLayer::LayerIterator class in the header.
+
+        * Shared/WebRenderLayer.cpp:
+        (WebKit::WebRenderLayer::WebRenderLayer):
+        (WebKit::WebRenderLayer::createArrayFromLayerList): Deleted.
+        * Shared/WebRenderLayer.h:
+
 2018-10-11  Tim Horton  <timothy_horton@apple.com>
 
         iOS: Scrolling using the arrow keys doesn't show the scroll indicator like it does on macOS
index 0a0cb15..a483bc5 100644 (file)
@@ -65,20 +65,6 @@ Ref<WebRenderLayer> WebRenderLayer::create(RefPtr<WebRenderObject>&& renderer, b
     return adoptRef(*new WebRenderLayer(WTFMove(renderer), isReflection, isClipping, isClipped, type, absoluteBoundingBox, backingStoreMemoryEstimate, WTFMove(negativeZOrderList), WTFMove(normalFlowList), WTFMove(positiveZOrderList), WTFMove(frameContentsLayer)));
 }
 
-RefPtr<API::Array> WebRenderLayer::createArrayFromLayerList(Vector<WebCore::RenderLayer*>* list)
-{
-    if (!list || !list->size())
-        return nullptr;
-
-    Vector<RefPtr<API::Object>> layers;
-    layers.reserveInitialCapacity(list->size());
-
-    for (const auto& layer : *list)
-        layers.uncheckedAppend(adoptRef(new WebRenderLayer(layer)));
-
-    return API::Array::create(WTFMove(layers));
-}
-
 WebRenderLayer::WebRenderLayer(WebCore::RenderLayer* layer)
 {
     m_renderer = WebRenderObject::create(&layer->renderer());
@@ -113,9 +99,22 @@ WebRenderLayer::WebRenderLayer(WebCore::RenderLayer* layer)
 
     m_absoluteBoundingBox = layer->absoluteBoundingBox();
 
-    m_negativeZOrderList = createArrayFromLayerList(layer->negZOrderList());
-    m_normalFlowList = createArrayFromLayerList(layer->normalFlowList());
-    m_positiveZOrderList = createArrayFromLayerList(layer->posZOrderList());
+    auto createArrayFromLayerList = [] (WebCore::RenderLayer::LayerList list) -> RefPtr<API::Array> {
+        if (!list.size())
+            return nullptr;
+
+        Vector<RefPtr<API::Object>> layers;
+        layers.reserveInitialCapacity(list.size());
+
+        for (auto* layer : list)
+            layers.uncheckedAppend(adoptRef(new WebRenderLayer(layer)));
+
+        return API::Array::create(WTFMove(layers));
+    };
+
+    m_negativeZOrderList = createArrayFromLayerList(layer->negativeZOrderLayers());
+    m_normalFlowList = createArrayFromLayerList(layer->normalFlowLayers());
+    m_positiveZOrderList = createArrayFromLayerList(layer->positiveZOrderLayers());
 
     if (is<WebCore::RenderWidget>(layer->renderer())) {
         if (WebCore::Document* contentDocument = downcast<WebCore::RenderWidget>(layer->renderer()).frameOwnerElement().contentDocument()) {
index 51414df..7e50ba5 100644 (file)
@@ -29,7 +29,7 @@
 #include "WebRenderObject.h"
 
 namespace WebCore {
-    class RenderLayer;
+class RenderLayer;
 }
 
 namespace WebKit {
@@ -60,8 +60,6 @@ private:
     explicit WebRenderLayer(WebCore::RenderLayer*);
     WebRenderLayer(RefPtr<WebRenderObject>&& renderer, bool isReflection, bool isClipping, bool isClipped, CompositingLayerType, WebCore::IntRect absoluteBoundingBox, double backingStoreMemoryEstimate, RefPtr<API::Array>&& negativeZOrderList, RefPtr<API::Array>&& normalFlowList, RefPtr<API::Array>&& positiveZOrderList, RefPtr<WebRenderLayer>&& frameContentsLayer);
 
-    static RefPtr<API::Array> createArrayFromLayerList(Vector<WebCore::RenderLayer*>*);
-
     RefPtr<WebRenderObject> m_renderer;
     bool m_isReflection;
     bool m_isClipping;