Bug 1465306 - Make D3D11YCbCrRecycleAllocator handle device reset r=nical
authorsotaro <sotaro.ikeda.g@gmail.com>
Thu, 31 May 2018 09:35:24 +0900
changeset 420553 c71e5c7d684ed72b815e00b33c4289d35d2284ca
parent 420552 c8429320386e60f8da51d3df151fbb2c3abc2c99
child 420554 0025e7906c15066a48ac474e61cc7815f7a134cb
push id103830
push usersikeda@mozilla.com
push dateThu, 31 May 2018 00:35:36 +0000
treeherdermozilla-inbound@c71e5c7d684e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnical
bugs1465306
milestone62.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 1465306 - Make D3D11YCbCrRecycleAllocator handle device reset r=nical
gfx/layers/D3D11YCbCrImage.cpp
gfx/layers/D3D11YCbCrImage.h
gfx/layers/ImageContainer.cpp
gfx/thebes/DeviceManagerDx.cpp
gfx/thebes/DeviceManagerDx.h
--- a/gfx/layers/D3D11YCbCrImage.cpp
+++ b/gfx/layers/D3D11YCbCrImage.cpp
@@ -2,16 +2,17 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "D3D11YCbCrImage.h"
 #include "YCbCrUtils.h"
 #include "mozilla/gfx/gfxVars.h"
