Bug 1595994 - P8: Use RemoteDecoderModule to communicate with GPU and RDD. r=mattwoodrow
authorDan Glastonbury <dan.glastonbury@gmail.com>
Tue, 20 Oct 2020 23:26:30 +0000
changeset 553737 c177bcba1c076d041e3470c8058bb2b4adaa1123
parent 553736 57607f8b6d8e1619b5c488494fd57547944c47b1
child 553738 fca05e774f8871907817edffb1839397b855646a
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)
reviewersmattwoodrow
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 - P8: Use RemoteDecoderModule to communicate with GPU and RDD. r=mattwoodrow Depends on D54879 Differential Revision: https://phabricator.services.mozilla.com/D54880
dom/media/ipc/RemoteDecoderManagerChild.cpp
dom/media/ipc/RemoteDecoderManagerChild.h
dom/media/ipc/RemoteDecoderModule.cpp
dom/media/ipc/RemoteDecoderModule.h
dom/media/platforms/PDMFactory.cpp
dom/media/platforms/PDMFactory.h
--- a/dom/media/ipc/RemoteDecoderManagerChild.cpp
+++ b/dom/media/ipc/RemoteDecoderManagerChild.cpp
@@ -298,18 +298,23 @@ RemoteDecoderManagerChild::CreateVideoDe
   }
 
   RefPtr<RemoteMediaDataDecoder> object = new RemoteMediaDataDecoder(child);
 
   return object.forget();
 }
 
 /* static */
