Store and return D2D singletons in RefPtrs. (bug 1380922 part 1, r=mchang)
authorDavid Anderson <danderson@mozilla.com>
Tue, 18 Jul 2017 12:15:39 -0700
changeset 418322 bc529efe4e79d71e03de734674c7812b13ce9e99
parent 418321 fc909021a397a1a679726b94f2c0451c48e5beba
child 418323 50011cd297845aa9b6ddae72993d6ffa2ec1a25e
push id7566
push usermtabara@mozilla.com
push dateWed, 02 Aug 2017 08:25:16 +0000
treeherdermozilla-beta@86913f512c3c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmchang
bugs1380922
milestone56.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
Store and return D2D singletons in RefPtrs. (bug 1380922 part 1, r=mchang)
gfx/2d/2D.h
gfx/2d/DrawTargetD2D1.cpp
gfx/2d/DrawTargetD2D1.h
gfx/2d/Factory.cpp
gfx/2d/HelpersD2D.h
gfx/2d/NativeFontResourceDWrite.cpp
gfx/2d/ScaledFontDWrite.cpp
gfx/2d/SourceSurfaceD2D1.cpp
gfx/thebes/gfxDWriteCommon.cpp
gfx/thebes/gfxWindowsPlatform.cpp
--- a/gfx/2d/2D.h
+++ b/gfx/2d/2D.h
@@ -22,16 +22,17 @@
 #include "mozilla/GenericRefCounted.h"
 #include "mozilla/MemoryReporting.h"
 
 // This RefPtr class isn't ideal for usage in Azure, as it doesn't allow T**
 // outparams using the &-operator. But it will have to do as there's no easy
 // solution.
 #include "mozilla/RefPtr.h"
 #include "mozilla/ServoUtils.h"
+#include "mozilla/StaticPtr.h"
 #include "mozilla/WeakPtr.h"
 
 #include "mozilla/DebugOnly.h"
 
 #if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GTK)
   #ifndef MOZ_ENABLE_FREETYPE
   #define MOZ_ENABLE_FREETYPE
   #endif
