Changeset 260557 in webkit


Ignore:
Timestamp:
Apr 22, 2020 10:19:34 PM (4 years ago)
Author:
Simon Fraser
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.

Location:
trunk/Source/WebCore
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r260556 r260557  
     12020-04-22  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Make it possible to eagerly apply scrolling tree state from the main thread
     4        https://bugs.webkit.org/show_bug.cgi?id=210883
     5
     6        Reviewed by Tim Horton.
     7
     8        Work towards fixing webkit.org/b/210884: at the beginning of Page::updateRendering(),
     9        we are going to need to pull the current state of the scrolling tree back to the
     10        main thread, so that JS-exposed scroll offsets match scrolling tree state.
     11
     12        To this end, expose a scrolling tree traversal function from ScrollingTree, which
     13        takes the lock and then calls a visitor function for each node. For scrolling nodes,
     14        the visitor gets the scroll position and optional layout viewport origin. These
     15        match the data passed back currently via AsyncScrollingCoordinator::scheduleUpdateScrollPositionAfterAsyncScroll().
     16
     17        The new code is not called yet.
     18
     19        * page/scrolling/AsyncScrollingCoordinator.cpp:
     20        (WebCore::AsyncScrollingCoordinator::synchronizeStateFromScrollingTree):
     21        * page/scrolling/AsyncScrollingCoordinator.h:
     22        * page/scrolling/ScrollingCoordinator.h:
     23        (WebCore::ScrollingCoordinator::synchronizeStateFromScrollingTree):
     24        * page/scrolling/ScrollingTree.cpp:
     25        (WebCore::ScrollingTree::traverseScrollingTree):
     26        (WebCore::ScrollingTree::traverseScrollingTreeRecursive):
     27        * page/scrolling/ScrollingTree.h:
     28        * page/scrolling/ScrollingTreeScrollingNode.cpp:
     29        (WebCore::ScrollingTreeScrollingNode::currentScrollPositionChanged): applyLayerPositions() calls these two
     30        functions, so just call it instead.
     31
    1322020-04-22  Commit Queue  <commit-queue@webkit.org>
    233
  • trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp

    r260403 r260557  
    276276}
    277277
     278void AsyncScrollingCoordinator::synchronizeStateFromScrollingTree()
     279{
     280    ASSERT(isMainThread());
     281
     282    m_scrollingTree->traverseScrollingTree([&](ScrollingNodeID nodeID, ScrollingNodeType, Optional<FloatPoint> scrollPosition, Optional<FloatPoint> layoutViewportOrigin) {
     283        if (scrollPosition) {
     284            LOG_WITH_STREAM(Scrolling, stream << "AsyncScrollingCoordinator::synchronizeStateFromScrollingTree - node " << nodeID << " scroll position " << scrollPosition);
     285            updateScrollPositionAfterAsyncScroll(nodeID, scrollPosition.value(), layoutViewportOrigin, ScrollType::User, ScrollingLayerPositionAction::Set);
     286        }
     287    });
     288}
     289
    278290void AsyncScrollingCoordinator::noteScrollingThreadSyncCompleteForNode(ScrollingNodeID nodeID)
    279291{
  • trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h

    r260403 r260557  
    101101
    102102    WEBCORE_EXPORT void applyScrollingTreeLayerPositions() override;
     103    WEBCORE_EXPORT void synchronizeStateFromScrollingTree() override;
    103104
    104105    WEBCORE_EXPORT ScrollingNodeID createNode(ScrollingNodeType, ScrollingNodeID newNodeID) override;
  • trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.h

    r260403 r260557  
    112112    virtual void applyScrollingTreeLayerPositions() { }
    113113
     114    // Takes scroll positions from the scrolling tree and applies them to ScrollableAreas.
     115    virtual void synchronizeStateFromScrollingTree() { }
     116
    114117#if PLATFORM(COCOA)
    115118    // Dispatched by the scrolling tree during handleWheelEvent. This is required as long as scrollbars are painted on the main thread.
  • trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp

    r260403 r260557  
    149149}
    150150
     151void ScrollingTree::traverseScrollingTree(VisitorFunction&& visitorFunction)
     152{
     153    LockHolder locker(m_treeMutex);
     154    if (!m_rootNode)
     155        return;
     156
     157    auto function = WTFMove(visitorFunction);
     158    traverseScrollingTreeRecursive(*m_rootNode, function);
     159}
     160
     161void ScrollingTree::traverseScrollingTreeRecursive(ScrollingTreeNode& node, const VisitorFunction& visitorFunction)
     162{
     163    Optional<FloatPoint> scrollPosition;
     164    if (is<ScrollingTreeScrollingNode>(node))
     165        scrollPosition = downcast<ScrollingTreeScrollingNode>(node).currentScrollPosition();
     166
     167    Optional<FloatPoint> layoutViewportOrigin;
     168    if (is<ScrollingTreeFrameScrollingNode>(node))
     169        layoutViewportOrigin = downcast<ScrollingTreeFrameScrollingNode>(node).layoutViewport().location();
     170
     171    visitorFunction(node.scrollingNodeID(), node.nodeType(), scrollPosition, layoutViewportOrigin);
     172
     173    for (auto& child : node.children())
     174        traverseScrollingTreeRecursive(child.get(), visitorFunction);
     175}
     176
    151177void ScrollingTree::mainFrameViewportChangedViaDelegatedScrolling(const FloatPoint& scrollPosition, const FloatRect& layoutViewport, double)
    152178{
  • trunk/Source/WebCore/page/scrolling/ScrollingTree.h

    r260195 r260557  
    8888    WEBCORE_EXPORT ScrollingTreeNode* nodeForID(ScrollingNodeID) const;
    8989
     90    using VisitorFunction = WTF::Function<void (ScrollingNodeID, ScrollingNodeType, Optional<FloatPoint> scrollPosition, Optional<FloatPoint> layoutViewportOrigin)>;
     91    void traverseScrollingTree(VisitorFunction&&);
     92
    9093    // Called after a scrolling tree node has handled a scroll and updated its layers.
    9194    // Updates FrameView/RenderLayer scrolling state and GraphicsLayers.
     
    185188
    186189    void applyLayerPositionsRecursive(ScrollingTreeNode&);
    187 
    188190    void notifyRelatedNodesRecursive(ScrollingTreeNode&);
     191    void traverseScrollingTreeRecursive(ScrollingTreeNode&, const VisitorFunction&);
    189192
    190193    WEBCORE_EXPORT virtual RefPtr<ScrollingTreeNode> scrollingNodeForPoint(FloatPoint);
  • trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp

    r260450 r260557  
    246246void ScrollingTreeScrollingNode::currentScrollPositionChanged()
    247247{
    248     repositionScrollingLayers();
    249     repositionRelatedLayers();
     248    applyLayerPositions();
    250249
    251250    scrollingTree().notifyRelatedNodesAfterScrollPositionChange(*this);
Note: See TracChangeset for help on using the changeset viewer.