Bug 1083071. Disable D3D11 and D3D9 layers on broken drivers. r=bjacob, a=sledru
💩💩 backed out by 77e045dd0f7c 💩 💩
authorJeff Muizelaar <jmuizelaar@mozilla.com>
Thu, 23 Oct 2014 00:15:22 -0400
changeset 218110 1b2b105a4c54
parent 218109 e890ed642ccc
child 218111 77e045dd0f7c
push id544
push userjmuizelaar@mozilla.com
push date2014-10-23 13:57 +0000
treeherdermozilla-release@1b2b105a4c54 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbjacob, sledru
bugs1083071
milestone33.0.1
Bug 1083071. Disable D3D11 and D3D9 layers on broken drivers. r=bjacob, a=sledru This will hopefully prevent black screen problems that people are seeing.
gfx/thebes/gfxWindowsPlatform.cpp
gfx/thebes/gfxWindowsPlatform.h
widget/windows/nsWindow.cpp
--- a/gfx/thebes/gfxWindowsPlatform.cpp
+++ b/gfx/thebes/gfxWindowsPlatform.cpp
@@ -380,17 +380,20 @@ gfxWindowsPlatform::UpdateRenderMode()
     bool tryD2D = d2dForceEnabled || (!d2dBlocked && !gfxPrefs::LayersPreferD3D9());
 
     // Do not ever try if d2d is explicitly disabled,
     // or if we're not using DWrite fonts.
     if (d2dDisabled || mUsingGDIFonts) {
         tryD2D = false;
     }
 
-    if (isVistaOrHigher  && !safeMode && tryD2D) {
+    ID3D11Device *device = GetD3D11Device();
+    if (isVistaOrHigher && !safeMode && tryD2D && device &&
+        DoesD3D11DeviceSupportResourceSharing(device)) {
+
         VerifyD2DDevice(d2dForceEnabled);
         if (mD2DDevice && GetD3D11Device()) {
             mRenderMode = RENDER_DIRECT2D;
             mUseDirectWrite = true;
         }
     } else {
         mD2DDevice = nullptr;
     }
@@ -1476,8 +1479,65 @@ gfxWindowsPlatform::GetDXGIAdapter()
     }
   }
 
   // We leak this module everywhere, we might as well do so here as well.
   dxgiModule.disown();
 
   return mAdapter;
 }
+
+// See bug 1083071. On some drivers, Direct3D 11 CreateShaderResourceView fails
+// with E_OUTOFMEMORY.
+bool DoesD3D11DeviceSupportResourceSharing(ID3D11Device *device)
+{
+  RefPtr<ID3D11Texture2D> texture;
+  D3D11_TEXTURE2D_DESC desc;
+  desc.Width = 32;
+  desc.Height = 32;
+  desc.MipLevels = 1;
+  desc.ArraySize = 1;
+  desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
+  desc.SampleDesc.Count = 1;
+  desc.SampleDesc.Quality = 0;
+  desc.Usage = D3D11_USAGE_DEFAULT;
+  desc.CPUAccessFlags = 0;
+  desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
+  desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
+  if (FAILED(device->CreateTexture2D(&desc, NULL, byRef(texture)))) {
+    return false;
+  }
+
+  HANDLE shareHandle;
+  nsRefPtr<IDXGIResource> otherResource;
+  if (FAILED(texture->QueryInterface(__uuidof(IDXGIResource),
+                                     getter_AddRefs(otherResource))))
+  {
+    return false;
+  }
+
+  if (FAILED(otherResource->GetSharedHandle(&shareHandle))) {
+    return false;
+  }
+
+  nsRefPtr<ID3D11Resource> sharedResource;
+  nsRefPtr<ID3D11Texture2D> sharedTexture;
+  if (FAILED(device->OpenSharedResource(shareHandle, __uuidof(ID3D11Resource),
+                                        getter_AddRefs(sharedResource))))
+  {
+    return false;
+  }
+
+  if (FAILED(sharedResource->QueryInterface(__uuidof(ID3D11Texture2D),
+                                            getter_AddRefs(sharedTexture))))
+  {
+    return false;
+  }
+
+  RefPtr<ID3D11ShaderResourceView> sharedView;
+
+  // This if(FAILED()) is the one that actually fails on systems affected by bug 1083071.
+  if (FAILED(device->CreateShaderResourceView(sharedTexture, NULL, byRef(sharedView)))) {
+    return false;
+  }
+
+  return true;
+}
--- a/gfx/thebes/gfxWindowsPlatform.h
+++ b/gfx/thebes/gfxWindowsPlatform.h
@@ -288,9 +288,11 @@ private:
     bool mD3D11DeviceInitialized;
 
     virtual void GetPlatformCMSOutputProfile(void* &mem, size_t &size);
 
     // TODO: unify this with mPrefFonts (NB: holds families, not fonts) in gfxPlatformFontList
     nsDataHashtable<nsCStringHashKey, nsTArray<nsRefPtr<gfxFontEntry> > > mPrefFonts;
 };
 
+bool DoesD3D11DeviceSupportResourceSharing(ID3D11Device *device);
+
 #endif /* GFX_WINDOWS_PLATFORM_H */
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -6735,20 +6735,28 @@ nsWindow::GetPreferredCompositorBackends
   // We don't currently support using an accelerated layer manager with
   // transparent windows so don't even try. I'm also not sure if we even
   // want to support this case. See bug 593471
   if (!(prefs.mDisableAcceleration ||
         mTransparencyMode == eTransparencyTransparent)) {
     if (prefs.mPreferOpenGL) {
       aHints.AppendElement(LayersBackend::LAYERS_OPENGL);
     }
-    if (!prefs.mPreferD3D9) {
-      aHints.AppendElement(LayersBackend::LAYERS_D3D11);
-    }
-    aHints.AppendElement(LayersBackend::LAYERS_D3D9);
+
+    ID3D11Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D11Device();
+    if (device && !DoesD3D11DeviceSupportResourceSharing(device))
+    {
+      // bug 1083071 - bad things - fall back to basic layers
+    }
+    else {
+      if (!prefs.mPreferD3D9) {
+        aHints.AppendElement(LayersBackend::LAYERS_D3D11);
+      }
+      aHints.AppendElement(LayersBackend::LAYERS_D3D9);
+    }
   }
   aHints.AppendElement(LayersBackend::LAYERS_BASIC);
 }
 
 void
 nsWindow::WindowUsesOMTC()
 {
   ULONG_PTR style = ::GetClassLongPtr(mWnd, GCL_STYLE);