Remove the requirement of D3D_FEATURE_LEVEL_11_0, but export the D3D_FEATURE_LEVEL through APIs
D3D_FEATURE_LEVEL_11_0 is not offically documented on MSDN to be a requirement of DXGI duplicator APIs. So instead of using D3D_FEATURE_LEVEL_11_0 as a requirement in D3dDevice::Initialize(), this change adds a ScreenCapturerWinDirectx::SupportedFeatureLevel() function to retrieves minimum and maximium for further reference (in HostTraits to control the experiment). BUG=314516 Review-Url: https://codereview.webrtc.org/2468083002 Cr-Commit-Position: refs/heads/master@{#14962}
This commit is contained in:
parent
6f601afcf4
commit
556f49d6b6
@ -31,6 +31,7 @@ bool D3dDevice::Initialize(const ComPtr<IDXGIAdapter>& adapter) {
|
||||
}
|
||||
|
||||
D3D_FEATURE_LEVEL feature_level;
|
||||
// Default feature levels contain D3D 9.1 through D3D 11.0.
|
||||
_com_error error = D3D11CreateDevice(
|
||||
adapter.Get(), D3D_DRIVER_TYPE_UNKNOWN, nullptr,
|
||||
D3D11_CREATE_DEVICE_BGRA_SUPPORT | D3D11_CREATE_DEVICE_SINGLETHREADED,
|
||||
@ -44,16 +45,18 @@ bool D3dDevice::Initialize(const ComPtr<IDXGIAdapter>& adapter) {
|
||||
|
||||
if (feature_level < D3D_FEATURE_LEVEL_11_0) {
|
||||
LOG(LS_WARNING) << "D3D11CreateDevice returns an instance without DirectX "
|
||||
"11 support, level "
|
||||
<< feature_level;
|
||||
return false;
|
||||
"11 support, level " << feature_level
|
||||
<< ". Following initialization may fail.";
|
||||
// D3D_FEATURE_LEVEL_11_0 is not officially documented on MSDN to be a
|
||||
// requirement of Dxgi duplicator APIs.
|
||||
}
|
||||
|
||||
error = d3d_device_.As(&dxgi_device_);
|
||||
if (error.Error() != S_OK || !dxgi_device_) {
|
||||
LOG(LS_WARNING) << "ID3D11Device is not an implementation of IDXGIDevice, "
|
||||
"this usually means the system does not support DirectX "
|
||||
"11";
|
||||
"11. Error "
|
||||
<< error.ErrorMessage() << " with code " << error.Error();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -44,6 +44,15 @@ bool DxgiDuplicatorController::IsSupported() {
|
||||
return Initialize();
|
||||
}
|
||||
|
||||
bool DxgiDuplicatorController::RetrieveD3dInfo(D3dInfo* info) {
|
||||
rtc::CritScope lock(&lock_);
|
||||
if (!Initialize()) {
|
||||
return false;
|
||||
}
|
||||
*info = d3d_info_;
|
||||
return true;
|
||||
}
|
||||
|
||||
DesktopVector DxgiDuplicatorController::dpi() {
|
||||
rtc::CritScope lock(&lock_);
|
||||
if (Initialize()) {
|
||||
@ -121,6 +130,9 @@ bool DxgiDuplicatorController::DoInitialize() {
|
||||
RTC_DCHECK(desktop_rect_.is_empty());
|
||||
RTC_DCHECK(duplicators_.empty());
|
||||
|
||||
d3d_info_.min_feature_level = static_cast<D3D_FEATURE_LEVEL>(0);
|
||||
d3d_info_.max_feature_level = static_cast<D3D_FEATURE_LEVEL>(0);
|
||||
|
||||
std::vector<D3dDevice> devices = D3dDevice::EnumDevices();
|
||||
if (devices.empty()) {
|
||||
return false;
|
||||
@ -131,6 +143,18 @@ bool DxgiDuplicatorController::DoInitialize() {
|
||||
if (!duplicators_.back().Initialize()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
D3D_FEATURE_LEVEL feature_level =
|
||||
devices[i].d3d_device()->GetFeatureLevel();
|
||||
if (d3d_info_.max_feature_level == 0 ||
|
||||
feature_level > d3d_info_.max_feature_level) {
|
||||
d3d_info_.max_feature_level = feature_level;
|
||||
}
|
||||
if (d3d_info_.min_feature_level == 0 ||
|
||||
feature_level < d3d_info_.min_feature_level) {
|
||||
d3d_info_.min_feature_level = feature_level;
|
||||
}
|
||||
|
||||
if (desktop_rect_.is_empty()) {
|
||||
desktop_rect_ = duplicators_.back().desktop_rect();
|
||||
} else {
|
||||
|
||||
@ -11,6 +11,8 @@
|
||||
#ifndef WEBRTC_MODULES_DESKTOP_CAPTURE_WIN_DXGI_DUPLICATOR_CONTROLLER_H_
|
||||
#define WEBRTC_MODULES_DESKTOP_CAPTURE_WIN_DXGI_DUPLICATOR_CONTROLLER_H_
|
||||
|
||||
#include <D3DCommon.h>
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
@ -57,6 +59,21 @@ class DxgiDuplicatorController {
|
||||
std::vector<DxgiAdapterDuplicator::Context> contexts_;
|
||||
};
|
||||
|
||||
// A collection of D3d information we are interested on, which may impact
|
||||
// capturer performance or reliability.
|
||||
struct D3dInfo {
|
||||
// Each video adapter has its own D3D_FEATURE_LEVEL, so this structure
|
||||
// contains the minimum and maximium D3D_FEATURE_LEVELs current system
|
||||
// supports.
|
||||
// Both fields can be 0, which is the default value to indicate no valid
|
||||
// D3D_FEATURE_LEVEL has been retrieved from underlying OS APIs.
|
||||
D3D_FEATURE_LEVEL min_feature_level;
|
||||
D3D_FEATURE_LEVEL max_feature_level;
|
||||
|
||||
// TODO(zijiehe): Add more fields, such as manufacturer name, mode, driver
|
||||
// version.
|
||||
};
|
||||
|
||||
// Returns the singleton instance of DxgiDuplicatorController.
|
||||
static DxgiDuplicatorController* Instance();
|
||||
|
||||
@ -64,9 +81,15 @@ class DxgiDuplicatorController {
|
||||
// containers are destructed in correct order.
|
||||
~DxgiDuplicatorController();
|
||||
|
||||
// All the following functions implicitly call Initialize() function is
|
||||
// current instance has not been initialized.
|
||||
|
||||
// Detects whether the system supports DXGI based capturer.
|
||||
bool IsSupported();
|
||||
|
||||
// Returns a copy of D3dInfo composed by last Initialize() function call.
|
||||
bool RetrieveD3dInfo(D3dInfo* info);
|
||||
|
||||
// Captures current screen and writes into target. Since we are using double
|
||||
// buffering, |last_frame|.updated_region() is used to represent the not
|
||||
// updated regions in current |target| frame, which should also be copied this
|
||||
@ -153,6 +176,7 @@ class DxgiDuplicatorController {
|
||||
DesktopRect desktop_rect_;
|
||||
DesktopVector dpi_;
|
||||
std::vector<DxgiAdapterDuplicator> duplicators_;
|
||||
D3dInfo d3d_info_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -23,10 +23,17 @@ using Microsoft::WRL::ComPtr;
|
||||
|
||||
// static
|
||||
bool ScreenCapturerWinDirectx::IsSupported() {
|
||||
// Forward IsSupported function call to DxgiDuplicatorController.
|
||||
// Forwards IsSupported() function call to DxgiDuplicatorController.
|
||||
return DxgiDuplicatorController::Instance()->IsSupported();
|
||||
}
|
||||
|
||||
// static
|
||||
bool ScreenCapturerWinDirectx::RetrieveD3dInfo(D3dInfo* info) {
|
||||
// Forwards SupportedFeatureLevels() function call to
|
||||
// DxgiDuplicatorController.
|
||||
return DxgiDuplicatorController::Instance()->RetrieveD3dInfo(info);
|
||||
}
|
||||
|
||||
ScreenCapturerWinDirectx::ScreenCapturerWinDirectx(
|
||||
const DesktopCaptureOptions& options)
|
||||
: callback_(nullptr) {}
|
||||
|
||||
@ -13,6 +13,8 @@
|
||||
|
||||
#include "webrtc/modules/desktop_capture/screen_capturer.h"
|
||||
|
||||
#include <D3DCommon.h>
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
@ -24,13 +26,24 @@
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// ScreenCapturerWinDirectx captures 32bit RGBA using DirectX. This
|
||||
// implementation won't work when ScreenCaptureFrameQueue.kQueueLength is not 2.
|
||||
// ScreenCapturerWinDirectx captures 32bit RGBA using DirectX.
|
||||
class ScreenCapturerWinDirectx : public ScreenCapturer {
|
||||
public:
|
||||
using D3dInfo = DxgiDuplicatorController::D3dInfo;
|
||||
|
||||
// Whether the system supports DirectX based capturing.
|
||||
static bool IsSupported();
|
||||
|
||||
// Returns a most recent D3dInfo composed by
|
||||
// DxgiDuplicatorController::Initialize() function. This function implicitly
|
||||
// calls DxgiDuplicatorController::Initialize() if it has not been
|
||||
// initialized. This function returns false and output parameter is kept
|
||||
// unchanged if DxgiDuplicatorController::Initialize() failed.
|
||||
// The D3dInfo may change based on hardware configuration even without
|
||||
// restarting the hardware and software. Refer to https://goo.gl/OOCppq. So
|
||||
// consumers should not cache the result returned by this function.
|
||||
static bool RetrieveD3dInfo(D3dInfo* info);
|
||||
|
||||
explicit ScreenCapturerWinDirectx(const DesktopCaptureOptions& options);
|
||||
|
||||
~ScreenCapturerWinDirectx() override;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user