Title: [245818] trunk
Revision
245818
Author
[email protected]
Date
2019-05-28 11:11:52 -0700 (Tue, 28 May 2019)

Log Message

[async scrolling] Fixed positioning inside stacking context overflow scroll is jumpy
https://bugs.webkit.org/show_bug.cgi?id=198292

Reviewed by Darin Adler.

Source/WebCore:

Tests: scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll-2.html
       scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll.html

We were computing delta from the layout scroll position in ScrollingTree::notifyRelatedNodesAfterScrollPositionChange
based on the passed in node only. If any other node had deltas they were not taken into account at all. This would occur
frequently since the function is always invoked for the root node after layer tree commit.

Fix by moving the delta computation (and fetching layoutViewport) to ScrollingTreeFixedNode.

* page/scrolling/ScrollingTree.cpp:
(WebCore::ScrollingTree::applyLayerPositions):

No need to pass offset and layoutViewport around anymore.

(WebCore::ScrollingTree::applyLayerPositionsRecursive):
(WebCore::ScrollingTree::notifyRelatedNodesAfterScrollPositionChange):

Remove the offset and layoutViewport computations.

(WebCore::ScrollingTree::notifyRelatedNodesRecursive):
* page/scrolling/ScrollingTree.h:
* page/scrolling/ScrollingTreeFrameHostingNode.cpp:
(WebCore::ScrollingTreeFrameHostingNode::applyLayerPositions):
* page/scrolling/ScrollingTreeFrameHostingNode.h:
* page/scrolling/ScrollingTreeNode.cpp:
(WebCore::ScrollingTreeNode::relatedNodeScrollPositionDidChange):
* page/scrolling/ScrollingTreeNode.h:
* page/scrolling/ScrollingTreeScrollingNode.cpp:
(WebCore::ScrollingTreeScrollingNode::applyLayerPositions):
* page/scrolling/ScrollingTreeScrollingNode.h:
* page/scrolling/cocoa/ScrollingTreeFixedNode.h:
* page/scrolling/cocoa/ScrollingTreeFixedNode.mm:
(WebCore::ScrollingTreeFixedNode::applyLayerPositions):

Compute them here instead, always taking all overflow scrollers up to the closest frame into account.

* page/scrolling/cocoa/ScrollingTreePositionedNode.h:
* page/scrolling/cocoa/ScrollingTreePositionedNode.mm:
(WebCore::ScrollingTreePositionedNode::applyLayerPositions):
(WebCore::ScrollingTreePositionedNode::relatedNodeScrollPositionDidChange):
* page/scrolling/cocoa/ScrollingTreeStickyNode.h:
* page/scrolling/cocoa/ScrollingTreeStickyNode.mm:
(WebCore::ScrollingTreeStickyNode::applyLayerPositions):

LayoutTests:

* scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll-2-expected.html: Added.
* scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll-2.html: Added.
* scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll-expected.html: Added.
* scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (245817 => 245818)


--- trunk/LayoutTests/ChangeLog	2019-05-28 17:33:58 UTC (rev 245817)
+++ trunk/LayoutTests/ChangeLog	2019-05-28 18:11:52 UTC (rev 245818)
@@ -1,3 +1,15 @@
+2019-05-28  Antti Koivisto  <[email protected]>
+
+        [async scrolling] Fixed positioning inside stacking context overflow scroll is jumpy
+        https://bugs.webkit.org/show_bug.cgi?id=198292
+
+        Reviewed by Darin Adler.
+
+        * scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll-2-expected.html: Added.
+        * scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll-2.html: Added.
+        * scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll-expected.html: Added.
+        * scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll.html: Added.
+
 2019-05-27  Takashi Komori  <[email protected]>
 
         [CURL] Fix crashing SocketStreamHandle.

Added: trunk/LayoutTests/scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll-2-expected.html (0 => 245818)


--- trunk/LayoutTests/scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll-2-expected.html	                        (rev 0)
+++ trunk/LayoutTests/scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll-2-expected.html	2019-05-28 18:11:52 UTC (rev 245818)
@@ -0,0 +1,56 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true internal:AsyncOverflowScrollingEnabled=true internal:AsyncFrameScrollingEnabled=true ] -->
+<html>
+<head>
+    <meta name="viewport" content="initial-scale=1.0">
+    <style>
+        #scroller {
+            left: 100px;
+            margin: 10px;
+            height: 300px;
+            width: 300px;
+            border: 1px solid black;
+            overflow: scroll;
+            z-index: 0;
+            position: relative;
+        }
+        
+        .box {
+            position: fixed;
+            margin-top: 200px;
+            width: 200px;
+            height: 200px;
+            background-color: green;
+        }
+        
+        .spacer {
+            border: 2px solid blue;
+            height: 5000px;
+        }
+    </style>
+    <script src=""
+    <script>
+        if (window.testRunner)
+            testRunner.waitUntilDone();
+
+        async function doTest()
+        {
+            await UIHelper.ensurePresentationUpdate(); // Not sure why this is necessary, but it is.
+            window.scrollTo(0, 50);
+            await UIHelper.ensurePresentationUpdate();
+
+            if (window.testRunner)
+                testRunner.notifyDone();
+        }
+        
+        window.addEventListener('load', doTest, false);
+    </script>
+</head>
+<body>
+    <div class="spacer">
+        <div id="scroller">
+            <div class="box"></div>
+            <div class="spacer"></div>
+        </div>
+    </div>
+</body>
+</html>

