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

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

Issue 2099123002: [Chromoting] Improve DirectX capturer to support multiple outputs (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Fix several lint errors Created 4 years, 4 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_adapter_duplicator.cc
diff --git a/webrtc/modules/desktop_capture/win/dxgi_adapter_duplicator.cc b/webrtc/modules/desktop_capture/win/dxgi_adapter_duplicator.cc
new file mode 100644
index 0000000000000000000000000000000000000000..abe7908afe5673826b1ff80c3466dbd971066b4f
--- /dev/null
+++ b/webrtc/modules/desktop_capture/win/dxgi_adapter_duplicator.cc
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2016 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 "webrtc/modules/desktop_capture/win/dxgi_adapter_duplicator.h"
+
+#include <comdef.h>
+#include <DXGI.h>
+
+#include <algorithm>
+
+#include "webrtc/base/checks.h"
+#include "webrtc/base/logging.h"
+
+namespace webrtc {
+
+using Microsoft::WRL::ComPtr;
+
+namespace {
+
+bool IsValidRect(const RECT& rect) {
+ return rect.left >= 0 && rect.top >= 0 && rect.right > rect.left &&
+ rect.bottom > rect.top;
+}
+
+} // namespace
+
+DxgiAdapterDuplicator::DxgiAdapterDuplicator(const D3dDevice& device)
+ : device_(device) {}
+
+DxgiAdapterDuplicator::DxgiAdapterDuplicator(DxgiAdapterDuplicator&&) = default;
+
+bool DxgiAdapterDuplicator::Initialize() {
+ if (DoInitialize()) {
+ return true;
+ }
+ duplicators_.clear();
+ return false;
+}
+
+bool DxgiAdapterDuplicator::DoInitialize() {
+ for (int i = 0;; i++) {
+ ComPtr<IDXGIOutput> output;
+ _com_error error =
+ device_.dxgi_adapter()->EnumOutputs(i, output.GetAddressOf());
+ if (error.Error() == DXGI_ERROR_NOT_FOUND) {
+ break;
+ }
+
+ if (error.Error() != S_OK || !output) {
+ LOG(LS_WARNING) << "IDXGIAdapter::EnumOutputs returns an unexpected "
+ "result "
+ << error.ErrorMessage() << " with error code"
+ << error.Error();
+ return false;
+ }
+
+ DXGI_OUTPUT_DESC desc;
+ error = _com_error(output->GetDesc(&desc));
+ if (error.Error() == S_OK) {
+ if (desc.AttachedToDesktop && IsValidRect(desc.DesktopCoordinates)) {
+ ComPtr<IDXGIOutput1> output1;
+ error = _com_error(output.As(&output1));
+ if (error.Error() != S_OK || !output1) {
+ LOG(LS_WARNING) << "Failed to convert IDXGIOutput to IDXGIOutput1, "
+ "this usually means the system does not support "
+ "DirectX 11";
+ return false;
+ }
+ duplicators_.emplace_back(device_, output1, desc);
+ if (!duplicators_.back().Initialize()) {
+ return false;
+ }
+ if (desktop_rect_.is_empty()) {
+ desktop_rect_ = duplicators_.back().desktop_rect();
+ } else {
+ const DesktopRect& left = desktop_rect_;
+ const DesktopRect& right = duplicators_.back().desktop_rect();
+ desktop_rect_ =
+ DesktopRect::MakeLTRB(std::min(left.left(), right.left()),
+ std::min(left.top(), right.top()),
+ std::max(left.right(), right.right()),
+ std::max(left.bottom(), right.bottom()));
+ }
+ }
+ } else {
+ LOG(LS_WARNING) << "Failed to get output description of device " << i
+ << ", ignore.";
+ }
+ }
+ return true;
+}
+
+void DxgiAdapterDuplicator::Setup(Context* context) {
+ RTC_DCHECK(context->contexts.empty());
+ context->contexts.resize(duplicators_.size());
+ for (size_t i = 0; i < duplicators_.size(); i++) {
+ duplicators_[i].Setup(&context->contexts[i]);
+ }
+}
+
+void DxgiAdapterDuplicator::Unregister(const Context* const context) {
+ RTC_DCHECK_EQ(context->contexts.size(), duplicators_.size());
+ for (size_t i = 0; i < duplicators_.size(); i++) {
+ duplicators_[i].Unregister(&context->contexts[i]);
+ }
+}
+
+bool DxgiAdapterDuplicator::Duplicate(Context* context,
+ const DesktopFrame* last_frame,
+ DesktopFrame* target) {
+ RTC_DCHECK_EQ(context->contexts.size(), duplicators_.size());
+ for (size_t i = 0; i < duplicators_.size(); i++) {
+ if (!duplicators_[i].Duplicate(&context->contexts[i], last_frame,
+ duplicators_[i].desktop_rect().top_left(),
+ target)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool DxgiAdapterDuplicator::DuplicateMonitor(Context* context,
+ int monitor_id,
+ const DesktopFrame* last_frame,
+ DesktopFrame* target) {
+ RTC_DCHECK(monitor_id >= 0 &&
+ monitor_id < static_cast<int>(duplicators_.size()) &&
+ context->contexts.size() == duplicators_.size());
+ return duplicators_[monitor_id].Duplicate(
+ &context->contexts[monitor_id], last_frame, DesktopVector(), target);
+}
+
+DesktopRect DxgiAdapterDuplicator::ScreenRect(int id) const {
+ RTC_DCHECK(id >= 0 && id < static_cast<int>(duplicators_.size()));
+ return duplicators_[id].desktop_rect();
+}
+
+} // namespace webrtc

Powered by Google App Engine
This is Rietveld 408576698