Title: [164759] trunk/Source/WebCore
Revision
164759
Author
simon.fra...@apple.com
Date
2014-02-26 17:04:23 -0800 (Wed, 26 Feb 2014)

Log Message

Prepare for overflow scrolling nodes in the scrolling tree
https://bugs.webkit.org/show_bug.cgi?id=129398

Reviewed by Tim Horton.

Lay some groundwork for overflow:scrolling nodes in the scrolling tree.
Change terminology to refer to "scroll-coordinatored" layers now, not just viewport-constrained
layers.

A given layer can be both viewport-constrained and overflow-scrolling (e.g. position:fixed,
overflow:scroll), so handle that in RenderLayerBacking, and use some "reason" flags
in RenderLayerCompositor.

* page/FrameView.cpp:
(WebCore::FrameView::scrollLayerID): Rename
* page/scrolling/ScrollingStateTree.cpp:
(WebCore::ScrollingStateTree::attachNode): Remove invalid assertion.
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::RenderLayerBacking):
(WebCore::RenderLayerBacking::updateGraphicsLayerGeometry):
(WebCore::RenderLayerBacking::updateScrollingLayers): Simplify the logic with
an early return.
(WebCore::RenderLayerBacking::detachFromScrollingCoordinator):
Allow a layer to play both viewport-constrained and scrolling roles
in the scrolling tree.
* rendering/RenderLayerBacking.h:
(WebCore::RenderLayerBacking::viewportConstrainedNodeID):
(WebCore::RenderLayerBacking::setViewportConstrainedNodeID):
(WebCore::RenderLayerBacking::scrollingNodeID):
(WebCore::RenderLayerBacking::setScrollingNodeID):
(WebCore::RenderLayerBacking::scrollingNodeIDForChildren):
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::flushPendingLayerChanges):
(WebCore::RenderLayerCompositor::didFlushChangesForLayer):
(WebCore::RenderLayerCompositor::updateBacking):
(WebCore::RenderLayerCompositor::layerWillBeRemoved):
(WebCore::RenderLayerCompositor::fixedRootBackgroundLayerChanged):
(WebCore::RenderLayerCompositor::clearBackingForLayerIncludingDescendants):
(WebCore::RenderLayerCompositor::requiresCompositingLayer):
(WebCore::RenderLayerCompositor::requiresOwnBackingStore):
(WebCore::RenderLayerCompositor::reasonsForCompositing):
(WebCore::RenderLayerCompositor::requiresCompositingForScrolling):
(WebCore::isViewportConstrainedFixedOrStickyLayer):
(WebCore::isMainFrameScrollingOrOverflowScrolling):
(WebCore::RenderLayerCompositor::rootLayerAttachmentChanged):
(WebCore::RenderLayerCompositor::updateScrollCoordinatedStatus):
(WebCore::RenderLayerCompositor::removeFromScrollCoordinatedLayers):
(WebCore::nearestScrollCoordinatedAncestor):
(WebCore::RenderLayerCompositor::updateScrollCoordinatedLayer):
(WebCore::RenderLayerCompositor::detachScrollCoordinatedLayer):
(WebCore::RenderLayerCompositor::registerAllViewportConstrainedLayers):
(WebCore::RenderLayerCompositor::willRemoveScrollingLayer):
(WebCore::RenderLayerCompositor::didAddScrollingLayer):
* rendering/RenderLayerCompositor.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (164758 => 164759)


