Title: [140999] trunk
Revision
140999
Author
voll...@chromium.org
Date
2013-01-28 13:18:14 -0800 (Mon, 28 Jan 2013)

Log Message

Promote composited-scrolling layers to stacking containers.
https://bugs.webkit.org/show_bug.cgi?id=106142

Reviewed by Simon Fraser.

With this patch, RenderLayers that use composited scrolling are
treated as stacking contexts. Since isStackingContainer now depends on
the value of m_needsCompositedScrolling, special care needed to be
taken to ensure that the value of isStackingContainer is not used when
updating m_needsCompositedScrolling. In particular, the code for
rebuilding the layer lists needed to be generalized so that we could
build the layer lists using the value of isStackingContext rather than
isStackingContainer when building the layer lists used to determine if
the descendants are contiguous in stacking order. Also, updating
m_needsCompositedScrolling can now affect stacking container status
and can therefore dirty layer lists.

Source/WebCore:

Test: compositing/overflow/composited-scrolling-creates-a-stacking-container.html

* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::updateDescendantsAreContiguousInStackingOrder):
  Modified to use layer lists built based on isStackingContext rather
  than isStackingContainer.
(WebCore::RenderLayer::updateNeedsCompositedScrolling):
  This function can now affect stacking container status and layer
  lists.
(WebCore::RenderLayer::rebuildZOrderLists):
  Refactored to generalize layer list building.
(WebCore::RenderLayer::collectLayers):
  This function can now stop at either stacking containers or
  contexts.
(WebCore::RenderLayer::updateLayerListsIfNeeded):
  Layer lists may need to be built a 2nd time if we opt into
  composited scrolling.
* rendering/RenderLayer.h:
(RenderLayer):
(WebCore::RenderLayer::isStackingContainer):
  Returns true if we use composited scrolling.

LayoutTests:

* compositing/overflow/composited-scrolling-creates-a-stacking-container-expected.txt: Added.
* compositing/overflow/composited-scrolling-creates-a-stacking-container.html: Added.
* platform/chromium/TestExpectations:
* platform/mac/compositing/overflow/composited-scrolling-creates-a-stacking-container-expected.txt: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (140998 => 140999)


--- trunk/LayoutTests/ChangeLog	2013-01-28 21:15:32 UTC (rev 140998)
+++ trunk/LayoutTests/ChangeLog	2013-01-28 21:18:14 UTC (rev 140999)
@@ -1,3 +1,27 @@
+2013-01-28  Ian Vollick  <voll...@chromium.org>
+
+        Promote composited-scrolling layers to stacking containers.
+        https://bugs.webkit.org/show_bug.cgi?id=106142
+
+        Reviewed by Simon Fraser.
+
+        With this patch, RenderLayers that use composited scrolling are
+        treated as stacking contexts. Since isStackingContainer now depends on
+        the value of m_needsCompositedScrolling, special care needed to be
+        taken to ensure that the value of isStackingContainer is not used when
+        updating m_needsCompositedScrolling. In particular, the code for
+        rebuilding the layer lists needed to be generalized so that we could
+        build the layer lists using the value of isStackingContext rather than
+        isStackingContainer when building the layer lists used to determine if
+        the descendants are contiguous in stacking order. Also, updating
+        m_needsCompositedScrolling can now affect stacking container status
+        and can therefore dirty layer lists.
+
+        * compositing/overflow/composited-scrolling-creates-a-stacking-container-expected.txt: Added.
+        * compositing/overflow/composited-scrolling-creates-a-stacking-container.html: Added.
+        * platform/chromium/TestExpectations:
+        * platform/mac/compositing/overflow/composited-scrolling-creates-a-stacking-container-expected.txt: Added.
+
 2013-01-28  Max Vujovic  <mvujo...@adobe.com>
 
         [CSS Shaders] Parse @-webkit-filter

Added: trunk/LayoutTests/compositing/overflow/composited-scrolling-creates-a-stacking-container-expected.txt (0 => 140999)


