diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn index c5be998083..ceb0a1fb0e 100644 --- a/rtc_base/BUILD.gn +++ b/rtc_base/BUILD.gn @@ -126,6 +126,8 @@ rtc_library("rtc_base_approved") { if (is_win) { sources += [ + "win/create_direct3d_device.cc", + "win/create_direct3d_device.h", "win/get_activation_factory.cc", "win/get_activation_factory.h", "win/hstring.cc", diff --git a/rtc_base/win/create_direct3d_device.cc b/rtc_base/win/create_direct3d_device.cc new file mode 100644 index 0000000000..02fe340d56 --- /dev/null +++ b/rtc_base/win/create_direct3d_device.cc @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "rtc_base/win/create_direct3d_device.h" + +#include +#include + +namespace { + +FARPROC LoadD3D11Function(const char* function_name) { + static HMODULE const handle = + ::LoadLibraryExW(L"d3d11.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32); + return handle ? ::GetProcAddress(handle, function_name) : nullptr; +} + +decltype(&::CreateDirect3D11DeviceFromDXGIDevice) +GetCreateDirect3D11DeviceFromDXGIDevice() { + static decltype(&::CreateDirect3D11DeviceFromDXGIDevice) const function = + reinterpret_cast( + LoadD3D11Function("CreateDirect3D11DeviceFromDXGIDevice")); + return function; +} + +} // namespace + +namespace webrtc { + +bool ResolveCoreWinRTDirect3DDelayload() { + return GetCreateDirect3D11DeviceFromDXGIDevice(); +} + +HRESULT CreateDirect3DDeviceFromDXGIDevice( + IDXGIDevice* dxgi_device, + ABI::Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice** + out_d3d11_device) { + decltype(&::CreateDirect3D11DeviceFromDXGIDevice) create_d3d11_device_func = + GetCreateDirect3D11DeviceFromDXGIDevice(); + if (!create_d3d11_device_func) + return E_FAIL; + + Microsoft::WRL::ComPtr inspectableSurface; + HRESULT hr = create_d3d11_device_func(dxgi_device, &inspectableSurface); + if (FAILED(hr)) + return hr; + + return inspectableSurface->QueryInterface(IID_PPV_ARGS(out_d3d11_device)); +} + +} // namespace webrtc diff --git a/rtc_base/win/create_direct3d_device.h b/rtc_base/win/create_direct3d_device.h new file mode 100644 index 0000000000..102f74148c --- /dev/null +++ b/rtc_base/win/create_direct3d_device.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef RTC_BASE_WIN_CREATE_DIRECT3D_DEVICE_H_ +#define RTC_BASE_WIN_CREATE_DIRECT3D_DEVICE_H_ + +#include +#include +#include +#include + +namespace webrtc { + +// Callers must check the return value of ResolveCoreWinRTDirect3DDelayload() +// before using CreateDirect3DDeviceFromDXGIDevice(). +bool ResolveCoreWinRTDirect3DDelayload(); + +// Allows for the creating of Direct3D Devices from a DXGI device on versions +// of Windows greater than Win7. +HRESULT CreateDirect3DDeviceFromDXGIDevice( + IDXGIDevice* dxgi_device, + ABI::Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice** + out_d3d11_device); + +} // namespace webrtc + +#endif // RTC_BASE_WIN_CREATE_DIRECT3D_DEVICE_H_ diff --git a/rtc_base/win/get_activation_factory.h b/rtc_base/win/get_activation_factory.h index 801f39d313..08f602f0c4 100644 --- a/rtc_base/win/get_activation_factory.h +++ b/rtc_base/win/get_activation_factory.h @@ -40,8 +40,10 @@ HRESULT GetActivationFactory(InterfaceType** factory) { return hr; hr = RoGetActivationFactoryProxy(class_id_hstring, IID_PPV_ARGS(factory)); - if (FAILED(hr)) + if (FAILED(hr)) { + DeleteHstring(class_id_hstring); return hr; + } return DeleteHstring(class_id_hstring); } diff --git a/rtc_base/win/scoped_com_initializer.cc b/rtc_base/win/scoped_com_initializer.cc index b83ad32a67..81079fb54c 100644 --- a/rtc_base/win/scoped_com_initializer.cc +++ b/rtc_base/win/scoped_com_initializer.cc @@ -10,6 +10,9 @@ #include "rtc_base/win/scoped_com_initializer.h" +#include "rtc_base/checks.h" +#include "rtc_base/logging.h" + namespace webrtc { ScopedCOMInitializer::ScopedCOMInitializer() { diff --git a/rtc_base/win/scoped_com_initializer.h b/rtc_base/win/scoped_com_initializer.h index 918812fc72..2427097b5b 100644 --- a/rtc_base/win/scoped_com_initializer.h +++ b/rtc_base/win/scoped_com_initializer.h @@ -13,8 +13,6 @@ #include -#include "rtc_base/logging.h" - namespace webrtc { // Initializes COM in the constructor (STA or MTA), and uninitializes COM in the