author | Dan Glastonbury <dan.glastonbury@gmail.com> |
Tue, 20 Oct 2020 23:23:40 +0000 | |
changeset 553730 | c910232fb2e8fbc3ba93dce729f6fffb1942edd1 |
parent 553729 | 2a46f29c8cdd6f6269483e86c6e21e649ffa7127 |
child 553731 | 44471f99280cba96d7adac8649ce09e3c4c21ed4 |
push id | 37881 |
push user | smolnar@mozilla.com |
push date | Wed, 21 Oct 2020 09:51:28 +0000 |
treeherder | mozilla-central@d8861d51b01e [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | kamidphish |
bugs | 1595994 |
milestone | 84.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/media/ipc/RemoteDecoderManagerChild.cpp +++ b/dom/media/ipc/RemoteDecoderManagerChild.cpp @@ -10,22 +10,25 @@ #include "mozilla/dom/ContentChild.h" // for launching RDD w/ ContentChild #include "mozilla/gfx/2D.h" #include "mozilla/gfx/DataSurfaceHelpers.h" #include "mozilla/ipc/ProtocolUtils.h" #include "mozilla/layers/ISurfaceAllocator.h" #include "mozilla/layers/SynchronousTask.h" #include "nsIObserver.h" #include <mozilla/DataMutex.h> +#include "mozilla/SyncRunnable.h" namespace mozilla { using namespace layers; using namespace gfx; +StaticMutex RemoteDecoderManagerChild::sLaunchMonitor; + // Only modified on the main-thread, read on any thread. While it could be read // on the main thread directly, for clarity we force access via the DataMutex // wrapper. StaticDataMutex<StaticRefPtr<nsIThread>> sRemoteDecoderManagerChildThread( "sRemoteDecoderManagerChildThread"); // Only accessed from sRemoteDecoderManagerChildThread static StaticRefPtr<RemoteDecoderManagerChild> @@ -159,16 +162,53 @@ RemoteDecoderManagerChild* RemoteDecoder } /* static */ nsISerialEventTarget* RemoteDecoderManagerChild::GetManagerThread() { auto remoteDecoderManagerThread = sRemoteDecoderManagerChildThread.Lock(); return *remoteDecoderManagerThread; } +/* static */ +void RemoteDecoderManagerChild::LaunchRDDProcessIfNeeded() { + if (!XRE_IsContentProcess()) { + return; + } + + StaticMutexAutoLock mon(sLaunchMonitor); + + // We have a couple possible states here. We are in a content process + // and: + // 1) the RDD process has never been launched. RDD should be launched + // and the IPC connections setup. + // 2) the RDD process has been launched, but this particular content + // process has not setup (or has lost) its IPC connection. + // In the code below, we assume we need to launch the RDD process and + // setup the IPC connections. However, if the manager thread for + // RemoteDecoderManagerChild is available we do a quick check to see + // if we can send (meaning the IPC channel is open). If we can send, + // then no work is necessary. If we can't send, then we call + // LaunchRDDProcess which will launch RDD if necessary, and setup the + // IPC connections between *this* content process and the RDD process. + bool needsLaunch = true; + nsCOMPtr<nsISerialEventTarget> managerThread = GetManagerThread(); + if (managerThread) { + RefPtr<Runnable> task = NS_NewRunnableFunction( + "RemoteDecoderManagerChild::LaunchRDDProcessIfNeeded-CheckSend", [&]() { + auto* rps = GetRDDProcessSingleton(); + needsLaunch = rps ? !rps->CanSend() : true; + }); + SyncRunnable::DispatchToThread(managerThread, task); + } + + if (needsLaunch) { + dom::ContentChild::GetSingleton()->LaunchRDDProcess(); + } +} + PRemoteDecoderChild* RemoteDecoderManagerChild::AllocPRemoteDecoderChild( const RemoteDecoderInfoIPDL& /* not used */, const CreateDecoderParams::OptionSet& aOptions, const Maybe<layers::TextureFactoryIdentifier>& aIdentifier, bool* aSuccess, nsCString* /* not used */) { // RemoteDecoderModule is responsible for creating RemoteDecoderChild // classes. MOZ_ASSERT(false,
--- a/dom/media/ipc/RemoteDecoderManagerChild.h +++ b/dom/media/ipc/RemoteDecoderManagerChild.h @@ -21,16 +21,17 @@ class RemoteDecoderManagerChild final NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RemoteDecoderManagerChild, override) // Can only be called from the manager thread static RemoteDecoderManagerChild* GetRDDProcessSingleton(); static RemoteDecoderManagerChild* GetGPUProcessSingleton(); // Can be called from any thread. static nsISerialEventTarget* GetManagerThread(); + static void LaunchRDDProcessIfNeeded(); // Can be called from any thread, dispatches the request to the IPDL thread // internally and will be ignored if the IPDL actor has been destroyed. already_AddRefed<gfx::SourceSurface> Readback( const SurfaceDescriptorGPUVideo& aSD) override; void DeallocateSurfaceDescriptor( const SurfaceDescriptorGPUVideo& aSD) override; @@ -84,16 +85,18 @@ class RemoteDecoderManagerChild final explicit RemoteDecoderManagerChild(layers::VideoBridgeSource aSource); ~RemoteDecoderManagerChild() = default; static void OpenForRDDProcess( Endpoint<PRemoteDecoderManagerChild>&& aEndpoint); static void OpenForGPUProcess( Endpoint<PRemoteDecoderManagerChild>&& aEndpoint); + static StaticMutex sLaunchMonitor; + RefPtr<RemoteDecoderManagerChild> mIPDLSelfRef; // The associated source of this decoder manager layers::VideoBridgeSource mSource; }; } // namespace mozilla
--- a/dom/media/ipc/RemoteDecoderModule.cpp +++ b/dom/media/ipc/RemoteDecoderModule.cpp @@ -24,25 +24,25 @@ #include "nsIXULRuntime.h" // for BrowserTabsRemoteAutostart namespace mozilla { using dom::ContentChild; using namespace ipc; using namespace layers; -StaticMutex RemoteDecoderModule::sLaunchMonitor; - RemoteDecoderModule::RemoteDecoderModule() : mManagerThread(RemoteDecoderManagerChild::GetManagerThread()) { MOZ_DIAGNOSTIC_ASSERT(mManagerThread); } /* static */ void RemoteDecoderModule::Init() { + MOZ_ASSERT(NS_IsMainThread()); + if (!BrowserTabsRemoteAutostart()) { return; } RemoteDecoderManagerChild::InitializeThread(); } bool RemoteDecoderModule::SupportsMimeType( const nsACString& aMimeType, DecoderDoctorDiagnostics* aDiagnostics) const { @@ -72,54 +72,19 @@ bool RemoteDecoderModule::SupportsMimeTy } MOZ_LOG( sPDMLog, LogLevel::Debug, ("Sandbox decoder %s requested type", supports ? "supports" : "rejects")); return supports; } -void RemoteDecoderModule::LaunchRDDProcessIfNeeded() const { - if (!XRE_IsContentProcess()) { - return; - } - - StaticMutexAutoLock mon(sLaunchMonitor); - - // We have a couple possible states here. We are in a content process - // and: - // 1) the RDD process has never been launched. RDD should be launched - // and the IPC connections setup. - // 2) the RDD process has been launched, but this particular content - // process has not setup (or has lost) its IPC connection. - // In the code below, we assume we need to launch the RDD process and - // setup the IPC connections. However, if the manager thread for - // RemoteDecoderManagerChild is available we do a quick check to see - // if we can send (meaning the IPC channel is open). If we can send, - // then no work is necessary. If we can't send, then we call - // LaunchRDDProcess which will launch RDD if necessary, and setup the - // IPC connections between *this* content process and the RDD process. - bool needsLaunch = true; - RefPtr<Runnable> task = NS_NewRunnableFunction( - "RemoteDecoderModule::LaunchRDDProcessIfNeeded-CheckSend", [&]() { - if (RemoteDecoderManagerChild::GetRDDProcessSingleton()) { - needsLaunch = - !RemoteDecoderManagerChild::GetRDDProcessSingleton()->CanSend(); - } - }); - SyncRunnable::DispatchToThread(mManagerThread, task); - - if (needsLaunch) { - ContentChild::GetSingleton()->LaunchRDDProcess(); - } -} - already_AddRefed<MediaDataDecoder> RemoteDecoderModule::CreateAudioDecoder( const CreateDecoderParams& aParams) { - LaunchRDDProcessIfNeeded(); + RemoteDecoderManagerChild::LaunchRDDProcessIfNeeded(); // OpusDataDecoder will check this option to provide the same info // that IsDefaultPlaybackDeviceMono provides. We want to avoid calls // to IsDefaultPlaybackDeviceMono on RDD because initializing audio // backends on RDD will be blocked by the sandbox. CreateDecoderParams::OptionSet options(aParams.mOptions); if (OpusDataDecoder::IsOpus(aParams.mConfig.mMimeType) && IsDefaultPlaybackDeviceMono()) { @@ -155,17 +120,17 @@ already_AddRefed<MediaDataDecoder> Remot RefPtr<RemoteMediaDataDecoder> object = new RemoteMediaDataDecoder(child); return object.forget(); } already_AddRefed<MediaDataDecoder> RemoteDecoderModule::CreateVideoDecoder( const CreateDecoderParams& aParams) { - LaunchRDDProcessIfNeeded(); + RemoteDecoderManagerChild::LaunchRDDProcessIfNeeded(); RefPtr<RemoteVideoDecoderChild> child = new RemoteVideoDecoderChild(); MediaResult result(NS_OK); // We can use child as a ref here because this is a sync dispatch. In // the error case for InitIPDL, we can't just let the RefPtr go out of // scope at the end of the method because it will release the // RemoteVideoDecoderChild on the wrong thread. This will assert in // RemoteDecoderChild's destructor. Passing the RefPtr by reference
--- a/dom/media/ipc/RemoteDecoderModule.h +++ b/dom/media/ipc/RemoteDecoderModule.h @@ -24,19 +24,15 @@ class RemoteDecoderModule : public Platf DecoderDoctorDiagnostics* aDiagnostics) const override; already_AddRefed<MediaDataDecoder> CreateVideoDecoder( const CreateDecoderParams& aParams) override; already_AddRefed<MediaDataDecoder> CreateAudioDecoder( const CreateDecoderParams& aParams) override; - protected: - void LaunchRDDProcessIfNeeded() const; - private: const nsCOMPtr<nsISerialEventTarget> mManagerThread; - static StaticMutex sLaunchMonitor; }; } // namespace mozilla #endif // include_dom_media_ipc_RemoteDecoderModule_h