Added: trunk/LayoutTests/scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll-2.html (0 => 245818)


--- trunk/LayoutTests/scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll-2.html	                        (rev 0)
+++ trunk/LayoutTests/scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll-2.html	2019-05-28 18:11:52 UTC (rev 245818)
@@ -0,0 +1,59 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true internal:AsyncOverflowScrollingEnabled=true internal:AsyncFrameScrollingEnabled=true ] -->
+<html>
+<head>
+    <meta name="viewport" content="initial-scale=1.0">
+    <style>
+        .scroller {
+            left: 100px;
+            margin: 10px;
+            height: 300px;
+            width: 300px;
+            border: 1px solid black;
+            overflow: scroll;
+            z-index: 0;
+            position: relative;
+        }
+        
+        .box {
+            position: fixed;
+            margin-top: 200px;
+            width: 200px;
+            height: 200px;
+            background-color: green;
+        }
+        
+        .spacer {
+            border: 2px solid blue;
+            height: 5000px;
+        }
+    </style>
+    <script src=""
+    <script>
+        if (window.testRunner)
+            testRunner.waitUntilDone();
+
+        async function doTest()
+        {
+            if (!window.testRunner)
+                return;
+
+            if (!testRunner.runUIScript)
+                return;
+
+            const scrollUpdatesDisabled = true;
+            await UIHelper.immediateScrollElementAtContentPointToOffset(50, 50, 0, 50, scrollUpdatesDisabled);
+            testRunner.notifyDone();
+        }
+        
+        window.addEventListener('load', doTest, false);
+    </script>
+</head>
+<body>
+    <div class="spacer">
+        <div class="scroller">
+            <div class="box"></div>
+            <div class="spacer"></div>
+        </div>
+    </div>
+</body>
+</html>

Added: trunk/LayoutTests/scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll-expected.html (0 => 245818)


--- trunk/LayoutTests/scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll-expected.html	                        (rev 0)
+++ trunk/LayoutTests/scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll-expected.html	2019-05-28 18:11:52 UTC (rev 245818)
@@ -0,0 +1,55 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true internal:AsyncOverflowScrollingEnabled=true internal:AsyncFrameScrollingEnabled=true ] -->
+<html>
+<head>
+    <meta name="viewport" content="initial-scale=1.0">
+    <style>
+        #scroller {
+            margin: 10px;
+            height: 300px;
+            width: 300px;
+            border: 1px solid black;
+            overflow: scroll;
+            z-index: 0;
+            position: relative;
+        }
+        
+        .box {
+            position: fixed;
+            margin-top: 200px;
+            width: 200px;
+            height: 200px;
+            background-color: green;
+        }
+        
+        .spacer {
+            border: 2px solid blue;
+            height: 5000px;
+        }
+    </style>
+    <script src=""
+    <script>
+        if (window.testRunner)
+            testRunner.waitUntilDone();
+
+        async function doTest()
+        {
+            await UIHelper.ensurePresentationUpdate(); // Not sure why this is necessary, but it is.
+            scroller.scrollTo(0, 200);
+            await UIHelper.ensurePresentationUpdate();
+
+            if (window.testRunner)
+                testRunner.notifyDone();
+        }
+        
+        window.addEventListener('load', doTest, false);
+    </script>
+</head>
+<body>
+    <div class="spacer">
+        <div id="scroller">
+            <div class="box"></div>
+            <div class="spacer"></div>
+        </div>
+    </div>
+</body>
+</html>

Added: trunk/LayoutTests/scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll.html (0 => 245818)


