Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(29)

Unified Diff: webrtc/modules/desktop_capture/win/dxgi_duplicator_controller.cc

Issue 2937663003: Ensure Dxgi duplicator works correctly in session 0 (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: webrtc/modules/desktop_capture/win/dxgi_duplicator_controller.cc
diff --git a/webrtc/modules/desktop_capture/win/dxgi_duplicator_controller.cc b/webrtc/modules/desktop_capture/win/dxgi_duplicator_controller.cc
index c17bd1481c7fffa9e09939e3fbcb75f70deaee87..75c3ed11b6e83032648d7db7c0a66e28a1a0cc85 100644
--- a/webrtc/modules/desktop_capture/win/dxgi_duplicator_controller.cc
+++ b/webrtc/modules/desktop_capture/win/dxgi_duplicator_controller.cc
@@ -16,7 +16,9 @@
#include <string>
#include "webrtc/base/checks.h"
+#include "webrtc/base/logging.h"
#include "webrtc/base/timeutils.h"
+#include "webrtc/base/win32.h"
#include "webrtc/modules/desktop_capture/desktop_capture_types.h"
#include "webrtc/modules/desktop_capture/win/dxgi_frame.h"
#include "webrtc/modules/desktop_capture/win/screen_capture_utils.h"
@@ -24,6 +26,19 @@
namespace webrtc {
+namespace {
+
+bool IsRunningInSession0() {
+ DWORD session_id = 0;
+ if (!::ProcessIdToSessionId(::GetCurrentProcessId(), &session_id)) {
+ LOG(LS_WARNING) << "Failed to retrieve current session Id, no priviledge?";
+ return true;
+ }
+ return session_id == 0;
+}
+
+} // namespace
+
// static
DxgiDuplicatorController* DxgiDuplicatorController::Instance() {
// The static instance won't be deleted to ensure it can be used by other
@@ -40,17 +55,48 @@ DxgiDuplicatorController::~DxgiDuplicatorController() {
}
bool DxgiDuplicatorController::IsSupported() {
- rtc::CritScope lock(&lock_);
- return Initialize();
+ bool result = false;
+ {
+ rtc::CritScope lock(&lock_);
+ result = Initialize();
+ }
+
+ if (result) {
+ return true;
+ }
+
+ if (IsRunningInSession0()) {
+ LOG(LS_WARNING) << "Current binary is running in session 0. DXGI "
+ "components cannot be initialized. Fallback to use "
+ "Windows version to decide the support of DirectX "
+ "capturer. It may be inaccurate.";
+ return rtc::IsWindows8OrLater();
Sergey Ulanov 2017/06/26 23:41:41 In this case DX capturer is effectively unsupporte
Hzj_jie 2017/06/27 04:37:33 A very good point, I have moved this logic into ht
+ }
+
+ return false;
}
bool DxgiDuplicatorController::RetrieveD3dInfo(D3dInfo* info) {
- rtc::CritScope lock(&lock_);
- if (!Initialize()) {
- return false;
+ bool result = false;
+ {
+ rtc::CritScope lock(&lock_);
+ result = Initialize();
}
- *info = d3d_info_;
- return true;
+
+ if (result) {
+ *info = d3d_info_;
+ return true;
+ }
+
+ if (IsRunningInSession0()) {
+ LOG(LS_WARNING) << "Current binary is running in session 0. Initialization "
+ "of DXGI components are expected to fail. But "
+ "retrieving feature level is still supported.";
+ *info = d3d_info_;
+ return true;
+ }
+
+ return false;
}
DxgiDuplicatorController::Result
@@ -104,6 +150,12 @@ DxgiDuplicatorController::DoDuplicate(DxgiFrame* frame, int monitor_id) {
}
if (!Initialize()) {
+ if (succeeded_duplications_ == 0 && IsRunningInSession0()) {
+ LOG(LS_WARNING) << "Current binary is running in session 0. DXGI "
+ "components cannot be initialized.";
+ return Result::UNSUPPORTED_SESSION;
+ }
+
// Cannot initialize COM components now, display mode may be changing.
return Result::INITIALIZATION_FAILED;
}
@@ -115,6 +167,7 @@ DxgiDuplicatorController::DoDuplicate(DxgiFrame* frame, int monitor_id) {
frame->frame()->mutable_updated_region()->Clear();
if (DoDuplicateUnlocked(frame->context(), monitor_id, frame->frame())) {
+ succeeded_duplications_++;
return Result::SUCCEEDED;
}
if (monitor_id >= ScreenCountUnlocked()) {
@@ -162,15 +215,11 @@ bool DxgiDuplicatorController::DoInitialize() {
std::vector<D3dDevice> devices = D3dDevice::EnumDevices();
if (devices.empty()) {
+ LOG(LS_WARNING) << "No D3dDevice found.";
return false;
}
for (size_t i = 0; i < devices.size(); i++) {
- duplicators_.emplace_back(devices[i]);
- if (!duplicators_.back().Initialize()) {
- return false;
- }
-
D3D_FEATURE_LEVEL feature_level =
devices[i].d3d_device()->GetFeatureLevel();
if (d3d_info_.max_feature_level == 0 ||
@@ -182,6 +231,16 @@ bool DxgiDuplicatorController::DoInitialize() {
d3d_info_.min_feature_level = feature_level;
}
+ DxgiAdapterDuplicator duplicator(devices[i]);
+ if (!duplicator.Initialize()) {
+ LOG(LS_WARNING) << "Failed to initialize DxgiAdapterDuplicator on "
+ "adapter "
+ << i;
+ continue;
Sergey Ulanov 2017/06/26 23:41:41 Why do we need to keep trying initialization after
Hzj_jie 2017/06/27 04:37:33 This issue happens when a virtual adapter is insta
+ }
+ RTC_DCHECK(!duplicator.desktop_rect().is_empty());
+ duplicators_.push_back(std::move(duplicator));
+
desktop_rect_.UnionWith(duplicators_.back().desktop_rect());
}
TranslateRect();
@@ -194,7 +253,12 @@ bool DxgiDuplicatorController::DoInitialize() {
}
identity_++;
- return true;
+
+ if (duplicators_.empty()) {
+ LOG(LS_WARNING) << "Cannot initialize any DxgiAdapterDuplicator instance.";
+ }
+
+ return !duplicators_.empty();
}
void DxgiDuplicatorController::Deinitialize() {

Powered by Google App Engine
This is Rietveld 408576698