Move RenderLayers z-index lists dirtying to post style change
authorjchaffraix@webkit.org <jchaffraix@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 9 May 2012 02:18:38 +0000 (02:18 +0000)
committerjchaffraix@webkit.org <jchaffraix@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 9 May 2012 02:18:38 +0000 (02:18 +0000)
https://bugs.webkit.org/show_bug.cgi?id=85437

Reviewed by Darin Adler.

No expected change in behavior.

This change moves the z-order lists to RenderLayer::styleChanged. As part of this
change, also added proper handling of stacking context transition. This enabled
us to tighten more of the dirtyZOrderLists / clearZOrderLists code.

* rendering/RenderBoxModelObject.cpp:
(WebCore::RenderBoxModelObject::styleWillChange):
Removed this code, moved to updateStackingContextsAfterStyleChange.

* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::RenderLayer):
Only stacking contexts start with dirty z-order lists.

(WebCore::RenderLayer::dirtyZOrderLists):
Added an ASSERT.

(WebCore::RenderLayer::updateStackingContextsAfterStyleChange):
Refactored the code to handle the transition between stacking context status.

(WebCore::RenderLayer::styleChanged):
Added a call to updateStackingContextsAfterStyleChange.

* rendering/RenderLayer.h:
(WebCore::RenderLayer::isStackingContext):
Added a call to the next function.

(WebCore::RenderLayer::layerWithStyleIsStackingContext):
Factored the isStackingContext logic here so that we can reuse it inside
updateStackingContextsAfterStyleChange.

(WebCore::RenderLayer::clearZOrderLists):
Added an ASSERT.

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

Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderBoxModelObject.cpp
Source/WebCore/rendering/RenderLayer.cpp
Source/WebCore/rendering/RenderLayer.h

index e76b07c..3814230 100644 (file)
@@ -1,3 +1,44 @@
+2012-05-08  Julien Chaffraix  <jchaffraix@webkit.org>
+
+        Move RenderLayers z-index lists dirtying to post style change
+        https://bugs.webkit.org/show_bug.cgi?id=85437
+
+        Reviewed by Darin Adler.
+
+        No expected change in behavior.
+
+        This change moves the z-order lists to RenderLayer::styleChanged. As part of this
+        change, also added proper handling of stacking context transition. This enabled
+        us to tighten more of the dirtyZOrderLists / clearZOrderLists code.
+
+        * rendering/RenderBoxModelObject.cpp:
+        (WebCore::RenderBoxModelObject::styleWillChange):
+        Removed this code, moved to updateStackingContextsAfterStyleChange.
+
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::RenderLayer):
+        Only stacking contexts start with dirty z-order lists.
+
+        (WebCore::RenderLayer::dirtyZOrderLists):
+        Added an ASSERT.
+
+        (WebCore::RenderLayer::updateStackingContextsAfterStyleChange):
+        Refactored the code to handle the transition between stacking context status.
+
+        (WebCore::RenderLayer::styleChanged):
+        Added a call to updateStackingContextsAfterStyleChange.
+
+        * rendering/RenderLayer.h:
+        (WebCore::RenderLayer::isStackingContext):
+        Added a call to the next function.
+
+        (WebCore::RenderLayer::layerWithStyleIsStackingContext):
+        Factored the isStackingContext logic here so that we can reuse it inside
+        updateStackingContextsAfterStyleChange.
+
+        (WebCore::RenderLayer::clearZOrderLists):
+        Added an ASSERT.
+
 2012-05-08  Abhishek Arya  <inferno@chromium.org>
 
         Crash due to owning renderer not removed from custom scrollbar.
index f079d8b..fcca1b3 100644 (file)
@@ -411,15 +411,6 @@ void RenderBoxModelObject::styleWillChange(StyleDifference diff, const RenderSty
                 repaint();
             }
         }
-
-        if (hasLayer()
-            && (oldStyle->hasAutoZIndex() != newStyle->hasAutoZIndex()
-                || oldStyle->zIndex() != newStyle->zIndex()
-                || oldStyle->visibility() != newStyle->visibility())) {
-            layer()->dirtyStackingContextZOrderLists();
-            if (oldStyle->hasAutoZIndex() != newStyle->hasAutoZIndex() || oldStyle->visibility() != newStyle->visibility())
-                layer()->dirtyZOrderLists();
-        }
     }
 
     RenderObject::styleWillChange(diff, newStyle);
