-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[CoordinatedGraphics] Provide scheduled display-update events for better scrolling handling #10259
Conversation
EWS run on previous version of this PR (hash 8bbed56) |
8bbed56
to
c086f4f
Compare
EWS run on previous version of this PR (hash c086f4f) |
c086f4f
to
cde889c
Compare
EWS run on previous version of this PR (hash cde889c) |
{ | ||
m_display.displayUpdate = m_display.displayUpdate.nextUpdate(); | ||
|
||
WebProcess::singleton().eventDispatcher().notifyScrollingTreesDisplayDidRefresh(m_display.displayID); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did you remove the Client::displayDidRefresh
? EventDispatcher::notifyScrollingTreesDisplayDidRefresh
iterates all scrolling trees to notify that a display has been refreshed. Every tree checks if its displayID matches the given one. This is required when there's a global display notifying about a refresh, but in our case we have one display refresh monitor with its own displayID for every threaded compositor. So, we know what tree we wat to notify without having to iterate all trees.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is called from the composition thread, so LayerTreeHost::displayDidRefresh()
ends up loading the Page's ScrollingCoordinator and then its ScrollingTree from a non-main thread.
Using EventDispatcher avoids that, and it locks over the scrolling trees that are registered and unregistered on the main thread, so no threading problems.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, in that case I would add:
void EventDispatcher::notifyWebPageScrollingTreeDisplayDidRefresh(WebPage& page, PlatformDisplayID displayID);
And call it from LayerTreeHost::displayDidRefresh
. This avoids the tree iteration, fixes the threading issues and doesn't use WebProcess API from Shared.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume you would want to short-cut to the ScrollingTree in the new EventDispatcher method, through the WebPage. But that still operates on that WebPage on a non-main thread, so threading problems would remain.
Calling ThreadedScrollingTree::displayDidRefresh()
on every scrolling tree isn't ideal, and it can be improved, but I don't see it as critical.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be just getting the identifier that is the key of the trees map. Anyway, it's not critical since in most of the cases there's only one page per process. But still I prefer to call the dispatcher from LayerTreeHost::displayDidRefresh
, which is in WebProcess layer too. At some point we should move the threaded compositor code from Shared to WebProcess and stop pretending it's shared, though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I'm adding back LayerTreeHost::displayDidRefresh
.
cde889c
to
9f44e64
Compare
EWS run on previous version of this PR (hash 9f44e64) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still get some blocks, but less often, so let's try this. Thanks!
Source/WebKit/Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp
Show resolved
Hide resolved
Source/WebKit/Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp
Outdated
Show resolved
Hide resolved
9f44e64
to
3817582
Compare
EWS run on current version of this PR (hash 3817582) |
β¦ter scrolling handling https://bugs.webkit.org/show_bug.cgi?id=252467 Reviewed by Carlos Garcia Campos. In ThreadedCompositor, a timer is established on the composition thread that is used to mimic display updates at the desired update frequency. This is necessary in order to provide opportunities for update producers like the scrolling thread to actually enact the desired composition changes, like scrolling, independently of the main thread. The timer is put on the composition thread, matching the compositing-thread update timer in priority. Its delay is based on the established frequency of the display updates. ThreadedCompositor::displayUpdateFired() method is added and is dispatched upon every firing of the timer. It notifies the scrolling thread(s) for the given display ID through the EventDispatcher instance on the WebProcess singleton, and the next firing of the timer is then scheduled. When ThreadedCompositor enters into the composition phase, the display update timer is stopped, and the displayUpdateFired() dispatcher is invoked manually when the frame-complete signal is returned from the embedder's environment. This allows aligning the display update timer with the environment's vsync signals without disturbing the composition itself. The target update frequency logic is pulled from ThreadedDisplayRefreshMonitor into ThreadedCompositor, with the desired DisplayUpdate object now also kept in that class. In order for ThreadedDisplayRefreshMonitor to use a sensible DisplayUpdate object for each of its own dispatches, the DisplayUpdate object is passed through the requiresDisplayRefreshCallback() method to the monitor, where it's then stored for next invocation on the main thread, if it occurs. ScrollingTreeNicosia::applyLayerPositionsInternal() override is provided, establishing an update scope when running on the scrolling thread. This will cause the applied positions to actually go through composition whenever the scrolling is being handled on the scrolling thread, meaning outside of the usual update process. * Source/WebCore/page/scrolling/nicosia/ScrollingTreeNicosia.cpp: (WebCore::ScrollingTreeNicosia::applyLayerPositionsInternal): * Source/WebCore/page/scrolling/nicosia/ScrollingTreeNicosia.h: * Source/WebKit/Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp: (WebKit::m_displayRefreshMonitor): (WebKit::ThreadedCompositor::renderLayerTree): (WebKit::ThreadedCompositor::sceneUpdateFinished): (WebKit::ThreadedCompositor::frameComplete): (WebKit::ThreadedCompositor::targetRefreshRateDidChange): (WebKit::ThreadedCompositor::displayUpdateFired): * Source/WebKit/Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.h: * Source/WebKit/Shared/CoordinatedGraphics/threadedcompositor/ThreadedDisplayRefreshMonitor.cpp: (WebKit::ThreadedDisplayRefreshMonitor::ThreadedDisplayRefreshMonitor): (WebKit::ThreadedDisplayRefreshMonitor::requiresDisplayRefreshCallback): (WebKit::ThreadedDisplayRefreshMonitor::invalidate): (WebKit::ThreadedDisplayRefreshMonitor::displayRefreshCallback): (WebKit::ThreadedDisplayRefreshMonitor::setTargetRefreshRate): Deleted. * Source/WebKit/Shared/CoordinatedGraphics/threadedcompositor/ThreadedDisplayRefreshMonitor.h: * Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHost.cpp: (WebKit::LayerTreeHost::displayDidRefresh): Canonical link: https://commits.webkit.org/261124@main
3817582
to
06b9ec1
Compare
Committed 261124@main (06b9ec1): https://commits.webkit.org/261124@main Reviewed commits have been landed. Closing PR #10259 and removing active labels. |
06b9ec1
3817582
π macπ wpeπ wincairoπ§ͺ ios-wk2π§ͺ api-macπ§ͺ api-iosπ§ͺ mac-wk1π tvπ§ͺ mac-wk2π§ͺ api-gtkπ§ͺ mac-AS-debug-wk2π§ͺ mac-wk2-stressπ watch-sim