@@ -1657,20 +1658,22 @@ public:
 #ifdef WIN32
   static already_AddRefed<DrawTarget> CreateDrawTargetForD3D11Texture(ID3D11Texture2D *aTexture, SurfaceFormat aFormat);
 
   /*
    * 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 RefPtr<ID3D11Device> GetDirect3D11Device();
+  static RefPtr<ID2D1Device> GetD2D1Device();
+  static bool HasD2D1Device();
   static uint32_t GetD2D1DeviceSeq();
-  static IDWriteFactory *GetDWriteFactory();
+  static RefPtr<IDWriteFactory> GetDWriteFactory();
+  static bool SetDWriteFactory(IDWriteFactory *aFactory);
   static IDWriteFactory* EnsureDWriteFactory();
   static bool SupportsD2D1();
 
   static uint64_t GetD2DVRAMUsageDrawTarget();
   static uint64_t GetD2DVRAMUsageSourceSurface();
   static void D2DCleanup();
 
   static already_AddRefed<ScaledFont>
@@ -1682,19 +1685,19 @@ public:
                                   bool aForceGDIMode,
                                   IDWriteRenderingParams *aParams,
                                   Float aGamma,
                                   Float aContrast);
 
   static void UpdateSystemTextQuality();
 
 private:
-  static ID2D1Device *mD2D1Device;
-  static ID3D11Device *mD3D11Device;
-  static IDWriteFactory *mDWriteFactory;
+  static StaticRefPtr<ID2D1Device> mD2D1Device;
+  static StaticRefPtr<ID3D11Device> mD3D11Device;
+  static StaticRefPtr<IDWriteFactory> mDWriteFactory;
   static bool mDWriteFactoryInitialized;
   static Mutex* mDWriteFactoryLock;
 #endif
 
   static DrawEventRecorder *mRecorder;
 };
 
 } // namespace gfx
--- a/gfx/2d/DrawTargetD2D1.cpp
+++ b/gfx/2d/DrawTargetD2D1.cpp
@@ -29,19 +29,19 @@ typedef HRESULT (WINAPI*D2D1CreateFactor
     void **factory
 );
 
 namespace mozilla {
 namespace gfx {
 
 uint64_t DrawTargetD2D1::mVRAMUsageDT;
 uint64_t DrawTargetD2D1::mVRAMUsageSS;
-ID2D1Factory1* DrawTargetD2D1::mFactory = nullptr;
+StaticRefPtr<ID2D1Factory1> DrawTargetD2D1::mFactory;
 
-ID2D1Factory1 *D2DFactory1()
+RefPtr<ID2D1Factory1> D2DFactory()
 {
   return DrawTargetD2D1::factory();
 }
 
 DrawTargetD2D1::DrawTargetD2D1()
   : mPushedLayers(1)
   , mUsedCommandListsSincePurge(0)
   , mDidComplexBlendWithListInList(false)
@@ -1032,17 +1032,18 @@ DrawTargetD2D1::CreateGradientStops(Grad
                                       getter_AddRefs(stopCollection));
   delete [] stops;
 
   if (FAILED(hr)) {
     gfxWarning() << *this << ": Failed to create GradientStopCollection. Code: " << hexa(hr);
     return nullptr;
   }
 
-  return MakeAndAddRef<GradientStopsD2D>(stopCollection, Factory::GetDirect3D11Device());
+  RefPtr<ID3D11Device> device = Factory::GetDirect3D11Device();
+  return MakeAndAddRef<GradientStopsD2D>(stopCollection, device);
 }
 
 already_AddRefed<FilterNode>
 DrawTargetD2D1::CreateFilter(FilterType aType)
 {
   return FilterNodeD2D1::Create(mDC, aType);
 }
 
@@ -1064,17 +1065,17 @@ DrawTargetD2D1::GetGlyphRasterizationMet
   }
 }
 
 bool
 DrawTargetD2D1::Init(ID3D11Texture2D* aTexture, SurfaceFormat aFormat)
 {
   HRESULT hr;
 
-  ID2D1Device* device = Factory::GetD2D1Device();
+  RefPtr<ID2D1Device> device = Factory::GetD2D1Device();
   if (!device) {
     gfxCriticalNote << "[D2D1.1] Failed to obtain a device for DrawTargetD2D1::Init(ID3D11Texture2D*, SurfaceFormat).";
     return false;
   } else {
     mDeviceSeq = Factory::GetD2D1DeviceSeq();
   }
 
   hr = device->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTITHREADED_OPTIMIZATIONS, getter_AddRefs(mDC));
@@ -1131,23 +1132,22 @@ DrawTargetD2D1::Init(ID3D11Texture2D* aT
   return true;
 }
 
 bool
 DrawTargetD2D1::Init(const IntSize &aSize, SurfaceFormat aFormat)
 {
   HRESULT hr;
 
-  ID2D1Device* device = Factory::GetD2D1Device();
+  RefPtr<ID2D1Device> device = Factory::GetD2D1Device();
   if (!device) {
     gfxCriticalNote << "[D2D1.1] Failed to obtain a device for DrawTargetD2D1::Init(IntSize, SurfaceFormat).";
     return false;
-  } else {
-    mDeviceSeq = Factory::GetD2D1DeviceSeq();
   }
+  mDeviceSeq = Factory::GetD2D1DeviceSeq();
 
   hr = device->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTITHREADED_OPTIMIZATIONS, getter_AddRefs(mDC));
 
   if (FAILED(hr)) {
     gfxCriticalError() <<"[D2D1.1] 2Failed to create a DeviceContext, code: " << hexa(hr) << " format " << (int)aFormat;
     return false;
   }
 
@@ -1196,17 +1196,17 @@ DrawTargetD2D1::Init(const IntSize &aSiz
  * Private helpers.
  */
 uint32_t
 DrawTargetD2D1::GetByteSize() const
 {
   return mSize.width * mSize.height * BytesPerPixel(mFormat);
 }
 
-ID2D1Factory1*
+RefPtr<ID2D1Factory1>
 DrawTargetD2D1::factory()
 {
   if (mFactory) {
     return mFactory;
   }
 
   RefPtr<ID2D1Factory> factory;
   D2D1CreateFactoryFunc createD2DFactory;
@@ -1232,34 +1232,36 @@ DrawTargetD2D1::factory()
                                 &options,
                                 getter_AddRefs(factory));
 
   if (FAILED(hr) || !factory) {
     gfxCriticalNote << "Failed to create a D2D1 content device: " << hexa(hr);
     return nullptr;
   }
 