index 6d76189..70ceb6f 100644 (file)
@@ -147,7 +147,6 @@ void ClipRects::destroy(RenderArena* renderArena)
 RenderLayer::RenderLayer(RenderBoxModelObject* renderer)
     : m_inResizeMode(false)
     , m_scrollDimensionsDirty(true)
-    , m_zOrderListsDirty(true)
     , m_normalFlowListDirty(true)
     , m_usedTransparency(false)
     , m_paintingInsideReflection(false)
@@ -193,6 +192,9 @@ RenderLayer::RenderLayer(RenderBoxModelObject* renderer)
     , m_resizer(0)
 {
     m_isNormalFlowOnly = shouldBeNormalFlowOnly();
+    // Non-stacking contexts should have empty z-order lists. As this is already the case,
+    // there is no need to dirty / recompute these lists.
+    m_zOrderListsDirty = isStackingContext();
 
     ScrollableArea::setConstrainsScrollingToContentEdge(false);
 
@@ -4459,8 +4461,7 @@ static inline bool compareZIndex(RenderLayer* first, RenderLayer* second)
 void RenderLayer::dirtyZOrderLists()
 {
     ASSERT(m_layerListMutationAllowed);
-    // We cannot assume that we are called on a stacking context as it
-    // is called when we just got demoted from being a stacking context.
+    ASSERT(isStackingContext());
 
     if (m_posZOrderList)
         m_posZOrderList->clear();
@@ -4676,6 +4677,31 @@ bool RenderLayer::isSelfPaintingLayer() const
         || renderer()->isRenderIFrame();
 }
 
+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();
+        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();
+    }
+}
+
 static bool overflowCanHaveAScrollbar(EOverflow overflow)
 {
     return overflow == OAUTO || overflow == OSCROLL || overflow == OOVERLAY;
@@ -4730,7 +4756,8 @@ void RenderLayer::styleChanged(StyleDifference, const RenderStyle* oldStyle)
         delete m_marquee;
         m_marquee = 0;
     }
-    
+
+    updateStackingContextsAfterStyleChange(oldStyle);
     updateScrollbarsAfterStyleChange(oldStyle);
 
     if (!hasReflection() && m_reflection)
index 95c0f39..9b34e7f 100644 (file)
@@ -382,7 +382,7 @@ public:
     // Get the enclosing stacking context for this layer.  A stacking context is a layer
     // that has a non-auto z-index.
     RenderLayer* stackingContext() const;
-    bool isStackingContext() const { return !hasAutoZIndex() || renderer()->isRenderView(); }
+    bool isStackingContext() const { return isStackingContext(renderer()->style()); }
 
     void dirtyZOrderLists();
     void dirtyStackingContextZOrderLists();
@@ -443,7 +443,6 @@ public:
     void convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutPoint& location) const;
     void convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutRect&) const;
 
-    bool hasAutoZIndex() const { return renderer()->style()->hasAutoZIndex(); }
     int zIndex() const { return renderer()->style()->zIndex(); }
 
     enum PaintLayerFlag {
@@ -618,6 +617,7 @@ private:
 
     void updateNormalFlowList();
 
+    bool isStackingContext(const RenderStyle* style) const { return !style->hasAutoZIndex() || renderer()->isRenderView(); }
     bool isDirtyStackingContext() const { return m_zOrderListsDirty && isStackingContext(); }
 
     void computeRepaintRects(LayoutPoint* offsetFromRoot = 0);
@@ -629,6 +629,8 @@ private:
 
     bool shouldRepaintAfterLayout() const;
 
+    void updateStackingContextsAfterStyleChange(const RenderStyle* oldStyle);
+
     void updateScrollbarsAfterStyleChange(const RenderStyle* oldStyle);
     void updateScrollbarsAfterLayout();
 
@@ -936,6 +938,8 @@ private:
 
 inline void RenderLayer::clearZOrderLists()
 {
+    ASSERT(!isStackingContext());
+
     if (m_posZOrderList) {
         delete m_posZOrderList;
         m_posZOrderList = 0;