--- trunk/LayoutTests/compositing/overflow/composited-scrolling-creates-a-stacking-container-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/compositing/overflow/composited-scrolling-creates-a-stacking-container-expected.txt	2013-01-28 21:18:14 UTC (rev 140999)
@@ -0,0 +1,54 @@
+(GraphicsLayer
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (children 1
+        (GraphicsLayer
+          (position 28.00 20.00)
+          (bounds 202.00 202.00)
+          (drawsContent 1)
+          (children 4
+            (GraphicsLayer
+              (position 1.00 1.00)
+              (bounds 200.00 200.00)
+              (children 1
+                (GraphicsLayer
+                  (bounds 200.00 300.00)
+                  (drawsContent 1)
+                  (children 2
+                    (GraphicsLayer
+                      (bounds 202.00 202.00)
+                      (drawsContent 1)
+                    )
+                    (GraphicsLayer
+                      (bounds 200.00 150.00)
+                      (drawsContent 1)
+                    )
+                  )
+                )
+              )
+            )
+            (GraphicsLayer
+              (position 1.00 186.00)
+              (bounds 185.00 15.00)
+              (drawsContent 1)
+            )
+            (GraphicsLayer
+              (position 186.00 1.00)
+              (bounds 15.00 185.00)
+              (drawsContent 1)
+            )
+            (GraphicsLayer
+              (position 186.00 186.00)
+              (bounds 15.00 15.00)
+              (drawsContent 1)
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
+

Added: trunk/LayoutTests/compositing/overflow/composited-scrolling-creates-a-stacking-container.html (0 => 140999)


--- trunk/LayoutTests/compositing/overflow/composited-scrolling-creates-a-stacking-container.html	                        (rev 0)
+++ trunk/LayoutTests/compositing/overflow/composited-scrolling-creates-a-stacking-container.html	2013-01-28 21:18:14 UTC (rev 140999)
@@ -0,0 +1,76 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+   "http://www.w3.org/TR/html4/loose.dtd">
+
+<html lang="en">
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+  <title>Composited scrolling creates a stacking context.</title>
+  <style type="text/css" media="screen">
+    .container {
+      width: 200px;
+      height: 200px;
+      overflow: scroll;
+      margin: 20px;
+      border: 1px solid black;
+    }
+
+    .composited {
+      width: 200px;
+      height: 150px;
+      -webkit-transform: translateZ(0);
+      background-color: green;
+    }
+
+    .not-composited {
+      width: 200px;
+      height: 150px;
+      background-color: blue;
+    }
+
+    .in-flow-positioned {
+      position: relative;
+      display: block;
+    }
+
+    .fixed {
+      z-index: -1;
+      position: absolute;
+      width: 200px;
+      height: 300px;
+      background-color: red;
+    }
+  </style>
+  <script type="text/_javascript_" charset="utf-8">
+    if (window.testRunner)
+      testRunner.dumpAsText();
+
+    if (window.internals)
+      window.internals.settings.setAcceleratedCompositingForOverflowScrollEnabled(true);
+
+    function doTest()
+    {
+      document.body.offsetTop;
+
+      if (window.internals) {
+        var layerTree = window.internals.layerTreeAsText(document);
+        var pre = document.getElementById('console');
+        var text = document.createTextNode(layerTree + '\n');
+        pre.appendChild(text);
+      }
+    }
+
+    window.addEventListener('load', doTest, false);
+  </script>
+</head>
+<body>
+  <div class="container">
+    <div class="in-flow-positioned">
+      <div class="fixed"></div>
+    </div>
+    <div class="composited"></div>
+    <div class="not-composited"></div>
+  </div>
+  <pre id="console"></pre>
+</body>
+</html>
+

Modified: trunk/LayoutTests/platform/chromium/TestExpectations (140998 => 140999)


--- trunk/LayoutTests/platform/chromium/TestExpectations	2013-01-28 21:15:32 UTC (rev 140998)
+++ trunk/LayoutTests/platform/chromium/TestExpectations	2013-01-28 21:18:14 UTC (rev 140999)
@@ -3607,6 +3607,9 @@
 # Scrolling content draws beneath scrollbars in composited scrolling mode.
 webkit.org/b/103156 platform/chromium/virtual/gpu/compositedscrolling/scrollbars/custom-scrollbar-with-incomplete-style.html [ ImageOnlyFailure ]
 
+# Requires an updated baseline after 106142.
+webkit.org/b/106820 platform/chromium/virtual/gpu/compositedscrolling/overflow/overflow-scroll.html [ Failure ]
+
 # Fails due to Bug 85856.
 webkit.org/b/85856 [ Win Mac Android ] fast/block/float/028.html [ ImageOnlyFailure ]
 webkit.org/b/85856 [ Win Mac Android ] fast/block/float/026.html [ ImageOnlyFailure ]

Added: trunk/LayoutTests/platform/mac/compositing/overflow/composited-scrolling-creates-a-stacking-container-expected.txt (0 => 140999)


--- trunk/LayoutTests/platform/mac/compositing/overflow/composited-scrolling-creates-a-stacking-container-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/mac/compositing/overflow/composited-scrolling-creates-a-stacking-container-expected.txt	2013-01-28 21:18:14 UTC (rev 140999)
@@ -0,0 +1,38 @@
+(GraphicsLayer
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (children 1
+        (GraphicsLayer
+          (position 28.00 20.00)
+          (bounds 202.00 202.00)
+          (drawsContent 1)
+          (children 1
+            (GraphicsLayer
+              (position 1.00 1.00)
+              (bounds 200.00 200.00)
+              (children 1
+                (GraphicsLayer
+                  (bounds 200.00 300.00)
+                  (drawsContent 1)
+                  (children 2
+                    (GraphicsLayer
+                      (bounds 202.00 202.00)
+                      (drawsContent 1)
+                    )
+                    (GraphicsLayer
+                      (bounds 200.00 150.00)
+                    )
+                  )
+                )
+              )
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
+

Modified: trunk/Source/WebCore/ChangeLog (140998 => 140999)


--- trunk/Source/WebCore/ChangeLog	2013-01-28 21:15:32 UTC (rev 140998)
+++ trunk/Source/WebCore/ChangeLog	2013-01-28 21:18:14 UTC (rev 140999)
@@ -1,3 +1,44 @@
+2013-01-28  Ian Vollick  <voll...@chromium.org>
+
+        Promote composited-scrolling layers to stacking containers.
+        https://bugs.webkit.org/show_bug.cgi?id=106142
+
+        Reviewed by Simon Fraser.
+
+        With this patch, RenderLayers that use composited scrolling are
+        treated as stacking contexts. Since isStackingContainer now depends on
+        the value of m_needsCompositedScrolling, special care needed to be
+        taken to ensure that the value of isStackingContainer is not used when
+        updating m_needsCompositedScrolling. In particular, the code for
+        rebuilding the layer lists needed to be generalized so that we could
+        build the layer lists using the value of isStackingContext rather than
+        isStackingContainer when building the layer lists used to determine if
+        the descendants are contiguous in stacking order. Also, updating
+        m_needsCompositedScrolling can now affect stacking container status
+        and can therefore dirty layer lists.
+
+        Test: compositing/overflow/composited-scrolling-creates-a-stacking-container.html
+
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::updateDescendantsAreContiguousInStackingOrder):
+          Modified to use layer lists built based on isStackingContext rather
+          than isStackingContainer.
+        (WebCore::RenderLayer::updateNeedsCompositedScrolling):
+          This function can now affect stacking container status and layer
+          lists.
+        (WebCore::RenderLayer::rebuildZOrderLists):
+          Refactored to generalize layer list building.
+        (WebCore::RenderLayer::collectLayers):
+          This function can now stop at either stacking containers or
+          contexts.
+        (WebCore::RenderLayer::updateLayerListsIfNeeded):
+          Layer lists may need to be built a 2nd time if we opt into
+          composited scrolling.
+        * rendering/RenderLayer.h:
+        (RenderLayer):
+        (WebCore::RenderLayer::isStackingContainer):
+          Returns true if we use composited scrolling.
+
 2013-01-28  Max Vujovic  <mvujo...@adobe.com>
 
         [CSS Shaders] Parse @-webkit-filter

Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (140998 => 140999)


--- trunk/Source/WebCore/rendering/RenderLayer.cpp	2013-01-28 21:15:32 UTC (rev 140998)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp	2013-01-28 21:18:14 UTC (rev 140999)
@@ -607,25 +607,29 @@
     ASSERT(!m_normalFlowListDirty);
     ASSERT(!m_zOrderListsDirty);
 
+    OwnPtr<Vector<RenderLayer*> > posZOrderList;
+    OwnPtr<Vector<RenderLayer*> > negZOrderList;
+    rebuildZOrderLists(StopAtStackingContexts, posZOrderList, negZOrderList);
+
     // Create a reverse lookup.
     HashMap<const RenderLayer*, int> lookup;
 
-    if (m_negZOrderList) {
+    if (negZOrderList) {
         int stackingOrderIndex = -1;
-        size_t listSize = m_negZOrderList->size();
+        size_t listSize = negZOrderList->size();
         for (size_t i = 0; i < listSize; ++i) {
-            RenderLayer* currentLayer = m_negZOrderList->at(listSize - i - 1);
+            RenderLayer* currentLayer = negZOrderList->at(listSize - i - 1);
             if (!currentLayer->isStackingContext())
                 continue;
             lookup.set(currentLayer, stackingOrderIndex--);
         }
     }
 
-    if (m_posZOrderList) {
-        size_t listSize = m_posZOrderList->size();
+    if (posZOrderList) {
+        size_t listSize = posZOrderList->size();
         int stackingOrderIndex = 1;
         for (size_t i = 0; i < listSize; ++i) {
-            RenderLayer* currentLayer = m_posZOrderList->at(i);
+            RenderLayer* currentLayer = posZOrderList->at(i);
             if (!currentLayer->isStackingContext())
                 continue;
             lookup.set(currentLayer, stackingOrderIndex++);
@@ -1924,8 +1928,18 @@
 #endif
     }
 
-    if (oldNeedsCompositedScrolling != m_needsCompositedScrolling)
+    if (oldNeedsCompositedScrolling != m_needsCompositedScrolling) {
         updateSelfPaintingLayer();
+        if (isStackingContainer())
+            dirtyZOrderLists();
+        else
+            clearZOrderLists();
+
+        dirtyStackingContainerZOrderLists();
+
+        compositor()->setShouldReevaluateCompositingAfterLayout();
+        compositor()->setCompositingLayersNeedRebuild();
+    }
 }
 #endif
 
@@ -5160,7 +5174,12 @@
 {
     ASSERT(m_layerListMutationAllowed);
     ASSERT(isDirtyStackingContainer());
+    rebuildZOrderLists(StopAtStackingContainers, m_posZOrderList, m_negZOrderList);
+    m_zOrderListsDirty = false;
+}
 
+void RenderLayer::rebuildZOrderLists(CollectLayersBehavior behavior, OwnPtr<Vector<RenderLayer*> >& posZOrderList, OwnPtr<Vector<RenderLayer*> >& negZOrderList)
+{
 #if USE(ACCELERATED_COMPOSITING)
     bool includeHiddenLayers = compositor()->inCompositingMode();
 #else
@@ -5168,14 +5187,14 @@
 #endif
     for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
         if (!m_reflection || reflectionLayer() != child)
-            child->collectLayers(includeHiddenLayers, m_posZOrderList, m_negZOrderList);
+            child->collectLayers(includeHiddenLayers, behavior, posZOrderList, negZOrderList);
 
     // Sort the two lists.
-    if (m_posZOrderList)
-        std::stable_sort(m_posZOrderList->begin(), m_posZOrderList->end(), compareZIndex);
+    if (posZOrderList)
+        std::stable_sort(posZOrderList->begin(), posZOrderList->end(), compareZIndex);
 
-    if (m_negZOrderList)
-        std::stable_sort(m_negZOrderList->begin(), m_negZOrderList->end(), compareZIndex);
+    if (negZOrderList)
+        std::stable_sort(negZOrderList->begin(), negZOrderList->end(), compareZIndex);
 
 #if ENABLE(DIALOG_ELEMENT)
     // Append layers for top layer elements after normal layer collection, to ensure they are on top regardless of z-indexes.
@@ -5186,13 +5205,12 @@
             Element* childElement = (child->node() && child->node()->isElementNode()) ? toElement(child->node()) : 0;
             if (childElement && childElement->isInTopLayer()) {
                 RenderLayer* layer = toRenderLayerModelObject(child)->layer();
-                m_posZOrderList->append(layer);
+                posZOrderList->append(layer);
             }
         }
     }
 #endif
 
-    m_zOrderListsDirty = false;
 }
 
 void RenderLayer::updateNormalFlowList()
@@ -5214,7 +5232,7 @@
     m_normalFlowListDirty = false;
 }
 
-void RenderLayer::collectLayers(bool includeHiddenLayers, OwnPtr<Vector<RenderLayer*> >& posBuffer, OwnPtr<Vector<RenderLayer*> >& negBuffer)
+void RenderLayer::collectLayers(bool includeHiddenLayers, CollectLayersBehavior behavior, OwnPtr<Vector<RenderLayer*> >& posBuffer, OwnPtr<Vector<RenderLayer*> >& negBuffer)
 {
 #if ENABLE(DIALOG_ELEMENT)
     if (isInTopLayer())
@@ -5223,7 +5241,7 @@
 
     updateDescendantDependentFlags();
 
-    bool isStacking = isStackingContainer();
+    bool isStacking = behavior == StopAtStackingContexts ? isStackingContext() : isStackingContainer();
     // 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() && !renderer()->isRenderFlowThread()) {
@@ -5244,7 +5262,7 @@
         for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
             // Ignore reflections.
             if (!m_reflection || reflectionLayer() != child)
-                child->collectLayers(includeHiddenLayers, posBuffer, negBuffer);
+                child->collectLayers(includeHiddenLayers, behavior, posBuffer, negBuffer);
         }
     }
 }
@@ -5252,7 +5270,6 @@
 void RenderLayer::updateLayerListsIfNeeded()
 {
     bool shouldUpdateDescendantsAreContiguousInStackingOrder = isStackingContext() && (m_zOrderListsDirty || m_normalFlowListDirty);
-
     updateZOrderLists();
     updateNormalFlowList();
 
@@ -5261,8 +5278,13 @@
         reflectionLayer->updateNormalFlowList();
     }
 
-    if (shouldUpdateDescendantsAreContiguousInStackingOrder)
+    if (shouldUpdateDescendantsAreContiguousInStackingOrder) {
         updateDescendantsAreContiguousInStackingOrder();
+        // The above function can cause us to update m_needsCompositedScrolling
+        // and dirty our layer lists. Refresh them if necessary.
+        updateZOrderLists();
+        updateNormalFlowList();
+    }
 }
 
 void RenderLayer::updateCompositingAndLayerListsIfNeeded()

Modified: trunk/Source/WebCore/rendering/RenderLayer.h (140998 => 140999)


--- trunk/Source/WebCore/rendering/RenderLayer.h	2013-01-28 21:15:32 UTC (rev 140998)
+++ trunk/Source/WebCore/rendering/RenderLayer.h	2013-01-28 21:18:14 UTC (rev 140999)
@@ -432,8 +432,10 @@
     bool isStackingContext() const { return isStackingContext(renderer()->style()); }
 
     // A stacking container can have z-order lists. All stacking contexts are
-    // stacking containers, but the converse is not true.
-    bool isStackingContainer() const { return isStackingContext(); }
+    // stacking containers, but the converse is not true. Layers that use
+    // composited scrolling are stacking containers, but they may not
+    // necessarily be stacking contexts.
+    bool isStackingContainer() const { return isStackingContext() || needsCompositedScrolling(); }
 
     // Gets the enclosing stacking container for this layer.
     RenderLayer* stackingContainer() const;
@@ -759,8 +761,11 @@
 #endif
 
 private:
+    enum CollectLayersBehavior { StopAtStackingContexts, StopAtStackingContainers };
+
     void updateZOrderLists();
     void rebuildZOrderLists();
+    void rebuildZOrderLists(CollectLayersBehavior, OwnPtr<Vector<RenderLayer*> >&, OwnPtr<Vector<RenderLayer*> >&);
     void clearZOrderLists();
 
     void updateNormalFlowList();
@@ -831,7 +836,7 @@
     LayoutUnit renderBoxX() const { return renderBoxLocation().x(); }
     LayoutUnit renderBoxY() const { return renderBoxLocation().y(); }
 
-    void collectLayers(bool includeHiddenLayers, OwnPtr<Vector<RenderLayer*> >&, OwnPtr<Vector<RenderLayer*> >&);
+    void collectLayers(bool includeHiddenLayers, CollectLayersBehavior, OwnPtr<Vector<RenderLayer*> >&, OwnPtr<Vector<RenderLayer*> >&);
 
     void updateCompositingAndLayerListsIfNeeded();
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to