-  hr = factory->QueryInterface((ID2D1Factory1**)&mFactory);
-  if (FAILED(hr) || !mFactory) {
+  RefPtr<ID2D1Factory1> factory1;
+  hr = factory->QueryInterface(__uuidof(ID2D1Factory1), getter_AddRefs(factory1));
+  if (FAILED(hr) || !factory1) {
     return nullptr;
   }
 
+  mFactory = factory1;
+
   ExtendInputEffectD2D1::Register(mFactory);
   RadialGradientEffectD2D1::Register(mFactory);
 
   return mFactory;
 }
 
 void
 DrawTargetD2D1::CleanupD2D()
 {
   if (mFactory) {
     RadialGradientEffectD2D1::Unregister(mFactory);
     ExtendInputEffectD2D1::Unregister(mFactory);
-    mFactory->Release();
     mFactory = nullptr;
   }
 }
 
 void
 DrawTargetD2D1::MarkChanged()
 {
   if (mSnapshot) {
--- a/gfx/2d/DrawTargetD2D1.h
+++ b/gfx/2d/DrawTargetD2D1.h
@@ -6,16 +6,17 @@
 #ifndef MOZILLA_GFX_DRAWTARGETD2D1_H_
 #define MOZILLA_GFX_DRAWTARGETD2D1_H_
 
 #include "2D.h"
 #include <d3d11.h>
 #include <d2d1_1.h>
 #include "PathD2D.h"
 #include "HelpersD2D.h"
+#include "mozilla/StaticPtr.h"
 
 #include <vector>
 #include <sstream>
 
 #include <unordered_set>
 
 struct IDWriteFactory;
 
@@ -148,17 +149,17 @@ public:
                                               ExtendMode aExtendMode, const IntRect* aSourceRect = nullptr,
                                               bool aUserSpace = true);
 
   already_AddRefed<ID2D1Image> GetImageForSurface(SourceSurface *aSurface, ExtendMode aExtendMode) {
     Matrix mat;
     return GetImageForSurface(aSurface, mat, aExtendMode, nullptr);
   }
 
-  static ID2D1Factory1 *factory();
+  static RefPtr<ID2D1Factory1> factory();
   static void CleanupD2D();
 
   operator std::string() const {
     std::stringstream stream;
     stream << "DrawTargetD2D 1.1 (" << this << ")";
     return stream.str();
   }
 
@@ -287,17 +288,17 @@ private:
   uint32_t mUsedCommandListsSincePurge;
   // When a BlendEffect has been drawn to a command list, and that command list is
   // subsequently used -again- as an input to a blend effect for a command list,
   // this causes an infinite recursion inside D2D as it tries to resolve the bounds.
   // If we resolve the current command list before this happens
   // we can avoid the subsequent hang. (See bug 1293586)
   bool mDidComplexBlendWithListInList;
 
-  static ID2D1Factory1 *mFactory;
+  static StaticRefPtr<ID2D1Factory1> mFactory;
   // This value is uesed to verify if the DrawTarget is created by a stale device.
   uint32_t mDeviceSeq;
 
   // List of effects we use
   bool EnsureLuminanceEffect();
   RefPtr<ID2D1Effect> mLuminanceEffect;
 };
 
--- a/gfx/2d/Factory.cpp
+++ b/gfx/2d/Factory.cpp
@@ -196,19 +196,19 @@ int32_t LoggingPrefs::sGfxLogLevel = LOG
 
 #ifdef MOZ_ENABLE_FREETYPE
 FT_Library Factory::mFTLibrary = nullptr;
 Mutex* Factory::mFTLock = nullptr;
 #endif
 
 #ifdef WIN32
 static uint32_t mDeviceSeq = 0;
