Add WorkerClient for WebCore to access WebKit from worker threads, and use it to create a RemoteRenderingBackendProxy per-thread
73a4c71642dfa90e574348729f4cfd8beb3ee2dc
Add WorkerClient for WebCore to access WebKit from worker threads, and use it to create a RemoteRenderingBackendProxy per-thread https://bugs.webkit.org/show_bug.cgi?id=244828 Reviewed by NOBODY (OOPS!). The primary design goal here is to avoid having classes that are accessed from multiple threads (and need locking), and instead to have per-thread instances with separate state. Creates new subclass for HostWindow 'GraphicsClient', for the graphics specific subset. This currently only has createImageBuffer, but in the future will have other graphics-related WebKit functionality (like creating a WebGL context). Creates a new interface class WorkerClient (which implements GraphicsClient), for accessing WebKit graphics APIs from a worker thread. Adds an implementation of this in WebWorkerClient. Allocates an instance of (Web)WorkerClient for every dedicated and shared worker, and makes it available via WorkerGlobalScope. WebWorkerClient creates a dedicated GPUProcessConnection and RemoteRenderingBackendProx for each worker thread/instance, and uses this to create RemoteImageBufferProxys that are safe to use on that worker thread. GPUProcess updated to handle multiple instances of GPUConnectionToWebProcess per web process, by storing both the primary connection (connected to the main thread of the web process), and a list of secondary connections (for workers). ImageBitmap::createImageBuffer has been updated to determine the appropriate GraphicsClient for the thread from the ScriptExecutionContext, and uses that when allocating buffers, so that we get GPUP backed image buffers for workers. * Source/WebCore/Headers.cmake: * Source/WebCore/html/ImageBitmap.cpp: (WebCore::ImageBitmap::createImageBuffer): * Source/WebCore/page/Chrome.cpp: (WebCore::Chrome::createWorkerClient): * Source/WebCore/page/Chrome.h: * Source/WebCore/page/ChromeClient.h: (WebCore::ChromeClient::createWorkerClient): * Source/WebCore/page/WorkerClient.h: Added. * Source/WebCore/platform/GraphicsClient.h: Added. * Source/WebCore/workers/DedicatedWorkerThread.cpp: (WebCore::DedicatedWorkerThread::createWorkerGlobalScope): * Source/WebCore/workers/WorkerGlobalScope.cpp: (WebCore::WorkerGlobalScope::setWorkerClient): * Source/WebCore/workers/WorkerGlobalScope.h: (WebCore::WorkerGlobalScope::getWorkerClient): * Source/WebCore/workers/WorkerMessagingProxy.cpp: (WebCore::WorkerMessagingProxy::startWorkerGlobalScope): * Source/WebCore/workers/WorkerThread.h: (WebCore::WorkerThread::setWorkerClient): (WebCore::WorkerThread::workerClient): * Source/WebCore/workers/shared/context/SharedWorkerThread.cpp: (WebCore::SharedWorkerThread::createWorkerGlobalScope): * Source/WebCore/workers/shared/context/SharedWorkerThreadProxy.cpp: (WebCore::SharedWorkerThreadProxy::SharedWorkerThreadProxy): * Source/WebKit/GPUProcess/GPUProcess.cpp: (WebKit::GPUProcess::createGPUConnectionToWebProcess): (WebKit::GPUProcess::removeGPUConnectionToWebProcess): (WebKit::GPUProcess::canExitUnderMemoryPressure const): (WebKit::GPUProcess::lowMemoryHandler): (WebKit::GPUProcess::webProcessConnection const): (WebKit::GPUProcess::extraWebProcessConnections const): (WebKit::GPUProcess::setOrientationForMediaCapture): (WebKit::GPUProcess::displayConfigurationChanged): (WebKit::GPUProcess::processIsStartingToCaptureAudio): (WebKit::GPUProcess::requestBitmapImageForCurrentTime): * Source/WebKit/GPUProcess/GPUProcess.h: * Source/WebKit/GPUProcess/cocoa/GPUProcessCocoa.mm: (WebKit::GPUProcess::additionalStateForDiagnosticReport const): * Source/WebKit/Platform/IPC/StreamClientConnection.cpp: (IPC::StreamClientConnection::open): * Source/WebKit/Platform/IPC/StreamClientConnection.h: * Source/WebKit/Shared/GPUProcessConnectionParameters.h: (WebKit::GPUProcessConnectionParameters::encode const): (WebKit::GPUProcessConnectionParameters::decode): * Source/WebKit/Sources.txt: * Source/WebKit/WebKit.xcodeproj/project.pbxproj: * Source/WebKit/WebProcess/GPU/GPUProcessConnection.cpp: (WebKit::GPUProcessConnection::create): (WebKit::GPUProcessConnection::GPUProcessConnection): * Source/WebKit/WebProcess/GPU/GPUProcessConnection.h: * Source/WebKit/WebProcess/GPU/graphics/RemoteGraphicsContextGLProxy.cpp: (WebKit::RemoteGraphicsContextGLProxy::RemoteGraphicsContextGLProxy): * Source/WebKit/WebProcess/GPU/graphics/RemoteRenderingBackendProxy.cpp: (WebKit::RemoteRenderingBackendProxy::create): (WebKit::RemoteRenderingBackendProxy::RemoteRenderingBackendProxy): (WebKit::RemoteRenderingBackendProxy::ensureGPUProcessConnection): * Source/WebKit/WebProcess/GPU/graphics/RemoteRenderingBackendProxy.h: * Source/WebKit/WebProcess/GPU/graphics/WebGPU/RemoteGPUProxy.cpp: (WebKit::RemoteGPUProxy::RemoteGPUProxy): * Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp: (WebKit::WebChromeClient::createWorkerClient): * Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h: * Source/WebKit/WebProcess/WebCoreSupport/WebWorkerClient.cpp: Added. (WebKit::WebWorkerClient::WebWorkerClient): (WebKit::WebWorkerClient::ensureRenderingBackend const): (WebKit::WebWorkerClient::clone): (WebKit::WebWorkerClient::displayID const): (WebKit::WebWorkerClient::createImageBuffer const): * Source/WebKit/WebProcess/WebCoreSupport/WebWorkerClient.h: Added. * Source/WebKit/WebProcess/WebProcess.cpp: (WebKit::WebProcess::createGPUProcessConnection): * Source/WebKit/WebProcess/WebProcess.h: * Tools/TestWebKitAPI/Tests/IPC/StreamConnectionTests.cpp: (TestWebKitAPI::TEST_F):
2974d64e695f2019961aea93fc1d0aebb3931223
Create GraphicsClient for the graphics specific subset of ChromeClient that needs to be accessed from worker threads. https://bugs.webkit.org/show_bug.cgi?id=244828 Reviewed by NOBODY (OOPS!). * Source/WebCore/Headers.cmake: * Source/WebCore/WebCore.xcodeproj/project.pbxproj: * Source/WebCore/css/CSSFilterImageValue.cpp: * Source/WebCore/html/HTMLCanvasElement.cpp: (WebCore::HTMLCanvasElement::createImageBuffer const): * Source/WebCore/html/ImageBitmap.cpp: (WebCore::ImageBitmap::createImageBuffer): (WebCore::ImageBitmap::createPromise): * Source/WebCore/html/ImageBitmap.h: * Source/WebCore/html/OffscreenCanvas.cpp: (WebCore::OffscreenCanvas::transferToImageBitmap): (WebCore::OffscreenCanvas::createImageBuffer const): * Source/WebCore/page/Chrome.h: * Source/WebCore/platform/HostWindow.h: * Source/WebCore/platform/graphics/ImageBuffer.cpp: (WebCore::ImageBuffer::create): * Source/WebCore/platform/graphics/ImageBuffer.h: (WebCore::ImageBuffer::CreationContext::CreationContext): * Source/WebCore/platform/graphics/cg/ImageBufferIOSurfaceBackend.cpp: (WebCore::ImageBufferIOSurfaceBackend::create): * Source/WebCore/platform/graphics/cocoa/IOSurface.h: * Source/WebCore/platform/graphics/cocoa/IOSurface.mm: (WebCore::IOSurface::ensurePlatformContext):
0f1b2d34f5b8fd3655cecfdda9fc656b46564445
Allow creating IPC::Connection with a SerialFunctionDispatcher other than the main RunLoop. https://bugs.webkit.org/show_bug.cgi?id=244825 Reviewed by NOBODY (OOPS!). * Source/WebKit/Platform/IPC/Connection.cpp: (IPC::Connection::SyncMessageStateImpl::enqueueMatchingMessages): (IPC::Connection::SyncMessageStateImpl::processIncomingMessage): (IPC::Connection::SyncMessageStateImpl::dispatchMessages): (IPC::Connection::SyncMessageStateImpl::dispatchMessagesAndResetDidScheduleDispatchMessagesForConnection): (IPC::Connection::createServerConnection): (IPC::Connection::Connection): (IPC::Connection::~Connection): (IPC::Connection::connection): (IPC::Connection::enqueueMatchingMessagesToMessageReceiveQueue): (IPC::Connection::invalidate): (IPC::Connection::waitForMessage): (IPC::Connection::sendSyncMessage): (IPC::Connection::processIncomingMessage): (IPC::Connection::enableIncomingMessagesThrottling): (IPC::Connection::connectionDidClose): (IPC::Connection::dispatchSyncMessage): (IPC::Connection::dispatchDidReceiveInvalidMessage): (IPC::Connection::enqueueIncomingMessage): (IPC::Connection::dispatchMessage): (IPC::Connection::dispatchIncomingMessages): (IPC::Connection::wakeUpRunLoop): * Source/WebKit/Platform/IPC/Connection.h: (IPC::Connection::sendSync): (IPC::Connection::waitForAndDispatchImmediately): (IPC::Connection::waitForAsyncCallbackAndDispatchImmediately):
508461b6877e2c9f6c7b7875422d791c17d715f3
Don't force CompletionHandlerCallThread::MainThread for async replies https://bugs.webkit.org/show_bug.cgi?id=246308 Reviewed by NOBODY (OOPS!). This only changes an assertion, doesn't affect behaviour at all. * Source/WebKit/Platform/IPC/Connection.h: (IPC::Connection::sendWithAsyncReply):
c3b87699d4881942d8684b390236315333005a3a
Add SerialFunctionDispatcher interface. https://bugs.webkit.org/show_bug.cgi?id=246305 Reviewed by NOBODY (OOPS!). This creates a common interface between RunLoop, and WorkerOrWorkletThread, that lets you dispatch Functions that are guaranteed to be executed serially. * Source/WTF/wtf/FunctionDispatcher.h: (WTF::WTF_ASSERTS_ACQUIRED_CAPABILITY): * Source/WTF/wtf/RunLoop.cpp: (WTF::RunLoop::assertIsCurrent const): * Source/WTF/wtf/RunLoop.h: * Source/WebCore/workers/WorkerOrWorkletThread.cpp: (WebCore::WorkerOrWorkletThread::dispatch): (WebCore::WorkerOrWorkletThread::assertIsCurrent const): * Source/WebCore/workers/WorkerOrWorkletThread.h:
https://github.com/WebKit/WebKit/commit/73a4c71642dfa90e574348729f4cfd8beb3ee2dc
Full branch for extra context: https://github.com/mattwoodrow/WebKit/commits/eng/remote-rendering-workers
EWS run on previous version of this PR (hash https://github.com/WebKit/WebKit/commit/f71351e1da162df4d3e17ee01e3778c997215b57)
I think this work could be simplified to first pursue the changes needed with GraphicsClient.
It seems that we are lacking a per-worker factory for polymorphic object instantiations.
We have per-page factory ChromeClient that creates objects that depend on global state.
We need per-worker factory of similar sort, WorkerClient.
I would start with:
- Extract what ImageBuffer/WebGL needs from ChromeClient to GraphicsClient, make it work with current code.
2a. Investigate what is the object that workers use to configure the polymorphic objects via the global state. If there is none, add this interface
alternatively
2b. Add logic for ChromeClient to hold per-thread GraphicsClients
Small detail:
I suppose the ScriptExecutionContext would be the place to add the initial polymorphic query to get the GraphicsClient?
E.g. there's ScriptExecutionContext::notificationClient(), and similar to this, there could be one for graphics?
Things that initially do not make sense to me:
GPUProcess updated to handle multiple instances of GPUConnectionToWebProcess per web process
This does not seem to be needed. To me, it appears as if we just need a RemoteRenderingBackendProxy per worker. Then we just need to make sure that the closure/crash support works if it doesn't work with the main connection.
SerialDispatchQueue -- We already have WorkQueue, which is a serial dispatch queue. So the code about that doesn't make sense initially. Note: the implementation seems to be missing from this patch.
Things that initially do not make sense to me:
GPUProcess updated to handle multiple instances of GPUConnectionToWebProcess per web process
This does not seem to be needed. To me, it appears as if we just need a RemoteRenderingBackendProxy per worker. Then we just need to make sure that the closure/crash support works if it doesn't work with the main connection.
We'd also need to add support to IPC::Connection for sending sync messages from the worker thread, and make sure responses are handled without touching/blocking the main thread. That's pretty complicated, with all the complexity we already have for handling unrelated messages while blocking for a sync message.
Instead, I added support for creating new IPC::Connections that are bound to the worker thread (and can send sync messages from that thread), but don't support the re-entrant message handling (for simplicity, and we don't need that functionality for the current use case).
This does require creating a new GPUConnectionToWebProcess though, bound to the IPC::Connection for the worker.
This is all in https://github.com/WebKit/WebKit/pull/4043 (which is a dependency here, though GitHub doesn't let me express that in a useful way).
SerialDispatchQueue -- We already have WorkQueue, which is a serial dispatch queue. So the code about that doesn't make sense initially. Note: the implementation seems to be missing from this patch.
The implementation is in https://github.com/WebKit/WebKit/pull/4043.
The functionality we're trying to represent here is 'the main thread, or a worker', that we can dispatch tasks to, assert that we're currently running in the expected place, and hold on to a reference to (could be weak, or strong).
WorkQueue is a specific implementation, that neither the main thread or workers are. The closest existing thing that I can find is FunctionDispatcher (which isn't implemented by WorkerOrWorkletThread, but can be), but that doesn't offer refcounting, or assertions.
SerialDispatchQueue -- We already have WorkQueue, which is a serial dispatch queue. So the code about that doesn't make sense initially. Note: the implementation seems to be missing from this patch.
Note that WorkQueue could implement the SerialDispatchQueue interface, but ConcurrentWorkQueue can't really, so it's a bit tricky.
EWS run on previous version of this PR (hash https://github.com/WebKit/WebKit/commit/73a4c71642dfa90e574348729f4cfd8beb3ee2dc)
Please note, only the top two commits are truly part of this PR. The others are just there because GitHub (and EWS) don't support dependent branches.
EWS run on previous version of this PR (hash https://github.com/WebKit/WebKit/commit/03e85a2f9ccb083b399b2c0d78a07f5aa2bcb4cc)
EWS run on previous version of this PR (hash https://github.com/WebKit/WebKit/commit/2519ee1971fb96eecccc87e2445cc69c570be2fc)
EWS run on previous version of this PR (hash https://github.com/WebKit/WebKit/commit/cb76e02d79dace052fa933fd2f81f91dc559d622)
EWS run on previous version of this PR (hash https://github.com/WebKit/WebKit/commit/bd97b321ec6f9b4753f3625856f508858ff3784b)
EWS run on previous version of this PR (hash https://github.com/WebKit/WebKit/commit/3e63f3b35080638757f6a3804bac05d097a44806)
EWS run on previous version of this PR (hash https://github.com/WebKit/WebKit/commit/a5c08fde27838767e58533d8fc4f9a56d6ed6580)
EWS run on previous version of this PR (hash https://github.com/WebKit/WebKit/commit/87c252509985f8fa53c3eec8eb5ff63884119495)
EWS run on previous version of this PR (hash https://github.com/WebKit/WebKit/commit/a57a491d24c545e19b9ac1c0c549c2cae2693611)
EWS run on previous version of this PR (hash https://github.com/WebKit/WebKit/commit/895e663d7fc75cc23dc6054e3dc969899701d98d)
EWS run on previous version of this PR (hash https://github.com/WebKit/WebKit/commit/071a8ec085c95cda2f0979371cbd3fae22009bcf)
EWS run on previous version of this PR (hash https://github.com/WebKit/WebKit/commit/ce2d1ad51459aee4d7efec90196d4dbe9048a434)
EWS run on previous version of this PR (hash https://github.com/WebKit/WebKit/commit/510d83b64300b5cd2b21c77c2858a29a43a087d6)
EWS run on previous version of this PR (hash https://github.com/WebKit/WebKit/commit/7844c4a94cc3885c06936eeb5c8a82f1c10ba9ec)
EWS run on previous version of this PR (hash https://github.com/WebKit/WebKit/commit/4904912f49fd36d3f6d7d23827775f9aacd48749)
EWS run on previous version of this PR (hash https://github.com/WebKit/WebKit/commit/9d2f63b9af9b996d6a198408b31c3db2b43484ec)
EWS run on previous version of this PR (hash https://github.com/WebKit/WebKit/commit/3aba2e87bdd814e0d20c389bee9816f5c7486609)
EWS run on previous version of this PR (hash https://github.com/WebKit/WebKit/commit/5d21d44c89ec27c55c5899bdd3266326ef3a3253)
EWS run on current version of this PR (hash https://github.com/WebKit/WebKit/commit/7088983bee320a698f700fc39a7557388185a7eb)
Committed 257507@main (280e6cdf0e10): https://commits.webkit.org/257507@main
Reviewed commits have been landed. Closing PR #4085 and removing active labels.