Title: [260557] trunk/Source/WebCore
Revision
260557
Author
simon.fra...@apple.com
Date
2020-04-22 22:19:34 -0700 (Wed, 22 Apr 2020)

Log Message

Make it possible to eagerly apply scrolling tree state from the main thread
https://bugs.webkit.org/show_bug.cgi?id=210883

Reviewed by Tim Horton.

Work towards fixing webkit.org/b/210884: at the beginning of Page::updateRendering(),
we are going to need to pull the current state of the scrolling tree back to the
main thread, so that JS-exposed scroll offsets match scrolling tree state.

To this end, expose a scrolling tree traversal function from ScrollingTree, which
takes the lock and then calls a visitor function for each node. For scrolling nodes,
the visitor gets the scroll position and optional layout viewport origin. These
match the data passed back currently via AsyncScrollingCoordinator::scheduleUpdateScrollPositionAfterAsyncScroll().

The new code is not called yet.

* page/scrolling/AsyncScrollingCoordinator.cpp:
(WebCore::AsyncScrollingCoordinator::synchronizeStateFromScrollingTree):
* page/scrolling/AsyncScrollingCoordinator.h:
* page/scrolling/ScrollingCoordinator.h:
(WebCore::ScrollingCoordinator::synchronizeStateFromScrollingTree):
* page/scrolling/ScrollingTree.cpp:
(WebCore::ScrollingTree::traverseScrollingTree):
(WebCore::ScrollingTree::traverseScrollingTreeRecursive):
* page/scrolling/ScrollingTree.h:
* page/scrolling/ScrollingTreeScrollingNode.cpp:
(WebCore::ScrollingTreeScrollingNode::currentScrollPositionChanged): applyLayerPositions() calls these two
functions, so just call it instead.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (260556 => 260557)


--- trunk/Source/WebCore/ChangeLog	2020-04-23 04:56:44 UTC (rev 260556)
+++ trunk/Source/WebCore/ChangeLog	2020-04-23 05:19:34 UTC (rev 260557)
@@ -1,3 +1,34 @@
+2020-04-22  Simon Fraser  <simon.fra...@apple.com>
+
+        Make it possible to eagerly apply scrolling tree state from the main thread
+        https://bugs.webkit.org/show_bug.cgi?id=210883
+
+        Reviewed by Tim Horton.
+
+        Work towards fixing webkit.org/b/210884: at the beginning of Page::updateRendering(),
+        we are going to need to pull the current state of the scrolling tree back to the
+        main thread, so that JS-exposed scroll offsets match scrolling tree state.
+
+        To this end, expose a scrolling tree traversal function from ScrollingTree, which
+        takes the lock and then calls a visitor function for each node. For scrolling nodes,
+        the visitor gets the scroll position and optional layout viewport origin. These
+        match the data passed back currently via AsyncScrollingCoordinator::scheduleUpdateScrollPositionAfterAsyncScroll().
+
+        The new code is not called yet.
+
+        * page/scrolling/AsyncScrollingCoordinator.cpp:
+        (WebCore::AsyncScrollingCoordinator::synchronizeStateFromScrollingTree):
+        * page/scrolling/AsyncScrollingCoordinator.h:
+        * page/scrolling/ScrollingCoordinator.h:
+        (WebCore::ScrollingCoordinator::synchronizeStateFromScrollingTree):
+        * page/scrolling/ScrollingTree.cpp:
+        (WebCore::ScrollingTree::traverseScrollingTree):
+        (WebCore::ScrollingTree::traverseScrollingTreeRecursive):
+        * page/scrolling/ScrollingTree.h:
+        * page/scrolling/ScrollingTreeScrollingNode.cpp:
+        (WebCore::ScrollingTreeScrollingNode::currentScrollPositionChanged): applyLayerPositions() calls these two
+        functions, so just call it instead.
+
 2020-04-22  Commit Queue  <commit-qu...@webkit.org>
 
         Unreviewed, reverting r260535.

Modified: trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp (260556 => 260557)


--- trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp	2020-04-23 04:56:44 UTC (rev 260556)
+++ trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp	2020-04-23 05:19:34 UTC (rev 260557)
@@ -275,6 +275,18 @@
     m_scrollingTree->applyLayerPositions();
 }
 
