From a6c0c60716c2b54272a93985c3e75fd8dd9dc68c Mon Sep 17 00:00:00 2001 From: Matt Woodrow Date: Tue, 2 Aug 2016 18:46:27 +1200 Subject: [PATCH] Bug 1284672 - Try use an exsiting D3D11 device for video rather than creating new ones. r=dvander --HG-- extra : rebase_source : 0e9b01742f1726bf385bf28257392415a09360bd --- gfx/thebes/DeviceManagerD3D11.cpp | 99 +++++++++++++++++++++++-------- gfx/thebes/DeviceManagerD3D11.h | 10 +++- 2 files changed, 82 insertions(+), 27 deletions(-) diff --git a/gfx/thebes/DeviceManagerD3D11.cpp b/gfx/thebes/DeviceManagerD3D11.cpp index 156773d8fe89..133abe8d17b1 100644 --- a/gfx/thebes/DeviceManagerD3D11.cpp +++ b/gfx/thebes/DeviceManagerD3D11.cpp @@ -45,7 +45,8 @@ DeviceManagerD3D11::Shutdown() DeviceManagerD3D11::DeviceManagerD3D11() : mDeviceLock("gfxWindowsPlatform.mDeviceLock"), mIsWARP(false), - mTextureSharingWorks(false) + mTextureSharingWorks(false), + mCompositorDeviceSupportsVideo(false) { // Set up the D3D11 feature levels we can ask for. if (IsWin8OrLater()) { @@ -211,16 +212,20 @@ DeviceManagerD3D11::GetDXGIAdapter() } bool -DeviceManagerD3D11::AttemptD3D11DeviceCreationHelper( - IDXGIAdapter1* aAdapter, RefPtr& aOutDevice, HRESULT& aResOut) +DeviceManagerD3D11::AttemptD3D11DeviceCreationHelperInner( + IDXGIAdapter1* aAdapter, bool aAttemptVideoSupport, RefPtr& aOutDevice, HRESULT& aResOut) { + // Use D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS + // to prevent bug 1092260. IE 11 also uses this flag. + UINT flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT | D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS; + if (aAttemptVideoSupport) { + flags |= D3D11_CREATE_DEVICE_VIDEO_SUPPORT; + } + MOZ_SEH_TRY { aResOut = sD3D11CreateDeviceFn( - aAdapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr, - // Use D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS - // to prevent bug 1092260. IE 11 also uses this flag. - D3D11_CREATE_DEVICE_BGRA_SUPPORT | D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS, + aAdapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr, flags, mFeatureLevels.Elements(), mFeatureLevels.Length(), D3D11_SDK_VERSION, getter_AddRefs(aOutDevice), nullptr, nullptr); } MOZ_SEH_EXCEPT (EXCEPTION_EXECUTE_HANDLER) { @@ -229,6 +234,41 @@ DeviceManagerD3D11::AttemptD3D11DeviceCreationHelper( return true; } +bool +DeviceManagerD3D11::AttemptD3D11DeviceCreationHelper( + FeatureState& aD3d11, IDXGIAdapter1* aAdapter, bool aAttemptVideoSupport, RefPtr& aOutDevice) +{ + HRESULT hr; + RefPtr device; + if (!AttemptD3D11DeviceCreationHelperInner(aAdapter, aAttemptVideoSupport, device, hr)) { + if (!aAttemptVideoSupport) { + gfxCriticalError() << "Crash during D3D11 device creation"; + aD3d11.SetFailed(FeatureStatus::CrashedInHandler, "Crashed trying to acquire a D3D11 device", + NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_DEVICE1")); + } + return false; + } + + if (FAILED(hr) || !device) { + if (!aAttemptVideoSupport) { + gfxCriticalError() << "D3D11 device creation failed: " << hexa(hr); + aD3d11.SetFailed(FeatureStatus::Failed, "Failed to acquire a D3D11 device", + NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_DEVICE2")); + } + return false; + } + if (!D3D11Checks::DoesDeviceWork()) { + if (!aAttemptVideoSupport) { + aD3d11.SetFailed(FeatureStatus::Broken, "Direct3D11 device was determined to be broken", + NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_BROKEN")); + } + return false; + } + + aOutDevice = device; + return true; +} + void DeviceManagerD3D11::AttemptD3D11DeviceCreation(FeatureState& d3d11) { @@ -239,25 +279,15 @@ DeviceManagerD3D11::AttemptD3D11DeviceCreation(FeatureState& d3d11) return; } - HRESULT hr; RefPtr device; - if (!AttemptD3D11DeviceCreationHelper(adapter, device, hr)) { - gfxCriticalError() << "Crash during D3D11 device creation"; - d3d11.SetFailed(FeatureStatus::CrashedInHandler, "Crashed trying to acquire a D3D11 device", - NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_DEVICE1")); - return; - } - - if (FAILED(hr) || !device) { - gfxCriticalError() << "D3D11 device creation failed: " << hexa(hr); - d3d11.SetFailed(FeatureStatus::Failed, "Failed to acquire a D3D11 device", - NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_DEVICE2")); - return; - } - if (!D3D11Checks::DoesDeviceWork()) { - d3d11.SetFailed(FeatureStatus::Broken, "Direct3D11 device was determined to be broken", - NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_BROKEN")); - return; + if (!AttemptD3D11DeviceCreationHelper(d3d11, adapter, true, device)) { + // Try again without video support and record that it failed. + mCompositorDeviceSupportsVideo = false; + if (!AttemptD3D11DeviceCreationHelper(d3d11, adapter, false, device)) { + return; + } + } else { + mCompositorDeviceSupportsVideo = true; } { @@ -424,7 +454,7 @@ DeviceManagerD3D11::CreateD3D11DecoderDeviceHelper( aResOut = sD3D11CreateDeviceFn( aAdapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr, - D3D11_CREATE_DEVICE_VIDEO_SUPPORT, + D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS | D3D11_CREATE_DEVICE_VIDEO_SUPPORT, mFeatureLevels.Elements(), mFeatureLevels.Length(), D3D11_SDK_VERSION, getter_AddRefs(aDevice), nullptr, nullptr); @@ -437,6 +467,21 @@ DeviceManagerD3D11::CreateD3D11DecoderDeviceHelper( RefPtr DeviceManagerD3D11::CreateDecoderDevice() { + if (mCompositorDevice && mCompositorDeviceSupportsVideo && !mDecoderDevice) { + mDecoderDevice = mCompositorDevice; + + RefPtr multi; + mDecoderDevice->QueryInterface(__uuidof(ID3D10Multithread), getter_AddRefs(multi)); + if (multi) { + multi->SetMultithreadProtected(TRUE); + } + } + + if (mDecoderDevice) { + RefPtr dev = mDecoderDevice; + return dev.forget(); + } + if (!sD3D11CreateDeviceFn) { // We should just be on Windows Vista or XP in this case. return nullptr; @@ -461,6 +506,8 @@ DeviceManagerD3D11::CreateDecoderDevice() device->QueryInterface(__uuidof(ID3D10Multithread), getter_AddRefs(multi)); multi->SetMultithreadProtected(TRUE); + + mDecoderDevice = device; return device; } diff --git a/gfx/thebes/DeviceManagerD3D11.h b/gfx/thebes/DeviceManagerD3D11.h index d069377c9ecd..d20c415f221d 100644 --- a/gfx/thebes/DeviceManagerD3D11.h +++ b/gfx/thebes/DeviceManagerD3D11.h @@ -68,10 +68,16 @@ private: void DisableD3D11AfterCrash(); void AttemptD3D11DeviceCreation(mozilla::gfx::FeatureState& d3d11); - bool AttemptD3D11DeviceCreationHelper( + bool AttemptD3D11DeviceCreationHelperInner( IDXGIAdapter1* aAdapter, + bool aAttemptVideoSupport, RefPtr& aOutDevice, HRESULT& aResOut); + bool AttemptD3D11DeviceCreationHelper( + mozilla::gfx::FeatureState& aD3d11, + IDXGIAdapter1* aAdapter, + bool aAttemptVideoSupport, + RefPtr& aOutDevice); void AttemptWARPDeviceCreation(); bool AttemptWARPDeviceCreationHelper( @@ -98,8 +104,10 @@ private: RefPtr mAdapter; RefPtr mCompositorDevice; RefPtr mContentDevice; + RefPtr mDecoderDevice; mozilla::Atomic mIsWARP; mozilla::Atomic mTextureSharingWorks; + bool mCompositorDeviceSupportsVideo; }; } // namespace gfx