commit 9cc6b78dc079e599d2f5f2ab9b4824045f4b3027
parent a9a9ba3d6c4ddbaf1fa8cf9cba76e683df975d31
Author: Andrew Osmond <aosmond@gmail.com>
Date: Fri, 24 Oct 2025 19:34:29 +0000
Bug 1996352 - Refactor GPUProcessManager::AllocateAndConnectLayerTreeId to simplify/clarify. r=gfx-reviewers,bradwerth
Differential Revision: https://phabricator.services.mozilla.com/D270030
Diffstat:
3 files changed, 43 insertions(+), 36 deletions(-)
diff --git a/gfx/ipc/GPUProcessManager.cpp b/gfx/ipc/GPUProcessManager.cpp
@@ -1592,23 +1592,6 @@ nsresult GPUProcessManager::EnsureVideoBridge(
return NS_OK;
}
-void GPUProcessManager::MapLayerTreeId(LayersId aLayersId,
- base::ProcessId aOwningId) {
- if (NS_WARN_IF(NS_FAILED(EnsureGPUReady()))) {
- return;
- }
-
- if (mGPUChild) {
- mGPUChild->SendAddLayerTreeIdMapping(
- LayerTreeIdMapping(aLayersId, aOwningId));
- }
-
- // Must do this *after* the call to EnsureGPUReady, so that if the
- // process is launched as a result then it is initialized without this
- // LayersId, meaning it can be successfully mapped.
- LayerTreeOwnerTracker::Get()->Map(aLayersId, aOwningId);
-}
-
void GPUProcessManager::UnmapLayerTreeId(LayersId aLayersId,
base::ProcessId aOwningId) {
// If the GPU process is down, but not disabled, there is no need to relaunch
@@ -1673,26 +1656,40 @@ uint32_t GPUProcessManager::AllocateNamespace() {
bool GPUProcessManager::AllocateAndConnectLayerTreeId(
PCompositorBridgeChild* aCompositorBridge, base::ProcessId aOtherPid,
LayersId* aOutLayersId, CompositorOptions* aOutCompositorOptions) {
+ MOZ_ASSERT(aOutLayersId);
+
LayersId layersId = AllocateLayerTreeId();
*aOutLayersId = layersId;
- if (!mGPUChild || !aCompositorBridge) {
- // If we're not remoting to another process, or there is no compositor,
- // then we'll send at most one message. In this case we can just keep
- // the old behavior of making sure the mapping occurs, and maybe sending
- // a creation notification.
- MapLayerTreeId(layersId, aOtherPid);
- if (!aCompositorBridge) {
- return false;
+ // We always map the layer ID in the parent process so that we can recover
+ // from GPU process crashes. In that case, the tree will be shared with the
+ // new GPU process at initialization.
+ LayerTreeOwnerTracker::Get()->Map(layersId, aOtherPid);
+
+ if (NS_WARN_IF(NS_FAILED(EnsureGPUReady()))) {
+ return false;
+ }
+
+ // If we have a CompositorBridgeChild, then we need to call
+ // CompositorBridgeParent::NotifyChildCreated. If this is in the GPU process,
+ // we can combine it with LayerTreeOwnerTracker::Map to minimize IPC.
+ // messages.
+ if (aCompositorBridge) {
+ if (mGPUChild) {
+ return aCompositorBridge->SendMapAndNotifyChildCreated(
+ layersId, aOtherPid, aOutCompositorOptions);
}
return aCompositorBridge->SendNotifyChildCreated(layersId,
aOutCompositorOptions);
}
- // Use the combined message path.
- LayerTreeOwnerTracker::Get()->Map(layersId, aOtherPid);
- return aCompositorBridge->SendMapAndNotifyChildCreated(layersId, aOtherPid,
- aOutCompositorOptions);
+ // If we don't have a CompositorBridgeChild, we just need to call
+ // LayerTreeOwnerTracker::Map in the compositing process.
+ if (mGPUChild) {
+ mGPUChild->SendAddLayerTreeIdMapping(
+ LayerTreeIdMapping(layersId, aOtherPid));
+ }
+ return false;
}
void GPUProcessManager::EnsureVsyncIOThread() {
diff --git a/gfx/ipc/GPUProcessManager.h b/gfx/ipc/GPUProcessManager.h
@@ -132,10 +132,6 @@ class GPUProcessManager final : public GPUProcessHost::Listener {
mozilla::ipc::EndpointProcInfo aOtherProcess);
#endif
- // Maps the layer tree and process together so that aOwningPID is allowed
- // to access aLayersId across process.
- void MapLayerTreeId(LayersId aLayersId, base::ProcessId aOwningId);
-
// Release compositor-thread resources referred to by |aID|.
//
// Must run on the content main thread.
@@ -159,6 +155,9 @@ class GPUProcessManager final : public GPUProcessHost::Listener {
// null, the connect operation will not be performed, but an ID will still be
// allocated. This must be called from the browser main thread.
//
+ // It also maps the layer tree and process together so that aOwningPID is
+ // allowed to access aLayersId across process.
+ //
// Note that a layer tree id is always allocated, even if this returns false.
bool AllocateAndConnectLayerTreeId(PCompositorBridgeChild* aCompositorBridge,
base::ProcessId aOtherPid,
diff --git a/gfx/layers/ipc/LayerTreeOwnerTracker.cpp b/gfx/layers/ipc/LayerTreeOwnerTracker.cpp
@@ -35,15 +35,26 @@ void LayerTreeOwnerTracker::Map(LayersId aLayersId,
MutexAutoLock lock(mLayerIdsLock);
// Add the mapping to the list
- mLayerIds[aLayersId] = aProcessId;
+ const auto i = mLayerIds.insert({aLayersId, aProcessId});
+ MOZ_ASSERT(i.second, "Mapping already used layers ID!");
+ (void)i;
}
void LayerTreeOwnerTracker::Unmap(LayersId aLayersId,
base::ProcessId aProcessId) {
MutexAutoLock lock(mLayerIdsLock);
- MOZ_ASSERT(mLayerIds[aLayersId] == aProcessId);
- mLayerIds.erase(aLayersId);
+ auto i = mLayerIds.find(aLayersId);
+ if (i == mLayerIds.end()) {
+ return;
+ }
+
+ if (NS_WARN_IF(i->second != aProcessId)) {
+ MOZ_ASSERT_UNREACHABLE("Unmapping layers ID for another process!");
+ return;
+ }
+
+ mLayerIds.erase(i);
}
bool LayerTreeOwnerTracker::IsMapped(LayersId aLayersId,