--- trunk/LayoutTests/scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll.html	                        (rev 0)
+++ trunk/LayoutTests/scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll.html	2019-05-28 18:11:52 UTC (rev 245818)
@@ -0,0 +1,58 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true internal:AsyncOverflowScrollingEnabled=true internal:AsyncFrameScrollingEnabled=true ] -->
+<html>
+<head>
+    <meta name="viewport" content="initial-scale=1.0">
+    <style>
+        .scroller {
+            margin: 10px;
+            height: 300px;
+            width: 300px;
+            border: 1px solid black;
+            overflow: scroll;
+            z-index: 0;
+            position: relative;
+        }
+        
+        .box {
+            position: fixed;
+            margin-top: 200px;
+            width: 200px;
+            height: 200px;
+            background-color: green;
+        }
+        
+        .spacer {
+            border: 2px solid blue;
+            height: 5000px;
+        }
+    </style>
+    <script src=""
+    <script>
+        if (window.testRunner)
+            testRunner.waitUntilDone();
+
+        async function doTest()
+        {
+            if (!window.testRunner)
+                return;
+
+            if (!testRunner.runUIScript)
+                return;
+
+            const scrollUpdatesDisabled = true;
+            await UIHelper.immediateScrollElementAtContentPointToOffset(50, 50, 0, 200, scrollUpdatesDisabled);
+            testRunner.notifyDone();
+        }
+        
+        window.addEventListener('load', doTest, false);
+    </script>
+</head>
+<body>
+    <div class="spacer">
+        <div class="scroller">
+            <div class="box"></div>
+            <div class="spacer"></div>
+        </div>
+    </div>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (245817 => 245818)


--- trunk/Source/WebCore/ChangeLog	2019-05-28 17:33:58 UTC (rev 245817)
+++ trunk/Source/WebCore/ChangeLog	2019-05-28 18:11:52 UTC (rev 245818)
@@ -1,3 +1,54 @@
+2019-05-28  Antti Koivisto  <[email protected]>
+
+        [async scrolling] Fixed positioning inside stacking context overflow scroll is jumpy
+        https://bugs.webkit.org/show_bug.cgi?id=198292
+
+        Reviewed by Darin Adler.
+
+        Tests: scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll-2.html
+               scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll.html
+
+        We were computing delta from the layout scroll position in ScrollingTree::notifyRelatedNodesAfterScrollPositionChange
+        based on the passed in node only. If any other node had deltas they were not taken into account at all. This would occur
+        frequently since the function is always invoked for the root node after layer tree commit.
+
+        Fix by moving the delta computation (and fetching layoutViewport) to ScrollingTreeFixedNode.
+
+        * page/scrolling/ScrollingTree.cpp:
+        (WebCore::ScrollingTree::applyLayerPositions):
+
+        No need to pass offset and layoutViewport around anymore.
+
+        (WebCore::ScrollingTree::applyLayerPositionsRecursive):
+        (WebCore::ScrollingTree::notifyRelatedNodesAfterScrollPositionChange):
+
+        Remove the offset and layoutViewport computations.
+
+        (WebCore::ScrollingTree::notifyRelatedNodesRecursive):
+        * page/scrolling/ScrollingTree.h:
+        * page/scrolling/ScrollingTreeFrameHostingNode.cpp:
+        (WebCore::ScrollingTreeFrameHostingNode::applyLayerPositions):
+        * page/scrolling/ScrollingTreeFrameHostingNode.h:
+        * page/scrolling/ScrollingTreeNode.cpp:
+        (WebCore::ScrollingTreeNode::relatedNodeScrollPositionDidChange):
+        * page/scrolling/ScrollingTreeNode.h:
+        * page/scrolling/ScrollingTreeScrollingNode.cpp:
+        (WebCore::ScrollingTreeScrollingNode::applyLayerPositions):
+        * page/scrolling/ScrollingTreeScrollingNode.h:
+        * page/scrolling/cocoa/ScrollingTreeFixedNode.h:
+        * page/scrolling/cocoa/ScrollingTreeFixedNode.mm:
+        (WebCore::ScrollingTreeFixedNode::applyLayerPositions):
+
+        Compute them here instead, always taking all overflow scrollers up to the closest frame into account.
+
+        * page/scrolling/cocoa/ScrollingTreePositionedNode.h:
+        * page/scrolling/cocoa/ScrollingTreePositionedNode.mm:
+        (WebCore::ScrollingTreePositionedNode::applyLayerPositions):
+        (WebCore::ScrollingTreePositionedNode::relatedNodeScrollPositionDidChange):
+        * page/scrolling/cocoa/ScrollingTreeStickyNode.h:
+        * page/scrolling/cocoa/ScrollingTreeStickyNode.mm:
+        (WebCore::ScrollingTreeStickyNode::applyLayerPositions):
+
 2019-05-28  Zalan Bujtas  <[email protected]>
 
         [LFC][Verification] Add additional inline and block checks

Modified: trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp (245817 => 245818)


--- trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp	2019-05-28 17:33:58 UTC (rev 245817)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp	2019-05-28 18:11:52 UTC (rev 245818)
@@ -264,23 +264,18 @@
 
     LOG(Scrolling, "\nScrollingTree %p applyLayerPositions", this);
 
-    applyLayerPositionsRecursive(*m_rootNode, { }, { });
+    applyLayerPositionsRecursive(*m_rootNode);
 
     LOG(Scrolling, "ScrollingTree %p applyLayerPositions - done\n", this);
 }
 
-void ScrollingTree::applyLayerPositionsRecursive(ScrollingTreeNode& currNode, FloatRect layoutViewport, FloatSize cumulativeDelta)
+void ScrollingTree::applyLayerPositionsRecursive(ScrollingTreeNode& currNode)
 {
-    if (is<ScrollingTreeFrameScrollingNode>(currNode)) {
-        layoutViewport = downcast<ScrollingTreeFrameScrollingNode>(currNode).layoutViewport();
-        cumulativeDelta = { };
-    }
+    currNode.applyLayerPositions();
 
-    currNode.applyLayerPositions(layoutViewport, cumulativeDelta);
-
     if (auto children = currNode.children()) {
         for (auto& child : *children)
-            applyLayerPositionsRecursive(*child, layoutViewport, cumulativeDelta);
+            applyLayerPositionsRecursive(*child);
     }
 }
 
@@ -296,41 +291,31 @@
 {
     Vector<ScrollingNodeID> additionalUpdateRoots;
     
-    FloatSize deltaFromLastCommittedScrollPosition;
-    FloatRect currentFrameLayoutViewport;
-    if (is<ScrollingTreeFrameScrollingNode>(changedNode))
-        currentFrameLayoutViewport = downcast<ScrollingTreeFrameScrollingNode>(changedNode).layoutViewport();
-    else if (is<ScrollingTreeOverflowScrollingNode>(changedNode)) {
-        deltaFromLastCommittedScrollPosition = changedNode.lastCommittedScrollPosition() - changedNode.currentScrollPosition();
-
-        if (auto* frameScrollingNode = changedNode.enclosingFrameNodeIncludingSelf())
-            currentFrameLayoutViewport = frameScrollingNode->layoutViewport();
-        
+    if (is<ScrollingTreeOverflowScrollingNode>(changedNode))
         additionalUpdateRoots = overflowRelatedNodes().get(changedNode.scrollingNodeID());
-    }
 
-    notifyRelatedNodesRecursive(changedNode, changedNode, currentFrameLayoutViewport, deltaFromLastCommittedScrollPosition);
+    notifyRelatedNodesRecursive(changedNode, changedNode);
     
     for (auto positionedNodeID : additionalUpdateRoots) {
         auto* positionedNode = nodeForID(positionedNodeID);
         if (positionedNode)
-            notifyRelatedNodesRecursive(changedNode, *positionedNode, currentFrameLayoutViewport, deltaFromLastCommittedScrollPosition);
+            notifyRelatedNodesRecursive(changedNode, *positionedNode);
     }
 }
 
-void ScrollingTree::notifyRelatedNodesRecursive(ScrollingTreeScrollingNode& changedNode, ScrollingTreeNode& currNode, const FloatRect& layoutViewport, FloatSize cumulativeDelta)
+void ScrollingTree::notifyRelatedNodesRecursive(ScrollingTreeScrollingNode& changedNode, ScrollingTreeNode& currNode)
 {
-    currNode.relatedNodeScrollPositionDidChange(changedNode, layoutViewport, cumulativeDelta);
+    currNode.relatedNodeScrollPositionDidChange(changedNode);
 
     if (!currNode.children())
         return;
-    
+
     for (auto& child : *currNode.children()) {
         // Never need to cross frame boundaries, since scroll layer adjustments are isolated to each document.
         if (is<ScrollingTreeFrameScrollingNode>(child))
             continue;
 
-        notifyRelatedNodesRecursive(changedNode, *child, layoutViewport, cumulativeDelta);
+        notifyRelatedNodesRecursive(changedNode, *child);
     }
 }
 

Modified: trunk/Source/WebCore/page/scrolling/ScrollingTree.h (245817 => 245818)


--- trunk/Source/WebCore/page/scrolling/ScrollingTree.h	2019-05-28 17:33:58 UTC (rev 245817)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTree.h	2019-05-28 18:11:52 UTC (rev 245818)
@@ -165,9 +165,9 @@
     using OrphanScrollingNodeMap = HashMap<ScrollingNodeID, RefPtr<ScrollingTreeNode>>;
     void updateTreeFromStateNode(const ScrollingStateNode*, OrphanScrollingNodeMap&, HashSet<ScrollingNodeID>& unvisitedNodes);
 
