commit 3ef34f13f0ae4db66f96da5f2d24a4a36a8f66ef
parent 4d93b3cafc3ada6411954fdf218fffeb5ace9663
Author: Jamie Nicol <jnicol@mozilla.com>
Date: Fri, 14 Nov 2025 10:47:37 +0000
Bug 1960922 - Obtain reference to CompositorSurfaceManager asynchronously. r=aosmond
GPUProcessHost must obtain a reference to the GPU process'
CompositorSurfaceManager, which requires a round-trip to the IPC
launcher thread in order to interact with GeckoProcessManager.
Currently this is achieved using a synchronous task, which has the
downside of blocking the main thread during startup.
This patch attempts to obtain the reference asynchronously, by
scheduling a task to run on the IPC launcher thread to obtain the
reference from GeckoSurfaceManager, then another back on the main
thread to initialize GPUProcessHost's member variable.
If GPUProcessHost::WaitForLaunch() is called prior to the async
initialization completing, we fall back to the synchronous task
approach.
Differential Revision: https://phabricator.services.mozilla.com/D272309
Diffstat:
3 files changed, 51 insertions(+), 23 deletions(-)
diff --git a/gfx/ipc/GPUProcessHost.cpp b/gfx/ipc/GPUProcessHost.cpp
@@ -79,6 +79,7 @@ bool GPUProcessHost::Launch(geckoargs::ChildProcessArgs aExtraOpts) {
}
bool GPUProcessHost::WaitForLaunch() {
+ MOZ_ASSERT(mLaunchPhase != LaunchPhase::Unlaunched);
if (mLaunchPhase == LaunchPhase::Complete) {
return !!mGPUChild;
}
@@ -140,30 +141,39 @@ void GPUProcessHost::InitAfterConnect(bool aSucceeded) {
DebugOnly<bool> rv = TakeInitialEndpoint().Bind(mGPUChild.get());
MOZ_ASSERT(rv);
- mGPUChild->Init()->Then(
- GetCurrentSerialEventTarget(), __func__,
- [this, liveToken = mLiveToken](
- const GPUChild::InitPromiseType::ResolveOrRejectValue&) {
- if (*liveToken) {
- this->OnAsyncInitComplete();
- }
- });
+ nsTArray<RefPtr<GPUChild::InitPromiseType>> initPromises;
+ initPromises.AppendElement(mGPUChild->Init());
#ifdef MOZ_WIDGET_ANDROID
- nsCOMPtr<nsIEventTarget> launcherThread(GetIPCLauncher());
+ nsCOMPtr<nsISerialEventTarget> launcherThread(GetIPCLauncher());
MOZ_ASSERT(launcherThread);
- layers::SynchronousTask task(
- "GeckoProcessManager::GetCompositorSurfaceManager");
-
- launcherThread->Dispatch(NS_NewRunnableFunction(
- "GeckoProcessManager::GetCompositorSurfaceManager", [&]() {
- layers::AutoCompleteTask complete(&task);
- mCompositorSurfaceManager =
- java::GeckoProcessManager::GetCompositorSurfaceManager();
- }));
-
- task.Wait();
+ RefPtr<GPUChild::InitPromiseType> csmPromise =
+ InvokeAsync(
+ launcherThread, __func__,
+ [] {
+ java::CompositorSurfaceManager::LocalRef csm =
+ java::GeckoProcessManager::GetCompositorSurfaceManager();
+ return MozPromise<java::CompositorSurfaceManager::GlobalRef, Ok,
+ true>::CreateAndResolve(csm, __func__);
+ })
+ ->Map(GetCurrentSerialEventTarget(), __func__,
+ [this, liveToken = mLiveToken](
+ java::CompositorSurfaceManager::GlobalRef&& aCsm) {
+ if (*liveToken) {
+ mCompositorSurfaceManager = aCsm;
+ }
+ return Ok{};
+ });
+ initPromises.AppendElement(csmPromise);
#endif
+
+ GPUChild::InitPromiseType::All(GetCurrentSerialEventTarget(), initPromises)
+ ->Then(GetCurrentSerialEventTarget(), __func__,
+ [this, liveToken = mLiveToken]() {
+ if (*liveToken) {
+ this->OnAsyncInitComplete();
+ }
+ });
} else {
mLaunchPhase = LaunchPhase::Complete;
if (mListener) {
@@ -187,6 +197,24 @@ bool GPUProcessHost::CompleteInitSynchronously() {
const bool result = mGPUChild->EnsureGPUReady();
+#ifdef MOZ_WIDGET_ANDROID
+ if (!mCompositorSurfaceManager) {
+ layers::SynchronousTask task(
+ "GeckoProcessManager::GetCompositorSurfaceManager");
+
+ nsCOMPtr<nsIEventTarget> launcherThread(GetIPCLauncher());
+ MOZ_ASSERT(launcherThread);
+ launcherThread->Dispatch(NS_NewRunnableFunction(
+ "GeckoProcessManager::GetCompositorSurfaceManager", [&]() {
+ layers::AutoCompleteTask complete(&task);
+ mCompositorSurfaceManager =
+ java::GeckoProcessManager::GetCompositorSurfaceManager();
+ }));
+
+ task.Wait();
+ }
+#endif
+
mLaunchPhase = LaunchPhase::Complete;
if (mListener) {
mListener->OnProcessLaunchComplete(this);
diff --git a/ipc/glue/GeckoChildProcessHost.cpp b/ipc/glue/GeckoChildProcessHost.cpp
@@ -994,7 +994,7 @@ IPCLaunchThreadObserver::Observe(nsISupports* aSubject, const char* aTopic,
return rv;
}
-nsCOMPtr<nsIEventTarget> GetIPCLauncher() {
+nsCOMPtr<nsISerialEventTarget> GetIPCLauncher() {
StaticMutexAutoLock lock(gIPCLaunchThreadMutex);
if (!gIPCLaunchThread) {
nsCOMPtr<nsIThread> thread;
@@ -1011,7 +1011,7 @@ nsCOMPtr<nsIEventTarget> GetIPCLauncher() {
}
}
- nsCOMPtr<nsIEventTarget> thread = gIPCLaunchThread.get();
+ nsCOMPtr<nsISerialEventTarget> thread = gIPCLaunchThread.get();
MOZ_DIAGNOSTIC_ASSERT(thread);
return thread;
}
diff --git a/ipc/glue/GeckoChildProcessHost.h b/ipc/glue/GeckoChildProcessHost.h
@@ -315,7 +315,7 @@ class GeckoChildProcessHost : public SupportsWeakPtr,
static StaticMutex sMutex;
};
-nsCOMPtr<nsIEventTarget> GetIPCLauncher();
+nsCOMPtr<nsISerialEventTarget> GetIPCLauncher();
} /* namespace ipc */
} /* namespace mozilla */