+void AsyncScrollingCoordinator::synchronizeStateFromScrollingTree()
+{
+    ASSERT(isMainThread());
+
+    m_scrollingTree->traverseScrollingTree([&](ScrollingNodeID nodeID, ScrollingNodeType, Optional<FloatPoint> scrollPosition, Optional<FloatPoint> layoutViewportOrigin) {
+        if (scrollPosition) {
+            LOG_WITH_STREAM(Scrolling, stream << "AsyncScrollingCoordinator::synchronizeStateFromScrollingTree - node " << nodeID << " scroll position " << scrollPosition);
+            updateScrollPositionAfterAsyncScroll(nodeID, scrollPosition.value(), layoutViewportOrigin, ScrollType::User, ScrollingLayerPositionAction::Set);
+        }
+    });
+}
+
 void AsyncScrollingCoordinator::noteScrollingThreadSyncCompleteForNode(ScrollingNodeID nodeID)
 {
 #if PLATFORM(MAC)

Modified: trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h (260556 => 260557)


--- trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h	2020-04-23 04:56:44 UTC (rev 260556)
+++ trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h	2020-04-23 05:19:34 UTC (rev 260557)
@@ -100,6 +100,7 @@
     WEBCORE_EXPORT bool requestScrollPositionUpdate(ScrollableArea&, const IntPoint&, ScrollType, ScrollClamping) override;
 
     WEBCORE_EXPORT void applyScrollingTreeLayerPositions() override;
+    WEBCORE_EXPORT void synchronizeStateFromScrollingTree() override;
 
     WEBCORE_EXPORT ScrollingNodeID createNode(ScrollingNodeType, ScrollingNodeID newNodeID) override;
     WEBCORE_EXPORT ScrollingNodeID insertNode(ScrollingNodeType, ScrollingNodeID newNodeID, ScrollingNodeID parentID, size_t childIndex) override;

Modified: trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.h (260556 => 260557)


--- trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.h	2020-04-23 04:56:44 UTC (rev 260556)
+++ trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.h	2020-04-23 05:19:34 UTC (rev 260557)
@@ -111,6 +111,9 @@
     // Traverses the scrolling tree, setting layer positions to represent the current scrolled state.
     virtual void applyScrollingTreeLayerPositions() { }
 
+    // Takes scroll positions from the scrolling tree and applies them to ScrollableAreas.
+    virtual void synchronizeStateFromScrollingTree() { }
+
 #if PLATFORM(COCOA)
     // Dispatched by the scrolling tree during handleWheelEvent. This is required as long as scrollbars are painted on the main thread.
     void handleWheelEventPhase(PlatformWheelEventPhase);

Modified: trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp (260556 => 260557)


--- trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp	2020-04-23 04:56:44 UTC (rev 260556)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp	2020-04-23 05:19:34 UTC (rev 260557)
@@ -148,6 +148,32 @@
     return m_rootNode;
 }
 
+void ScrollingTree::traverseScrollingTree(VisitorFunction&& visitorFunction)
+{
+    LockHolder locker(m_treeMutex);
+    if (!m_rootNode)
+        return;
+
+    auto function = WTFMove(visitorFunction);
+    traverseScrollingTreeRecursive(*m_rootNode, function);
+}
+
+void ScrollingTree::traverseScrollingTreeRecursive(ScrollingTreeNode& node, const VisitorFunction& visitorFunction)
+{
+    Optional<FloatPoint> scrollPosition;
+    if (is<ScrollingTreeScrollingNode>(node))
+        scrollPosition = downcast<ScrollingTreeScrollingNode>(node).currentScrollPosition();
+
+    Optional<FloatPoint> layoutViewportOrigin;
+    if (is<ScrollingTreeFrameScrollingNode>(node))
+        layoutViewportOrigin = downcast<ScrollingTreeFrameScrollingNode>(node).layoutViewport().location();
+
+    visitorFunction(node.scrollingNodeID(), node.nodeType(), scrollPosition, layoutViewportOrigin);
+
+    for (auto& child : node.children())
+        traverseScrollingTreeRecursive(child.get(), visitorFunction);
+}
+
 void ScrollingTree::mainFrameViewportChangedViaDelegatedScrolling(const FloatPoint& scrollPosition, const FloatRect& layoutViewport, double)
 {
     LOG_WITH_STREAM(Scrolling, stream << "ScrollingTree::viewportChangedViaDelegatedScrolling - layoutViewport " << layoutViewport);

Modified: trunk/Source/WebCore/page/scrolling/ScrollingTree.h (260556 => 260557)


--- trunk/Source/WebCore/page/scrolling/ScrollingTree.h	2020-04-23 04:56:44 UTC (rev 260556)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTree.h	2020-04-23 05:19:34 UTC (rev 260557)
@@ -87,6 +87,9 @@
     
     WEBCORE_EXPORT ScrollingTreeNode* nodeForID(ScrollingNodeID) const;
 
+    using VisitorFunction = WTF::Function<void (ScrollingNodeID, ScrollingNodeType, Optional<FloatPoint> scrollPosition, Optional<FloatPoint> layoutViewportOrigin)>;
+    void traverseScrollingTree(VisitorFunction&&);
+
     // Called after a scrolling tree node has handled a scroll and updated its layers.
     // Updates FrameView/RenderLayer scrolling state and GraphicsLayers.
     virtual void scrollingTreeNodeDidScroll(ScrollingTreeScrollingNode&, ScrollingLayerPositionAction = ScrollingLayerPositionAction::Sync) = 0;
@@ -184,8 +187,8 @@
     virtual void propagateSynchronousScrollingReasons(const HashSet<ScrollingNodeID>&) { }
 
     void applyLayerPositionsRecursive(ScrollingTreeNode&);
-
     void notifyRelatedNodesRecursive(ScrollingTreeNode&);
+    void traverseScrollingTreeRecursive(ScrollingTreeNode&, const VisitorFunction&);
 
     WEBCORE_EXPORT virtual RefPtr<ScrollingTreeNode> scrollingNodeForPoint(FloatPoint);
     virtual void receivedWheelEvent(const PlatformWheelEvent&) { }

Modified: trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp (260556 => 260557)


--- trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp	2020-04-23 04:56:44 UTC (rev 260556)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp	2020-04-23 05:19:34 UTC (rev 260557)
@@ -245,8 +245,7 @@
 
 void ScrollingTreeScrollingNode::currentScrollPositionChanged()
 {
-    repositionScrollingLayers();
-    repositionRelatedLayers();
+    applyLayerPositions();
 
     scrollingTree().notifyRelatedNodesAfterScrollPositionChange(*this);
     scrollingTree().scrollingTreeNodeDidScroll(*this);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to