--- trunk/Source/WebCore/ChangeLog	2014-02-27 00:52:48 UTC (rev 164758)
+++ trunk/Source/WebCore/ChangeLog	2014-02-27 01:04:23 UTC (rev 164759)
@@ -1,3 +1,60 @@
+2014-02-26  Simon Fraser  <simon.fra...@apple.com>
+
+        Prepare for overflow scrolling nodes in the scrolling tree
+        https://bugs.webkit.org/show_bug.cgi?id=129398
+
+        Reviewed by Tim Horton.
+
+        Lay some groundwork for overflow:scrolling nodes in the scrolling tree.
+        Change terminology to refer to "scroll-coordinatored" layers now, not just viewport-constrained
+        layers.
+        
+        A given layer can be both viewport-constrained and overflow-scrolling (e.g. position:fixed,
+        overflow:scroll), so handle that in RenderLayerBacking, and use some "reason" flags
+        in RenderLayerCompositor.
+
+        * page/FrameView.cpp:
+        (WebCore::FrameView::scrollLayerID): Rename
+        * page/scrolling/ScrollingStateTree.cpp:
+        (WebCore::ScrollingStateTree::attachNode): Remove invalid assertion.
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::RenderLayerBacking::RenderLayerBacking):
+        (WebCore::RenderLayerBacking::updateGraphicsLayerGeometry):
+        (WebCore::RenderLayerBacking::updateScrollingLayers): Simplify the logic with
+        an early return.
+        (WebCore::RenderLayerBacking::detachFromScrollingCoordinator):
+        Allow a layer to play both viewport-constrained and scrolling roles
+        in the scrolling tree.
+        * rendering/RenderLayerBacking.h:
+        (WebCore::RenderLayerBacking::viewportConstrainedNodeID):
+        (WebCore::RenderLayerBacking::setViewportConstrainedNodeID):
+        (WebCore::RenderLayerBacking::scrollingNodeID):
+        (WebCore::RenderLayerBacking::setScrollingNodeID):
+        (WebCore::RenderLayerBacking::scrollingNodeIDForChildren):
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::flushPendingLayerChanges):
+        (WebCore::RenderLayerCompositor::didFlushChangesForLayer):
+        (WebCore::RenderLayerCompositor::updateBacking):
+        (WebCore::RenderLayerCompositor::layerWillBeRemoved):
+        (WebCore::RenderLayerCompositor::fixedRootBackgroundLayerChanged):
+        (WebCore::RenderLayerCompositor::clearBackingForLayerIncludingDescendants):
+        (WebCore::RenderLayerCompositor::requiresCompositingLayer):
+        (WebCore::RenderLayerCompositor::requiresOwnBackingStore):
+        (WebCore::RenderLayerCompositor::reasonsForCompositing):
+        (WebCore::RenderLayerCompositor::requiresCompositingForScrolling):
+        (WebCore::isViewportConstrainedFixedOrStickyLayer):
+        (WebCore::isMainFrameScrollingOrOverflowScrolling):
+        (WebCore::RenderLayerCompositor::rootLayerAttachmentChanged):
+        (WebCore::RenderLayerCompositor::updateScrollCoordinatedStatus):
+        (WebCore::RenderLayerCompositor::removeFromScrollCoordinatedLayers):
+        (WebCore::nearestScrollCoordinatedAncestor):
+        (WebCore::RenderLayerCompositor::updateScrollCoordinatedLayer):
+        (WebCore::RenderLayerCompositor::detachScrollCoordinatedLayer):
+        (WebCore::RenderLayerCompositor::registerAllViewportConstrainedLayers):
+        (WebCore::RenderLayerCompositor::willRemoveScrollingLayer):
+        (WebCore::RenderLayerCompositor::didAddScrollingLayer):
+        * rendering/RenderLayerCompositor.h:
+
 2014-02-26  Andy Estes  <aes...@apple.com>
 
         [iOS] Support network state notification using CPNetworkObserver

Modified: trunk/Source/WebCore/page/FrameView.cpp (164758 => 164759)


--- trunk/Source/WebCore/page/FrameView.cpp	2014-02-27 00:52:48 UTC (rev 164758)
+++ trunk/Source/WebCore/page/FrameView.cpp	2014-02-27 01:04:23 UTC (rev 164759)
@@ -814,7 +814,7 @@
     if (!backing)
         return 0;
 
-    return backing->scrollLayerID();
+    return backing->scrollingNodeID();
 }
 
 #if ENABLE(RUBBER_BANDING)

Modified: trunk/Source/WebCore/page/scrolling/ScrollingStateTree.cpp (164758 => 164759)


--- trunk/Source/WebCore/page/scrolling/ScrollingStateTree.cpp	2014-02-27 00:52:48 UTC (rev 164758)
+++ trunk/Source/WebCore/page/scrolling/ScrollingStateTree.cpp	2014-02-27 01:04:23 UTC (rev 164759)
@@ -108,8 +108,6 @@
             break;
         }
         case ScrollingNode: {
-            // FIXME: We currently only support child nodes that are fixed.
-            ASSERT_NOT_REACHED();
             OwnPtr<ScrollingStateScrollingNode> scrollingNode = ScrollingStateScrollingNode::create(*this, newNodeID);
             newNode = scrollingNode.get();
             parent->appendChild(scrollingNode.release());

Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.cpp (164758 => 164759)


--- trunk/Source/WebCore/rendering/RenderLayerBacking.cpp	2014-02-27 00:52:48 UTC (rev 164758)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.cpp	2014-02-27 01:04:23 UTC (rev 164759)
@@ -109,7 +109,8 @@
 
 RenderLayerBacking::RenderLayerBacking(RenderLayer& layer)
     : m_owningLayer(layer)
-    , m_scrollLayerID(0)
+    , m_viewportConstrainedNodeID(0)
+    , m_scrollingNodeID(0)
     , m_artificiallyInflatedBounds(false)
     , m_isMainFrameRenderViewLayer(false)
     , m_usingTiledCacheLayer(false)
@@ -951,9 +952,7 @@
         m_scrollingContentsLayer->setSize(scrollSize);
         // Scrolling the content layer does not need to trigger a repaint. The offset will be compensated away during painting.
         // FIXME: The paint offset and the scroll offset should really be separate concepts.
-        m_scrollingContentsLayer->setOffsetFromRenderer(paddingBox.location() - FloatPoint() - scrollOffset, GraphicsLayer::DontSetNeedsDisplay);
-        
-        compositor().scrollingLayerAddedOrUpdated(&m_owningLayer);
+        m_scrollingContentsLayer->setOffsetFromRenderer(paddingBox.location() - IntPoint() - scrollOffset, GraphicsLayer::DontSetNeedsDisplay);
 #else
         m_scrollingContentsLayer->setPosition(FloatPoint(-scrollOffset.width(), -scrollOffset.height()));
 
@@ -992,7 +991,7 @@
     updateDrawsContent(isSimpleContainer);
     updateAfterWidgetResize();
 
-    compositor().updateViewportConstraintStatus(m_owningLayer);
+    compositor().updateScrollCoordinatedStatus(m_owningLayer);
 }
 
 void RenderLayerBacking::adjustAncestorCompositingBoundsForFlowThread(LayoutRect& ancestorCompositingBounds, const RenderLayer* compositingAncestor) const
