Bug 1259810 - check that D2D1 device creation succeeds and otherwise fall to software backend. r=bas.schouten a=ritu
authorLee Salzman <lsalzman@mozilla.com>
Mon, 28 Mar 2016 12:53:42 -0400
changeset 325678 ee1fb75222074125e8be8b84ca942fc2fa87f5ba
parent 325677 21c01308022de9e326533480d4ba0f83ad9c76bb
child 325679 35e304886cc36220b2a04c6e1cab374fae6513ea
push id1128
push userjlund@mozilla.com
push dateWed, 01 Jun 2016 01:31:59 +0000
treeherdermozilla-release@fe0d30de989d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbas, ritu
bugs1259810
milestone47.0a2
Bug 1259810 - check that D2D1 device creation succeeds and otherwise fall to software backend. r=bas.schouten a=ritu MozReview-Commit-ID: 6oNG7ly2wsA
gfx/2d/2D.h
gfx/2d/Factory.cpp
gfx/thebes/gfxWindowsPlatform.cpp
--- a/gfx/2d/2D.h
+++ b/gfx/2d/2D.h
@@ -1359,17 +1359,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
@@ -617,38 +617,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
@@ -2539,18 +2539,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(