Bug 1393392 P6 - keep DXVA driver information in VideoDecoderManagerChild; draft
authorKaku Kuo <kaku@mozilla.com>
Wed, 23 Aug 2017 17:01:41 +0800
changeset 652824 3af17147ce107cbb926582ef6aa8e3a85b02e422
parent 652790 36371d435ae472bc9e6e4e66008d9c09abfdd235
child 652825 708b0ee70a73e6df5ac3929b3467a375fc6ef2b7
push id76161
push userbmo:kaku@mozilla.com
push dateFri, 25 Aug 2017 08:18:23 +0000
bugs1393392
milestone57.0a1
Bug 1393392 P6 - keep DXVA driver information in VideoDecoderManagerChild; The DXVA driver information are stored in VideoDecodermanagerChild as static variables. Those variables are assigned in sVideoDecoderChildThread but are accessed from MediaFormatReader's TaskQueue. However, they're totally free from racing because they're assigned while creating a RemoteVideoDecoder which is a sync task dispatched MediaFormatReader's TaskQueue to sVideoDecoderChildThread. So, we don't read/write these variables at the same time. MozReview-Commit-ID: 8mbN6qFugRG
dom/media/ipc/PVideoDecoderManager.ipdl
dom/media/ipc/VideoDecoderChild.cpp
dom/media/ipc/VideoDecoderManagerChild.cpp
dom/media/ipc/VideoDecoderManagerChild.h
dom/media/ipc/VideoDecoderManagerParent.cpp
dom/media/ipc/VideoDecoderManagerParent.h
ipc/ipdl/sync-messages.ini
--- a/dom/media/ipc/PVideoDecoderManager.ipdl
+++ b/dom/media/ipc/PVideoDecoderManager.ipdl
@@ -17,12 +17,14 @@ sync protocol PVideoDecoderManager
 {
   manages PVideoDecoder;
 parent:
   sync PVideoDecoder(VideoInfo info, TextureFactoryIdentifier identifier) returns (bool success);
 
   sync Readback(SurfaceDescriptorGPUVideo sd) returns (SurfaceDescriptor aResult);
 
   async DeallocateSurfaceDescriptorGPUVideo(SurfaceDescriptorGPUVideo sd);
+
+  sync ReadBlacklistedDrivers() returns (nsCString aD3D11Driver, nsCString aD3D9Driver);
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/media/ipc/VideoDecoderChild.cpp
+++ b/dom/media/ipc/VideoDecoderChild.cpp
@@ -170,16 +170,22 @@ VideoDecoderChild::InitIPDL(const VideoI
     return true;
   }
 
   mIPDLSelfRef = this;
   bool success = false;
   if (manager->SendPVideoDecoderConstructor(this, aVideoInfo, aIdentifier,
                                             &success)) {
     mCanSend = true;
+
+    nsCString d3d11;
+    nsCString d3d9;
+    Unused << manager->SendReadBlacklistedDrivers(&d3d11, &d3d9);
+    VideoDecoderManagerChild::SetD3D11BlacklistedDriver(d3d11);
+    VideoDecoderManagerChild::SetD3D9BlacklistedDriver(d3d9);
   }
   return success;
 }
 
 void
 VideoDecoderChild::DestroyIPDL()
 {
   if (mCanSend) {
--- a/dom/media/ipc/VideoDecoderManagerChild.cpp
+++ b/dom/media/ipc/VideoDecoderManagerChild.cpp
@@ -25,16 +25,26 @@ using namespace gfx;
 // Only modified on the main-thread
 StaticRefPtr<nsIThread> sVideoDecoderChildThread;
 StaticRefPtr<AbstractThread> sVideoDecoderChildAbstractThread;
 
 // Only accessed from sVideoDecoderChildThread
 static StaticRefPtr<VideoDecoderManagerChild> sDecoderManager;
 static UniquePtr<nsTArray<RefPtr<Runnable>>> sRecreateTasks;
 
+// Keep the HW decoding driver information for Telemetry usage.
+// The information is acquired in GPU process while we're initializing DXVA.
+// These two variables are assigned in sVideoDecoderChildThread but are accessed
+// from MediaFormatReader's TaskQueue. However, they're totally free from racing
+// because they're assigned while creating a RemoteVideoDecoder which is a sync
+// task dispatched MediaFormatReader's TaskQueue to sVideoDecoderChildThread.
+// So, we don't read/write these variables at the same time.
+static nsCString sD3D11BlacklistedDriver;
+static nsCString sD3D9BlacklistedDriver;
+
 /* static */ void
 VideoDecoderManagerChild::InitializeThread()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   if (!sVideoDecoderChildThread) {
     RefPtr<nsIThread> childThread;
     nsresult rv = NS_NewNamedThread("VideoChild", getter_AddRefs(childThread));
@@ -274,10 +284,36 @@ VideoDecoderManagerChild::DeallocateSurf
 }
 
 void
 VideoDecoderManagerChild::HandleFatalError(const char* aName, const char* aMsg) const
 {
   dom::ContentChild::FatalErrorIfNotUsingGPUProcess(aName, aMsg, OtherPid());
 }
 
+/* static */ const nsCString&
+VideoDecoderManagerChild::D3D11BlacklistedDriver()
+{
+  return sD3D11BlacklistedDriver;
+}
+
+/* static */ const nsCString&
+VideoDecoderManagerChild::D3D9BlacklistedDriver()
+{
+  return sD3D9BlacklistedDriver;
+}
+
+/* static */ void
+VideoDecoderManagerChild::SetD3D11BlacklistedDriver(const nsCString& aD3D11Driver)
+{
+  MOZ_ASSERT(NS_GetCurrentThread() == GetManagerThread());
+  sD3D11BlacklistedDriver = aD3D11Driver;
+}
+
+/* static */ void
+VideoDecoderManagerChild::SetD3D9BlacklistedDriver(const nsCString& aD3D9Driver)
+{
+  MOZ_ASSERT(NS_GetCurrentThread() == GetManagerThread());
+  sD3D9BlacklistedDriver = aD3D9Driver;
+}
+
 } // namespace dom
 } // namespace mozilla