@@ -1423,91 +1422,59 @@
 
 bool RenderLayerBacking::updateScrollingLayers(bool needsScrollingLayers)
 {
-    ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer);
+    if (needsScrollingLayers == !!m_scrollingLayer)
+        return false;
 
-    bool layerChanged = false;
-    if (needsScrollingLayers) {
-        if (!m_scrollingLayer) {
-            // Outer layer which corresponds with the scroll view.
-            m_scrollingLayer = createGraphicsLayer("Scrolling container");
-            m_scrollingLayer->setDrawsContent(false);
-            m_scrollingLayer->setMasksToBounds(true);
+    if (!m_scrollingLayer) {
+        // Outer layer which corresponds with the scroll view.
+        m_scrollingLayer = createGraphicsLayer("Scrolling container");
+        m_scrollingLayer->setDrawsContent(false);
+        m_scrollingLayer->setMasksToBounds(true);
 
-            // Inner layer which renders the content that scrolls.
-            m_scrollingContentsLayer = createGraphicsLayer("Scrolled Contents");
-            m_scrollingContentsLayer->setDrawsContent(true);
-            GraphicsLayerPaintingPhase paintPhase = GraphicsLayerPaintOverflowContents | GraphicsLayerPaintCompositedScroll;
-            if (!m_foregroundLayer)
-                paintPhase |= GraphicsLayerPaintForeground;
-            m_scrollingContentsLayer->setPaintingPhase(paintPhase);
-            m_scrollingLayer->addChild(m_scrollingContentsLayer.get());
+        // Inner layer which renders the content that scrolls.
+        m_scrollingContentsLayer = createGraphicsLayer("Scrolled Contents");
+        m_scrollingContentsLayer->setDrawsContent(true);
+        GraphicsLayerPaintingPhase paintPhase = GraphicsLayerPaintOverflowContents | GraphicsLayerPaintCompositedScroll;
+        if (!m_foregroundLayer)
+            paintPhase |= GraphicsLayerPaintForeground;
+        m_scrollingContentsLayer->setPaintingPhase(paintPhase);
+        m_scrollingLayer->addChild(m_scrollingContentsLayer.get());
+    } else {
+        compositor().willRemoveScrollingLayer(m_owningLayer);
 
-            layerChanged = true;
-            if (scrollingCoordinator)
-                scrollingCoordinator->scrollableAreaScrollLayerDidChange(&m_owningLayer);
-#if PLATFORM(IOS)
-            if (m_owningLayer.parent())
-                compositor().scrollingLayerAddedOrUpdated(&m_owningLayer);
-#endif
-        }
-    } else if (m_scrollingLayer) {
-#if PLATFORM(IOS)
-        if (!renderer().documentBeingDestroyed())
-            compositor().scrollingLayerRemoved(&m_owningLayer, m_scrollingLayer->platformLayer(), m_scrollingContentsLayer->platformLayer());
-#endif
         willDestroyLayer(m_scrollingLayer.get());
         willDestroyLayer(m_scrollingContentsLayer.get());
         m_scrollingLayer = nullptr;
         m_scrollingContentsLayer = nullptr;
-        layerChanged = true;
-        if (scrollingCoordinator)
-            scrollingCoordinator->scrollableAreaScrollLayerDidChange(&m_owningLayer);
     }
 
-    if (layerChanged) {
-        updateInternalHierarchy();
-        m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer());
-#if !PLATFORM(IOS)
-        m_graphicsLayer->setNeedsDisplay();
-        compositor().scrollingLayerDidChange(m_owningLayer);
-#endif
-    }
+    updateInternalHierarchy();
+    m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer());
+    m_graphicsLayer->setNeedsDisplay(); // Because painting phases changed.
 
-    return layerChanged;
+    if (m_scrollingLayer)
+        compositor().didAddScrollingLayer(m_owningLayer);
+    
+    return true;
 }
 
-void RenderLayerBacking::attachToScrollingCoordinatorWithParent(RenderLayerBacking* parent)
-{
-    ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer);
-    if (!scrollingCoordinator)
-        return;
-
-    // FIXME: When we support overflow areas, we will have to refine this for overflow areas that are also
-    // positon:fixed.
-    ScrollingNodeType nodeType;
-    if (renderer().style().position() == FixedPosition)
-        nodeType = FixedNode;
-    else if (renderer().style().position() == StickyPosition)
-        nodeType = StickyNode;
-    else
-        nodeType = ScrollingNode;
-
-    ScrollingNodeID parentID = parent ? parent->scrollLayerID() : 0;
-    m_scrollLayerID = scrollingCoordinator->attachToStateTree(nodeType, m_scrollLayerID ? m_scrollLayerID : scrollingCoordinator->uniqueScrollLayerID(), parentID);
-}
-
 void RenderLayerBacking::detachFromScrollingCoordinator()
 {
-    // If m_scrollLayerID is 0, then this backing is not attached to the ScrollingCoordinator.
-    if (!m_scrollLayerID)
+    if (!m_scrollingNodeID && !m_viewportConstrainedNodeID)
         return;
 
     ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer);
     if (!scrollingCoordinator)
         return;
 
