Bug 1393392 P4 - keep DXVA driver information in GPUProcessManager; draft
authorKaku Kuo <kaku@mozilla.com>
Mon, 21 Aug 2017 16:10:27 +0800
changeset 652789 daee2761899ef11cb062a2c1ff404487686be061
parent 652788 836313a64e44de102b1416bd82960fc98f62e739
child 652790 36371d435ae472bc9e6e4e66008d9c09abfdd235
push id76152
push userbmo:kaku@mozilla.com
push dateFri, 25 Aug 2017 07:50:59 +0000
bugs1393392
milestone57.0a1
Bug 1393392 P4 - keep DXVA driver information in GPUProcessManager; We need to keep the information in GPUProcessManager because we still need the information aftern GPU has crashed, so that's why we cannot put the info at GPUHost or GPUChild. MozReview-Commit-ID: 3we0N5wHpqM
dom/media/ipc/VideoDecoderManagerParent.cpp
dom/media/platforms/wmf/WMFVideoMFTManager.cpp
gfx/ipc/GPUChild.cpp
gfx/ipc/GPUChild.h
gfx/ipc/GPUProcessHost.h
gfx/ipc/GPUProcessManager.cpp
gfx/ipc/GPUProcessManager.h
gfx/ipc/PGPU.ipdl
--- a/dom/media/ipc/VideoDecoderManagerParent.cpp
+++ b/dom/media/ipc/VideoDecoderManagerParent.cpp
@@ -1,17 +1,19 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=99: */
 /* 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/. */
 #include "VideoDecoderManagerParent.h"
 #include "VideoDecoderParent.h"
 #include "base/thread.h"
+#include "mozilla/gfx/GPUParent.h"      // for GPUParent
 #include "mozilla/UniquePtr.h"
+#include "mozilla/Unused.h"
 #include "mozilla/Services.h"
 #include "mozilla/Observer.h"
 #include "nsIObserverService.h"
 #include "nsIObserver.h"
 #include "nsIEventTarget.h"
 #include "nsThreadUtils.h"
 #include "ImageContainer.h"
 #include "mozilla/layers/VideoBridgeChild.h"