-void RemoteDecoderManagerChild::LaunchRDDProcessIfNeeded() {
-  if (!XRE_IsContentProcess()) {
+void RemoteDecoderManagerChild::LaunchRDDProcessIfNeeded(
+    RemoteDecodeIn aLocation) {
+  MOZ_DIAGNOSTIC_ASSERT(XRE_IsContentProcess(),
+                        "Only supported from a content process.");
+
+  if (aLocation != RemoteDecodeIn::RddProcess) {
+    // Not targeting RDD process? No need to launch RDD.
     return;
   }
 
   StaticMutexAutoLock lock(sLaunchMutex);
 
   // 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
--- a/dom/media/ipc/RemoteDecoderManagerChild.h
+++ b/dom/media/ipc/RemoteDecoderManagerChild.h
@@ -35,17 +35,17 @@ class RemoteDecoderManagerChild final
                        DecoderDoctorDiagnostics* aDiagnostics);
   static already_AddRefed<MediaDataDecoder> CreateAudioDecoder(
       const CreateDecoderParams& aParams);
   static already_AddRefed<MediaDataDecoder> CreateVideoDecoder(
       const CreateDecoderParams& aParams, RemoteDecodeIn aLocation);
 
   // Can be called from any thread.
   static nsISerialEventTarget* GetManagerThread();
-  static void LaunchRDDProcessIfNeeded();
+  static void LaunchRDDProcessIfNeeded(RemoteDecodeIn aLocation);
 
   // 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;
 
--- a/dom/media/ipc/RemoteDecoderModule.cpp
+++ b/dom/media/ipc/RemoteDecoderModule.cpp
@@ -16,80 +16,70 @@
 #include "OpusDecoder.h"
 #include "RemoteAudioDecoder.h"
 #include "RemoteDecoderManagerChild.h"
 #include "RemoteMediaDataDecoder.h"
 #include "RemoteVideoDecoder.h"
 #include "VideoUtils.h"
 #include "VorbisDecoder.h"
 #include "WAVDecoder.h"
+#include "gfxConfig.h"
 #include "nsIXULRuntime.h"  // for BrowserTabsRemoteAutostart
 
 namespace mozilla {
 
-using dom::ContentChild;
 using namespace ipc;
 using namespace layers;
 
 /* static */
 void RemoteDecoderModule::Init() {
   MOZ_ASSERT(NS_IsMainThread());
 
   if (BrowserTabsRemoteAutostart()) {
     RemoteDecoderManagerChild::InitializeThread();
   }
 }
 
-already_AddRefed<PlatformDecoderModule> RemoteDecoderModule::Create() {
+already_AddRefed<PlatformDecoderModule> RemoteDecoderModule::Create(
+    RemoteDecodeIn aLocation) {
   MOZ_ASSERT(!XRE_IsGPUProcess() && !XRE_IsRDDProcess(),
              "Should not be created in GPU or RDD process.");
   if (!XRE_IsContentProcess()) {
     // For now, the RemoteDecoderModule is only available in the content
     // process.
     return nullptr;
   }
-  return MakeAndAddRef<RemoteDecoderModule>();
+  return MakeAndAddRef<RemoteDecoderModule>(aLocation);
 }
 
+RemoteDecoderModule::RemoteDecoderModule(RemoteDecodeIn aLocation)
+    : mLocation(aLocation) {}
+
 bool RemoteDecoderModule::SupportsMimeType(
     const nsACString& aMimeType, DecoderDoctorDiagnostics* aDiagnostics) const {
-  bool supports = false;
+  MOZ_CRASH("Deprecated: Use RemoteDecoderModule::Supports");
+}  // namespace mozilla
 
-#ifdef MOZ_AV1
-  if (StaticPrefs::media_av1_enabled()) {
-    supports |= AOMDecoder::IsAV1(aMimeType);
-  }
-#endif
-#if !defined(__MINGW32__)
-  // We can't let RDD handle the decision to support Vorbis decoding on
-  // MinGW builds because of Bug 1597408 (Vorbis decoding on RDD causing
-  // sandboxing failure on MinGW-clang).  Typically this would be dealt
-  // with using defines in StaticPrefList.yaml, but we must handle it
-  // here because of Bug 1598426 (the __MINGW32__ define isn't supported
-  // in StaticPrefList.yaml).
-  if (StaticPrefs::media_rdd_vorbis_enabled()) {
-    supports |= VorbisDataDecoder::IsVorbis(aMimeType);
-  }
-#endif
-  if (StaticPrefs::media_rdd_wav_enabled()) {
-    supports |= WaveDataDecoder::IsWave(aMimeType);
-  }
-  if (StaticPrefs::media_rdd_opus_enabled()) {
-    supports |= OpusDataDecoder::IsOpus(aMimeType);
-  }
+bool RemoteDecoderModule::Supports(
+    const SupportDecoderParams& aParams,
+    DecoderDoctorDiagnostics* aDiagnostics) const {
+  RemoteDecoderManagerChild::LaunchRDDProcessIfNeeded(mLocation);
 
-  MOZ_LOG(
-      sPDMLog, LogLevel::Debug,
-      ("Sandbox decoder %s requested type", supports ? "supports" : "rejects"));
+  bool supports =
+      RemoteDecoderManagerChild::Supports(mLocation, aParams, aDiagnostics);
+  MOZ_LOG(sPDMLog, LogLevel::Debug,
+          ("Sandbox %s decoder %s requested type",
+           mLocation == RemoteDecodeIn::GpuProcess ? "GPU" : "RDD",
+           supports ? "supports" : "rejects"));
   return supports;
 }
 
 already_AddRefed<MediaDataDecoder> RemoteDecoderModule::CreateAudioDecoder(
     const CreateDecoderParams& aParams) {
-  RemoteDecoderManagerChild::LaunchRDDProcessIfNeeded();
+  RemoteDecoderManagerChild::LaunchRDDProcessIfNeeded(mLocation);
 
   // 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.
   if (OpusDataDecoder::IsOpus(aParams.mConfig.mMimeType) &&
       IsDefaultPlaybackDeviceMono()) {
     CreateDecoderParams params = aParams;
@@ -97,14 +87,13 @@ already_AddRefed<MediaDataDecoder> Remot
     return RemoteDecoderManagerChild::CreateAudioDecoder(params);
   }
 
   return RemoteDecoderManagerChild::CreateAudioDecoder(aParams);
 }
 
 already_AddRefed<MediaDataDecoder> RemoteDecoderModule::CreateVideoDecoder(
     const CreateDecoderParams& aParams) {
-  RemoteDecoderManagerChild::LaunchRDDProcessIfNeeded();
-  return RemoteDecoderManagerChild::CreateVideoDecoder(
-      aParams, RemoteDecodeIn::RddProcess);
+  RemoteDecoderManagerChild::LaunchRDDProcessIfNeeded(mLocation);
+  return RemoteDecoderManagerChild::CreateVideoDecoder(aParams, mLocation);
 }
 
 }  // namespace mozilla
--- a/dom/media/ipc/RemoteDecoderModule.h
+++ b/dom/media/ipc/RemoteDecoderModule.h
@@ -4,33 +4,41 @@
  * 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"
 
 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.
+enum class RemoteDecodeIn;
+
+// A decoder module that proxies decoding to either GPU or RDD process.
 class RemoteDecoderModule : public PlatformDecoderModule {
   template <typename T, typename... Args>
   friend already_AddRefed<T> MakeAndAddRef(Args&&...);
 
  public:
   static void Init();
-  static already_AddRefed<PlatformDecoderModule> Create();
+  static already_AddRefed<PlatformDecoderModule> Create(
+      RemoteDecodeIn aLocation);
 
   bool SupportsMimeType(const nsACString& aMimeType,
                         DecoderDoctorDiagnostics* aDiagnostics) const override;
 
+  bool Supports(const SupportDecoderParams& aParams,
+                DecoderDoctorDiagnostics* aDiagnostics) const override;
+
   already_AddRefed<MediaDataDecoder> CreateVideoDecoder(
       const CreateDecoderParams& aParams) override;
 
   already_AddRefed<MediaDataDecoder> CreateAudioDecoder(
       const CreateDecoderParams& aParams) override;
+
+ private:
+  explicit RemoteDecoderModule(RemoteDecodeIn aLocation);
+
+  const RemoteDecodeIn mLocation;
 };
 
 }  // namespace mozilla
 
 #endif  // include_dom_media_ipc_RemoteDecoderModule_h
--- a/dom/media/platforms/PDMFactory.cpp
+++ b/dom/media/platforms/PDMFactory.cpp
@@ -15,16 +15,17 @@
 #include "H264.h"
 #include "MP4Decoder.h"
 #include "MediaChangeMonitor.h"
 #include "MediaInfo.h"
 #include "VPXDecoder.h"
 #include "mozilla/CDMProxy.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/GpuDecoderModule.h"
+#include "mozilla/RemoteDecoderManagerChild.h"
 #include "mozilla/RemoteDecoderModule.h"
 #include "mozilla/SharedThreadPool.h"
 #include "mozilla/StaticPrefs_media.h"
 #include "mozilla/StaticPtr.h"
 #include "mozilla/SyncRunnable.h"
 #include "mozilla/TaskQueue.h"
 #include "mozilla/gfx/gfxVars.h"
 #include "nsIXULRuntime.h"  // for BrowserTabsRemoteAutostart
@@ -356,19 +357,23 @@ void PDMFactory::CreateGpuPDMs() {
 
 void PDMFactory::CreateRddPDMs() {
   MOZ_ASSERT(XRE_IsRDDProcess());
   CreateAndStartupPDM<AgnosticDecoderModule>();
 }
 
 void PDMFactory::CreateDefaultPDMs() {
   MOZ_ASSERT(!XRE_IsGPUProcess() && !XRE_IsRDDProcess());
+  if (StaticPrefs::media_gpu_process_decoder()) {
+    CreateAndStartupPDM<RemoteDecoderModule>(RemoteDecodeIn::GpuProcess);
+  }
+
   if (StaticPrefs::media_rdd_process_enabled() &&
       BrowserTabsRemoteAutostart()) {
-    CreateAndStartupPDM<RemoteDecoderModule>();
+    CreateAndStartupPDM<RemoteDecoderModule>(RemoteDecodeIn::RddProcess);
   }
 
 #ifdef XP_WIN
   if (StaticPrefs::media_wmf_enabled() && !IsWin7AndPre2000Compatible()) {
     RefPtr<WMFDecoderModule> m = MakeAndAddRef<WMFDecoderModule>();
     StartupPDM(MakeAndAddRef<GpuDecoderModule>(m));
     if (!StartupPDM(m.forget())) {
       mFailureFlags += DecoderDoctorDiagnostics::Flags::WMFFailedToLoad;
--- a/dom/media/platforms/PDMFactory.h
+++ b/dom/media/platforms/PDMFactory.h
@@ -58,16 +58,17 @@ class PDMFactory final {
   void CreateGpuPDMs();
   void CreateRddPDMs();
   void CreateDefaultPDMs();
 
   template <typename DECODER_MODULE, typename... ARGS>
   bool CreateAndStartupPDM(ARGS&&... aArgs) {
     return StartupPDM(DECODER_MODULE::Create(std::forward<ARGS>(aArgs)...));
   }
+
   // Startup the provided PDM and add it to our list if successful.
   bool StartupPDM(already_AddRefed<PlatformDecoderModule> aPDM,
                   bool aInsertAtBeginning = false);
   // Returns the first PDM in our list supporting the mimetype.
   already_AddRefed<PlatformDecoderModule> GetDecoderModule(
       const SupportDecoderParams& aParams,
       DecoderDoctorDiagnostics* aDiagnostics) const;