-    void applyLayerPositionsRecursive(ScrollingTreeNode&, FloatRect layoutViewport, FloatSize cumulativeDelta);
+    void applyLayerPositionsRecursive(ScrollingTreeNode&);
 
-    void notifyRelatedNodesRecursive(ScrollingTreeScrollingNode& changedNode, ScrollingTreeNode& currNode, const FloatRect& layoutViewport, FloatSize cumulativeDelta);
+    void notifyRelatedNodesRecursive(ScrollingTreeScrollingNode& changedNode, ScrollingTreeNode& currNode);
 
     Lock m_treeMutex; // Protects the scrolling tree.
 

Modified: trunk/Source/WebCore/page/scrolling/ScrollingTreeFrameHostingNode.cpp (245817 => 245818)


--- trunk/Source/WebCore/page/scrolling/ScrollingTreeFrameHostingNode.cpp	2019-05-28 17:33:58 UTC (rev 245817)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTreeFrameHostingNode.cpp	2019-05-28 18:11:52 UTC (rev 245818)
@@ -57,7 +57,7 @@
         m_parentRelativeScrollableRect = frameHostingStateNode.parentRelativeScrollableRect();
 }
 
-void ScrollingTreeFrameHostingNode::applyLayerPositions(const FloatRect&, FloatSize&)
+void ScrollingTreeFrameHostingNode::applyLayerPositions()
 {
 }
 

Modified: trunk/Source/WebCore/page/scrolling/ScrollingTreeFrameHostingNode.h (245817 => 245818)


--- trunk/Source/WebCore/page/scrolling/ScrollingTreeFrameHostingNode.h	2019-05-28 17:33:58 UTC (rev 245817)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTreeFrameHostingNode.h	2019-05-28 18:11:52 UTC (rev 245818)
@@ -42,7 +42,7 @@
     ScrollingTreeFrameHostingNode(ScrollingTree&, ScrollingNodeID);
 
     void commitStateBeforeChildren(const ScrollingStateNode&) final;
-    void applyLayerPositions(const FloatRect&, FloatSize&) final;
+    void applyLayerPositions() final;
 
     const LayoutRect& parentRelativeScrollableRect() const { return m_parentRelativeScrollableRect; }
 

Modified: trunk/Source/WebCore/page/scrolling/ScrollingTreeNode.cpp (245817 => 245818)


--- trunk/Source/WebCore/page/scrolling/ScrollingTreeNode.cpp	2019-05-28 17:33:58 UTC (rev 245817)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTreeNode.cpp	2019-05-28 18:11:52 UTC (rev 245818)
@@ -77,9 +77,9 @@
     return m_scrollingTree.rootNode() == this;
 }
 
-void ScrollingTreeNode::relatedNodeScrollPositionDidChange(const ScrollingTreeScrollingNode&, const FloatRect& layoutViewport, FloatSize& cumulativeDelta)
+void ScrollingTreeNode::relatedNodeScrollPositionDidChange(const ScrollingTreeScrollingNode&)
 {
-    applyLayerPositions(layoutViewport, cumulativeDelta);
+    applyLayerPositions();
 }
 
 void ScrollingTreeNode::dumpProperties(TextStream& ts, ScrollingStateTreeAsTextBehavior behavior) const

Modified: trunk/Source/WebCore/page/scrolling/ScrollingTreeNode.h (245817 => 245818)


--- trunk/Source/WebCore/page/scrolling/ScrollingTreeNode.h	2019-05-28 17:33:58 UTC (rev 245817)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTreeNode.h	2019-05-28 18:11:52 UTC (rev 245818)
@@ -84,9 +84,9 @@
     ScrollingTreeNode(ScrollingTree&, ScrollingNodeType, ScrollingNodeID);
     ScrollingTree& scrollingTree() const { return m_scrollingTree; }
 
-    WEBCORE_EXPORT virtual void relatedNodeScrollPositionDidChange(const ScrollingTreeScrollingNode& changedNode, const FloatRect& layoutViewport, FloatSize& cumulativeDelta);
+    WEBCORE_EXPORT virtual void relatedNodeScrollPositionDidChange(const ScrollingTreeScrollingNode& changedNode);
 
-    virtual void applyLayerPositions(const FloatRect& layoutViewport, FloatSize& cumulativeDelta) = 0;
+    virtual void applyLayerPositions() = 0;
 
     WEBCORE_EXPORT virtual void dumpProperties(WTF::TextStream&, ScrollingStateTreeAsTextBehavior) const;
 

Modified: trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp (245817 => 245818)


--- trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp	2019-05-28 17:33:58 UTC (rev 245817)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp	2019-05-28 18:11:52 UTC (rev 245818)
@@ -188,7 +188,7 @@
     return position == m_currentScrollPosition;
 }
 