+#include "mozilla/gfx/DeviceManagerDx.h"
 #include "mozilla/layers/CompositableClient.h"
 #include "mozilla/layers/CompositableForwarder.h"
 #include "mozilla/layers/TextureD3D11.h"
 
 using namespace mozilla::gfx;
 
 namespace mozilla {
 namespace layers {
@@ -51,50 +52,55 @@ D3D11YCbCrImage::SetData(KnowsCompositor
   mColorSpace = aData.mYUVColorSpace;
 
   D3D11YCbCrRecycleAllocator* allocator =
     aContainer->GetD3D11YCbCrRecycleAllocator(aAllocator);
   if (!allocator) {
     return false;
   }
 
+  RefPtr<ID3D11Device> device = gfx::DeviceManagerDx::Get()->GetImageDevice();
+  if (!device) {
+    return false;
+  }
+
   {
-    DXGIYCbCrTextureAllocationHelper helper(aData, TextureFlags::DEFAULT, allocator->GetDevice());
+    DXGIYCbCrTextureAllocationHelper helper(aData, TextureFlags::DEFAULT, device);
     mTextureClient = allocator->CreateOrRecycle(helper);
   }
 
   if (!mTextureClient) {
     return false;
   }
 
   DXGIYCbCrTextureData* data =
     mTextureClient->GetInternalData()->AsDXGIYCbCrTextureData();
 
   ID3D11Texture2D* textureY = data->GetD3D11Texture(0);
   ID3D11Texture2D* textureCb = data->GetD3D11Texture(1);
   ID3D11Texture2D* textureCr = data->GetD3D11Texture(2);
 
   RefPtr<ID3D10Multithread> mt;
-  HRESULT hr = allocator->GetDevice()->QueryInterface(
+  HRESULT hr = device->QueryInterface(
     (ID3D10Multithread**)getter_AddRefs(mt));
 
   if (FAILED(hr) || !mt) {
     gfxCriticalError() << "Multithread safety interface not supported. " << hr;
     return false;
   }
 
   if (!mt->GetMultithreadProtected()) {
     gfxCriticalError() << "Device used not marked as multithread-safe.";
     return false;
   }
 
   D3D11MTAutoEnter mtAutoEnter(mt.forget());
 
   RefPtr<ID3D11DeviceContext> ctx;
-  allocator->GetDevice()->GetImmediateContext(getter_AddRefs(ctx));
+  device->GetImmediateContext(getter_AddRefs(ctx));
   if (!ctx) {
     gfxCriticalError() << "Failed to get immediate context.";
     return false;
   }
 
   AutoLockD3D11Texture lockY(textureY);
   AutoLockD3D11Texture lockCb(textureCb);
   AutoLockD3D11Texture lockCr(textureCr);
@@ -318,16 +324,24 @@ DXGIYCbCrTextureAllocationHelper::IsComp
   DXGIYCbCrTextureData* dxgiData = aTextureClient->GetInternalData()->AsDXGIYCbCrTextureData();
   if (!dxgiData ||
       aTextureClient->GetSize() != mData.mYSize ||
       dxgiData->GetYSize() != mData.mYSize ||
       dxgiData->GetCbCrSize() != mData.mCbCrSize ||
       dxgiData->GetYUVColorSpace() != mData.mYUVColorSpace) {
     return false;
   }
+
+  RefPtr<ID3D11Texture2D> texY = dxgiData->GetD3D11Texture(0);
+  RefPtr<ID3D11Device> device;
+  texY->GetDevice(getter_AddRefs(device));
+  if (!device || device != gfx::DeviceManagerDx::Get()->GetImageDevice()) {
+    return false;
+  }
+
   return true;
 }
 
 already_AddRefed<TextureClient>
 DXGIYCbCrTextureAllocationHelper::Allocate(KnowsCompositor* aAllocator)
 {
   CD3D11_TEXTURE2D_DESC newDesc(DXGI_FORMAT_R8_UNORM, mData.mYSize.width, mData.mYSize.height,
                                 1, 1);
--- a/gfx/layers/D3D11YCbCrImage.h
+++ b/gfx/layers/D3D11YCbCrImage.h
@@ -20,35 +20,30 @@ namespace layers {
 
 class ImageContainer;
 class DXGIYCbCrTextureClient;
 class DXGIYCbCrTextureData;
 
 class D3D11YCbCrRecycleAllocator : public TextureClientRecycleAllocator
 {
 public:
-  explicit D3D11YCbCrRecycleAllocator(KnowsCompositor* aAllocator,
-                                      ID3D11Device* aDevice)
+  explicit D3D11YCbCrRecycleAllocator(KnowsCompositor* aAllocator)
     : TextureClientRecycleAllocator(aAllocator)
-    , mDevice(aDevice)
   {
   }
 
-  ID3D11Device* GetDevice() const { return mDevice; }
   KnowsCompositor* GetAllocator() const { return mSurfaceAllocator; }
 
 protected:
   already_AddRefed<TextureClient>
   Allocate(gfx::SurfaceFormat aFormat,
            gfx::IntSize aSize,
            BackendSelector aSelector,
            TextureFlags aTextureFlags,
            TextureAllocationFlags aAllocFlags) override;
-
-  RefPtr<ID3D11Device> mDevice;
 };
 
 class D3D11YCbCrImage : public Image
 {
   friend class gl::GLBlitHelper;
 public:
   D3D11YCbCrImage();
   virtual ~D3D11YCbCrImage();
--- a/gfx/layers/ImageContainer.cpp
+++ b/gfx/layers/ImageContainer.cpp
@@ -467,36 +467,23 @@ ImageContainer::NotifyComposite(const Im
 D3D11YCbCrRecycleAllocator*
 ImageContainer::GetD3D11YCbCrRecycleAllocator(KnowsCompositor* aAllocator)
 {
   if (mD3D11YCbCrRecycleAllocator &&
       aAllocator == mD3D11YCbCrRecycleAllocator->GetAllocator()) {
     return mD3D11YCbCrRecycleAllocator;
   }
 
-  RefPtr<ID3D11Device> device = gfx::DeviceManagerDx::Get()->GetContentDevice();
-  if (!device) {
-    device = gfx::DeviceManagerDx::Get()->GetCompositorDevice();
-  }
-
-  if (!device || !aAllocator->SupportsD3D11()) {
+  if (!aAllocator->SupportsD3D11() ||
+      !gfx::DeviceManagerDx::Get()->GetImageDevice()) {
     return nullptr;
   }
 
-  RefPtr<ID3D10Multithread> multi;
-  HRESULT hr =
-    device->QueryInterface((ID3D10Multithread**)getter_AddRefs(multi));
-  if (FAILED(hr) || !multi) {
-    gfxWarning() << "Multithread safety interface not supported. " << hr;
-    return nullptr;
-  }
-  multi->SetMultithreadProtected(TRUE);
-
   mD3D11YCbCrRecycleAllocator =
-    new D3D11YCbCrRecycleAllocator(aAllocator, device);
+    new D3D11YCbCrRecycleAllocator(aAllocator);
   return mD3D11YCbCrRecycleAllocator;
 }
 #endif
 
 PlanarYCbCrImage::PlanarYCbCrImage()
   : Image(nullptr, ImageFormat::PLANAR_YCBCR)
   , mOffscreenFormat(SurfaceFormat::UNKNOWN)
   , mBufferSize(0)
--- a/gfx/thebes/DeviceManagerDx.cpp
+++ b/gfx/thebes/DeviceManagerDx.cpp
@@ -862,16 +862,17 @@ DeviceManagerDx::ResetDevices()
 
   MutexAutoLock lock(mDeviceLock);
 
   mAdapter = nullptr;
   mCompositorAttachments = nullptr;
   mMLGDevice = nullptr;
   mCompositorDevice = nullptr;
   mContentDevice = nullptr;
+  mImageDevice = nullptr;
   mDeviceStatus = Nothing();
   mDeviceResetReason = Nothing();
   Factory::SetDirect3D11Device(nullptr);
 }
 
 bool
 DeviceManagerDx::MaybeResetAndReacquireDevices()
 {
@@ -1049,16 +1050,47 @@ DeviceManagerDx::GetCompositorDevice()
 RefPtr<ID3D11Device>
 DeviceManagerDx::GetContentDevice()
 {
   MutexAutoLock lock(mDeviceLock);
   return mContentDevice;
 }
 
 RefPtr<ID3D11Device>
+DeviceManagerDx::GetImageDevice()
+{
+  MutexAutoLock lock(mDeviceLock);
+  if (mImageDevice) {
+    return mImageDevice;
+  }
+
+  RefPtr<ID3D11Device> device = mContentDevice;
+  if (!device) {
+    device = mCompositorDevice;
+  }
+
+  if (!device) {
+    return nullptr;
+  }
+
+  RefPtr<ID3D10Multithread> multi;
+  HRESULT hr =
+    device->QueryInterface((ID3D10Multithread**)getter_AddRefs(multi));
+  if (FAILED(hr) || !multi) {
+    gfxWarning() << "Multithread safety interface not supported. " << hr;
+    return nullptr;
+  }
+  multi->SetMultithreadProtected(TRUE);
+
+  mImageDevice = device;
+
+  return mImageDevice;
+}
+
+RefPtr<ID3D11Device>
 DeviceManagerDx::GetVRDevice()
 {
   MutexAutoLock lock(mDeviceLock);
   if (!mVRDevice) {
     CreateVRDevice();
   }
   return mVRDevice;
 }
--- a/gfx/thebes/DeviceManagerDx.h
+++ b/gfx/thebes/DeviceManagerDx.h
@@ -53,16 +53,17 @@ public:
   DeviceManagerDx();
 
   static DeviceManagerDx* Get() {
     return sInstance;
   }
 
   RefPtr<ID3D11Device> GetCompositorDevice();
   RefPtr<ID3D11Device> GetContentDevice();
+  RefPtr<ID3D11Device> GetImageDevice();
   RefPtr<IDCompositionDevice> GetDirectCompositionDevice();
   RefPtr<ID3D11Device> GetVRDevice();
   RefPtr<ID3D11Device> CreateDecoderDevice();
   RefPtr<layers::MLGDevice> GetMLGDevice();
   IDirectDraw7* GetDirectDraw();
 
   unsigned GetCompositorFeatureLevel() const;
   bool TextureSharingWorks();
@@ -158,16 +159,17 @@ private:
 
   nsModuleHandle mDcompModule;
 
   mozilla::Mutex mDeviceLock;
   nsTArray<D3D_FEATURE_LEVEL> mFeatureLevels;
   RefPtr<IDXGIAdapter1> mAdapter;
   RefPtr<ID3D11Device> mCompositorDevice;
   RefPtr<ID3D11Device> mContentDevice;
+  RefPtr<ID3D11Device> mImageDevice;
   RefPtr<ID3D11Device> mVRDevice;
   RefPtr<ID3D11Device> mDecoderDevice;
   RefPtr<IDCompositionDevice> mDirectCompositionDevice;
 
   RefPtr<layers::DeviceAttachmentsD3D11> mCompositorAttachments;
   RefPtr<layers::MLGDevice> mMLGDevice;
   bool mCompositorDeviceSupportsVideo;