@@ -19,16 +21,22 @@
 #include "mozilla/layers/ImageDataSerializer.h"
 #include "mozilla/SyncRunnable.h"
 
 #if XP_WIN
 #include <objbase.h>
 #endif
 
 namespace mozilla {
+
+#ifdef XP_WIN
+extern const nsCString GetFoundD3D11BlacklistedDLL();
+extern const nsCString GetFoundD3D9BlacklistedDLL();
+#endif // XP_WIN
+
 namespace dom {
 
 using namespace ipc;
 using namespace layers;
 using namespace gfx;
 
 SurfaceDescriptorGPUVideo
 VideoDecoderManagerParent::StoreImage(Image* aImage, TextureClient* aTexture)
@@ -194,19 +202,30 @@ PVideoDecoderParent*
 VideoDecoderManagerParent::AllocPVideoDecoderParent(const VideoInfo& aVideoInfo,
                                                     const layers::TextureFactoryIdentifier& aIdentifier,
                                                     bool* aSuccess)
 {
   RefPtr<TaskQueue> decodeTaskQueue = new TaskQueue(
     SharedThreadPool::Get(NS_LITERAL_CSTRING("VideoDecoderParent"), 4),
     "VideoDecoderParent::mDecodeTaskQueue");
 
-  return new VideoDecoderParent(
-    this, aVideoInfo, aIdentifier,
-    sManagerTaskQueue, decodeTaskQueue, aSuccess);
+  auto* parent = new VideoDecoderParent(
+    this, aVideoInfo, aIdentifier, sManagerTaskQueue, decodeTaskQueue, aSuccess);
+
+#ifdef XP_WIN
+  NS_DispatchToMainThread(NS_NewRunnableFunction(
+    "GPUParent::SendSetBlacklistedDrivers",
+    []() -> void {
+      const nsCString d3d11Driver = GetFoundD3D11BlacklistedDLL();
+      const nsCString d3d9Driver = GetFoundD3D9BlacklistedDLL();
+      Unused << GPUParent::GetSingleton()->SendSetBlacklistedDrivers(d3d11Driver, d3d9Driver);
+    }));
+#endif // XP_WIN
+
+  return parent;
 }
 
 bool
 VideoDecoderManagerParent::DeallocPVideoDecoderParent(PVideoDecoderParent* actor)
 {
   VideoDecoderParent* parent = static_cast<VideoDecoderParent*>(actor);
   parent->Destroy();
   return true;
--- a/dom/media/platforms/wmf/WMFVideoMFTManager.cpp
+++ b/dom/media/platforms/wmf/WMFVideoMFTManager.cpp
@@ -382,16 +382,36 @@ FindD3D11BlacklistedDLL()
 static const nsCString&
 FindD3D9BlacklistedDLL()
 {
   return FindDXVABlacklistedDLL(sD3D9BlacklistingCache,
                                 gfx::gfxVars::PDMWMFDisableD3D9Dlls(),
                                 "media.wmf.disable-d3d9-for-dlls");
 }
 
+const nsCString
+GetFoundD3D11BlacklistedDLL()
+{
+  if (sD3D11BlacklistingCache) {
+    return sD3D11BlacklistingCache->mBlacklistedDLL;
+  }
+
+  return nsCString();
+}
+
+const nsCString
+GetFoundD3D9BlacklistedDLL()
+{
+  if (sD3D9BlacklistingCache) {
+    return sD3D9BlacklistingCache->mBlacklistedDLL;
+  }
+
+  return nsCString();
+}
+
 class CreateDXVAManagerEvent : public Runnable
 {
 public:
   CreateDXVAManagerEvent(layers::KnowsCompositor* aKnowsCompositor,
                          nsCString& aFailureReason)
     : Runnable("CreateDXVAManagerEvent")
     , mBackend(LayersBackend::LAYERS_D3D11)
     , mKnowsCompositor(aKnowsCompositor)
--- a/gfx/ipc/GPUChild.cpp
+++ b/gfx/ipc/GPUChild.cpp
@@ -322,10 +322,17 @@ private:
 };
 
 /* static */ void
 GPUChild::Destroy(UniquePtr<GPUChild>&& aChild)
 {
   NS_DispatchToMainThread(new DeferredDeleteGPUChild(Move(aChild)));
 }
 
+mozilla::ipc::IPCResult
+GPUChild::RecvSetBlacklistedDrivers(const nsCString& aD3D11Driver, const nsCString& aD3D9Driver)
+{
+  mHost->mListener->OnSetBlacklistedDrivers(aD3D11Driver, aD3D9Driver);
+  return IPC_OK();
+}
+
 } // namespace gfx
 } // namespace mozilla
--- a/gfx/ipc/GPUChild.h
+++ b/gfx/ipc/GPUChild.h
@@ -64,16 +64,18 @@ public:
 
   bool SendRequestMemoryReport(const uint32_t& aGeneration,
                                const bool& aAnonymize,
                                const bool& aMinimizeMemoryUsage,
                                const MaybeFileDesc& aDMDFile);
 
   static void Destroy(UniquePtr<GPUChild>&& aChild);
 
+  mozilla::ipc::IPCResult RecvSetBlacklistedDrivers(const nsCString& aD3D11Driver, const nsCString& aD3D9Driver) override;
+
 private:
   GPUProcessHost* mHost;
   UniquePtr<ipc::CrashReporterHost> mCrashReporter;
   UniquePtr<MemoryReportRequestHost> mMemoryReportRequest;
   bool mGPUReady;
 };
 
 } // namespace gfx
--- a/gfx/ipc/GPUProcessHost.h
+++ b/gfx/ipc/GPUProcessHost.h
@@ -40,16 +40,20 @@ public:
     // The GPUProcessHost has unexpectedly shutdown or had its connection
     // severed. This is not called if an error occurs after calling
     // Shutdown().
     virtual void OnProcessUnexpectedShutdown(GPUProcessHost* aHost)
     {}
 
     virtual void OnRemoteProcessDeviceReset(GPUProcessHost* aHost)
     {}
+
+    virtual void OnSetBlacklistedDrivers(const nsCString& aD3D11Driver,
+                                         const nsCString& aD3D9Driver)
+    {}
   };
 
 public:
   explicit GPUProcessHost(Listener* listener);
   ~GPUProcessHost();
 
   // Launch the subprocess asynchronously. On failure, false is returned.
   // Otherwise, true is returned, and the OnLaunchComplete listener callback
--- a/gfx/ipc/GPUProcessManager.cpp
+++ b/gfx/ipc/GPUProcessManager.cpp
@@ -1215,10 +1215,18 @@ RefPtr<MemoryReportingProcess>
 GPUProcessManager::GetProcessMemoryReporter()
 {
   if (!EnsureGPUReady()) {
     return nullptr;
   }
   return new GPUMemoryReporter();
 }
 
+void
+GPUProcessManager::OnSetBlacklistedDrivers(const nsCString& aD3D11Driver,
+                                           const nsCString& aD3D9Driver)
+{
+  mD3D11BlacklistedDriver = aD3D11Driver;
+  mD3D9BlacklistedDriver = aD3D9Driver;
+}
+
 } // namespace gfx
 } // namespace mozilla
--- a/gfx/ipc/GPUProcessManager.h
+++ b/gfx/ipc/GPUProcessManager.h
@@ -148,16 +148,17 @@ public:
 
   void OnProcessLaunchComplete(GPUProcessHost* aHost) override;
   void OnProcessUnexpectedShutdown(GPUProcessHost* aHost) override;
   void SimulateDeviceReset();
   void DisableWebRender();
   void OnInProcessDeviceReset();
   void OnRemoteProcessDeviceReset(GPUProcessHost* aHost) override;
   void NotifyListenersOnCompositeDeviceReset();
+  void OnSetBlacklistedDrivers(const nsCString& aD3D11Driver, const nsCString& aD3D9Driver) override;
 
   // Notify the GPUProcessManager that a top-level PGPU protocol has been
   // terminated. This may be called from any thread.
   void NotifyRemoteActorDestroyed(const uint64_t& aProcessToken);
 
   void AddListener(GPUProcessListener* aListener);
   void RemoveListener(GPUProcessListener* aListener);
 
@@ -277,14 +278,19 @@ private:
   uint32_t mDeviceResetCount;
   TimeStamp mDeviceResetLastTime;
 
   // Fields that are associated with the current GPU process.
   GPUProcessHost* mProcess;
   MOZ_INIT_OUTSIDE_CTOR uint64_t mProcessToken;
   GPUChild* mGPUChild;
   RefPtr<VsyncBridgeChild> mVsyncBridge;
+
+  // Keep the HW decoding driver information for Telemetry usage.
+  // These are acquired in GPU process while we're initializing DXVA.
+  nsCString mD3D11BlacklistedDriver;
+  nsCString mD3D9BlacklistedDriver;
 };
 
 } // namespace gfx
 } // namespace mozilla
 
 #endif // _include_mozilla_gfx_ipc_GPUProcessManager_h_
--- a/gfx/ipc/PGPU.ipdl
+++ b/gfx/ipc/PGPU.ipdl
@@ -122,12 +122,15 @@ child:
   // Update the UI process after a feature's status has changed. This is used
   // outside of the normal startup flow.
   async UpdateFeature(Feature aFeature, FeatureFailure aChange);
 
   // Notify about:support/Telemetry that a fallback occurred.
   async UsedFallback(Fallback aFallback, nsCString message);
 
   async BHRThreadHang(HangDetails aDetails);
+
+  // Set the blacklisted driver names for Telemetry usage.
+  async SetBlacklistedDrivers(nsCString aD3D11Driver, nsCString aD3D9Driver);
 };
 
 } // namespace gfx
 } // namespace mozilla