-    scrollingCoordinator->detachFromStateTree(m_scrollLayerID);
-    m_scrollLayerID = 0;
+    if (m_scrollingNodeID)
+        scrollingCoordinator->detachFromStateTree(m_scrollingNodeID);
+
+    if (m_viewportConstrainedNodeID)
+        scrollingCoordinator->detachFromStateTree(m_viewportConstrainedNodeID);
+
+    m_scrollingNodeID = 0;
+    m_viewportConstrainedNodeID = 0;
 }
 
 GraphicsLayerPaintingPhase RenderLayerBacking::paintingPhaseForPrimaryLayer() const

Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.h (164758 => 164759)


--- trunk/Source/WebCore/rendering/RenderLayerBacking.h	2014-02-27 00:52:48 UTC (rev 164758)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.h	2014-02-27 01:04:23 UTC (rev 164759)
@@ -31,6 +31,7 @@
 #include "GraphicsLayer.h"
 #include "GraphicsLayerClient.h"
 #include "RenderLayer.h"
+#include "ScrollingCoordinator.h"
 
 namespace WebCore {
 
@@ -101,10 +102,16 @@
     GraphicsLayer* scrollingLayer() const { return m_scrollingLayer.get(); }
     GraphicsLayer* scrollingContentsLayer() const { return m_scrollingContentsLayer.get(); }
 
-    void attachToScrollingCoordinatorWithParent(RenderLayerBacking* parent);
     void detachFromScrollingCoordinator();
-    uint64_t scrollLayerID() const { return m_scrollLayerID; }
+
+    ScrollingNodeID viewportConstrainedNodeID() const { return m_viewportConstrainedNodeID; }
+    void setViewportConstrainedNodeID(ScrollingNodeID nodeID) { m_viewportConstrainedNodeID = nodeID; }
+
+    ScrollingNodeID scrollingNodeID() const { return m_scrollingNodeID; }
+    void setScrollingNodeID(ScrollingNodeID nodeID) { m_scrollingNodeID = nodeID; }
     
+    ScrollingNodeID scrollingNodeIDForChildren() const { return m_scrollingNodeID ? m_scrollingNodeID : m_viewportConstrainedNodeID; }
+
     bool hasMaskLayer() const { return m_maskLayer != 0; }
 
     GraphicsLayer* parentForSublayers() const;
@@ -308,7 +315,8 @@
     std::unique_ptr<GraphicsLayer> m_scrollingLayer; // Only used if the layer is using composited scrolling.
     std::unique_ptr<GraphicsLayer> m_scrollingContentsLayer; // Only used if the layer is using composited scrolling.
 
-    uint64_t m_scrollLayerID;
+    ScrollingNodeID m_viewportConstrainedNodeID;
+    ScrollingNodeID m_scrollingNodeID;
 
     LayoutRect m_compositedBounds;
     LayoutSize m_devicePixelFractionFromRenderer;

Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp (164758 => 164759)


--- trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp	2014-02-27 00:52:48 UTC (rev 164758)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp	2014-02-27 01:04:23 UTC (rev 164759)
@@ -439,10 +439,10 @@
         client->didFlushCompositingLayers();
 #endif
 
-    for (auto it = m_viewportConstrainedLayersNeedingUpdate.begin(), end = m_viewportConstrainedLayersNeedingUpdate.end(); it != end; ++it)
-        registerOrUpdateViewportConstrainedLayer(**it);
+    for (auto it = m_scrollCoordinatedLayersNeedingUpdate.begin(), end = m_scrollCoordinatedLayersNeedingUpdate.end(); it != end; ++it)
+        updateScrollCoordinatedStatus(**it);
 
-    m_viewportConstrainedLayersNeedingUpdate.clear();
+    m_scrollCoordinatedLayersNeedingUpdate.clear();
     startLayerFlushTimerIfNeeded();
 }
 
@@ -488,8 +488,8 @@
 
 void RenderLayerCompositor::didFlushChangesForLayer(RenderLayer& layer, const GraphicsLayer* graphicsLayer)
 {
-    if (m_viewportConstrainedLayers.contains(&layer))
-        m_viewportConstrainedLayersNeedingUpdate.add(&layer);
+    if (m_scrollCoordinatedLayers.contains(&layer))
+        m_scrollCoordinatedLayersNeedingUpdate.add(&layer);
 
 #if PLATFORM(IOS)
     if (m_scrollingLayers.contains(&layer))
@@ -774,7 +774,7 @@
 
             // At this time, the ScrollingCoordinator only supports the top-level frame.
             if (layer.isRootLayer() && !m_renderView.document().ownerElement()) {
-                layer.backing()->attachToScrollingCoordinatorWithParent(0);
+                updateScrollCoordinatedStatus(layer);
                 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
                     scrollingCoordinator->frameViewRootLayerDidChange(&m_renderView.frameView());
 #if ENABLE(RUBBER_BANDING)
@@ -807,7 +807,7 @@
                 }
             }
 
