⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 286411 in webkit


Ignore:
Timestamp:
Dec 1, 2021, 8:58:54 PM (5 years ago)
Author:
Simon Fraser
Message:

Scrolling complex websites can stutter: scrolling thread frame can fail to process wheel events
https://bugs.webkit.org/show_bug.cgi?id=233739
rdar://85946176

Reviewed by Tim Horton.

While the scrolling thread is chilling in
ThreadedScrollingTree::waitForRenderingUpdateCompletionOrTimeout(), waiting up to half a
frame to allow the main thread to handle the commit (for scroll synchronization), wheel
events may have been dispatched to the scrolling thread.

If we blow the timeout and commit anyway, we need to make sure we've handled these wheel
events first, so that the current frame can commit some layer movement. We can achieve this
by dispatching the applyLayerPositions(), which will enqueue it behind any waiting wheel
event dispatch from EventDispatcher::internalWheelEvent().

  • page/scrolling/ScrollingTree.cpp:

(WebCore::ScrollingTree::applyLayerPositions):

  • page/scrolling/ThreadedScrollingTree.cpp:

(WebCore::ThreadedScrollingTree::waitForRenderingUpdateCompletionOrTimeout):

Location:
trunk/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r286410 r286411  
     12021-12-01  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Scrolling complex websites can stutter: scrolling thread frame can fail to process wheel events
     4        https://bugs.webkit.org/show_bug.cgi?id=233739
     5        rdar://85946176
     6
     7        Reviewed by Tim Horton.
     8
     9        While the scrolling thread is chilling in
     10        ThreadedScrollingTree::waitForRenderingUpdateCompletionOrTimeout(), waiting up to half a
     11        frame to allow the main thread to handle the commit (for scroll synchronization), wheel
     12        events may have been dispatched to the scrolling thread.
     13
     14        If we blow the timeout and commit anyway, we need to make sure we've handled these wheel
     15        events first, so that the current frame can commit some layer movement. We can achieve this
     16        by dispatching the applyLayerPositions(), which will enqueue it behind any waiting wheel
     17        event dispatch from EventDispatcher::internalWheelEvent().
     18
     19        * page/scrolling/ScrollingTree.cpp:
     20        (WebCore::ScrollingTree::applyLayerPositions):
     21        * page/scrolling/ThreadedScrollingTree.cpp:
     22        (WebCore::ThreadedScrollingTree::waitForRenderingUpdateCompletionOrTimeout):
     23
    1242021-12-01  Simon Fraser  <simon.fraser@apple.com>
    225
  • trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp

    r286352 r286411  
    438438void ScrollingTree::applyLayerPositions()
    439439{
    440     ASSERT(isMainThread());
    441440    Locker locker { m_treeLock };
    442441
  • trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.cpp

    r286410 r286411  
    418418        // At this point we know the main thread is taking too long in the rendering update,
    419419        // so we give up trying to sync with the main thread and update layers here on the scrolling thread.
    420         if (canUpdateLayersOnScrollingThread())
    421             applyLayerPositionsInternal();
     420        if (canUpdateLayersOnScrollingThread()) {
     421            // Dispatch to allow for the scrolling thread to handle any outstanding wheel events before we commit layers.
     422            ScrollingThread::dispatch([protectedThis = Ref { *this }]() {
     423                protectedThis->applyLayerPositions();
     424            });
     425        }
    422426        tracePoint(ScrollingThreadRenderUpdateSyncEnd, 1);
    423427    } else
Note: See TracChangeset for help on using the changeset viewer.