Don't create remote D3D11 devices when remote presentation is broken. (bug 1310443, r=rhunt)
authorDavid Anderson <danderson@mozilla.com>
Tue, 25 Oct 2016 18:42:20 -0700
changeset 362290 b943d19facc65a7d74adcd9202055e2d1bd1cdbc
parent 362289 d23e41c16872a973e44d7f3b8e664b8b8b3f0fc8
child 362291 43f9a388633e084c9826673563f346e87830c151
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-beta@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrhunt
bugs1310443
milestone52.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
Don't create remote D3D11 devices when remote presentation is broken. (bug 1310443, r=rhunt)
gfx/thebes/D3D11Checks.cpp
gfx/thebes/D3D11Checks.h
gfx/thebes/DeviceManagerDx.cpp
--- a/gfx/thebes/D3D11Checks.cpp
+++ b/gfx/thebes/D3D11Checks.cpp
@@ -7,16 +7,17 @@
 #include "gfxConfig.h"
 #include "GfxDriverInfo.h"
 #include "gfxPrefs.h"
 #include "gfxWindowsPlatform.h"
 #include "mozilla/RefPtr.h"
 #include "mozilla/gfx/Logging.h"
 #include "nsIGfxInfo.h"
 #include <dxgi.h>
+#include <dxgi1_2.h>
 #include <d3d10_1.h>
 #include <d3d11.h>
 
 namespace mozilla {
 namespace gfx {
 
 using namespace mozilla::widget;
 
@@ -385,11 +386,19 @@ D3D11Checks::WarnOnAdapterMismatch(ID3D1
   gfxInfo->GetAdapterVendorID(vendorID);
   nsresult ec;
   int32_t vendor = vendorID.ToInteger(&ec, 16);
   if (vendor != desc.VendorId) {
     gfxCriticalNote << "VendorIDMismatch V " << hexa(vendor) << " " << hexa(desc.VendorId);
   }
 }
 
+/* static */ bool
+D3D11Checks::DoesRemotePresentWork(IDXGIAdapter* adapter)
+{
+  // Remote presentation was added in DXGI 1.2, for Windows 8 and the Platform Update to Windows 7.
+  RefPtr<IDXGIAdapter2> check;
+  HRESULT hr = adapter->QueryInterface(__uuidof(IDXGIAdapter2), getter_AddRefs(check));
+  return SUCCEEDED(hr) && check;
+}
 
 } // namespace gfx
 } // namespace mozilla
--- a/gfx/thebes/D3D11Checks.h
+++ b/gfx/thebes/D3D11Checks.h
@@ -2,27 +2,29 @@
  * 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/. */
 
 #ifndef mozilla_gfx_thebes_D3D11Checks_h
 #define mozilla_gfx_thebes_D3D11Checks_h
 
 struct ID3D11Device;
+struct IDXGIAdapter;
 struct DXGI_ADAPTER_DESC;
 
 namespace mozilla {
 namespace gfx {
 
 struct D3D11Checks
 {
   static bool DoesRenderTargetViewNeedRecreating(ID3D11Device* aDevice);
   static bool DoesDeviceWork();
   static bool DoesTextureSharingWork(ID3D11Device *device);
   static bool DoesAlphaTextureSharingWork(ID3D11Device *device);
   static void WarnOnAdapterMismatch(ID3D11Device* device);
   static bool GetDxgiDesc(ID3D11Device* device, DXGI_ADAPTER_DESC* out);
+  static bool DoesRemotePresentWork(IDXGIAdapter* adapter);
 };
 
 } // namespace gfx
 } // namespace mozilla
 
 #endif // mozilla_gfx_thebes_D3D11Checks_h
--- a/gfx/thebes/DeviceManagerDx.cpp
+++ b/gfx/thebes/DeviceManagerDx.cpp
@@ -309,16 +309,24 @@ DeviceManagerDx::CreateCompositorDevice(
 
   RefPtr<IDXGIAdapter1> adapter = GetDXGIAdapter();
   if (!adapter) {
     d3d11.SetFailed(FeatureStatus::Unavailable, "Failed to acquire a DXGI adapter",
                     NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_DXGI"));
     return;
   }
 
+  if (XRE_IsGPUProcess() && !D3D11Checks::DoesRemotePresentWork(adapter)) {
+    d3d11.SetFailed(
+      FeatureStatus::Unavailable,
+      "DXGI does not support out-of-process presentation",
+      NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_REMOTE_PRESENT"));
+    return;
+  }
+
   RefPtr<ID3D11Device> device;
   if (!CreateCompositorDeviceHelper(d3d11, adapter, true, device)) {
     // Try again without video support and record that it failed.
     mCompositorDeviceSupportsVideo = false;
     if (!CreateCompositorDeviceHelper(d3d11, adapter, false, device)) {
       return;
     }
   } else {