-ID3D11Device *Factory::mD3D11Device = nullptr;
-ID2D1Device *Factory::mD2D1Device = nullptr;
-IDWriteFactory *Factory::mDWriteFactory = nullptr;
+StaticRefPtr<ID3D11Device> Factory::mD3D11Device;
+StaticRefPtr<ID2D1Device> Factory::mD2D1Device;
+StaticRefPtr<IDWriteFactory> Factory::mDWriteFactory;
 bool Factory::mDWriteFactoryInitialized = false;
 Mutex* Factory::mDWriteFactoryLock = nullptr;
 #endif
 
 DrawEventRecorder *Factory::mRecorder;
 
 mozilla::gfx::Config* Factory::sConfig = nullptr;
 
@@ -748,60 +748,67 @@ Factory::CreateDrawTargetForD3D11Texture
 }
 
 bool
 Factory::SetDirect3D11Device(ID3D11Device *aDevice)
 {
   mD3D11Device = aDevice;
 
   if (mD2D1Device) {
-    mD2D1Device->Release();
     mD2D1Device = nullptr;
   }
 
   if (!aDevice) {
     return true;
   }
 
-  RefPtr<ID2D1Factory1> factory = D2DFactory1();
+  RefPtr<ID2D1Factory1> factory = D2DFactory();
 
   RefPtr<IDXGIDevice> device;
   aDevice->QueryInterface((IDXGIDevice**)getter_AddRefs(device));
-  HRESULT hr = factory->CreateDevice(device, &mD2D1Device);
+
+  RefPtr<ID2D1Device> d2dDevice;
+  HRESULT hr = factory->CreateDevice(device, getter_AddRefs(d2dDevice));
   if (FAILED(hr)) {
     gfxCriticalError() << "[D2D1] Failed to create gfx factory's D2D1 device, code: " << hexa(hr);
 
     mD3D11Device = nullptr;
     return false;
-  } else {
-    mDeviceSeq++;
   }
 
+  mDeviceSeq++;
+  mD2D1Device = d2dDevice;
   return true;
 }
 
-ID3D11Device*
+RefPtr<ID3D11Device>
 Factory::GetDirect3D11Device()
 {
   return mD3D11Device;
 }
 
-ID2D1Device*
+RefPtr<ID2D1Device>
 Factory::GetD2D1Device()
 {
-  return mD2D1Device;
+  return mD2D1Device.get();
+}
+
+bool
+Factory::HasD2D1Device()
+{
+  return !!GetD2D1Device();
 }
 
 uint32_t
 Factory::GetD2D1DeviceSeq()
 {
   return mDeviceSeq;
 }
 
