Bug 1101130: Make Direct2D 1.1 clean up its resources on shutdown. r=jrmuizel
authorBas Schouten <bschouten@mozilla.com>
Thu, 20 Nov 2014 00:16:48 +0000
changeset 240880 c3fbfee4a06b70215e764f1bc73a61430caf67bd
parent 240879 e46da4d0299d557964d01276c5efb2b37fc2f596
child 240881 8681a64218039f4bc6ea8113c522a6c2acee209e
push id4311
push userraliiev@mozilla.com
push dateMon, 12 Jan 2015 19:37:41 +0000
treeherdermozilla-beta@150c9fed433b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1101130
milestone36.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
Bug 1101130: Make Direct2D 1.1 clean up its resources on shutdown. r=jrmuizel
gfx/2d/DrawTargetD2D1.cpp
gfx/2d/Factory.cpp
gfx/2d/RadialGradientEffectD2D1.cpp
gfx/2d/RadialGradientEffectD2D1.h
--- a/gfx/2d/DrawTargetD2D1.cpp
+++ b/gfx/2d/DrawTargetD2D1.cpp
@@ -846,16 +846,26 @@ DrawTargetD2D1::factory()
   }
 
   RadialGradientEffectD2D1::Register(mFactory);
 
   return mFactory;
 }
 
 void
+DrawTargetD2D1::CleanupD2D()
+{
+  if (mFactory) {
+    RadialGradientEffectD2D1::Unregister(mFactory);
+    mFactory->Release();
+    mFactory = nullptr;
+  }
+}
+
+void
 DrawTargetD2D1::MarkChanged()
 {
   if (mSnapshot) {
     if (mSnapshot->hasOneRef()) {
       // Just destroy it, since no-one else knows about it.
       mSnapshot = nullptr;
     } else {
       mSnapshot->DrawTargetWillChange();
--- a/gfx/2d/Factory.cpp
+++ b/gfx/2d/Factory.cpp
@@ -604,16 +604,21 @@ Factory::CreateDrawTargetForD3D11Texture
   return nullptr;
 }
 
 void
 Factory::SetDirect3D11Device(ID3D11Device *aDevice)
 {
   mD3D11Device = aDevice;
 
+  if (mD2D1Device) {
+    mD2D1Device->Release();
+    mD2D1Device = nullptr;
+  }
+
   RefPtr<ID2D1Factory1> factory = D2DFactory1();
 
   RefPtr<IDXGIDevice> device;
   aDevice->QueryInterface((IDXGIDevice**)byRef(device));
   factory->CreateDevice(device, &mD2D1Device);
 }
 
 ID3D11Device*
@@ -651,17 +656,22 @@ uint64_t
 Factory::GetD2DVRAMUsageSourceSurface()
 {
   return DrawTargetD2D::mVRAMUsageSS;
 }
 
 void
 Factory::D2DCleanup()
 {
+  if (mD2D1Device) {
+    mD2D1Device->Release();
+    mD2D1Device = nullptr;
+  }
   DrawTargetD2D::CleanupD2D();
+  DrawTargetD2D1::CleanupD2D();
 }
 
 #endif // XP_WIN
 
 #ifdef USE_SKIA_GPU
 TemporaryRef<DrawTarget>
 Factory::CreateDrawTargetSkiaWithGrContext(GrContext* aGrContext,
                                            const IntSize &aSize,
--- a/gfx/2d/RadialGradientEffectD2D1.cpp
+++ b/gfx/2d/RadialGradientEffectD2D1.cpp
@@ -279,16 +279,22 @@ RadialGradientEffectD2D1::Register(ID2D1
   HRESULT hr = aFactory->RegisterEffectFromString(CLSID_RadialGradientEffect, kXmlDescription, bindings, ARRAYSIZE(bindings), CreateEffect);
 
   if (FAILED(hr)) {
     gfxWarning() << "Failed to register radial gradient effect.";
   }
   return hr;
 }
 
+void
+RadialGradientEffectD2D1::Unregister(ID2D1Factory1 *aFactory)
+{
+  aFactory->UnregisterEffect(CLSID_RadialGradientEffect);
+}
+
 HRESULT __stdcall
 RadialGradientEffectD2D1::CreateEffect(IUnknown **aEffectImpl)
 {
   *aEffectImpl = static_cast<ID2D1EffectImpl*>(new RadialGradientEffectD2D1());
   (*aEffectImpl)->AddRef();
 
   return S_OK;
 }
--- a/gfx/2d/RadialGradientEffectD2D1.h
+++ b/gfx/2d/RadialGradientEffectD2D1.h
@@ -67,16 +67,17 @@ public:
 
   // ID2D1TransformNode
   IFACEMETHODIMP_(UINT32) GetInputCount() const { return 1; }
 
   // ID2D1DrawTransform
   IFACEMETHODIMP SetDrawInfo(ID2D1DrawInfo *pDrawInfo);
 
   static HRESULT Register(ID2D1Factory1* aFactory);
+  static void Unregister(ID2D1Factory1* aFactory);
   static HRESULT __stdcall CreateEffect(IUnknown** aEffectImpl);
 
   HRESULT SetStopCollection(IUnknown *aStopCollection);
   IUnknown *GetStopCollection() const { return mStopCollection; }
 
 private:
   TemporaryRef<ID2D1ResourceTexture> CreateGradientTexture();