Bug 1400457 - Part 2: Create new D3D11Device for WebVR draft
authorKearwood "Kip" Gilbert <kgilbert@mozilla.com>
Mon, 28 Aug 2017 15:56:43 -0700
changeset 672863 8dd40316eb04b393db573b51fe1757359541bd72
parent 672236 143610c742812e22a025a064c681e0aa54ed6e1a
child 733944 e33dc8c7092ec3c760247954c6fd85f588a0a3a1
push id82397
push userkgilbert@mozilla.com
push dateFri, 29 Sep 2017 20:47:58 +0000
bugs1400457, 1362578
milestone58.0a1
Bug 1400457 - Part 2: Create new D3D11Device for WebVR - As we are creating a separate VR process in Bug 1362578, we will need our own D3D11Device. - Eventually, we will be allowing the VR device runtimes to help select the appropriate adapter / device based on the physical connection. This function will be updated at that time. MozReview-Commit-ID: EewUkNxU3BI
gfx/thebes/DeviceManagerDx.cpp
gfx/thebes/DeviceManagerDx.h
gfx/vr/VRDisplayHost.cpp
gfx/vr/gfxVROculus.cpp
--- a/gfx/thebes/DeviceManagerDx.cpp
+++ b/gfx/thebes/DeviceManagerDx.cpp
@@ -104,16 +104,17 @@ DeviceManagerDx::LoadD3D11()
   return true;
 }
 
 void
 DeviceManagerDx::ReleaseD3D11()
 {
   MOZ_ASSERT(!mCompositorDevice);
   MOZ_ASSERT(!mContentDevice);
+  MOZ_ASSERT(!mVRDevice);
   MOZ_ASSERT(!mDecoderDevice);
 
   mD3D11Module.reset();
   sD3D11CreateDeviceFn = nullptr;
 }
 
 static inline bool
 ProcessOwnsCompositor()
@@ -164,16 +165,56 @@ DeviceManagerDx::CreateCompositorDevices
   if (!d3d11.IsEnabled()) {
     return false;
   }
 
   PreloadAttachmentsOnCompositorThread();
   return true;
 }
 
+bool
+DeviceManagerDx::CreateVRDevice()
+{
+  MOZ_ASSERT(ProcessOwnsCompositor());
+
+  if (mVRDevice) {
+    return true;
+  }
+
+  if (!gfxConfig::IsEnabled(Feature::D3D11_COMPOSITING)) {
+    NS_WARNING("Direct3D11 Compositing required for VR");
+    return false;
+  }
+
+  if (!LoadD3D11()) {
+    return false;
+  }
+
+  RefPtr<IDXGIAdapter1> adapter = GetDXGIAdapter();
+  if (!adapter) {
+    NS_WARNING("Failed to acquire a DXGI adapter for VR");
+    return false;
+  }
+
+  UINT flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
+
+  HRESULT hr;
+  if (!CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, flags, hr, mVRDevice)) {
+    gfxCriticalError() << "Crash during D3D11 device creation for VR";
+    return false;
+  }
+
+  if (FAILED(hr) || !mVRDevice) {
+    NS_WARNING("Failed to acquire a D3D11 device for VR");
+    return false;
+  }
+
+  return true;
+}
+
 void
 DeviceManagerDx::ImportDeviceInfo(const D3D11DeviceStatus& aDeviceStatus)
 {
   MOZ_ASSERT(!ProcessOwnsCompositor());
 
   mDeviceStatus = Some(aDeviceStatus);
 }
 
@@ -938,16 +979,26 @@ DeviceManagerDx::GetCompositorDevice()
 
 RefPtr<ID3D11Device>
 DeviceManagerDx::GetContentDevice()
 {
   MutexAutoLock lock(mDeviceLock);
   return mContentDevice;
 }
 
+RefPtr<ID3D11Device>
+DeviceManagerDx::GetVRDevice()
+{
+  MutexAutoLock lock(mDeviceLock);
+  if(!mVRDevice) {
+    CreateVRDevice();
+  }
+  return mVRDevice;
+}
+
 unsigned
 DeviceManagerDx::GetCompositorFeatureLevel() const
 {
   if (!mDeviceStatus) {
     return 0;
   }
   return mDeviceStatus->featureLevel();
 }