-IDWriteFactory*
+RefPtr<IDWriteFactory>
 Factory::GetDWriteFactory()
 {
   return mDWriteFactory;
 }
 
 IDWriteFactory*
 Factory::EnsureDWriteFactory()
 {
@@ -831,17 +838,17 @@ Factory::EnsureDWriteFactory()
   }
 
   return mDWriteFactory;
 }
 
 bool
 Factory::SupportsD2D1()
 {
-  return !!D2DFactory1();
+  return !!D2DFactory();
 }
 
 BYTE sSystemTextQuality = CLEARTYPE_QUALITY;
 void
 Factory::UpdateSystemTextQuality()
 {
 #ifdef WIN32
   gfx::UpdateSystemTextQuality();
@@ -859,17 +866,16 @@ Factory::GetD2DVRAMUsageSourceSurface()
 {
   return DrawTargetD2D1::mVRAMUsageSS;
 }
 
 void
 Factory::D2DCleanup()
 {
   if (mD2D1Device) {
-    mD2D1Device->Release();
     mD2D1Device = nullptr;
   }
   DrawTargetD2D1::CleanupD2D();
 }
 
 already_AddRefed<ScaledFont>
 Factory::CreateScaledFontForDWriteFont(IDWriteFontFace* aFontFace,
                                        const gfxFontStyle* aStyle,
--- a/gfx/2d/HelpersD2D.h
+++ b/gfx/2d/HelpersD2D.h
@@ -20,18 +20,17 @@
 #include "ScaledFontDWrite.h"
 
 #undef min
 #undef max
 
 namespace mozilla {
 namespace gfx {
 
-ID2D1Factory1* D2DFactory1();
-static ID2D1Factory* D2DFactory() { return D2DFactory1(); }
+RefPtr<ID2D1Factory1> D2DFactory();
 
 static inline D2D1_POINT_2F D2DPoint(const Point &aPoint)
 {
   return D2D1::Point2F(aPoint.x, aPoint.y);
 }
 
 static inline D2D1_SIZE_U D2DIntSize(const IntSize &aSize)
 {
--- a/gfx/2d/NativeFontResourceDWrite.cpp
+++ b/gfx/2d/NativeFontResourceDWrite.cpp
@@ -216,17 +216,17 @@ DWriteFontFileStream::ReleaseFileFragmen
 {
 }
 
 /* static */
 already_AddRefed<NativeFontResourceDWrite>
 NativeFontResourceDWrite::Create(uint8_t *aFontData, uint32_t aDataLength,
                                  bool aNeedsCairo)
 {
-  IDWriteFactory *factory = Factory::EnsureDWriteFactory();
+  RefPtr<IDWriteFactory> factory = Factory::GetDWriteFactory();
   if (!factory) {
     gfxWarning() << "Failed to get DWrite Factory.";
     return nullptr;
   }
 
   uint64_t fontFileKey = sNextFontFileKey++;
   RefPtr<IDWriteFontFileStream> ffsRef =
     new DWriteFontFileStream(aFontData, aDataLength, fontFileKey);
--- a/gfx/2d/ScaledFontDWrite.cpp
+++ b/gfx/2d/ScaledFontDWrite.cpp
@@ -146,17 +146,17 @@ ScaledFontDWrite::GetPathForGlyphs(const
 }
 
 
 #ifdef USE_SKIA
 SkTypeface*
 ScaledFontDWrite::GetSkTypeface()
 {
   if (!mTypeface) {
-    IDWriteFactory *factory = Factory::GetDWriteFactory();
+    RefPtr<IDWriteFactory> factory = Factory::GetDWriteFactory();
     if (!factory) {
       return nullptr;
     }
 
     mTypeface = SkCreateTypefaceFromDWriteFont(factory, mFontFace, mStyle, mForceGDIMode, mGamma, mContrast);
   }
   return mTypeface;
 }
--- a/gfx/2d/SourceSurfaceD2D1.cpp
+++ b/gfx/2d/SourceSurfaceD2D1.cpp
@@ -75,17 +75,17 @@ SourceSurfaceD2D1::GetDataSurface()
 bool
 SourceSurfaceD2D1::EnsureRealizedBitmap()
 {
   if (mRealizedBitmap) {
     return true;
   }
 
   // Why aren't we using mDevice here or anywhere else?
-  ID2D1Device* device = Factory::GetD2D1Device();
+  RefPtr<ID2D1Device> device = Factory::GetD2D1Device();
   if (!device) {
     return false;
   }
 
   RefPtr<ID2D1DeviceContext> dc;
   device->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_NONE, getter_AddRefs(dc));
 
   D2D1_BITMAP_PROPERTIES1 props;
--- a/gfx/thebes/gfxDWriteCommon.cpp
+++ b/gfx/thebes/gfxDWriteCommon.cpp
@@ -153,17 +153,17 @@ gfxDWriteFontFileLoader::CreateStreamFro
 HRESULT
 gfxDWriteFontFileLoader::CreateCustomFontFile(FallibleTArray<uint8_t>& aFontData,
                                               IDWriteFontFile** aFontFile,
                                               IDWriteFontFileStream** aFontFileStream)
 {
   MOZ_ASSERT(aFontFile);
   MOZ_ASSERT(aFontFileStream);
 
-  IDWriteFactory *factory = mozilla::gfx::Factory::GetDWriteFactory();
+  RefPtr<IDWriteFactory> factory = mozilla::gfx::Factory::GetDWriteFactory();
   if (!factory) {
     gfxCriticalError() << "Failed to get DWrite Factory in CreateCustomFontFile.";
     return E_FAIL;
   }
 
   uint64_t fontFileKey = sNextFontFileKey++;
   RefPtr<IDWriteFontFileStream> ffsRef = new gfxDWriteFontFileStream(&aFontData, fontFileKey);
   sFontFileStreams[fontFileKey] = ffsRef;
--- a/gfx/thebes/gfxWindowsPlatform.cpp
+++ b/gfx/thebes/gfxWindowsPlatform.cpp
@@ -56,16 +56,17 @@
 #include <d3d10_1.h>
 
 #include "mozilla/gfx/2D.h"
 
 #include "nsMemory.h"
 
 #include <dwmapi.h>
 #include <d3d11.h>
+#include <d2d1_1.h>
 
 #include "nsIMemoryReporter.h"
 #include <winternl.h>
 #include "d3dkmtQueryStatistics.h"
 
 #include "base/thread.h"
 #include "gfxPrefs.h"
 #include "gfxConfig.h"
@@ -145,24 +146,23 @@ NS_IMPL_ISUPPORTS(GfxD2DVramReporter, ns
 #define GFX_CLEARTYPE_PARAMS_STRUCTURE "gfx.font_rendering.cleartype_params.pixel_structure"
 #define GFX_CLEARTYPE_PARAMS_MODE      "gfx.font_rendering.cleartype_params.rendering_mode"
 
 class GPUAdapterReporter final : public nsIMemoryReporter
 {
     // Callers must Release the DXGIAdapter after use or risk mem-leak
     static bool GetDXGIAdapter(IDXGIAdapter **aDXGIAdapter)
     {
-        ID3D11Device *d3d11Device;
-        IDXGIDevice *dxgiDevice;
+        RefPtr<ID3D11Device> d3d11Device;
+        RefPtr<IDXGIDevice> dxgiDevice;
         bool result = false;
 
         if ((d3d11Device = mozilla::gfx::Factory::GetDirect3D11Device())) {
-            if (d3d11Device->QueryInterface(__uuidof(IDXGIDevice), (void **)&dxgiDevice) == S_OK) {
+            if (d3d11Device->QueryInterface(__uuidof(IDXGIDevice), getter_AddRefs(dxgiDevice)) == S_OK) {
                 result = (dxgiDevice->GetAdapter(aDXGIAdapter) == S_OK);
-                dxgiDevice->Release();
             }
         }
 
         return result;
     }
 
     ~GPUAdapterReporter() {}
 
@@ -427,17 +427,17 @@ gfxWindowsPlatform::HandleDeviceReset()
 void
 gfxWindowsPlatform::UpdateBackendPrefs()
 {
   uint32_t canvasMask = BackendTypeBit(BackendType::CAIRO) |
                         BackendTypeBit(BackendType::SKIA);
   uint32_t contentMask = BackendTypeBit(BackendType::CAIRO) |
                          BackendTypeBit(BackendType::SKIA);
   BackendType defaultBackend = BackendType::SKIA;
-  if (gfxConfig::IsEnabled(Feature::DIRECT2D) && Factory::GetD2D1Device()) {
+  if (gfxConfig::IsEnabled(Feature::DIRECT2D) && Factory::HasD2D1Device()) {
     contentMask |= BackendTypeBit(BackendType::DIRECT2D1_1);
     canvasMask |= BackendTypeBit(BackendType::DIRECT2D1_1);
     defaultBackend = BackendType::DIRECT2D1_1;
   }
   InitBackendPrefs(canvasMask, defaultBackend, contentMask, defaultBackend);
 }
 
 bool
@@ -453,19 +453,19 @@ gfxWindowsPlatform::UpdateRenderMode()
 
   UpdateBackendPrefs();
 
   if (didReset) {
     mScreenReferenceDrawTarget =
       CreateOffscreenContentDrawTarget(IntSize(1, 1), SurfaceFormat::B8G8R8A8);
     if (!mScreenReferenceDrawTarget) {
       gfxCriticalNote << "Failed to update reference draw target after device reset"
-                      << ", D3D11 device:" << hexa(Factory::GetDirect3D11Device())
+                      << ", D3D11 device:" << hexa(Factory::GetDirect3D11Device().get())
                       << ", D3D11 status:" << FeatureStatusToString(gfxConfig::GetValue(Feature::D3D11_COMPOSITING))
-                      << ", D2D1 device:" << hexa(Factory::GetD2D1Device())
+                      << ", D2D1 device:" << hexa(Factory::GetD2D1Device().get())
                       << ", D2D1 status:" << FeatureStatusToString(gfxConfig::GetValue(Feature::DIRECT2D))
                       << ", content:" << int(GetDefaultContentBackend())
                       << ", compositor:" << int(GetCompositorBackend());
       MOZ_CRASH("GFX: Failed to update reference draw target after device reset");
     }
   }
 }