Bug 1595994 - P1: Move LaunchRDDProcessIfNeeded to RemoteDecoderManagerChild. r=kamidphish
authorDan Glastonbury <dan.glastonbury@gmail.com>
Tue, 20 Oct 2020 23:23:40 +0000
changeset 553730 c910232fb2e8fbc3ba93dce729f6fffb1942edd1
parent 553729 2a46f29c8cdd6f6269483e86c6e21e649ffa7127
child 553731 44471f99280cba96d7adac8649ce09e3c4c21ed4
push id37881
push usersmolnar@mozilla.com
push dateWed, 21 Oct 2020 09:51:28 +0000
treeherdermozilla-central@d8861d51b01e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskamidphish
bugs1595994
milestone84.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
Bug 1595994 - P1: Move LaunchRDDProcessIfNeeded to RemoteDecoderManagerChild. r=kamidphish It uses data and threads from the RemoteDecoderManagerChild not RemoteDecoderModule. Differential Revision: https://phabricator.services.mozilla.com/D52796
dom/media/ipc/RemoteDecoderManagerChild.cpp
dom/media/ipc/RemoteDecoderManagerChild.h
dom/media/ipc/RemoteDecoderModule.cpp
dom/media/ipc/RemoteDecoderModule.h
--- 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