Bug 1650996 - P2. Always initialise the RemoteDecoderChild manager thread. r=mjf
☠☠ backed out by b8fad3d28fcd ☠ ☠
authorJean-Yves Avenard <jyavenard@mozilla.com>
Thu, 09 Jul 2020 05:57:22 +0000
changeset 539512 374598f9c37a0189ddb2f0baffbf1897e346602c
parent 539511 236757acc073d19d42b3a32a6577094ceaa4c6ca
child 539513 8f8174ba409dd3bb236f0bebd6ba9279ad3bf65f
push id37582
push userapavel@mozilla.com
push dateThu, 09 Jul 2020 15:42:10 +0000
treeherdermozilla-central@ccd521ebc464 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmjf
bugs1650996
milestone80.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 1650996 - P2. Always initialise the RemoteDecoderChild manager thread. r=mjf This allows to simplify the lifetime management off the RemoteDecoderModule's mManagerThread member. Differential Revision: https://phabricator.services.mozilla.com/D82502
dom/media/ipc/RemoteDecoderChild.h
dom/media/ipc/RemoteDecoderManagerChild.h
dom/media/ipc/RemoteDecoderModule.cpp
dom/media/ipc/RemoteDecoderModule.h
dom/media/platforms/PDMFactory.cpp
--- a/dom/media/ipc/RemoteDecoderChild.h
+++ b/dom/media/ipc/RemoteDecoderChild.h
@@ -50,17 +50,17 @@ class RemoteDecoderChild : public PRemot
 
   virtual MediaResult ProcessOutput(const DecodedOutputIPDL& aDecodedData) = 0;
   virtual void RecordShutdownTelemetry(bool aForAbnormalShutdown) {}
 
   RefPtr<RemoteDecoderChild> mIPDLSelfRef;
   MediaDataDecoder::DecodedData mDecodedData;
 
  private:
-  RefPtr<nsIThread> mThread;
+  const RefPtr<nsIThread> mThread;
 
   MozPromiseHolder<MediaDataDecoder::InitPromise> mInitPromise;
   MozPromiseRequestHolder<PRemoteDecoderChild::InitPromise> mInitPromiseRequest;
   MozPromiseHolder<MediaDataDecoder::DecodePromise> mDecodePromise;
   MozPromiseHolder<MediaDataDecoder::DecodePromise> mDrainPromise;
   MozPromiseHolder<MediaDataDecoder::FlushPromise> mFlushPromise;
   MozPromiseHolder<mozilla::ShutdownPromise> mShutdownPromise;
 
--- a/dom/media/ipc/RemoteDecoderManagerChild.h
+++ b/dom/media/ipc/RemoteDecoderManagerChild.h
@@ -1,18 +1,18 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #ifndef include_dom_media_ipc_RemoteDecoderManagerChild_h
 #define include_dom_media_ipc_RemoteDecoderManagerChild_h
+#include "GPUVideoImage.h"
 #include "mozilla/PRemoteDecoderManagerChild.h"
 #include "mozilla/layers/VideoBridgeUtils.h"
-#include "GPUVideoImage.h"
 
 namespace mozilla {
 
 class RemoteDecoderManagerChild final
     : public PRemoteDecoderManagerChild,
       public mozilla::ipc::IShmemAllocator,
       public mozilla::layers::IGPUVideoSurfaceManager {
   friend class PRemoteDecoderManagerChild;
@@ -46,16 +46,17 @@ class RemoteDecoderManagerChild final
                                                         aShmem);
   }
 
   // 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.
   bool DeallocShmem(mozilla::ipc::Shmem& aShmem) override;
 
   // Main thread only
+  static void InitializeThread();
   static void InitForRDDProcess(
       Endpoint<PRemoteDecoderManagerChild>&& aVideoManager);
   static void InitForGPUProcess(
       Endpoint<PRemoteDecoderManagerChild>&& aVideoManager);
   static void Shutdown();
 
   // Run aTask (on the manager thread) when we next attempt to create a new
   // manager (even if creation fails). Intended to be called from ActorDestroy
