Bug 1254400 - Make access to d3d9 device manager thread-safe. r=dvander
authorMorris Tseng <mtseng@mozilla.com>
Tue, 29 Mar 2016 09:26:29 +0800
changeset 290777 2626d857b9851ac400e8c727f15b0dea126c286c
parent 290776 f75d2232611e65b453f280e02dfd5ca76a1e6477
child 290778 2a875129c6f35701ecfa2866fbcd319d2fb7d726
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)
reviewersdvander
bugs1254400
milestone48.0a1
Bug 1254400 - Make access to d3d9 device manager thread-safe. r=dvander
gfx/layers/d3d9/TextureD3D9.cpp
gfx/thebes/gfxWindowsPlatform.cpp
gfx/thebes/gfxWindowsPlatform.h
--- a/gfx/layers/d3d9/TextureD3D9.cpp
+++ b/gfx/layers/d3d9/TextureD3D9.cpp
@@ -336,17 +336,17 @@ DataTextureSourceD3D9::Update(gfx::DataS
   MOZ_ASSERT(!aSrcOffset);
 
   if (!mCompositor || !mCompositor->device()) {
     NS_WARNING("No D3D device to update the texture.");
     return false;
   }
 
   uint32_t bpp = BytesPerPixel(aSurface->GetFormat());
-  DeviceManagerD3D9* deviceManager = gfxWindowsPlatform::GetPlatform()->GetD3D9DeviceManager();
+  RefPtr<DeviceManagerD3D9> deviceManager = gfxWindowsPlatform::GetPlatform()->GetD3D9DeviceManager();
 
   mSize = aSurface->GetSize();
   mFormat = aSurface->GetFormat();
 
   _D3DFORMAT format = D3DFMT_A8R8G8B8;
   switch (mFormat) {
   case SurfaceFormat::B8G8R8X8:
     format = D3DFMT_X8R8G8B8;
@@ -563,17 +563,17 @@ D3D9TextureData::~D3D9TextureData()
   MOZ_COUNT_DTOR(D3D9TextureData);
 }
 
 D3D9TextureData*
 D3D9TextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
                         TextureAllocationFlags aAllocFlags)
 {
   _D3DFORMAT format = SurfaceFormatToD3D9Format(aFormat);
-  DeviceManagerD3D9* deviceManager = gfxWindowsPlatform::GetPlatform()->GetD3D9DeviceManager();
+  RefPtr<DeviceManagerD3D9> deviceManager = gfxWindowsPlatform::GetPlatform()->GetD3D9DeviceManager();
   RefPtr<IDirect3DTexture9> d3d9Texture = deviceManager ? deviceManager->CreateTexture(aSize, format,
                                                                                        D3DPOOL_SYSTEMMEM,
                                                                                        nullptr)
                                                         : nullptr;
   if (!d3d9Texture) {
     NS_WARNING("Could not create a d3d9 texture");
     return nullptr;
   }
@@ -825,17 +825,17 @@ DataTextureSourceD3D9::UpdateFromTexture
     // If we changed the compositor, the size might have been reset to zero
     // Otherwise the texture size must not change.
     MOZ_ASSERT(mFormat == D3D9FormatToSurfaceFormat(desc.Format));
     MOZ_ASSERT(!mSize.width || mSize.width == desc.Width);
     MOZ_ASSERT(!mSize.height || mSize.height == desc.Height);
     mSize = IntSize(desc.Width, desc.Height);
   }
 
-  DeviceManagerD3D9* dm = gfxWindowsPlatform::GetPlatform()->GetD3D9DeviceManager();
+  RefPtr<DeviceManagerD3D9> dm = gfxWindowsPlatform::GetPlatform()->GetD3D9DeviceManager();
   if (!dm || !dm->device()) {
     return false;
   }
 
   if (!mTexture) {
     mTexture = dm->CreateTexture(mSize, SurfaceFormatToD3D9Format(mFormat),
                                  D3DPOOL_DEFAULT, this);
     if (!mTexture) {
--- a/gfx/thebes/gfxWindowsPlatform.cpp
+++ b/gfx/thebes/gfxWindowsPlatform.cpp
@@ -1381,48 +1381,52 @@ gfxWindowsPlatform::SetupClearTypeParams
             getter_AddRefs(mRenderingParams[TEXT_RENDERING_GDI_CLASSIC]));
     }
 }
 
 void
 gfxWindowsPlatform::OnDeviceManagerDestroy(DeviceManagerD3D9* aDeviceManager)
 {
   if (aDeviceManager == mDeviceManager) {
+    MutexAutoLock lock(mDeviceLock);
     mDeviceManager = nullptr;
   }
 }
 
 IDirect3DDevice9*
 gfxWindowsPlatform::GetD3D9Device()
 {
-  DeviceManagerD3D9* manager = GetD3D9DeviceManager();
+  RefPtr<DeviceManagerD3D9> manager = GetD3D9DeviceManager();
   return manager ? manager->device() : nullptr;
 }
 
 void
 gfxWindowsPlatform::D3D9DeviceReset() {
   mHasD3D9DeviceReset = true;
 }
 
-DeviceManagerD3D9*
+already_AddRefed<DeviceManagerD3D9>
 gfxWindowsPlatform::GetD3D9DeviceManager()
 {
   // We should only create the d3d9 device on the compositor thread
   // or we don't have a compositor thread.
+  RefPtr<DeviceManagerD3D9> result;
   if (!mDeviceManager &&
       (!gfxPlatform::UsesOffMainThreadCompositing() ||
        CompositorBridgeParent::IsInCompositorThread())) {
     mDeviceManager = new DeviceManagerD3D9();
     if (!mDeviceManager->Init()) {
       gfxCriticalError() << "[D3D9] Could not Initialize the DeviceManagerD3D9";
       mDeviceManager = nullptr;
     }
   }
 
-  return mDeviceManager;
+  MutexAutoLock lock(mDeviceLock);
+  result = mDeviceManager;
+  return result.forget();
 }
 
 bool
 gfxWindowsPlatform::GetD3D11Device(RefPtr<ID3D11Device>* aOutDevice)
 {
   MutexAutoLock lock(mDeviceLock);
   *aOutDevice = mD3D11Device;
   return !!mD3D11Device;
--- a/gfx/thebes/gfxWindowsPlatform.h
+++ b/gfx/thebes/gfxWindowsPlatform.h
@@ -205,17 +205,17 @@ public:
     IDWriteRenderingParams *GetRenderingParams(TextRenderingMode aRenderMode)
     { return mRenderingParams[aRenderMode]; }
 
     bool GetD3D11Device(RefPtr<ID3D11Device>* aOutDevice);
     bool GetD3D11DeviceForCurrentThread(RefPtr<ID3D11Device>* aOutDevice);
     bool GetD3D11ImageBridgeDevice(RefPtr<ID3D11Device>* aOutDevice);
 
     void OnDeviceManagerDestroy(mozilla::layers::DeviceManagerD3D9* aDeviceManager);
-    mozilla::layers::DeviceManagerD3D9* GetD3D9DeviceManager();
+    already_AddRefed<mozilla::layers::DeviceManagerD3D9> GetD3D9DeviceManager();
     IDirect3DDevice9* GetD3D9Device();
     void D3D9DeviceReset();
     ID3D11Device *GetD3D11ContentDevice();
 
     // Create a D3D11 device to be used for DXVA decoding.
     already_AddRefed<ID3D11Device> CreateD3D11DecoderDevice();
     bool CreateD3D11DecoderDeviceHelper(
       IDXGIAdapter1* aAdapter, RefPtr<ID3D11Device>& aDevice,