Bug 1153123 - Don't upload in the ImageBridge thread if A8 texture sharing is broken. r=Bas
☠☠ backed out by 38d40bcd0c46 ☠ ☠
authorMatt Woodrow <mwoodrow@mozilla.com>
Wed, 13 May 2015 23:42:32 +1200
changeset 244137 75502ee740e0d5f02a01d45311d946053014c378
parent 244136 1184021538f6ba44d79a18ff11eae5b5e6b6df2a
child 244138 36d9c1b097a8c8bfb04d3048e6c7b213d8597ee7
push id59845
push usermwoodrow@mozilla.com
push dateSat, 16 May 2015 01:22:55 +0000
treeherdermozilla-inbound@75502ee740e0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersBas
bugs1153123
milestone41.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 1153123 - Don't upload in the ImageBridge thread if A8 texture sharing is broken. r=Bas
gfx/layers/IMFYCbCrImage.cpp
gfx/thebes/gfxWindowsPlatform.cpp
gfx/thebes/gfxWindowsPlatform.h
--- a/gfx/layers/IMFYCbCrImage.cpp
+++ b/gfx/layers/IMFYCbCrImage.cpp
@@ -203,19 +203,19 @@ IMFYCbCrImage::GetD3D9TextureClient(Comp
                                                   mData.mCbCrSize);
 
   return mTextureClient;
 }
 
 TextureClient*
 IMFYCbCrImage::GetTextureClient(CompositableClient* aClient)
 {
-  ID3D11Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D11MediaDevice();
+  ID3D11Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D11ImageBridgeDevice();
   if (!device ||
-    aClient->GetForwarder()->GetCompositorBackendType() != LayersBackend::LAYERS_D3D11) {
+      aClient->GetForwarder()->GetCompositorBackendType() != LayersBackend::LAYERS_D3D11) {
 
     IDirect3DDevice9* d3d9device = gfxWindowsPlatform::GetPlatform()->GetD3D9Device();
     if (d3d9device && aClient->GetForwarder()->GetCompositorBackendType() == LayersBackend::LAYERS_D3D9) {
       return GetD3D9TextureClient(aClient);
     }
     return nullptr;
   }
 
--- a/gfx/thebes/gfxWindowsPlatform.cpp
+++ b/gfx/thebes/gfxWindowsPlatform.cpp
@@ -406,17 +406,16 @@ public:
   }
 };
 
 NS_IMPL_ISUPPORTS(D3D9SharedTextureReporter, nsIMemoryReporter)
 
 gfxWindowsPlatform::gfxWindowsPlatform()
   : mD3D11DeviceInitialized(false)
   , mIsWARP(false)