-            removeViewportConstrainedLayer(layer);
+            detachScrollCoordinatedLayer(layer);
             
             layer.clearBacking();
             layerChanged = true;
@@ -930,7 +930,7 @@
     if (!child.isComposited() || parent.renderer().documentBeingDestroyed())
         return;
 
-    removeViewportConstrainedLayer(child);
+    removeFromScrollCoordinatedLayers(child);
     repaintInCompositedAncestor(child, child.backing()->compositedBounds());
 
     setCompositingParent(child, nullptr);
@@ -1559,13 +1559,8 @@
     if (m_renderView.documentBeingDestroyed())
         return;
 
-    if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) {
-        RenderLayerBacking* renderViewBacking = m_renderView.layer()->backing();
-        if (!renderViewBacking)
-            return;
-
-        scrollingCoordinator->updateScrollingNode(renderViewBacking->scrollLayerID(), scrollLayer(), nullptr, fixedRootBackgroundLayer());
-    }
+    if (m_renderView.layer()->isComposited())
+        updateScrollCoordinatedStatus(*m_renderView.layer());
 }
 
 String RenderLayerCompositor::layerTreeAsText(LayerTreeFlags flags)
@@ -1867,7 +1862,7 @@
 void RenderLayerCompositor::clearBackingForLayerIncludingDescendants(RenderLayer& layer)
 {
     if (layer.isComposited()) {
-        removeViewportConstrainedLayer(layer);
+        removeFromScrollCoordinatedLayers(layer);
         layer.clearBacking();
     }
 
@@ -1985,7 +1980,7 @@
         || requiresCompositingForFilters(*renderer)
         || requiresCompositingForPosition(*renderer, *renderer->layer(), viewportConstrainedNotCompositedReason)
 #if PLATFORM(IOS)
-        || requiresCompositingForScrolling(*renderer)
+        || requiresCompositingForScrolling(*renderer->layer())
 #endif
         || requiresCompositingForOverflowScrolling(*renderer->layer());
 }
@@ -2033,7 +2028,7 @@
         || renderer.hasReflection()
         || renderer.hasFilter()
 #if PLATFORM(IOS)
-        || requiresCompositingForScrolling(renderer)
+        || requiresCompositingForScrolling(layer)
 #endif
         )
         return true;
@@ -2093,7 +2088,7 @@
         reasons |= renderer->style().position() == FixedPosition ? CompositingReasonPositionFixed : CompositingReasonPositionSticky;
 
 #if PLATFORM(IOS)
-    if (requiresCompositingForScrolling(*renderer))
+    if (requiresCompositingForScrolling(*renderer->layer()))
         reasons |= CompositingReasonOverflowScrollingTouch;
 #endif
 
@@ -2416,9 +2411,9 @@
 }
 
 #if PLATFORM(IOS)
-bool RenderLayerCompositor::requiresCompositingForScrolling(RenderLayerModelObject& renderer) const
+bool RenderLayerCompositor::requiresCompositingForScrolling(const RenderLayer& layer) const
 {
-    return renderer.hasLayer() && toRenderBoxModelObject(renderer).layer()->hasAcceleratedTouchScrolling();
+    return layer.hasAcceleratedTouchScrolling();
 }
 #endif
 
@@ -2464,6 +2459,7 @@
     if (layer.renderer().style().position() != FixedPosition)
         return false;
 
+    // FIXME: Handle fixed inside of a transform, which should not behave as fixed.
     for (RenderLayer* stackingContainer = layer.stackingContainer(); stackingContainer; stackingContainer = stackingContainer->stackingContainer()) {
         if (stackingContainer->isComposited() && stackingContainer->renderer().style().position() == FixedPosition)
             return false;
@@ -2472,6 +2468,18 @@
     return true;
 }
 