-void ScrollingTreeScrollingNode::applyLayerPositions(const FloatRect&, FloatSize&)
+void ScrollingTreeScrollingNode::applyLayerPositions()
 {
     repositionScrollingLayers();
     repositionRelatedLayers();

Modified: trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h (245817 => 245818)


--- trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h	2019-05-28 17:33:58 UTC (rev 245817)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h	2019-05-28 18:11:52 UTC (rev 245818)
@@ -107,7 +107,7 @@
     virtual void repositionScrollingLayers() { }
     virtual void repositionRelatedLayers() { }
 
-    void applyLayerPositions(const FloatRect& layoutViewport, FloatSize& cumulativeDelta) override;
+    void applyLayerPositions() override;
 
     const FloatSize& reachableContentsSize() const { return m_reachableContentsSize; }
     const LayoutRect& parentRelativeScrollableRect() const { return m_parentRelativeScrollableRect; }

Modified: trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreeFixedNode.h (245817 => 245818)


--- trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreeFixedNode.h	2019-05-28 17:33:58 UTC (rev 245817)
+++ trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreeFixedNode.h	2019-05-28 18:11:52 UTC (rev 245818)
@@ -47,7 +47,7 @@
     ScrollingTreeFixedNode(ScrollingTree&, ScrollingNodeID);
 
     void commitStateBeforeChildren(const ScrollingStateNode&) override;
-    void applyLayerPositions(const FloatRect&, FloatSize&) override;
+    void applyLayerPositions() override;
 
     void dumpProperties(WTF::TextStream&, ScrollingStateTreeAsTextBehavior) const override;
 

Modified: trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreeFixedNode.mm (245817 => 245818)


--- trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreeFixedNode.mm	2019-05-28 17:33:58 UTC (rev 245817)
+++ trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreeFixedNode.mm	2019-05-28 18:11:52 UTC (rev 245818)
@@ -31,6 +31,8 @@
 #import "Logging.h"
 #import "ScrollingStateFixedNode.h"
 #import "ScrollingTree.h"
+#import "ScrollingTreeFrameScrollingNode.h"
+#import "ScrollingTreeOverflowScrollingNode.h"
 #import "WebCoreCALayerExtras.h"
 #import <wtf/text/TextStream.h>
 
@@ -63,16 +65,36 @@
         m_constraints = fixedStateNode.viewportConstraints();
 }
 
-void ScrollingTreeFixedNode::applyLayerPositions(const FloatRect& layoutViewport, FloatSize& cumulativeDelta)
+void ScrollingTreeFixedNode::applyLayerPositions()
 {
-    FloatPoint layerPosition = m_constraints.layerPositionForViewportRect(layoutViewport);
+    auto computeLayerPosition = [&] {
+        FloatSize overflowScrollDelta;
+        // FIXME: This code is wrong in complex cases where the fixed element is inside a positioned node as
+        //        the scroll container order does not match the scrolling tree ancestor order.
+        for (auto* node = parent(); node; node = node->parent()) {
+            if (is<ScrollingTreeFrameScrollingNode>(*node)) {
+                // Fixed nodes are positioned relative to the containing frame scrolling node.
+                // We bail out after finding one.
+                auto layoutViewport = downcast<ScrollingTreeFrameScrollingNode>(*node).layoutViewport();
+                return m_constraints.layerPositionForViewportRect(layoutViewport) - overflowScrollDelta;
+            }
 
-    LOG_WITH_STREAM(Scrolling, stream << "ScrollingTreeFixedNode " << scrollingNodeID() << " relatedNodeScrollPositionDidChange: new viewport " << layoutViewport << " viewportRectAtLastLayout " << m_constraints.viewportRectAtLastLayout() << " last layer pos " << m_constraints.layerPositionAtLastLayout() << " new offset from top " << (layoutViewport.y() - layerPosition.y()));
+            if (is<ScrollingTreeOverflowScrollingNode>(*node)) {
+                // To keep the layer still during async scrolling we adjust by how much the position has changed since layout.
+                auto& overflowNode = downcast<ScrollingTreeOverflowScrollingNode>(*node);
+                auto localDelta = overflowNode.lastCommittedScrollPosition() - overflowNode.currentScrollPosition();
+                overflowScrollDelta += localDelta;
+            }
+        }
+        ASSERT_NOT_REACHED();
+        return FloatPoint();
+    };
 
-    layerPosition -= cumulativeDelta;
+    auto layerPosition = computeLayerPosition();
 
+    LOG_WITH_STREAM(Scrolling, stream << "ScrollingTreeFixedNode " << scrollingNodeID() << " relatedNodeScrollPositionDidChange: viewportRectAtLastLayout " << m_constraints.viewportRectAtLastLayout() << " last layer pos " << m_constraints.layerPositionAtLastLayout() << " layerPosition " << layerPosition);
+
     [m_layer _web_setLayerTopLeftPosition:layerPosition - m_constraints.alignmentOffset()];
-    cumulativeDelta += layerPosition - m_constraints.layerPositionAtLastLayout();
 }
 
 void ScrollingTreeFixedNode::dumpProperties(TextStream& ts, ScrollingStateTreeAsTextBehavior behavior) const

Modified: trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreePositionedNode.h (245817 => 245818)


--- trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreePositionedNode.h	2019-05-28 17:33:58 UTC (rev 245817)
+++ trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreePositionedNode.h	2019-05-28 18:11:52 UTC (rev 245818)
@@ -50,9 +50,9 @@
     ScrollingTreePositionedNode(ScrollingTree&, ScrollingNodeID);
 
     void commitStateBeforeChildren(const ScrollingStateNode&) override;
-    void relatedNodeScrollPositionDidChange(const ScrollingTreeScrollingNode& changedNode, const FloatRect& layoutViewport, FloatSize& cumulativeDelta) override;
+    void relatedNodeScrollPositionDidChange(const ScrollingTreeScrollingNode& changedNode) override;
 
-    void applyLayerPositions(const FloatRect& layoutViewport, FloatSize& cumulativeDelta) override;
+    void applyLayerPositions() override;
 
     WEBCORE_EXPORT void dumpProperties(WTF::TextStream&, ScrollingStateTreeAsTextBehavior) const override;
 

Modified: trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreePositionedNode.mm (245817 => 245818)


--- trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreePositionedNode.mm	2019-05-28 17:33:58 UTC (rev 245817)
+++ trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreePositionedNode.mm	2019-05-28 18:11:52 UTC (rev 245818)
@@ -76,10 +76,8 @@
         scrollingTree().positionedNodesWithRelatedOverflow().add(scrollingNodeID());
 }
 