-  , mCanInitMediaDevice(false)
   , mHasDeviceReset(false)
 {
     mUseClearTypeForDownloadableFonts = UNINITIALIZED_VALUE;
     mUseClearTypeAlways = UNINITIALIZED_VALUE;
 
     mUsingGDIFonts = false;
 
     /* 
@@ -1595,65 +1594,25 @@ gfxWindowsPlatform::GetD3D11ContentDevic
   }
 
   InitD3D11Devices();
 
   return mD3D11ContentDevice;
 }
 
 ID3D11Device*
-gfxWindowsPlatform::GetD3D11MediaDevice()
+gfxWindowsPlatform::GetD3D11ImageBridgeDevice()
 {
-  if (mD3D11MediaDevice) {
-    return mD3D11MediaDevice;
-  }
-
-  if (!mCanInitMediaDevice) {
-    return nullptr;
+  if (mD3D11DeviceInitialized) {
+    return mD3D11ImageBridgeDevice;
   }
 
-  mCanInitMediaDevice = false;
-
-  nsModuleHandle d3d11Module(LoadLibrarySystem32(L"d3d11.dll"));
-  decltype(D3D11CreateDevice)* d3d11CreateDevice = (decltype(D3D11CreateDevice)*)
-    GetProcAddress(d3d11Module, "D3D11CreateDevice");
-  MOZ_ASSERT(d3d11CreateDevice);
-
-  nsTArray<D3D_FEATURE_LEVEL> featureLevels;
-  if (IsWin8OrLater()) {
-    featureLevels.AppendElement(D3D_FEATURE_LEVEL_11_1);
-  }
-  featureLevels.AppendElement(D3D_FEATURE_LEVEL_11_0);
-  featureLevels.AppendElement(D3D_FEATURE_LEVEL_10_1);
-  featureLevels.AppendElement(D3D_FEATURE_LEVEL_10_0);
-  featureLevels.AppendElement(D3D_FEATURE_LEVEL_9_3);
-
-  RefPtr<IDXGIAdapter1> adapter = GetDXGIAdapter();
-  MOZ_ASSERT(adapter);
+  InitD3D11Devices();
 
-  HRESULT hr = E_INVALIDARG;
-
-  MOZ_SEH_TRY{
-    hr = d3d11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr,
-                           D3D11_CREATE_DEVICE_BGRA_SUPPORT,
-                           featureLevels.Elements(), featureLevels.Length(),
-                           D3D11_SDK_VERSION, byRef(mD3D11MediaDevice), nullptr, nullptr);
-  } MOZ_SEH_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
-    mD3D11MediaDevice = nullptr;
-  }
-
-  d3d11Module.disown();
-
-  if (FAILED(hr)) {
-    return nullptr;
-  }
-
-  mD3D11MediaDevice->SetExceptionMode(0);
-
-  return mD3D11MediaDevice;
+  return mD3D11ImageBridgeDevice;
 }
 
 
 ReadbackManagerD3D11*
 gfxWindowsPlatform::GetReadbackManager()
 {
   if (!mD3D11ReadbackManager) {
     mD3D11ReadbackManager = new ReadbackManagerD3D11();
@@ -1771,29 +1730,21 @@ bool DoesD3D11DeviceWork(ID3D11Device *d
     }
   }
   result = true;
   return true;
 }
 
 // See bug 1083071. On some drivers, Direct3D 11 CreateShaderResourceView fails
 // with E_OUTOFMEMORY.
-bool DoesD3D11TextureSharingWork(ID3D11Device *device)
+bool DoesD3D11TextureSharingWorkInternal(ID3D11Device *device, ID3D11Device *dest, DXGI_FORMAT format)
 {
-  static bool checked = false;
-  static bool result = false;
-
-  if (checked)
-      return result;
-  checked = true;
-
   if (gfxPrefs::Direct2DForceEnabled() ||
       gfxPrefs::LayersAccelerationForceEnabled())
   {
-    result = true;
     return true;
   }
 
   if (GetModuleHandleW(L"atidxx32.dll")) {
     nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
     if (gfxInfo) {
       nsString vendorID, vendorID2;
       gfxInfo->GetAdapterVendorID(vendorID);
@@ -1808,17 +1759,17 @@ bool DoesD3D11TextureSharingWork(ID3D11D
   }
 
   RefPtr<ID3D11Texture2D> texture;
   D3D11_TEXTURE2D_DESC desc;
   desc.Width = 32;
   desc.Height = 32;
   desc.MipLevels = 1;
   desc.ArraySize = 1;
-  desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
+  desc.Format = format;
   desc.SampleDesc.Count = 1;
   desc.SampleDesc.Quality = 0;
   desc.Usage = D3D11_USAGE_DEFAULT;
   desc.CPUAccessFlags = 0;
   desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
   desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
   if (FAILED(device->CreateTexture2D(&desc, NULL, byRef(texture)))) {
     return false;
@@ -1833,42 +1784,54 @@ bool DoesD3D11TextureSharingWork(ID3D11D
   }
 
   if (FAILED(otherResource->GetSharedHandle(&shareHandle))) {
     return false;
   }
 
   nsRefPtr<ID3D11Resource> sharedResource;
   nsRefPtr<ID3D11Texture2D> sharedTexture;
-  if (FAILED(device->OpenSharedResource(shareHandle, __uuidof(ID3D11Resource),
-                                        getter_AddRefs(sharedResource))))
+  if (FAILED(dest->OpenSharedResource(shareHandle, __uuidof(ID3D11Resource),
+                                      getter_AddRefs(sharedResource))))
   {
     return false;
   }
 
   if (FAILED(sharedResource->QueryInterface(__uuidof(ID3D11Texture2D),
                                             getter_AddRefs(sharedTexture))))
   {
     return false;
   }
 
   RefPtr<ID3D11ShaderResourceView> sharedView;
 
   // This if(FAILED()) is the one that actually fails on systems affected by bug 1083071.
-  if (FAILED(device->CreateShaderResourceView(sharedTexture, NULL, byRef(sharedView)))) {
+  if (FAILED(dest->CreateShaderResourceView(sharedTexture, NULL, byRef(sharedView)))) {
 #if defined(MOZ_CRASHREPORTER)
     CrashReporter::AppendAppNotesToCrashReport(NS_LITERAL_CSTRING("CreateShaderResourceView failed\n"));
 #endif
     return false;
   }
 
-  result = true;
   return true;
 }
 
+bool DoesD3D11TextureSharingWork(ID3D11Device *device)
+{
+  static bool checked;
+  static bool result;
+
+  if (checked)
+    return result;
+  checked = true;
+
+  result = DoesD3D11TextureSharingWorkInternal(device, device, DXGI_FORMAT_B8G8R8A8_UNORM);
+  return result;
+}
+
 void
 gfxWindowsPlatform::InitD3D11Devices()
 {
   // This function attempts to initialize our D3D11 devices. If the hardware
   // is not blacklisted for D3D11 layers. This will first attempt to create a
   // hardware accelerated device. If this creation fails or the hardware is
   // blacklisted, then this function will abort if WARP is disabled, causing us
   // to fallback to D3D9 or Basic layers. If WARP is not disabled it will use
@@ -2019,17 +1982,37 @@ gfxWindowsPlatform::InitD3D11Devices()
     }
 
     mD3D11ContentDevice->SetExceptionMode(0);
 
     Factory::SetDirect3D11Device(mD3D11ContentDevice);
   }
 
   if (!useWARP) {
-    mCanInitMediaDevice = true;
+    hr = E_INVALIDARG;
+
+    MOZ_SEH_TRY{
+      hr = d3d11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr,
+                             D3D11_CREATE_DEVICE_BGRA_SUPPORT,
+                             featureLevels.Elements(), featureLevels.Length(),
+                             D3D11_SDK_VERSION, byRef(mD3D11ImageBridgeDevice), nullptr, nullptr);
+    } MOZ_SEH_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
+      mD3D11ImageBridgeDevice = nullptr;
+    }
+
+    if (FAILED(hr)) {
+      d3d11Module.disown();
+      return;
+    }
+
+    mD3D11ImageBridgeDevice->SetExceptionMode(0);
+
+    if (!DoesD3D11TextureSharingWorkInternal(mD3D11ImageBridgeDevice, mD3D11Device, DXGI_FORMAT_A8_UNORM)) {
+      mD3D11ImageBridgeDevice = nullptr;
+    }
   }
 
   // We leak these everywhere and we need them our entire runtime anyway, let's
   // leak it here as well.
   d3d11Module.disown();
 }
 
 TemporaryRef<ID3D11Device>
--- a/gfx/thebes/gfxWindowsPlatform.h
+++ b/gfx/thebes/gfxWindowsPlatform.h
@@ -239,17 +239,18 @@ public:
     mozilla::layers::DeviceManagerD3D9* GetD3D9DeviceManager();
     IDirect3DDevice9* GetD3D9Device();
 #ifdef CAIRO_HAS_D2D_SURFACE
     cairo_device_t *GetD2DDevice() { return mD2DDevice; }
     ID3D10Device1 *GetD3D10Device() { return mD2DDevice ? cairo_d2d_device_get_device(mD2DDevice) : nullptr; }
 #endif
     ID3D11Device *GetD3D11Device();
     ID3D11Device *GetD3D11ContentDevice();
-    ID3D11Device *GetD3D11MediaDevice();
+    // Device to be used on the ImageBridge thread
+    ID3D11Device *GetD3D11ImageBridgeDevice();
 
     // Create a D3D11 device to be used for DXVA decoding.
     mozilla::TemporaryRef<ID3D11Device> CreateD3D11DecoderDevice();
 
     mozilla::layers::ReadbackManagerD3D11* GetReadbackManager();
 
     static bool IsOptimus();
 
@@ -289,21 +290,20 @@ private:
 #endif
 #ifdef CAIRO_HAS_D2D_SURFACE
     cairo_device_t *mD2DDevice;
 #endif
     mozilla::RefPtr<IDXGIAdapter1> mAdapter;
     nsRefPtr<mozilla::layers::DeviceManagerD3D9> mDeviceManager;
     mozilla::RefPtr<ID3D11Device> mD3D11Device;
     mozilla::RefPtr<ID3D11Device> mD3D11ContentDevice;
-    mozilla::RefPtr<ID3D11Device> mD3D11MediaDevice;
+    mozilla::RefPtr<ID3D11Device> mD3D11ImageBridgeDevice;
     bool mD3D11DeviceInitialized;
     mozilla::RefPtr<mozilla::layers::ReadbackManagerD3D11> mD3D11ReadbackManager;
     bool mIsWARP;
-    bool mCanInitMediaDevice;
     bool mHasDeviceReset;
     DeviceResetReason mDeviceResetReason;
 
     virtual void GetPlatformCMSOutputProfile(void* &mem, size_t &size);
 };
 
 bool DoesD3D11TextureSharingWork(ID3D11Device *device);
 bool DoesD3D11DeviceWork(ID3D11Device *device);