Bug 1259810 - check that D2D1 device creation succeeds and otherwise fall to software backend. r=bas.schouten
authorLee Salzman <lsalzman@mozilla.com>
Mon, 28 Mar 2016 12:53:42 -0400
changeset 290731 c39faad857e5316b57235e155a3cad4dc0ea8252
parent 290730 d820bfb71d3a431acf00e4a6036a3d7cf9e0bbae
child 290732 4d6500208358f342d24b25e5ef32117e73138327
push id19656
push usergwagner@mozilla.com
push dateMon, 04 Apr 2016 13:43:23 +0000
treeherderb2g-inbound@e99061fde28a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbas
bugs1259810
milestone48.0a1
Bug 1259810 - check that D2D1 device creation succeeds and otherwise fall to software backend. r=bas.schouten
gfx/2d/2D.h
gfx/2d/Factory.cpp
gfx/thebes/gfxWindowsPlatform.cpp
--- a/gfx/2d/2D.h
+++ b/gfx/2d/2D.h
@@ -1368,17 +1368,21 @@ public:
   static already_AddRefed<DrawTarget> CreateDrawTargetForCairoCGContext(CGContextRef cg, const IntSize& aSize);
   static already_AddRefed<GlyphRenderingOptions>
     CreateCGGlyphRenderingOptions(const Color &aFontSmoothingBackgroundColor);
 #endif
 
 #ifdef WIN32
   static already_AddRefed<DrawTarget> CreateDrawTargetForD3D11Texture(ID3D11Texture2D *aTexture, SurfaceFormat aFormat);
 
-  static void SetDirect3D11Device(ID3D11Device *aDevice);
+  /*
+   * Attempts to create and install a D2D1 device from the supplied Direct3D11 device.
+   * Returns true on success, or false on failure and leaves the D2D1/Direct3D11 devices unset.
+   */
+  static bool SetDirect3D11Device(ID3D11Device *aDevice);
   static ID3D11Device *GetDirect3D11Device();
   static ID2D1Device *GetD2D1Device();
   static bool SupportsD2D1();
 
   static already_AddRefed<GlyphRenderingOptions>
     CreateDWriteGlyphRenderingOptions(IDWriteRenderingParams *aParams);
 
   static uint64_t GetD2DVRAMUsageDrawTarget();
--- a/gfx/2d/Factory.cpp
+++ b/gfx/2d/Factory.cpp
@@ -618,38 +618,43 @@ Factory::CreateDrawTargetForD3D11Texture
   }
 
   gfxWarning() << "Failed to create draw target for D3D11 texture.";
 
   // Failed
   return nullptr;
 }
 
-void
+bool
 Factory::SetDirect3D11Device(ID3D11Device *aDevice)
 {
   mD3D11Device = aDevice;
 
   if (mD2D1Device) {
     mD2D1Device->Release();
     mD2D1Device = nullptr;
   }
 
   if (!aDevice) {
-    return;
+    return true;
   }
 
   RefPtr<ID2D1Factory1> factory = D2DFactory1();
 
   RefPtr<IDXGIDevice> device;
   aDevice->QueryInterface((IDXGIDevice**)getter_AddRefs(device));
   HRESULT hr = factory->CreateDevice(device, &mD2D1Device);
   if (FAILED(hr)) {
     gfxCriticalError() << "[D2D1] Failed to create gfx factory's D2D1 device, code: " << hexa(hr);
+
+    mD3D11Device = nullptr;
+    return false;
   }
+
+  return true;
 }
 
 ID3D11Device*
 Factory::GetDirect3D11Device()
 {
   return mD3D11Device;
 }
 
--- a/gfx/thebes/gfxWindowsPlatform.cpp
+++ b/gfx/thebes/gfxWindowsPlatform.cpp
@@ -2512,18 +2512,21 @@ gfxWindowsPlatform::InitializeD2D()
   }
 
   // Using Direct2D depends on DWrite support.
   if (!mDWriteFactory && !InitDWriteSupport()) {
     mD2D1Status = FeatureStatus::Failed;
     return;
   }
 
-  mD2D1Status = FeatureStatus::Available;
-  Factory::SetDirect3D11Device(mD3D11ContentDevice);
+  // Verify that Direct2D device creation succeeded.
+  if (!Factory::SetDirect3D11Device(mD3D11ContentDevice)) {
+    mD2D1Status = FeatureStatus::Failed;
+    return;
+  }
 
   d2d1_1.SetSuccessful();
 
   mD2D1Status = FeatureStatus::Available;
 }
 
 bool
 gfxWindowsPlatform::CreateD3D11DecoderDeviceHelper(