+static bool isMainFrameScrollingOrOverflowScrolling(RenderView& view, const RenderLayer& layer)
+{
+    if (layer.isRootLayer() && !view.document().ownerElement())
+        return true;
+
+#if PLATFORM(IOS)
+    return layer.hasAcceleratedTouchScrolling();
+#else
+    return layer.needsCompositedScrolling();
+#endif
+}
+
 bool RenderLayerCompositor::requiresCompositingForPosition(RenderLayerModelObject& renderer, const RenderLayer& layer, RenderLayer::ViewportConstrainedNotCompositedReason* viewportConstrainedNotCompositedReason) const
 {
     // position:fixed elements that create their own stacking context (e.g. have an explicit z-index,
@@ -3268,7 +3276,7 @@
 void RenderLayerCompositor::rootLayerAttachmentChanged()
 {
     // The attachment can affect whether the RenderView layer's paintsIntoWindow() behavior,
-    // so call updateGraphicsLayerGeometry() to udpate that.
+    // so call updateDrawsContent() to update that.
     RenderLayer* layer = m_renderView.layer();
     if (RenderLayerBacking* backing = layer ? layer->backing() : 0)
         backing->updateDrawsContent();
@@ -3342,28 +3350,30 @@
         rootLayer->noteDeviceOrPageScaleFactorChangedIncludingDescendants();
 }
 
-void RenderLayerCompositor::updateViewportConstraintStatus(RenderLayer& layer)
+void RenderLayerCompositor::updateScrollCoordinatedStatus(RenderLayer& layer)
 {
+    ScrollCoordinationReasons coordinationReasons = 0;
     if (isViewportConstrainedFixedOrStickyLayer(layer))
-        addViewportConstrainedLayer(layer);
-    else
-        removeViewportConstrainedLayer(layer);
-}
+        coordinationReasons |= FixedOrSticky;
 
-void RenderLayerCompositor::addViewportConstrainedLayer(RenderLayer& layer)
-{
-    m_viewportConstrainedLayers.add(&layer);
-    registerOrUpdateViewportConstrainedLayer(layer);
+    if (isMainFrameScrollingOrOverflowScrolling(m_renderView, layer))
+        coordinationReasons |= Scrolling;
+        
+    if (coordinationReasons) {
+        m_scrollCoordinatedLayers.add(&layer);
+        updateScrollCoordinatedLayer(layer, coordinationReasons);
+    } else
+        removeFromScrollCoordinatedLayers(layer);
 }
 
-void RenderLayerCompositor::removeViewportConstrainedLayer(RenderLayer& layer)
+void RenderLayerCompositor::removeFromScrollCoordinatedLayers(RenderLayer& layer)
 {
-    if (!m_viewportConstrainedLayers.contains(&layer))
+    if (!m_scrollCoordinatedLayers.contains(&layer))
         return;
 
-    unregisterViewportConstrainedLayer(layer);
-    m_viewportConstrainedLayers.remove(&layer);
-    m_viewportConstrainedLayersNeedingUpdate.remove(&layer);
+    removeFromScrollCoordinatedLayers(layer);
+    m_scrollCoordinatedLayers.remove(&layer);
+    m_scrollCoordinatedLayersNeedingUpdate.remove(&layer);
 }
 
 FixedPositionViewportConstraints RenderLayerCompositor::computeFixedViewportConstraints(RenderLayer& layer) const
@@ -3424,12 +3434,12 @@
     return constraints;
 }
 