@@ -75,19 +76,16 @@ class RemoteDecoderManagerChild final
   PRemoteDecoderChild* AllocPRemoteDecoderChild(
       const RemoteDecoderInfoIPDL& aRemoteDecoderInfo,
       const CreateDecoderParams::OptionSet& aOptions,
       const Maybe<layers::TextureFactoryIdentifier>& aIdentifier,
       bool* aSuccess, nsCString* aErrorDescription);
   bool DeallocPRemoteDecoderChild(PRemoteDecoderChild* actor);
 
  private:
-  // Main thread only
-  static void InitializeThread();
-
   explicit RemoteDecoderManagerChild(layers::VideoBridgeSource aSource);
   ~RemoteDecoderManagerChild() = default;
 
   static void OpenForRDDProcess(
       Endpoint<PRemoteDecoderManagerChild>&& aEndpoint);
   static void OpenForGPUProcess(
       Endpoint<PRemoteDecoderManagerChild>&& aEndpoint);
 
--- a/dom/media/ipc/RemoteDecoderModule.cpp
+++ b/dom/media/ipc/RemoteDecoderModule.cpp
@@ -17,27 +17,38 @@
 #include "RemoteAudioDecoder.h"
 #include "RemoteDecoderManagerChild.h"
 #include "RemoteMediaDataDecoder.h"
 #include "RemoteVideoDecoder.h"
 #include "OpusDecoder.h"
 #include "VideoUtils.h"
 #include "VorbisDecoder.h"
 #include "WAVDecoder.h"