-void ScrollingTreePositionedNode::applyLayerPositions(const FloatRect&, FloatSize& cumulativeDelta)
+void ScrollingTreePositionedNode::applyLayerPositions()
 {
-    // Note that we ignore cumulativeDelta because it will contain the delta for ancestor scrollers,
-    // but not non-ancestor ones, so it's simpler to just recompute from the scrollers we know about here.
     FloatSize scrollOffsetSinceLastCommit;
     for (auto nodeID : m_relatedOverflowScrollingNodes) {
         if (auto* node = scrollingTree().nodeForID(nodeID)) {
@@ -100,17 +98,14 @@
     LOG_WITH_STREAM(Scrolling, stream << "ScrollingTreePositionedNode " << scrollingNodeID() << " applyLayerPositions: overflow delta " << scrollOffsetSinceLastCommit << " moving layer to " << layerPosition);
 
     [m_layer _web_setLayerTopLeftPosition:layerPosition - m_constraints.alignmentOffset()];
-
-    // FIXME: Should our scroller deltas propagate to descendants?
-    cumulativeDelta = layerPosition - m_constraints.layerPositionAtLastLayout();
 }
 
-void ScrollingTreePositionedNode::relatedNodeScrollPositionDidChange(const ScrollingTreeScrollingNode& changedNode, const FloatRect& layoutViewport, FloatSize& cumulativeDelta)
+void ScrollingTreePositionedNode::relatedNodeScrollPositionDidChange(const ScrollingTreeScrollingNode& changedNode)
 {
     if (!m_relatedOverflowScrollingNodes.contains(changedNode.scrollingNodeID()))
         return;
 
-    applyLayerPositions(layoutViewport, cumulativeDelta);
+    applyLayerPositions();
 }
 
 void ScrollingTreePositionedNode::dumpProperties(TextStream& ts, ScrollingStateTreeAsTextBehavior behavior) const

Modified: trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreeStickyNode.h (245817 => 245818)


--- trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreeStickyNode.h	2019-05-28 17:33:58 UTC (rev 245817)
+++ trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreeStickyNode.h	2019-05-28 18:11:52 UTC (rev 245818)
@@ -45,7 +45,7 @@
     ScrollingTreeStickyNode(ScrollingTree&, ScrollingNodeID);
 
     void commitStateBeforeChildren(const ScrollingStateNode&) override;
-    void applyLayerPositions(const FloatRect& layoutViewport, FloatSize& cumulativeDelta) override;
+    void applyLayerPositions() override;
 
     void dumpProperties(WTF::TextStream&, ScrollingStateTreeAsTextBehavior) const override;
 

Modified: trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreeStickyNode.mm (245817 => 245818)


--- trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreeStickyNode.mm	2019-05-28 17:33:58 UTC (rev 245817)
+++ trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreeStickyNode.mm	2019-05-28 18:11:52 UTC (rev 245818)
@@ -65,7 +65,7 @@
         m_constraints = stickyStateNode.viewportConstraints();
 }
 
-void ScrollingTreeStickyNode::applyLayerPositions(const FloatRect& layoutViewport, FloatSize& cumulativeDelta)
+void ScrollingTreeStickyNode::applyLayerPositions()
 {
     FloatRect constrainingRect;
 
@@ -73,16 +73,15 @@
     if (is<ScrollingTreeOverflowScrollingNode>(enclosingScrollingNode))
         constrainingRect = FloatRect(downcast<ScrollingTreeOverflowScrollingNode>(*enclosingScrollingNode).currentScrollPosition(), m_constraints.constrainingRectAtLastLayout().size());
     else if (is<ScrollingTreeFrameScrollingNode>(enclosingScrollingNode))
-        constrainingRect = layoutViewport;
+        constrainingRect = downcast<ScrollingTreeFrameScrollingNode>(enclosingScrollingNode)->layoutViewport();
     else
         return;
 
-    LOG_WITH_STREAM(Scrolling, stream << "ScrollingTreeStickyNode " << scrollingNodeID() << " relatedNodeScrollPositionDidChange: new viewport " << layoutViewport << " constrainingRectAtLastLayout " << m_constraints.constrainingRectAtLastLayout() << " last layer pos " << m_constraints.layerPositionAtLastLayout());
+    FloatPoint layerPosition = m_constraints.layerPositionForConstrainingRect(constrainingRect) - m_constraints.alignmentOffset();
 
-    FloatPoint layerPosition = m_constraints.layerPositionForConstrainingRect(constrainingRect) - m_constraints.alignmentOffset();
+    LOG_WITH_STREAM(Scrolling, stream << "ScrollingTreeStickyNode " << scrollingNodeID() << " constrainingRect " << constrainingRect << " constrainingRectAtLastLayout " << m_constraints.constrainingRectAtLastLayout() << " last layer pos " << m_constraints.layerPositionAtLastLayout() << " layerPosition " << layerPosition);
+
     [m_layer _web_setLayerTopLeftPosition:layerPosition];
-
-    cumulativeDelta += layerPosition - m_constraints.layerPositionAtLastLayout();
 }
 
 void ScrollingTreeStickyNode::dumpProperties(TextStream& ts, ScrollingStateTreeAsTextBehavior behavior) const

Modified: trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFixedNode.cpp (245817 => 245818)


--- trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFixedNode.cpp	2019-05-28 17:33:58 UTC (rev 245817)
+++ trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFixedNode.cpp	2019-05-28 18:11:52 UTC (rev 245818)
@@ -54,7 +54,7 @@
 {
 }
 
-void ScrollingTreeFixedNode::applyLayerPositions(const FloatRect&, FloatSize&)
+void ScrollingTreeFixedNode::applyLayerPositions()
 {
 }
 

Modified: trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFixedNode.h (245817 => 245818)


--- trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFixedNode.h	2019-05-28 17:33:58 UTC (rev 245817)
+++ trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFixedNode.h	2019-05-28 18:11:52 UTC (rev 245818)
@@ -42,7 +42,7 @@
     ScrollingTreeFixedNode(ScrollingTree&, ScrollingNodeID);
 
     void commitStateBeforeChildren(const ScrollingStateNode&) override;
-    void applyLayerPositions(const FloatRect& layoutViewport, FloatSize& cumulativeDelta) override;
+    void applyLayerPositions() override;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeStickyNode.cpp (245817 => 245818)


--- trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeStickyNode.cpp	2019-05-28 17:33:58 UTC (rev 245817)
+++ trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeStickyNode.cpp	2019-05-28 18:11:52 UTC (rev 245818)
@@ -54,7 +54,7 @@
 {
 }
 
-void ScrollingTreeStickyNode::applyLayerPositions(const FloatRect&, FloatSize&)
+void ScrollingTreeStickyNode::applyLayerPositions()
 {
 }
 

Modified: trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeStickyNode.h (245817 => 245818)


--- trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeStickyNode.h	2019-05-28 17:33:58 UTC (rev 245817)
+++ trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeStickyNode.h	2019-05-28 18:11:52 UTC (rev 245818)
@@ -42,7 +42,7 @@
     ScrollingTreeStickyNode(ScrollingTree&, ScrollingNodeID);
 
     void commitStateBeforeChildren(const ScrollingStateNode&) override;
-    void applyLayerPositions(const FloatRect& layoutViewport, FloatSize& cumulativeDelta) override;
+    void applyLayerPositions() override;
 
 };
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to