Bug 1158089 - Fall back to d3d9 DXVA if d3d11 initialization fails. r=cpearce
authorMatt Woodrow <mwoodrow@mozilla.com>
Mon, 11 May 2015 16:21:31 +1200
changeset 243329 c61b05d0af51c0b7e2e61e0370a5d678e467e29d
parent 243328 651e2c2015f61b930e1fa36b6fa2457c51f99f41
child 243330 5ec60cbf124c89669f4b3bbe6c84bd6bc1e8150a
push id28738
push usercbook@mozilla.com
push dateTue, 12 May 2015 14:11:31 +0000
treeherdermozilla-central@bedce1b405a3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscpearce
bugs1158089
milestone40.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 1158089 - Fall back to d3d9 DXVA if d3d11 initialization fails. r=cpearce
dom/media/fmp4/wmf/WMFVideoMFTManager.cpp
dom/media/fmp4/wmf/WMFVideoMFTManager.h
dom/media/wmf/DXVA2Manager.cpp
dom/media/wmf/DXVA2Manager.h
--- a/dom/media/fmp4/wmf/WMFVideoMFTManager.cpp
+++ b/dom/media/fmp4/wmf/WMFVideoMFTManager.cpp
@@ -142,48 +142,64 @@ public:
     }
     return NS_OK;
   }
   nsAutoPtr<DXVA2Manager> mDXVA2Manager;
   LayersBackend mBackend;
 };
 
 bool
-WMFVideoMFTManager::InitializeDXVA()
+WMFVideoMFTManager::InitializeDXVA(bool aForceD3D9)
 {
   MOZ_ASSERT(!mDXVA2Manager);
 
   // If we use DXVA but aren't running with a D3D layer manager then the
   // readback of decoded video frames from GPU to CPU memory grinds painting
   // to a halt, and makes playback performance *worse*.
   if (!mDXVAEnabled ||
       (mLayersBackend != LayersBackend::LAYERS_D3D9 &&
        mLayersBackend != LayersBackend::LAYERS_D3D10 &&
        mLayersBackend != LayersBackend::LAYERS_D3D11)) {
     return false;
   }
 
   // The DXVA manager must be created on the main thread.
-  nsRefPtr<CreateDXVAManagerEvent> event(new CreateDXVAManagerEvent(mLayersBackend));
+  nsRefPtr<CreateDXVAManagerEvent> event = 
+    new CreateDXVAManagerEvent(aForceD3D9 ? LayersBackend::LAYERS_D3D9 : mLayersBackend);
 
   if (NS_IsMainThread()) {
     event->Run();
   } else {
     NS_DispatchToMainThread(event, NS_DISPATCH_SYNC);
   }
   mDXVA2Manager = event->mDXVA2Manager;
 
   return mDXVA2Manager != nullptr;
 }
 
 TemporaryRef<MFTDecoder>
 WMFVideoMFTManager::Init()
 {
+  RefPtr<MFTDecoder> decoder = InitInternal(/* aForceD3D9 = */ false);
+
+  // If initialization failed with d3d11 DXVA then try falling back
+  // to d3d9.
+  if (!decoder && mDXVA2Manager && mDXVA2Manager->IsD3D11()) {
+    mDXVA2Manager = nullptr;
+    decoder = InitInternal(true);
+  }
+
+  return decoder.forget();
+}
+
+TemporaryRef<MFTDecoder>
+WMFVideoMFTManager::InitInternal(bool aForceD3D9)
+{
   mUseHwAccel = false; // default value; changed if D3D setup succeeds.
-  bool useDxva = InitializeDXVA();
+  bool useDxva = InitializeDXVA(aForceD3D9);
 
   RefPtr<MFTDecoder> decoder(new MFTDecoder());
 
   HRESULT hr = decoder->Create(GetMFTGUID());
   NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
 
   if (useDxva) {
     RefPtr<IMFAttributes> attr(decoder->GetAttributes());
--- a/dom/media/fmp4/wmf/WMFVideoMFTManager.h
+++ b/dom/media/fmp4/wmf/WMFVideoMFTManager.h
@@ -34,17 +34,19 @@ public:
                          nsRefPtr<MediaData>& aOutput) override;
 
   virtual void Shutdown() override;
 
   virtual bool IsHardwareAccelerated() const override;
 
 private:
 
-  bool InitializeDXVA();
+  bool InitializeDXVA(bool aForceD3D9);
+
+  TemporaryRef<MFTDecoder> InitInternal(bool aForceD3D9);
 
   HRESULT ConfigureVideoFrameGeometry();
 
   HRESULT CreateBasicVideoFrame(IMFSample* aSample,
                                 int64_t aStreamOffset,
                                 VideoData** aOutVideoData);
 
   HRESULT CreateD3DVideoFrame(IMFSample* aSample,
--- a/dom/media/wmf/DXVA2Manager.cpp
+++ b/dom/media/wmf/DXVA2Manager.cpp
@@ -233,16 +233,18 @@ public:
   // into an image which is returned by aOutImage.
   HRESULT CopyToImage(IMFSample* aVideoSample,
                       const nsIntRect& aRegion,
                       ImageContainer* aContainer,
                       Image** aOutImage) override;
 
   virtual HRESULT ConfigureForSize(uint32_t aWidth, uint32_t aHeight) override;
 
+  virtual bool IsD3D11() override { return true; }
+
 private:
   HRESULT CreateFormatConverter();
 
   HRESULT CreateOutputSample(RefPtr<IMFSample>& aSample,
                              RefPtr<ID3D11Texture2D>& aTexture);
 
   RefPtr<ID3D11Device> mDevice;
   RefPtr<ID3D11DeviceContext> mContext;
--- a/dom/media/wmf/DXVA2Manager.h
+++ b/dom/media/wmf/DXVA2Manager.h
@@ -35,16 +35,18 @@ public:
   // Creates an Image for the video frame stored in aVideoSample.
   virtual HRESULT CopyToImage(IMFSample* aVideoSample,
                               const nsIntRect& aRegion,
                               layers::ImageContainer* aContainer,
                               layers::Image** aOutImage) = 0;
 
   virtual HRESULT ConfigureForSize(uint32_t aWidth, uint32_t aHeight) { return S_OK; }
 
+  virtual bool IsD3D11() { return false; }
+
   virtual ~DXVA2Manager();
 
 protected:
   Mutex mLock;
   DXVA2Manager();
 };
 
 } // namespace mozilla