tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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:
Mdom/ipc/ContentParent.cpp | 11+++++------
Mdom/media/ipc/RDDChild.cpp | 18+++++++++---------
Mdom/media/ipc/RDDProcessManager.cpp | 51+++++++++++++++++++++++++++++++++++++++++++++------
Mdom/media/ipc/RDDProcessManager.h | 1+
Mgfx/ipc/GPUProcessManager.cpp | 79++++++++-----------------------------------------------------------------------
Mgfx/ipc/GPUProcessManager.h | 24++++++------------------
Mgfx/thebes/gfxPlatform.cpp | 8+++-----
Mipc/glue/UtilityMediaServiceChild.cpp | 71++++++++++++++++++++++++++++++++++++++++++++++-------------------------
Mipc/glue/UtilityMediaServiceChild.h | 2+-
Mipc/glue/UtilityProcessManager.cpp | 2+-
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__);