| Index: content/common/gpu/media/dxva_video_decode_accelerator.cc
|
| diff --git a/content/common/gpu/media/dxva_video_decode_accelerator.cc b/content/common/gpu/media/dxva_video_decode_accelerator.cc
|
| index a33bc224b8159e110b9fdcab698aad44a9039899..58ef91e58417799fbd50407f154e0a61f534a4af 100644
|
| --- a/content/common/gpu/media/dxva_video_decode_accelerator.cc
|
| +++ b/content/common/gpu/media/dxva_video_decode_accelerator.cc
|
| @@ -33,6 +33,8 @@
|
| #include "content/public/common/content_switches.h"
|
| #include "media/base/win/mf_initializer.h"
|
| #include "media/video/video_decode_accelerator.h"
|
| +#include "third_party/angle/include/EGL/egl.h"
|
| +#include "third_party/angle/include/EGL/eglext.h"
|
| #include "ui/gl/gl_bindings.h"
|
| #include "ui/gl/gl_context.h"
|
| #include "ui/gl/gl_surface_egl.h"
|
| @@ -276,6 +278,63 @@ HRESULT CreateCOMObjectFromDll(HMODULE dll, const CLSID& clsid, const IID& iid,
|
| return hr;
|
| }
|
|
|
| +// Helper function to query the ANGLE device object. The template argument T
|
| +// identifies the device interface being queried. IDirect3DDevice9Ex for d3d9
|
| +// and ID3D11Device for dx11.
|
| +template<class T>
|
| +base::win::ScopedComPtr<T> QueryDeviceObjectFromANGLE(int object_type) {
|
| + base::win::ScopedComPtr<T> device_object;
|
| +
|
| + EGLDisplay egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay();
|
| + intptr_t egl_device = 0;
|
| + intptr_t device = 0;
|
| +
|
| + RETURN_ON_FAILURE(
|
| + gfx::GLSurfaceEGL::HasEGLExtension("EGL_EXT_device_query"),
|
| + "EGL_EXT_device_query missing",
|
| + device_object);
|
| +
|
| + PFNEGLQUERYDISPLAYATTRIBEXTPROC QueryDisplayAttribEXT =
|
| + reinterpret_cast<PFNEGLQUERYDISPLAYATTRIBEXTPROC>(eglGetProcAddress(
|
| + "eglQueryDisplayAttribEXT"));
|
| +
|
| + RETURN_ON_FAILURE(
|
| + QueryDisplayAttribEXT,
|
| + "Failed to get the eglQueryDisplayAttribEXT function from ANGLE",
|
| + device_object);
|
| +
|
| + PFNEGLQUERYDEVICEATTRIBEXTPROC QueryDeviceAttribEXT =
|
| + reinterpret_cast<PFNEGLQUERYDEVICEATTRIBEXTPROC>(eglGetProcAddress(
|
| + "eglQueryDeviceAttribEXT"));
|
| +
|
| + RETURN_ON_FAILURE(
|
| + QueryDeviceAttribEXT,
|
| + "Failed to get the eglQueryDeviceAttribEXT function from ANGLE",
|
| + device_object);
|
| +
|
| + RETURN_ON_FAILURE(
|
| + QueryDisplayAttribEXT(egl_display, EGL_DEVICE_EXT, &egl_device),
|
| + "The eglQueryDisplayAttribEXT function failed to get the EGL device",
|
| + device_object);
|
| +
|
| + RETURN_ON_FAILURE(
|
| + egl_device,
|
| + "Failed to get the EGL device",
|
| + device_object);
|
| +
|
| + RETURN_ON_FAILURE(
|
| + QueryDeviceAttribEXT(
|
| + reinterpret_cast<EGLDeviceEXT>(egl_device), object_type, &device),
|
| + "The eglQueryDeviceAttribEXT function failed to get the device",
|
| + device_object);
|
| +
|
| + RETURN_ON_FAILURE(device, "Failed to get the ANGLE device", device_object);
|
| +
|
| + device_object = reinterpret_cast<T*>(device);
|
| + return device_object;
|
| +}
|
| +
|
| +
|
| // Maintains information about a DXVA picture buffer, i.e. whether it is
|
| // available for rendering, the texture information, etc.
|
| struct DXVAVideoDecodeAccelerator::DXVAPictureBuffer {
|
| @@ -661,32 +720,49 @@ bool DXVAVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile,
|
| bool DXVAVideoDecodeAccelerator::CreateD3DDevManager() {
|
| TRACE_EVENT0("gpu", "DXVAVideoDecodeAccelerator_CreateD3DDevManager");
|
|
|
| - HRESULT hr = Direct3DCreate9Ex(D3D_SDK_VERSION, d3d9_.Receive());
|
| + HRESULT hr = E_FAIL;
|
| +
|
| + hr = Direct3DCreate9Ex(D3D_SDK_VERSION, d3d9_.Receive());
|
| RETURN_ON_HR_FAILURE(hr, "Direct3DCreate9Ex failed", false);
|
|
|
| - D3DPRESENT_PARAMETERS present_params = {0};
|
| - present_params.BackBufferWidth = 1;
|
| - present_params.BackBufferHeight = 1;
|
| - present_params.BackBufferFormat = D3DFMT_UNKNOWN;
|
| - present_params.BackBufferCount = 1;
|
| - present_params.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
| - present_params.hDeviceWindow = ::GetShellWindow();
|
| - present_params.Windowed = TRUE;
|
| - present_params.Flags = D3DPRESENTFLAG_VIDEO;
|
| - present_params.FullScreen_RefreshRateInHz = 0;
|
| - present_params.PresentationInterval = 0;
|
| -
|
| - hr = d3d9_->CreateDeviceEx(D3DADAPTER_DEFAULT,
|
| - D3DDEVTYPE_HAL,
|
| - ::GetShellWindow(),
|
| - D3DCREATE_FPU_PRESERVE |
|
| - D3DCREATE_SOFTWARE_VERTEXPROCESSING |
|
| - D3DCREATE_DISABLE_PSGP_THREADING |
|
| - D3DCREATE_MULTITHREADED,
|
| - &present_params,
|
| - NULL,
|
| - d3d9_device_ex_.Receive());
|
| - RETURN_ON_HR_FAILURE(hr, "Failed to create D3D device", false);
|
| + if (base::CommandLine::ForCurrentProcess()->HasSwitch(
|
| + switches::kDisableD3D11)) {
|
| + base::win::ScopedComPtr<IDirect3DDevice9> angle_device =
|
| + QueryDeviceObjectFromANGLE<IDirect3DDevice9>(EGL_D3D9_DEVICE_ANGLE);
|
| + RETURN_ON_FAILURE(
|
| + angle_device.get(),
|
| + "Failed to query D3D9 device object from ANGLE",
|
| + false);
|
| +
|
| + hr = d3d9_device_ex_.QueryFrom(angle_device.get());
|
| + RETURN_ON_HR_FAILURE(hr,
|
| + "QueryInterface for IDirect3DDevice9Ex from angle device failed",
|
| + false);
|
| + } else {
|
| + D3DPRESENT_PARAMETERS present_params = {0};
|
| + present_params.BackBufferWidth = 1;
|
| + present_params.BackBufferHeight = 1;
|
| + present_params.BackBufferFormat = D3DFMT_UNKNOWN;
|
| + present_params.BackBufferCount = 1;
|
| + present_params.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
| + present_params.hDeviceWindow = ::GetShellWindow();
|
| + present_params.Windowed = TRUE;
|
| + present_params.Flags = D3DPRESENTFLAG_VIDEO;
|
| + present_params.FullScreen_RefreshRateInHz = 0;
|
| + present_params.PresentationInterval = 0;
|
| +
|
| + hr = d3d9_->CreateDeviceEx(D3DADAPTER_DEFAULT,
|
| + D3DDEVTYPE_HAL,
|
| + ::GetShellWindow(),
|
| + D3DCREATE_FPU_PRESERVE |
|
| + D3DCREATE_HARDWARE_VERTEXPROCESSING |
|
| + D3DCREATE_DISABLE_PSGP_THREADING |
|
| + D3DCREATE_MULTITHREADED,
|
| + &present_params,
|
| + NULL,
|
| + d3d9_device_ex_.Receive());
|
| + RETURN_ON_HR_FAILURE(hr, "Failed to create D3D device", false);
|
| + }
|
|
|
| hr = DXVA2CreateDirect3DDeviceManager9(&dev_manager_reset_token_,
|
| device_manager_.Receive());
|
| @@ -710,36 +786,19 @@ bool DXVAVideoDecodeAccelerator::CreateDX11DevManager() {
|
| d3d11_device_manager_.Receive());
|
| RETURN_ON_HR_FAILURE(hr, "MFCreateDXGIDeviceManager failed", false);
|
|
|
| - // This array defines the set of DirectX hardware feature levels we support.
|
| - // The ordering MUST be preserved. All applications are assumed to support
|
| - // 9.1 unless otherwise stated by the application, which is not our case.
|
| - D3D_FEATURE_LEVEL feature_levels[] = {
|
| - D3D_FEATURE_LEVEL_11_1,
|
| - D3D_FEATURE_LEVEL_11_0,
|
| - D3D_FEATURE_LEVEL_10_1,
|
| - D3D_FEATURE_LEVEL_10_0,
|
| - D3D_FEATURE_LEVEL_9_3,
|
| - D3D_FEATURE_LEVEL_9_2,
|
| - D3D_FEATURE_LEVEL_9_1 };
|
| -
|
| - UINT flags = D3D11_CREATE_DEVICE_VIDEO_SUPPORT;
|
| -
|
| -#if defined _DEBUG
|
| - flags |= D3D11_CREATE_DEVICE_DEBUG;
|
| -#endif
|
| -
|
| - D3D_FEATURE_LEVEL feature_level_out = D3D_FEATURE_LEVEL_11_0;
|
| - hr = D3D11CreateDevice(NULL,
|
| - D3D_DRIVER_TYPE_HARDWARE,
|
| - NULL,
|
| - flags,
|
| - feature_levels,
|
| - arraysize(feature_levels),
|
| - D3D11_SDK_VERSION,
|
| - d3d11_device_.Receive(),
|
| - &feature_level_out,
|
| - d3d11_device_context_.Receive());
|
| - RETURN_ON_HR_FAILURE(hr, "Failed to create DX11 device", false);
|
| + base::win::ScopedComPtr<ID3D11Device> angle_device =
|
| + QueryDeviceObjectFromANGLE<ID3D11Device>(EGL_D3D11_DEVICE_ANGLE);
|
| + RETURN_ON_FAILURE(
|
| + angle_device.get(),
|
| + "Failed to query DX11 device object from ANGLE",
|
| + false);
|
| +
|
| + d3d11_device_ = angle_device;
|
| + d3d11_device_->GetImmediateContext(d3d11_device_context_.Receive());
|
| + RETURN_ON_FAILURE(
|
| + d3d11_device_context_.get(),
|
| + "Failed to query DX11 device context from ANGLE device",
|
| + false);
|
|
|
| // Enable multithreaded mode on the context. This ensures that accesses to
|
| // context are synchronized across threads. We have multiple threads
|
|
|