--- a/dom/media/ipc/VideoDecoderManagerChild.h
+++ b/dom/media/ipc/VideoDecoderManagerChild.h
@@ -57,16 +57,21 @@ public:
   // 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 when we get
   // notified that the old manager is being destroyed.
   // Can only be called from the manager thread.
   void RunWhenRecreated(already_AddRefed<Runnable> aTask);
 
   bool CanSend();
 
+  static const nsCString& D3D11BlacklistedDriver();
+  static const nsCString& D3D9BlacklistedDriver();
+  static void SetD3D11BlacklistedDriver(const nsCString& aD3D11Driver);
+  static void SetD3D9BlacklistedDriver(const nsCString& aD3D9Driver);
+
 protected:
   void InitIPDL();
 
   void ActorDestroy(ActorDestroyReason aWhy) override;
   void DeallocPVideoDecoderManagerChild() override;
 
   void HandleFatalError(const char* aName, const char* aMsg) const override;
 
--- a/dom/media/ipc/VideoDecoderManagerParent.cpp
+++ b/dom/media/ipc/VideoDecoderManagerParent.cpp
@@ -292,10 +292,20 @@ VideoDecoderManagerParent::RecvReadback(
 mozilla::ipc::IPCResult
 VideoDecoderManagerParent::RecvDeallocateSurfaceDescriptorGPUVideo(const SurfaceDescriptorGPUVideo& aSD)
 {
   mImageMap.erase(aSD.handle());
   mTextureMap.erase(aSD.handle());
   return IPC_OK();
 }
 
+mozilla::ipc::IPCResult
+VideoDecoderManagerParent::RecvReadBlacklistedDrivers(nsCString* aD3D11Driver, nsCString* aD3D9Driver)
+{
+#ifdef XP_WIN
+  *aD3D11Driver = GetFoundD3D11BlacklistedDLL();
+  *aD3D9Driver = GetFoundD3D9BlacklistedDLL();
+#endif // XP_WIN
+  return IPC_OK();
+}
+
 } // namespace dom
 } // namespace mozilla
--- a/dom/media/ipc/VideoDecoderManagerParent.h
+++ b/dom/media/ipc/VideoDecoderManagerParent.h
@@ -36,16 +36,18 @@ protected:
 
   mozilla::ipc::IPCResult RecvReadback(const SurfaceDescriptorGPUVideo& aSD, SurfaceDescriptor* aResult) override;
   mozilla::ipc::IPCResult RecvDeallocateSurfaceDescriptorGPUVideo(const SurfaceDescriptorGPUVideo& aSD) override;
 
   void ActorDestroy(mozilla::ipc::IProtocol::ActorDestroyReason) override;
 
   void DeallocPVideoDecoderManagerParent() override;
 
+  mozilla::ipc::IPCResult RecvReadBlacklistedDrivers(nsCString* aD3D11Driver, nsCString* aD3D9Driver) override;
+
 private:
   explicit VideoDecoderManagerParent(VideoDecoderManagerThreadHolder* aThreadHolder);
   ~VideoDecoderManagerParent();
 
   void Open(Endpoint<PVideoDecoderManagerParent>&& aEndpoint);
 
   std::map<uint64_t, RefPtr<layers::Image>> mImageMap;
   std::map<uint64_t, RefPtr<layers::TextureClient>> mTextureMap;
--- a/ipc/ipdl/sync-messages.ini
+++ b/ipc/ipdl/sync-messages.ini
@@ -923,16 +923,18 @@ description =
 [PGMPVideoDecoder::NeedShmem]
 description =
 [PGMPVideoEncoder::NeedShmem]
 description =
 [PVideoDecoderManager::PVideoDecoder]
 description =
 [PVideoDecoderManager::Readback]
 description =
+[PVideoDecoderManager::ReadBlacklistedDrivers]
+description =
 [PBrowserStream::NPN_RequestRead]
 description =
 [PBackgroundStorage::Preload]
 description =
 [PRemoteSpellcheckEngine::Check]
 description =
 [PRemoteSpellcheckEngine::CheckAndSuggest]
 description =