+#include "nsIXULRuntime.h"  // for BrowserTabsRemoteAutostart
 
 namespace mozilla {
 
 using dom::ContentChild;
 using namespace ipc;
 using namespace layers;
 
 StaticMutex RemoteDecoderModule::sLaunchMonitor;
 
 RemoteDecoderModule::RemoteDecoderModule()
-    : mManagerThread(RemoteDecoderManagerChild::GetManagerThread()) {}
+    : mManagerThread(RemoteDecoderManagerChild::GetManagerThread()) {
+  MOZ_DIAGNOSTIC_ASSERT(mManagerThread);
+}
+
+/* static */
+void RemoteDecoderModule::Init() {
+  if (!BrowserTabsRemoteAutostart()) {
+    return;
+  }
+  RemoteDecoderManagerChild::InitializeThread();
+}
 
 bool RemoteDecoderModule::SupportsMimeType(
     const nsACString& aMimeType, DecoderDoctorDiagnostics* aDiagnostics) const {
   bool supports = false;
 
 #ifdef MOZ_AV1
   if (StaticPrefs::media_av1_enabled()) {
     supports |= AOMDecoder::IsAV1(aMimeType);
@@ -62,17 +73,17 @@ bool RemoteDecoderModule::SupportsMimeTy
   }
 
   MOZ_LOG(
       sPDMLog, LogLevel::Debug,
       ("Sandbox decoder %s requested type", supports ? "supports" : "rejects"));
   return supports;
 }
 
-void RemoteDecoderModule::LaunchRDDProcessIfNeeded() {
+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:
@@ -83,41 +94,34 @@ void RemoteDecoderModule::LaunchRDDProce
   // 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;
-  if (mManagerThread) {
-    RefPtr<Runnable> task = NS_NewRunnableFunction(
-        "RemoteDecoderModule::LaunchRDDProcessIfNeeded-CheckSend", [&]() {
-          if (RemoteDecoderManagerChild::GetRDDProcessSingleton()) {
-            needsLaunch =
-                !RemoteDecoderManagerChild::GetRDDProcessSingleton()->CanSend();
-          }
-        });
-    SyncRunnable::DispatchToThread(mManagerThread, task);
-  }
+  RefPtr<Runnable> task = NS_NewRunnableFunction(
+      "RemoteDecoderModule::LaunchRDDProcessIfNeeded-CheckSend", [&]() {
+        if (RemoteDecoderManagerChild::GetRDDProcessSingleton()) {
+          needsLaunch =
+              !RemoteDecoderManagerChild::GetRDDProcessSingleton()->CanSend();
+        }
+      });
+  SyncRunnable::DispatchToThread(mManagerThread, task);
 
   if (needsLaunch) {
     ContentChild::GetSingleton()->LaunchRDDProcess();
-    mManagerThread = RemoteDecoderManagerChild::GetManagerThread();
   }
 }
 
 already_AddRefed<MediaDataDecoder> RemoteDecoderModule::CreateAudioDecoder(
     const CreateDecoderParams& aParams) {
   LaunchRDDProcessIfNeeded();
 
-  if (!mManagerThread) {
-    return nullptr;
-  }
-
   // 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()) {
     options += CreateDecoderParams::Option::DefaultPlaybackDeviceMono;
@@ -154,20 +158,16 @@ already_AddRefed<MediaDataDecoder> Remot
 
   return object.forget();
 }
 
 already_AddRefed<MediaDataDecoder> RemoteDecoderModule::CreateVideoDecoder(
     const CreateDecoderParams& aParams) {
   LaunchRDDProcessIfNeeded();
 
-  if (!mManagerThread) {
-    return nullptr;
-  }
-
   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
   // allows us to release the RemoteVideoDecoderChild on the manager
--- a/dom/media/ipc/RemoteDecoderModule.h
+++ b/dom/media/ipc/RemoteDecoderModule.h
@@ -1,41 +1,42 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #ifndef include_dom_media_ipc_RemoteDecoderModule_h
 #define include_dom_media_ipc_RemoteDecoderModule_h
 #include "PlatformDecoderModule.h"
-
 #include "mozilla/StaticMutex.h"
 
 namespace mozilla {
 
 // A PDM implementation that creates a RemoteMediaDataDecoder (a
 // MediaDataDecoder) that proxies to a RemoteVideoDecoderChild.
 // A decoder child will talk to its respective decoder parent
 // (RemoteVideoDecoderParent) on the RDD process.
 class RemoteDecoderModule : public PlatformDecoderModule {
  public:
+  static void Init();
+
   RemoteDecoderModule();
 
   bool SupportsMimeType(const nsACString& aMimeType,
                         DecoderDoctorDiagnostics* aDiagnostics) const override;
 
   already_AddRefed<MediaDataDecoder> CreateVideoDecoder(
       const CreateDecoderParams& aParams) override;
 
   already_AddRefed<MediaDataDecoder> CreateAudioDecoder(
       const CreateDecoderParams& aParams) override;
 
  protected:
-  void LaunchRDDProcessIfNeeded();
+  void LaunchRDDProcessIfNeeded() const;
 
  private:
-  RefPtr<nsIThread> mManagerThread;
+  const nsCOMPtr<nsISerialEventTarget> mManagerThread;
   static StaticMutex sLaunchMonitor;
 };
 
 }  // namespace mozilla
 
 #endif  // include_dom_media_ipc_RemoteDecoderModule_h
--- a/dom/media/platforms/PDMFactory.cpp
+++ b/dom/media/platforms/PDMFactory.cpp
@@ -67,16 +67,17 @@ class PDMFactoryImpl final {
     OmxDecoderModule::Init();
 #endif
 #ifdef MOZ_FFVPX
     FFVPXRuntimeLinker::Init();
 #endif
 #ifdef MOZ_FFMPEG
     FFmpegRuntimeLinker::Init();
 #endif
+    RemoteDecoderModule::Init();
   }
 };
 
 StaticAutoPtr<PDMFactoryImpl> PDMFactory::sInstance;
 StaticMutex PDMFactory::sMonitor;
 
 class SupportChecker {
  public: