Bug 1464032 Part 9: Add a D3D11 device to be used on canvas threads in the GPU process. r=jrmuizel
authorBob Owen <bobowencode@gmail.com>
Sun, 02 Dec 2018 14:17:02 +0000
changeset 477760 0e6cf27e972802cd890667321ea8e37a043d8d38
parent 477759 fcc9f5f6dfe1c94e7f76582ee972e960539cb060
child 477761 04067aec22bb2f8da87a34893c99e2195efd0b8c
push id113373
push userbobowencode@gmail.com
push dateFri, 07 Jun 2019 11:10:59 +0000
treeherdermozilla-inbound@2195b79ea888 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1464032
milestone69.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 1464032 Part 9: Add a D3D11 device to be used on canvas threads in the GPU process. r=jrmuizel
gfx/ipc/GPUParent.cpp
gfx/thebes/DeviceManagerDx.cpp
gfx/thebes/DeviceManagerDx.h
--- a/gfx/ipc/GPUParent.cpp
+++ b/gfx/ipc/GPUParent.cpp
@@ -200,17 +200,21 @@ mozilla::ipc::IPCResult GPUParent::RecvI
   }
 
   // We bypass gfxPlatform::Init, so we must initialize any relevant libraries
   // here that would normally be initialized there.
   SkGraphics::Init();
 
 #if defined(XP_WIN)
   if (gfxConfig::IsEnabled(Feature::D3D11_COMPOSITING)) {
-    DeviceManagerDx::Get()->CreateCompositorDevices();
+    if (DeviceManagerDx::Get()->CreateCompositorDevices() &&
+        gfxVars::RemoteCanvasEnabled()) {
+      MOZ_ALWAYS_TRUE(DeviceManagerDx::Get()->CreateCanvasDevice());
+      MOZ_ALWAYS_TRUE(Factory::EnsureDWriteFactory());
+    }
   }
   if (gfxVars::UseWebRender()) {
     DeviceManagerDx::Get()->CreateDirectCompositionDevice();
     // Ensure to initialize GfxInfo
     nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
     Unused << gfxInfo;
 
     Factory::EnsureDWriteFactory();
--- a/gfx/thebes/DeviceManagerDx.cpp
+++ b/gfx/thebes/DeviceManagerDx.cpp
@@ -262,16 +262,54 @@ bool DeviceManagerDx::CreateVRDevice() {
   if (FAILED(hr) || !mVRDevice) {
     NS_WARNING("Failed to acquire a D3D11 device for VR");
     return false;
   }
 
   return true;
 }
 
+bool DeviceManagerDx::CreateCanvasDevice() {
+  MOZ_ASSERT(ProcessOwnsCompositor());
+
+  if (mCanvasDevice) {
+    return true;
+  }
+
+  if (!LoadD3D11()) {
+    return false;
+  }
+
+  RefPtr<IDXGIAdapter1> adapter = GetDXGIAdapter();
+  if (!adapter) {
+    NS_WARNING("Failed to acquire a DXGI adapter for Canvas");
+    return false;
+  }
+
+  UINT flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
+
+  HRESULT hr;
+  if (!CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, flags, hr,
+                    mCanvasDevice)) {
+    gfxCriticalError() << "Crash during D3D11 device creation for Canvas";
+    return false;
+  }
+
+  if (FAILED(hr) || !mCanvasDevice) {
+    NS_WARNING("Failed to acquire a D3D11 device for Canvas");
+    return false;
+  }
+
+  if (XRE_IsGPUProcess()) {
+    Factory::SetDirect3D11Device(mCanvasDevice);
+  }
+
+  return true;
+}
+
 void DeviceManagerDx::CreateDirectCompositionDevice() {
   if (!gfxVars::UseWebRenderDCompWin()) {
     return;
   }
 
   if (!mCompositorDevice) {
     return;
   }
@@ -861,16 +899,17 @@ void DeviceManagerDx::ResetDevices() {
 
   MutexAutoLock lock(mDeviceLock);
 
   mAdapter = nullptr;
   mCompositorAttachments = nullptr;
   mMLGDevice = nullptr;
   mCompositorDevice = nullptr;
   mContentDevice = nullptr;
+  mCanvasDevice = nullptr;
   mImageDevice = nullptr;
   mDeviceStatus = Nothing();
   mDeviceResetReason = Nothing();
   Factory::SetDirect3D11Device(nullptr);
 }
 
 bool DeviceManagerDx::MaybeResetAndReacquireDevices() {
   DeviceResetReason resetReason;
@@ -883,26 +922,30 @@ bool DeviceManagerDx::MaybeResetAndReacq
                           uint32_t(resetReason));
   }
 
   CrashReporter::AnnotateCrashReport(
       CrashReporter::Annotation::DeviceResetReason, int(resetReason));
 
   bool createCompositorDevice = !!mCompositorDevice;
   bool createContentDevice = !!mContentDevice;
+  bool createCanvasDevice = !!mCanvasDevice;
 
   ResetDevices();
 
   if (createCompositorDevice && !CreateCompositorDevices()) {
     // Just stop, don't try anything more
     return true;
   }
   if (createContentDevice) {
     CreateContentDevices();
   }
+  if (createCanvasDevice) {
+    CreateCanvasDevice();
+  }
 
   return true;
 }
 
 bool DeviceManagerDx::ContentAdapterIsParentAdapter(ID3D11Device* device) {
   DXGI_ADAPTER_DESC desc;
   if (!D3D11Checks::GetDxgiDesc(device, &desc)) {
     gfxCriticalNote << "Could not query device DXGI adapter info";
@@ -981,17 +1024,18 @@ static inline bool DidDeviceReset(const 
 }
 
 bool DeviceManagerDx::GetAnyDeviceRemovedReason(DeviceResetReason* aOutReason) {
   // Caller must own the lock, since we access devices directly, and can be
   // called from any thread.
   mDeviceLock.AssertCurrentThreadOwns();
 
   if (DidDeviceReset(mCompositorDevice, aOutReason) ||
-      DidDeviceReset(mContentDevice, aOutReason)) {
+      DidDeviceReset(mContentDevice, aOutReason) ||
+      DidDeviceReset(mCanvasDevice, aOutReason)) {
     return true;
   }
 
   if (XRE_IsParentProcess() && NS_IsMainThread() &&
       StaticPrefs::DeviceResetForTesting()) {
     StaticPrefs::SetDeviceResetForTesting(0);
     *aOutReason = DeviceResetReason::FORCED_RESET;
     return true;
@@ -1064,16 +1108,24 @@ RefPtr<ID3D11Device> DeviceManagerDx::Ge
 RefPtr<ID3D11Device> DeviceManagerDx::GetVRDevice() {
   MutexAutoLock lock(mDeviceLock);
   if (!mVRDevice) {
     CreateVRDevice();
   }
   return mVRDevice;
 }
 
+RefPtr<ID3D11Device> DeviceManagerDx::GetCanvasDevice() {
+  MutexAutoLock lock(mDeviceLock);
+  if (!mCanvasDevice) {
+    CreateCanvasDevice();
+  }
+  return mCanvasDevice;
+}
+
 RefPtr<IDCompositionDevice> DeviceManagerDx::GetDirectCompositionDevice() {
   MutexAutoLock lock(mDeviceLock);
   return mDirectCompositionDevice;
 }
 
 unsigned DeviceManagerDx::GetCompositorFeatureLevel() const {
   if (!mDeviceStatus) {
     return 0;
--- a/gfx/thebes/DeviceManagerDx.h
+++ b/gfx/thebes/DeviceManagerDx.h
@@ -14,16 +14,17 @@
 #include "mozilla/StaticPtr.h"
 #include "mozilla/gfx/GraphicsMessages.h"
 #include "nsTArray.h"
 #include "nsWindowsHelpers.h"
 
 #include <windows.h>
 #include <objbase.h>
 
+#include <d3d11.h>
 #include <dxgi.h>
 #include <dxgi1_6.h>
 
 // This header is available in the June 2010 SDK and in the Win8 SDK
 #include <d3dcommon.h>
 // Win 8.0 SDK types we'll need when building using older sdks.
 #if !defined(D3D_FEATURE_LEVEL_11_1)  // defined in the 8.0 SDK only
 #  define D3D_FEATURE_LEVEL_11_1 static_cast<D3D_FEATURE_LEVEL>(0xb100)
@@ -51,16 +52,17 @@ class DeviceManagerDx final {
   static void Shutdown();
 
   DeviceManagerDx();
 
   static DeviceManagerDx* Get() { return sInstance; }
 
   RefPtr<ID3D11Device> GetCompositorDevice();
   RefPtr<ID3D11Device> GetContentDevice();
+  RefPtr<ID3D11Device> GetCanvasDevice();
   RefPtr<ID3D11Device> GetImageDevice();
   RefPtr<IDCompositionDevice> GetDirectCompositionDevice();
   RefPtr<ID3D11Device> GetVRDevice();
   RefPtr<ID3D11Device> CreateDecoderDevice();
   RefPtr<layers::MLGDevice> GetMLGDevice();
   IDirectDraw7* GetDirectDraw();
 
   unsigned GetCompositorFeatureLevel() const;
@@ -83,16 +85,17 @@ class DeviceManagerDx final {
   bool HasCrashyInitData();
 
   // Enumerate and return all outputs on the current adapter.
   nsTArray<DXGI_OUTPUT_DESC1> EnumerateOutputs();
 
   bool CreateCompositorDevices();
   void CreateContentDevices();
   void CreateDirectCompositionDevice();
+  bool CreateCanvasDevice();
 
   void GetCompositorDevices(
       RefPtr<ID3D11Device>* aOutDevice,
       RefPtr<layers::DeviceAttachmentsD3D11>* aOutAttachments);
 
   void ImportDeviceInfo(const D3D11DeviceStatus& aDeviceStatus);
   void ExportDeviceInfo(D3D11DeviceStatus* aOut);
 
@@ -160,16 +163,17 @@ class DeviceManagerDx final {
 
   nsModuleHandle mDcompModule;
 
   mozilla::Mutex mDeviceLock;
   nsTArray<D3D_FEATURE_LEVEL> mFeatureLevels;
   RefPtr<IDXGIAdapter1> mAdapter;
   RefPtr<ID3D11Device> mCompositorDevice;
   RefPtr<ID3D11Device> mContentDevice;
+  RefPtr<ID3D11Device> mCanvasDevice;
   RefPtr<ID3D11Device> mImageDevice;
   RefPtr<ID3D11Device> mVRDevice;
   RefPtr<ID3D11Device> mDecoderDevice;
   RefPtr<IDCompositionDevice> mDirectCompositionDevice;
 
   RefPtr<layers::DeviceAttachmentsD3D11> mCompositorAttachments;
   RefPtr<layers::MLGDevice> mMLGDevice;
   bool mCompositorDeviceSupportsVideo;