Bug 1284672 - Try use an exsiting D3D11 device for video rather than creating new ones. r=dvander

--HG--
extra : rebase_source : 0e9b01742f1726bf385bf28257392415a09360bd
This commit is contained in:
Matt Woodrow 2016-08-02 18:46:27 +12:00
Родитель 0917ac7c50
Коммит a6c0c60716
2 изменённых файлов: 82 добавлений и 27 удалений

Просмотреть файл

@ -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<ID3D11Device>& aOutDevice, HRESULT& aResOut)
DeviceManagerD3D11::AttemptD3D11DeviceCreationHelperInner(
IDXGIAdapter1* aAdapter, bool aAttemptVideoSupport, RefPtr<ID3D11Device>& 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<ID3D11Device>& aOutDevice)
{
HRESULT hr;
RefPtr<ID3D11Device> 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<ID3D11Device> 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<ID3D11Device>
DeviceManagerD3D11::CreateDecoderDevice()
{
if (mCompositorDevice && mCompositorDeviceSupportsVideo && !mDecoderDevice) {
mDecoderDevice = mCompositorDevice;
RefPtr<ID3D10Multithread> multi;
mDecoderDevice->QueryInterface(__uuidof(ID3D10Multithread), getter_AddRefs(multi));
if (multi) {
multi->SetMultithreadProtected(TRUE);
}
}
if (mDecoderDevice) {
RefPtr<ID3D11Device> 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;
}

Просмотреть файл

@ -68,10 +68,16 @@ private:
void DisableD3D11AfterCrash();
void AttemptD3D11DeviceCreation(mozilla::gfx::FeatureState& d3d11);
bool AttemptD3D11DeviceCreationHelper(
bool AttemptD3D11DeviceCreationHelperInner(
IDXGIAdapter1* aAdapter,
bool aAttemptVideoSupport,
RefPtr<ID3D11Device>& aOutDevice,
HRESULT& aResOut);
bool AttemptD3D11DeviceCreationHelper(
mozilla::gfx::FeatureState& aD3d11,
IDXGIAdapter1* aAdapter,
bool aAttemptVideoSupport,
RefPtr<ID3D11Device>& aOutDevice);
void AttemptWARPDeviceCreation();
bool AttemptWARPDeviceCreationHelper(
@ -98,8 +104,10 @@ private:
RefPtr<IDXGIAdapter1> mAdapter;
RefPtr<ID3D11Device> mCompositorDevice;
RefPtr<ID3D11Device> mContentDevice;
RefPtr<ID3D11Device> mDecoderDevice;
mozilla::Atomic<bool> mIsWARP;
mozilla::Atomic<bool> mTextureSharingWorks;
bool mCompositorDeviceSupportsVideo;
};
} // namespace gfx