-static RenderLayerBacking* nearestScrollingCoordinatorAncestor(RenderLayer& layer)
+static RenderLayerBacking* nearestScrollCoordinatedAncestor(RenderLayer& layer)
 {
     RenderLayer* ancestor = layer.parent();
     while (ancestor) {
         if (RenderLayerBacking* backing = ancestor->backing()) {
-            if (backing->scrollLayerID() && !ancestor->scrollsOverflow())
+            if (backing->scrollingNodeIDForChildren())
                 return backing;
         }
         ancestor = ancestor->parent();
@@ -3438,46 +3448,92 @@
     return nullptr;
 }
 
-void RenderLayerCompositor::registerOrUpdateViewportConstrainedLayer(RenderLayer& layer)
+void RenderLayerCompositor::updateScrollCoordinatedLayer(RenderLayer& layer, ScrollCoordinationReasons reasons)
 {
-    // FIXME: We should support sticky position here! And we should eventuall support fixed/sticky elements
-    // that are inside non-main frames once we get non-main frames scrolling with the ScrollingCoordinator.
+    // FIXME: support scrolling layers in iframes.
     if (m_renderView.document().ownerElement())
         return;
 
     ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator();
     if (!scrollingCoordinator)
         return;
+    
+    bool isRootLayer = &layer == m_renderView.layer();
 
-    // FIXME: rename to supportsViewportConstrainedPositionLayers()?
-    if (!scrollingCoordinator->supportsFixedPositionLayers() || !layer.parent())
+    // FIXME: Remove supportsFixedPositionLayers() since all platforms support them now.
+    if (!scrollingCoordinator->supportsFixedPositionLayers() || (!layer.parent() && !isRootLayer))
         return;
 
-    ASSERT(m_viewportConstrainedLayers.contains(&layer));
+    ASSERT(m_scrollCoordinatedLayers.contains(&layer));
     ASSERT(layer.isComposited());
 
     RenderLayerBacking* backing = layer.backing();
     if (!backing)
         return;
 
-    ScrollingNodeID nodeID = backing->scrollLayerID();
-    RenderLayerBacking* parent = nearestScrollingCoordinatorAncestor(layer);
-    if (!parent)
+    RenderLayerBacking* parent = nearestScrollCoordinatedAncestor(layer);
+    if (!parent && !isRootLayer)
         return;
 
+    ScrollingNodeID parentNodeID = parent ? parent->scrollingNodeIDForChildren() : 0;
+    
     // Always call this even if the backing is already attached because the parent may have changed.
-    backing->attachToScrollingCoordinatorWithParent(parent);
-    nodeID = backing->scrollLayerID();
+    // If a node plays both roles, fixed/sticky is always the ancestor node of scrolling.
+    if (reasons & FixedOrSticky) {
+        ScrollingNodeID nodeID = backing->viewportConstrainedNodeID();
+        if (!nodeID)
+            nodeID = scrollingCoordinator->uniqueScrollLayerID();
 
-    if (layer.renderer().isStickyPositioned())
-        scrollingCoordinator->updateViewportConstrainedNode(nodeID, computeStickyViewportConstraints(layer), backing->graphicsLayer());
-    else
-        scrollingCoordinator->updateViewportConstrainedNode(nodeID, computeFixedViewportConstraints(layer), backing->graphicsLayer());
+        ScrollingNodeType nodeType = ScrollingNode;
+        if (layer.renderer().style().position() == FixedPosition)
+            nodeType = FixedNode;
+        else if (layer.renderer().style().position() == StickyPosition)
+            nodeType = StickyNode;
+        else
+            ASSERT_NOT_REACHED();
+
+        nodeID = scrollingCoordinator->attachToStateTree(nodeType, nodeID, parentNodeID);
+        backing->setViewportConstrainedNodeID(nodeID);
+
+        switch (nodeType) {
+        case FixedNode:
+            scrollingCoordinator->updateViewportConstrainedNode(nodeID, computeFixedViewportConstraints(layer), backing->graphicsLayer());
+            break;
+        case StickyNode:
+            scrollingCoordinator->updateViewportConstrainedNode(nodeID, computeStickyViewportConstraints(layer), backing->graphicsLayer());
+            break;
+        case ScrollingNode:
+            break;
+        }
+        
+        parentNodeID = nodeID;
+    }
+
+    if (reasons & Scrolling) {
+        ScrollingNodeID nodeID = backing->scrollingNodeID();
+        if (!nodeID)
+            nodeID = scrollingCoordinator->uniqueScrollLayerID();
+
+        nodeID = scrollingCoordinator->attachToStateTree(ScrollingNode, nodeID, parentNodeID);
+        backing->setScrollingNodeID(nodeID);
+
+        GraphicsLayer* scrollingLayer = backing->scrollingLayer();
+        GraphicsLayer* scrolledContentsLayer = backing->scrollingContentsLayer();
+        GraphicsLayer* counterScrollingLayer = nullptr;
+
+        if (&layer == m_renderView.layer()) {
+            scrollingLayer = m_scrollLayer.get();
+            scrolledContentsLayer = nullptr;
+            counterScrollingLayer = fixedRootBackgroundLayer();
+        }
+    
+        scrollingCoordinator->updateScrollingNode(nodeID, scrollingLayer, scrolledContentsLayer, counterScrollingLayer);
+    }
 }
 
-void RenderLayerCompositor::unregisterViewportConstrainedLayer(RenderLayer& layer)
+void RenderLayerCompositor::detachScrollCoordinatedLayer(RenderLayer& layer)
 {
-    ASSERT(m_viewportConstrainedLayers.contains(&layer));
+    ASSERT(m_scrollCoordinatedLayers.contains(&layer));
 
     if (RenderLayerBacking* backing = layer.backing())
         backing->detachFromScrollingCoordinator();
@@ -3499,7 +3555,7 @@
     LayerMap layerMap;
     StickyContainerMap stickyContainerMap;
 
-    for (auto it = m_viewportConstrainedLayers.begin(), end = m_viewportConstrainedLayers.end(); it != end; ++it) {
+    for (auto it = m_scrollCoordinatedLayers.begin(), end = m_scrollCoordinatedLayers.end(); it != end; ++it) {
         RenderLayer& layer = **it;
         ASSERT(layer.isComposited());
 
@@ -3511,8 +3567,10 @@
                 ASSERT(enclosingTouchScrollableLayer->isComposited());
                 stickyContainerMap.add(layer.backing()->graphicsLayer()->platformLayer(), enclosingTouchScrollableLayer->backing()->scrollingLayer()->platformLayer());
             }
-        } else
+        } else if (layer.renderer().style().position() == FixedPosition)
             constraints = std::make_unique<FixedPositionViewportConstraints>(computeFixedViewportConstraints(layer));
+        else
+            continue;
 
         layerMap.add(layer.backing()->graphicsLayer()->platformLayer(), adoptPtr(constraints.release()));
     }
@@ -3560,26 +3618,51 @@
         client->removeScrollingLayer(layer.renderer().element(), backing->scrollingLayer()->platformLayer(), backing->scrollingContentsLayer()->platformLayer());
     }
 }
+#endif
 
-// Called when the size of the contentsLayer changes, and when the contentsLayer is replaced by another layer.
-void RenderLayerCompositor::scrollingLayerAddedOrUpdated(RenderLayer* layer)
+void RenderLayerCompositor::willRemoveScrollingLayer(RenderLayer& layer)
 {
-    ASSERT(!m_renderView.document().inPageCache());
-    m_scrollingLayers.add(layer);
+    if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) {
+        RenderLayerBacking* backing = layer.backing();
+    
+        if (backing)
+            scrollingCoordinator->detachFromStateTree(backing->scrollingNodeID());
+
+        // For Coordinated Graphics.
+        scrollingCoordinator->scrollableAreaScrollLayerDidChange(&layer);
+        return;
+    }
+
+#if PLATFORM(IOS)
+    m_scrollingLayersNeedingUpdate.remove(&layer);
+    m_scrollingLayers.remove(&layer);
+
+    if (m_renderView.document().inPageCache() || !layer.backing())
+        return;
+
+    if (ChromeClient* client = this->chromeClient()) {
+        PlatformLayer* scrollingLayer = layer.backing()->scrollingLayer()->platformLayer();
+        PlatformLayer* contentsLayer = layer.backing()->scrollingContentsLayer()->platformLayer();
+        client->removeScrollingLayer(layer.renderer().element(), scrollingLayer, contentsLayer);
+    }
+#endif
 }
 