--- a/gfx/thebes/DeviceManagerDx.h
+++ b/gfx/thebes/DeviceManagerDx.h
@@ -52,16 +52,17 @@ public:
   DeviceManagerDx();
 
   static DeviceManagerDx* Get() {
     return sInstance;
   }
 
   RefPtr<ID3D11Device> GetCompositorDevice();
   RefPtr<ID3D11Device> GetContentDevice();
+  RefPtr<ID3D11Device> GetVRDevice();
   RefPtr<ID3D11Device> CreateDecoderDevice();
   RefPtr<layers::MLGDevice> GetMLGDevice();
   IDirectDraw7* GetDirectDraw();
 
   unsigned GetCompositorFeatureLevel() const;
   bool TextureSharingWorks();
   bool IsWARP();
   bool CanUseNV12();
@@ -118,16 +119,17 @@ private:
   bool CreateCompositorDeviceHelper(
       mozilla::gfx::FeatureState& aD3d11,
       IDXGIAdapter1* aAdapter,
       bool aAttemptVideoSupport,
       RefPtr<ID3D11Device>& aOutDevice);
 
   void CreateWARPCompositorDevice();
   void CreateMLGDevice();
+  bool CreateVRDevice();
 
   mozilla::gfx::FeatureStatus CreateContentDevice();
 
   bool CreateDevice(IDXGIAdapter* aAdapter,
                     D3D_DRIVER_TYPE aDriverType,
                     UINT aFlags,
                     HRESULT& aResOut,
                     RefPtr<ID3D11Device>& aOutDevice);
@@ -149,16 +151,17 @@ private:
   // the ref and unassign the module).
   nsModuleHandle mD3D11Module;
 
   mozilla::Mutex mDeviceLock;
   nsTArray<D3D_FEATURE_LEVEL> mFeatureLevels;
   RefPtr<IDXGIAdapter1> mAdapter;
   RefPtr<ID3D11Device> mCompositorDevice;
   RefPtr<ID3D11Device> mContentDevice;
+  RefPtr<ID3D11Device> mVRDevice;
   RefPtr<ID3D11Device> mDecoderDevice;
   RefPtr<layers::DeviceAttachmentsD3D11> mCompositorAttachments;
   RefPtr<layers::MLGDevice> mMLGDevice;
   bool mCompositorDeviceSupportsVideo;
 
   Maybe<D3D11DeviceStatus> mDeviceStatus;
 
   nsModuleHandle mDirectDrawDLL;
--- a/gfx/vr/VRDisplayHost.cpp
+++ b/gfx/vr/VRDisplayHost.cpp
@@ -74,17 +74,17 @@ VRDisplayHost::~VRDisplayHost()
   MOZ_COUNT_DTOR(VRDisplayHost);
 }
 
 #if defined(XP_WIN)
 bool
 VRDisplayHost::CreateD3DObjects()
 {
   if (!mDevice) {
-    RefPtr<ID3D11Device> device = gfx::DeviceManagerDx::Get()->GetCompositorDevice();
+    RefPtr<ID3D11Device> device = gfx::DeviceManagerDx::Get()->GetVRDevice();
     if (!device) {
       NS_WARNING("VRDisplayHost::CreateD3DObjects failed to get a D3D11Device");
       return false;
     }
     if (FAILED(device->QueryInterface(__uuidof(ID3D11Device1), getter_AddRefs(mDevice)))) {
       NS_WARNING("VRDisplayHost::CreateD3DObjects failed to get a D3D11Device1");
       return false;
     }
--- a/gfx/vr/gfxVROculus.cpp
+++ b/gfx/vr/gfxVROculus.cpp
@@ -409,17 +409,17 @@ VROculusSession::Initialize(ovrInitFlags
 bool
 VROculusSession::StartRendering()
 {
   if (!mPresenting) {
     // Nothing to do if we aren't presenting
     return true;
   }
   if (!mDevice) {
-    mDevice = gfx::DeviceManagerDx::Get()->GetCompositorDevice();
+    mDevice = gfx::DeviceManagerDx::Get()->GetVRDevice();
     if (!mDevice) {
       NS_WARNING("Failed to get a D3D11Device for Oculus");
       return false;
     }
   }
 
   if (!mTextureSet) {
     /**