commit 54afadf9a3a55c7f88823ec522d3d975cada501b
parent 8fbbb50184640ff2f7fbaad5382da08656fabbde
Author: Serban Stanca <sstanca@mozilla.com>
Date: Mon, 20 Oct 2025 07:23:14 +0300
Revert "Bug 1993758 - Rework how RDD/utility processes initialize PVideoBridge with the GPU process. r=gfx-reviewers,lsalzman" for causing VideoBridge related failures.
This reverts commit 8fbbb50184640ff2f7fbaad5382da08656fabbde.
Diffstat:
10 files changed, 125 insertions(+), 142 deletions(-)
diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp
@@ -2786,15 +2786,12 @@ bool ContentParent::InitInternal(ProcessPriority aInitialPriority) {
xpcomInit.userContentSheetURL() = nullptr;
}
- // 1. Ensure the GPU process is ready, as we know we are not yet in shutdown.
- GPUProcessManager* gpm = GPUProcessManager::Get();
- gpm->EnsureGPUReady();
- // 2. Build ContentDeviceData first, as it may affect some gfxVars.
+ // 1. Build ContentDeviceData first, as it may affect some gfxVars.
gfxPlatform::GetPlatform()->BuildContentDeviceData(
&xpcomInit.contentDeviceData());
- // 3. Gather non-default gfxVars.
+ // 2. Gather non-default gfxVars.
xpcomInit.gfxNonDefaultVarUpdates() = gfxVars::FetchNonDefaultVars();
- // 4. Start listening for gfxVars updates, to notify content process later on.
+ // 3. Start listening for gfxVars updates, to notify content process later on.
gfxVars::AddReceiver(this);
nsCOMPtr<nsIGfxInfo> gfxInfo = components::GfxInfo::Service();
@@ -2908,6 +2905,8 @@ bool ContentParent::InitInternal(ProcessPriority aInitialPriority) {
// PBrowsers are created, because they rely on the Compositor
// already being around. (Creation is async, so can't happen
// on demand.)
+ GPUProcessManager* gpm = GPUProcessManager::Get();
+
Endpoint<PCompositorManagerChild> compositor;
Endpoint<PImageBridgeChild> imageBridge;
Endpoint<PVRManagerChild> vrBridge;
diff --git a/dom/media/ipc/RDDChild.cpp b/dom/media/ipc/RDDChild.cpp
@@ -72,6 +72,10 @@ bool RDDChild::Init() {
Unused << SendInitProfiler(ProfilerParent::CreateForProcess(OtherPid()));
gfxVars::AddReceiver(this);
+ auto* gpm = gfx::GPUProcessManager::Get();
+ if (gpm) {
+ gpm->AddListener(this);
+ }
return true;
}
@@ -106,14 +110,9 @@ bool RDDChild::SendRequestMemoryReport(const uint32_t& aGeneration,
}
void RDDChild::OnCompositorUnexpectedShutdown() {
- if (!CanSend()) {
- return;
- }
-
- if (RDDProcessManager* rddpm = RDDProcessManager::Get()) {
- if (auto* gpm = GPUProcessManager::Get()) {
- gpm->CreateRddVideoBridge(rddpm, this);
- }
+ auto* rddm = RDDProcessManager::Get();
+ if (rddm) {
+ rddm->CreateVideoBridge();
}
}
@@ -208,7 +207,8 @@ void RDDChild::ActorDestroy(ActorDestroyReason aWhy) {
GenerateCrashReport();
}
- if (auto* gpm = gfx::GPUProcessManager::Get()) {
+ auto* gpm = gfx::GPUProcessManager::Get();
+ if (gpm) {
// Note: the manager could have shutdown already.
gpm->RemoveListener(this);
}
diff --git a/dom/media/ipc/RDDProcessManager.cpp b/dom/media/ipc/RDDProcessManager.cpp
@@ -173,17 +173,12 @@ RefPtr<GenericNonExclusivePromise> RDDProcessManager::LaunchRDDProcess() {
CrashReporter::RecordAnnotationCString(
CrashReporter::Annotation::RDDProcessStatus, "Running");
- auto* gpm = GPUProcessManager::Get();
- if (NS_WARN_IF(!mRDDChild->CanSend()) || NS_WARN_IF(!gpm) ||
- NS_WARN_IF(NS_FAILED(gpm->EnsureGPUReady())) ||
- NS_WARN_IF(NS_FAILED(gpm->CreateRddVideoBridge(this, mRDDChild)))) {
+ if (!CreateVideoBridge()) {
mNumProcessAttempts++;
DestroyProcess();
return GenericNonExclusivePromise::CreateAndReject(
NS_ERROR_NOT_AVAILABLE, __func__);
}
-
- gpm->AddListener(mRDDChild);
return GenericNonExclusivePromise::CreateAndResolve(true, __func__);
},
[this](nsresult aError) {
@@ -309,6 +304,50 @@ bool RDDProcessManager::CreateContentBridge(
return true;
}
+bool RDDProcessManager::CreateVideoBridge() {
+ MOZ_ASSERT(NS_IsMainThread());
+ ipc::Endpoint<PVideoBridgeParent> parentPipe;
+ ipc::Endpoint<PVideoBridgeChild> childPipe;
+
+ GPUProcessManager* gpuManager = GPUProcessManager::Get();
+ ipc::EndpointProcInfo gpuProcessInfo = gpuManager
+ ? gpuManager->GPUEndpointProcInfo()
+ : ipc::EndpointProcInfo::Invalid();
+
+ // Build content device data first; this ensure that the GPU process is fully
+ // ready.
+ ContentDeviceData contentDeviceData;
+ gfxPlatform::GetPlatform()->BuildContentDeviceData(&contentDeviceData);
+
+ // The child end is the producer of video frames; the parent end is the
+ // consumer.
+ ipc::EndpointProcInfo childInfo = RDDEndpointProcInfo();
+ ipc::EndpointProcInfo parentInfo =
+ gpuProcessInfo != ipc::EndpointProcInfo::Invalid()
+ ? gpuProcessInfo
+ : ipc::EndpointProcInfo::Current();
+
+ nsresult rv = PVideoBridge::CreateEndpoints(parentInfo, childInfo,
+ &parentPipe, &childPipe);
+ if (NS_FAILED(rv)) {
+ MOZ_LOG(sPDMLog, LogLevel::Debug,
+ ("Could not create video bridge: %d", int(rv)));
+ return false;
+ }
+
+ mRDDChild->SendInitVideoBridge(std::move(childPipe),
+ mNumUnexpectedCrashes == 0, contentDeviceData);
+ if (gpuProcessInfo != ipc::EndpointProcInfo::Invalid()) {
+ gpuManager->InitVideoBridge(std::move(parentPipe),
+ VideoBridgeSource::RddProcess);
+ } else {
+ VideoBridgeParent::Open(std::move(parentPipe),
+ VideoBridgeSource::RddProcess);
+ }
+
+ return true;
+}
+
base::ProcessId RDDProcessManager::RDDProcessPid() {
MOZ_ASSERT(NS_IsMainThread());
base::ProcessId rddPid =
diff --git a/dom/media/ipc/RDDProcessManager.h b/dom/media/ipc/RDDProcessManager.h
@@ -76,6 +76,7 @@ class RDDProcessManager final : public RDDProcessHost::Listener {
private:
bool IsRDDProcessLaunching();
bool IsRDDProcessDestroyed() const;
+ bool CreateVideoBridge();
// Called from our xpcom-shutdown observer.
void OnXPCOMShutdown();
diff --git a/gfx/ipc/GPUProcessManager.cpp b/gfx/ipc/GPUProcessManager.cpp
@@ -13,15 +13,13 @@
#include "mozilla/AppShutdown.h"
#include "mozilla/MemoryReportingProcess.h"
#include "mozilla/Preferences.h"
-#include "mozilla/RDDChild.h"
-#include "mozilla/RDDProcessManager.h"
-#include "mozilla/RemoteMediaManagerChild.h"
-#include "mozilla/RemoteMediaManagerParent.h"
#include "mozilla/Sprintf.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/StaticPrefs_gfx.h"
#include "mozilla/StaticPrefs_layers.h"
#include "mozilla/StaticPrefs_media.h"
+#include "mozilla/RemoteMediaManagerChild.h"
+#include "mozilla/RemoteMediaManagerParent.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/gfx/gfxVars.h"
#include "mozilla/gfx/GPUChild.h"
@@ -41,7 +39,6 @@
#include "mozilla/layers/InProcessCompositorSession.h"
#include "mozilla/layers/LayerTreeOwnerTracker.h"
#include "mozilla/layers/RemoteCompositorSession.h"
-#include "mozilla/layers/VideoBridgeParent.h"
#include "mozilla/webrender/RenderThread.h"
#include "mozilla/widget/PlatformWidgetTypes.h"
#include "nsAppRunner.h"
@@ -59,10 +56,6 @@
#include "nsExceptionHandler.h"
#include "nsPrintfCString.h"
-#ifdef MOZ_WMF_MEDIA_ENGINE
-# include "mozilla/ipc/UtilityMediaServiceChild.h"
-#endif
-
#if defined(MOZ_WIDGET_ANDROID)
# include "mozilla/java/SurfaceControlManagerWrappers.h"
# include "mozilla/widget/AndroidUiThread.h"
@@ -1518,72 +1511,16 @@ void GPUProcessManager::CreateContentRemoteMediaManager(
*aOutEndpoint = std::move(childPipe);
}
-#ifdef MOZ_WMF_MEDIA_ENGINE
-nsresult GPUProcessManager::CreateUtilityMFCDMVideoBridge(
- mozilla::ipc::UtilityMediaServiceChild* aChild,
- mozilla::ipc::EndpointProcInfo aOtherProcess) {
- MOZ_ASSERT(aChild);
- MOZ_ASSERT(aChild->CanSend());
-
- ipc::Endpoint<PVideoBridgeChild> childPipe;
- nsresult rv = EnsureVideoBridge(VideoBridgeSource::MFMediaEngineCDMProcess,
- aOtherProcess, &childPipe);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
-
- gfx::ContentDeviceData contentDeviceData;
- gfxPlatform::GetPlatform()->BuildContentDeviceData(&contentDeviceData);
- aChild->SendInitVideoBridge(std::move(childPipe), contentDeviceData);
- return NS_OK;
-}
-#endif
-
-nsresult GPUProcessManager::CreateRddVideoBridge(RDDProcessManager* aRDD,
- RDDChild* aChild) {
- MOZ_ASSERT(aRDD);
- MOZ_ASSERT(aChild);
- MOZ_ASSERT(aChild->CanSend());
-
- ipc::Endpoint<PVideoBridgeChild> childPipe;
- nsresult rv = EnsureVideoBridge(VideoBridgeSource::RddProcess,
- aChild->OtherEndpointProcInfo(), &childPipe);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
-
- gfx::ContentDeviceData contentDeviceData;
- gfxPlatform::GetPlatform()->BuildContentDeviceData(&contentDeviceData);
- aChild->SendInitVideoBridge(std::move(childPipe),
- !aRDD->AttemptedRDDProcess(), contentDeviceData);
- return NS_OK;
-}
-
-nsresult GPUProcessManager::EnsureVideoBridge(
- layers::VideoBridgeSource aSource,
- mozilla::ipc::EndpointProcInfo aOtherProcess,
- mozilla::ipc::Endpoint<layers::PVideoBridgeChild>* aOutChildPipe) {
- MOZ_ASSERT(aOutChildPipe);
- MOZ_DIAGNOSTIC_ASSERT(IsGPUReady());
-
- ipc::EndpointProcInfo gpuInfo = mGPUChild ? mGPUChild->OtherEndpointProcInfo()
- : ipc::EndpointProcInfo::Current();
-
- // The child end is the producer of video frames; the parent end is the
- // consumer.
- ipc::Endpoint<PVideoBridgeParent> parentPipe;
- nsresult rv = PVideoBridge::CreateEndpoints(gpuInfo, aOtherProcess,
- &parentPipe, aOutChildPipe);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
+void GPUProcessManager::InitVideoBridge(
+ ipc::Endpoint<PVideoBridgeParent>&& aVideoBridge,
+ layers::VideoBridgeSource aSource) {
+ if (NS_WARN_IF(NS_FAILED(EnsureGPUReady()))) {
+ return;
}
if (mGPUChild) {
- mGPUChild->SendInitVideoBridge(std::move(parentPipe), aSource);
- } else {
- VideoBridgeParent::Open(std::move(parentPipe), aSource);
+ mGPUChild->SendInitVideoBridge(std::move(aVideoBridge), aSource);
}
- return NS_OK;
}
void GPUProcessManager::MapLayerTreeId(LayersId aLayersId,
diff --git a/gfx/ipc/GPUProcessManager.h b/gfx/ipc/GPUProcessManager.h
@@ -27,8 +27,6 @@ enum class DeviceResetReason;
namespace mozilla {
class MemoryReportingProcess;
class PRemoteMediaManagerChild;
-class RDDProcessManager;
-class RDDChild;
namespace layers {
class IAPZCTreeManager;
class CompositorOptions;
@@ -52,9 +50,6 @@ class BrowserParent;
} // namespace dom
namespace ipc {
class GeckoChildProcessHost;
-#ifdef MOZ_WMF_MEDIA_ENGINE
-class UtilityMediaServiceChild;
-#endif
} // namespace ipc
namespace gfx {
@@ -110,8 +105,6 @@ class GPUProcessManager final : public GPUProcessHost::Listener {
// in shutdown.
nsresult EnsureGPUReady();
- bool IsGPUReady() const;
-
already_AddRefed<CompositorSession> CreateTopLevelCompositor(
nsIWidget* aWidget, WebRenderLayerManager* aLayerManager,
CSSToLayoutDeviceScale aScale, const CompositorOptions& aOptions,
@@ -126,12 +119,10 @@ class GPUProcessManager final : public GPUProcessHost::Listener {
mozilla::ipc::Endpoint<PRemoteMediaManagerChild>* aOutVideoManager,
dom::ContentParentId aChildId, nsTArray<uint32_t>* aNamespaces);
- nsresult CreateRddVideoBridge(RDDProcessManager* aRDD, RDDChild* aChild);
-#ifdef MOZ_WMF_MEDIA_ENGINE
- nsresult CreateUtilityMFCDMVideoBridge(
- mozilla::ipc::UtilityMediaServiceChild* aChild,
- mozilla::ipc::EndpointProcInfo aOtherProcess);
-#endif
+ // Initialize GPU process with consuming end of PVideoBridge.
+ void InitVideoBridge(
+ mozilla::ipc::Endpoint<PVideoBridgeParent>&& aVideoBridge,
+ layers::VideoBridgeSource aSource);
// Maps the layer tree and process together so that aOwningPID is allowed
// to access aLayersId across process.
@@ -244,6 +235,8 @@ class GPUProcessManager final : public GPUProcessHost::Listener {
void OnPreferenceChange(const char16_t* aData);
void ScreenInformationChanged();
+ bool IsGPUReady() const;
+
bool CreateContentCompositorManager(
mozilla::ipc::EndpointProcInfo aOtherProcess,
dom::ContentParentId aChildId, uint32_t aNamespace,
@@ -261,11 +254,6 @@ class GPUProcessManager final : public GPUProcessHost::Listener {
dom::ContentParentId aChildId,
mozilla::ipc::Endpoint<PRemoteMediaManagerChild>* aOutEndPoint);
- nsresult EnsureVideoBridge(
- layers::VideoBridgeSource aSource,
- mozilla::ipc::EndpointProcInfo aOtherProcess,
- mozilla::ipc::Endpoint<layers::PVideoBridgeChild>* aOutChildPipe);
-
// Called from RemoteCompositorSession. We track remote sessions so we can
// notify their owning widgets that the session must be restarted.
void RegisterRemoteProcessSession(RemoteCompositorSession* aSession);
diff --git a/gfx/thebes/gfxPlatform.cpp b/gfx/thebes/gfxPlatform.cpp
@@ -4163,11 +4163,9 @@ void gfxPlatform::BuildContentDeviceData(
mozilla::gfx::ContentDeviceData* aOut) {
MOZ_ASSERT(XRE_IsParentProcess());
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
- if (auto* gpm = GPUProcessManager::Get()) {
- MOZ_DIAGNOSTIC_ASSERT(gpm->IsGPUReady());
- }
-#endif
+ // Make sure our settings are synchronized from the GPU process.
+ DebugOnly<nsresult> rv = GPUProcessManager::Get()->EnsureGPUReady();
+ MOZ_ASSERT(NS_SUCCEEDED(rv));
aOut->prefs().hwCompositing() = gfxConfig::GetValue(Feature::HW_COMPOSITING);
aOut->prefs().oglCompositing() =
diff --git a/ipc/glue/UtilityMediaServiceChild.cpp b/ipc/glue/UtilityMediaServiceChild.cpp
@@ -88,12 +88,6 @@ nsresult UtilityMediaServiceChild::BindToUtilityProcess(
void UtilityMediaServiceChild::ActorDestroy(ActorDestroyReason aReason) {
MOZ_ASSERT(NS_IsMainThread());
gfx::gfxVars::RemoveReceiver(this);
-#ifdef MOZ_WMF_MEDIA_ENGINE
- if (auto* gpm = gfx::GPUProcessManager::Get()) {
- // Note: the manager could have shutdown already.
- gpm->RemoveListener(this);
- }
-#endif
Shutdown(mSandbox);
}
@@ -150,33 +144,60 @@ void UtilityMediaServiceChild::OnCompositorUnexpectedShutdown() {
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mSandbox == SandboxingKind::MF_MEDIA_ENGINE_CDM);
mHasCreatedVideoBridge = State::None;
-
- if (auto* gpm = gfx::GPUProcessManager::Get()) {
- if (auto utilpm = UtilityProcessManager::GetSingleton())
- if (auto parent = utilpm->GetProcessParent(mSandbox)) {
- if (NS_SUCCEEDED(gpm->CreateUtilityMFCDMVideoBridge(
- this, parent->OtherEndpointProcInfo()))) {
- mHasCreatedVideoBridge = State::Creating;
- }
- }
- }
+ CreateVideoBridge();
}
-bool UtilityMediaServiceChild::CreateVideoBridge(
- mozilla::ipc::EndpointProcInfo aOtherProcess) {
+bool UtilityMediaServiceChild::CreateVideoBridge() {
MOZ_ASSERT(NS_IsMainThread());
+ ipc::Endpoint<layers::PVideoBridgeParent> parentPipe;
+ ipc::Endpoint<layers::PVideoBridgeChild> childPipe;
+
MOZ_ASSERT(mSandbox == SandboxingKind::MF_MEDIA_ENGINE_CDM);
- MOZ_ASSERT(mHasCreatedVideoBridge == State::None);
- auto* gpm = gfx::GPUProcessManager::Get();
- if (NS_WARN_IF(!gpm) || NS_WARN_IF(NS_FAILED(gpm->EnsureGPUReady())) ||
- NS_WARN_IF(
- NS_FAILED(gpm->CreateUtilityMFCDMVideoBridge(this, aOtherProcess)))) {
+ // Creating or already created, avoiding reinit a bridge.
+ if (mHasCreatedVideoBridge != State::None) {
+ return true;
+ }
+ mHasCreatedVideoBridge = State::Creating;
+
+ gfx::GPUProcessManager* gpuManager = gfx::GPUProcessManager::Get();
+ ipc::EndpointProcInfo gpuProcessInfo = gpuManager
+ ? gpuManager->GPUEndpointProcInfo()
+ : ipc::EndpointProcInfo::Invalid();
+
+ // Build content device data first; this ensure that the GPU process is fully
+ // ready.
+ gfx::ContentDeviceData contentDeviceData;
+ gfxPlatform::GetPlatform()->BuildContentDeviceData(&contentDeviceData);
+
+ // The child end is the producer of video frames; the parent end is the
+ // consumer.
+ EndpointProcInfo childInfo = UtilityProcessManager::GetSingleton()
+ ->GetProcessParent(mSandbox)
+ ->OtherEndpointProcInfo();
+ EndpointProcInfo parentInfo =
+ gpuProcessInfo != ipc::EndpointProcInfo::Invalid()
+ ? gpuProcessInfo
+ : ipc::EndpointProcInfo::Current();
+
+ nsresult rv = layers::PVideoBridge::CreateEndpoints(parentInfo, childInfo,
+ &parentPipe, &childPipe);
+ if (NS_FAILED(rv)) {
+ NS_WARNING("Failed to create endpoints for video bridge!");
return false;
}
- gpm->AddListener(this);
- mHasCreatedVideoBridge = State::Creating;
+ if (gpuProcessInfo != ipc::EndpointProcInfo::Invalid()) {
+ gpuManager->InitVideoBridge(
+ std::move(parentPipe),
+ layers::VideoBridgeSource::MFMediaEngineCDMProcess);
+ } else {
+ layers::VideoBridgeParent::Open(
+ std::move(parentPipe),
+ layers::VideoBridgeSource::MFMediaEngineCDMProcess);
+ }
+
+ SendInitVideoBridge(std::move(childPipe), contentDeviceData);
return true;
}
#endif
diff --git a/ipc/glue/UtilityMediaServiceChild.h b/ipc/glue/UtilityMediaServiceChild.h
@@ -77,7 +77,7 @@ class UtilityMediaServiceChild final : public PUtilityMediaServiceChild,
// True if creating a video bridge sucessfully. Currently only used for media
// engine cdm.
- bool CreateVideoBridge(mozilla::ipc::EndpointProcInfo aOtherProcess);
+ bool CreateVideoBridge();
#endif
#ifdef MOZ_WMF_CDM
diff --git a/ipc/glue/UtilityProcessManager.cpp b/ipc/glue/UtilityProcessManager.cpp
@@ -385,7 +385,7 @@ UtilityProcessManager::StartProcessForRemoteMediaDecoding(
#ifdef MOZ_WMF_MEDIA_ENGINE
if (aSandbox == SandboxingKind::MF_MEDIA_ENGINE_CDM &&
- !umsc->CreateVideoBridge(process)) {
+ !umsc->CreateVideoBridge()) {
MOZ_ASSERT(false, "Failed to create video bridge");
return RetPromise::CreateAndReject(
LaunchError("UMSC::CreateVideoBridge"), __func__);