-void RenderLayerCompositor::scrollingLayerRemoved(RenderLayer* layer, PlatformLayer* scrollingLayer, PlatformLayer* contentsLayer)
+void RenderLayerCompositor::didAddScrollingLayer(RenderLayer& layer)
 {
-    m_scrollingLayersNeedingUpdate.remove(layer);
-    m_scrollingLayers.remove(layer);
+    updateScrollCoordinatedStatus(layer);
 
-    if (m_renderView.document().inPageCache())
+    if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) {
+        // For Coordinated Graphics.
+        scrollingCoordinator->scrollableAreaScrollLayerDidChange(&layer);
         return;
+    }
 
-    if (ChromeClient* client = this->chromeClient())
-        client->removeScrollingLayer(layer->renderer().element(), scrollingLayer, contentsLayer);
+#if PLATFORM(IOS)
+    ASSERT(!m_renderView.document().inPageCache());
+    m_scrollingLayers.add(&layer);
+#endif
 }
-#endif
 
 void RenderLayerCompositor::windowScreenDidChange(PlatformDisplayID displayID)
 {

Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.h (164758 => 164759)


--- trunk/Source/WebCore/rendering/RenderLayerCompositor.h	2014-02-27 00:52:48 UTC (rev 164758)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.h	2014-02-27 01:04:23 UTC (rev 164759)
@@ -266,19 +266,20 @@
     GraphicsLayer* updateLayerForFooter(bool wantsLayer);
 #endif
 
-    void updateViewportConstraintStatus(RenderLayer&);
-    void removeViewportConstrainedLayer(RenderLayer&);
+    void updateScrollCoordinatedStatus(RenderLayer&);
+    void removeFromScrollCoordinatedLayers(RenderLayer&);
 
+    void willRemoveScrollingLayer(RenderLayer&);
+    void didAddScrollingLayer(RenderLayer&);
+
 #if PLATFORM(IOS)
     void registerAllViewportConstrainedLayers();
     void unregisterAllViewportConstrainedLayers();
 
-    void scrollingLayerAddedOrUpdated(RenderLayer*);
-    void scrollingLayerRemoved(RenderLayer*, PlatformLayer* scrollingLayer, PlatformLayer* contentsLayer);
-
     void registerAllScrollingLayers();
     void unregisterAllScrollingLayers();
 #endif
+
     void resetTrackedRepaintRects();
     void setTracksRepaints(bool);
 
@@ -395,7 +396,7 @@
     bool requiresCompositingForIndirectReason(RenderLayerModelObject&, bool hasCompositedDescendants, bool hasBlendedDescendants, bool has3DTransformedDescendants, RenderLayer::IndirectCompositingReason&) const;
 
 #if PLATFORM(IOS)
-    bool requiresCompositingForScrolling(RenderLayerModelObject&) const;
+    bool requiresCompositingForScrolling(const RenderLayer&) const;
 
     void updateCustomLayersAfterFlush();
 
@@ -403,10 +404,15 @@
 
 #endif
 
-    void addViewportConstrainedLayer(RenderLayer&);
-    void registerOrUpdateViewportConstrainedLayer(RenderLayer&);
-    void unregisterViewportConstrainedLayer(RenderLayer&);
+    enum ScrollCoordinationReason {
+        FixedOrSticky = 1 << 0,
+        Scrolling = 1 << 1
+    };
+    typedef unsigned ScrollCoordinationReasons;
 
+    void updateScrollCoordinatedLayer(RenderLayer&, ScrollCoordinationReasons);
+    void detachScrollCoordinatedLayer(RenderLayer&);
+
     FixedPositionViewportConstraints computeFixedViewportConstraints(RenderLayer&) const;
     StickyPositionViewportConstraints computeStickyViewportConstraints(RenderLayer&) const;
 
@@ -475,8 +481,8 @@
     HashSet<RenderLayer*> m_scrollingLayers;
     HashSet<RenderLayer*> m_scrollingLayersNeedingUpdate;
 #endif
-    HashSet<RenderLayer*> m_viewportConstrainedLayers;
-    HashSet<RenderLayer*> m_viewportConstrainedLayersNeedingUpdate;
+    HashSet<RenderLayer*> m_scrollCoordinatedLayers;
+    HashSet<RenderLayer*> m_scrollCoordinatedLayersNeedingUpdate;
 
     // Enclosing layer for overflow controls and the clipping layer
     std::unique_ptr<GraphicsLayer> m_overflowControlsHostLayer;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to