Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: 3056a40d3e2365131be19a444b3f25fe1b42a824
      
https://github.com/WebKit/WebKit/commit/3056a40d3e2365131be19a444b3f25fe1b42a824
  Author: Simon Fraser <[email protected]>
  Date:   2024-11-04 (Mon, 04 Nov 2024)

  Changed paths:
    M 
Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.cpp
    M Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.h
    M Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingTree.cpp
    M 
Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.h
    M Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteScrollingTreeIOS.cpp
    M Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteScrollingTreeIOS.h
    M Source/WebKit/UIProcess/RemoteLayerTree/mac/RemoteScrollingTreeMac.mm

  Log Message:
  -----------
  WebCore's main thread scroll position is poorly synchronized with the 
UI-process scroll position
https://bugs.webkit.org/show_bug.cgi?id=282215
rdar://138804403

Reviewed by Matt Woodrow.

When we adopted UI-side compositing on macOS, the synchronization between the 
UI-process scroll
position, and the web process scroll position became worse. This has 
consequences for things like
repainting non-root `background-attachment: fixed`, and for the scroll position 
exposed to JavaScript.
It's bad enough that even for a responsive web process (<16ms frames), the web 
content scroll position
is often a frame stale for a given rendering update.

There are some race conditions that cause this. A rendering update is triggered 
in the UI
process by a displayLink callback off the main thread. This callback triggers 
two things:

1. It is bounced to the scrolling thread where it triggers the generation of 
synthetic momentum events,
   which are handled by the scrolling tree. This results in layer 
repositioning, the actual manifestation of scrolling,
   and in "scrollingTreeNodeDidScroll" messages, which bounce back to the main 
thread, and then result
   in IPC to web content. It's these messages that determine the web content 
notion of scroll position.

2. It triggers a `DisplayDidRefresh` IPC message from the UI process main 
thread to the web process. This
   bounces through a zero-delay time in the web process which then starts the 
rendering update.

The raciness is between these two series of steps:
  i) Display link thread -> scrolling thread -> main thread -> IPC to web 
content (for scroll position)
 ii) Display link thread -> main thread -> IPC to web content -> zero delay 
timer (for rendering update trigger)

`RemoteLayerTreeDrawingAreaProxy::didRefreshDisplay()` tries to address this by 
eagerly calling
`scrollingCoordinatorProxy()->sendScrollingTreeNodeDidScroll()` but this was 
ineffective because the "node did scroll"
message often hasn't got back to the main thread yet.

The fix is to do what we do already in ThreadedScrollingTree (older the web 
process scrolling code): instead of
using a callback to get the "node did scroll" message back to the UI process 
main thread, add a `ScrollUpdate`
to the ScrollingTree's pending updates directly from the scrolling thread (with 
a lock). With that,
`RemoteLayerTreeDrawingAreaProxy::didRefreshDisplay()` sees the update in time.

`RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidScroll()` goes away, 
replaced with `scrollingThreadAddedPendingUpdate`,
and the iOS-specific behavior there about `propagatesMainFrameScrolls` moves 
into a `RemoteScrollingTreeIOS::scrollingTreeNodeDidScroll()`
override.

* Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.cpp:
(WebKit::RemoteScrollingCoordinatorProxy::sendScrollingTreeNodeDidScroll):
(WebKit::RemoteScrollingCoordinatorProxy::scrollingThreadAddedPendingUpdate):
(WebKit::RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidScroll): Deleted.
* Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.h:
(WebKit::RemoteScrollingCoordinatorProxy::propagatesMainFrameScrolls const): 
Deleted.
* Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingTree.cpp:
(WebKit::RemoteScrollingTree::scrollingTreeNodeDidScroll):
* 
Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.h:
* Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteScrollingTreeIOS.cpp:
(WebKit::RemoteScrollingTreeIOS::scrollingTreeNodeDidScroll):
* Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteScrollingTreeIOS.h:
* Source/WebKit/UIProcess/RemoteLayerTree/mac/RemoteScrollingTreeMac.mm:
(WebKit::RemoteScrollingTreeMac::scrollingTreeNodeDidScroll):

Canonical link: https://commits.webkit.org/286095@main



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to