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

Side by Side 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 unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "webrtc/modules/desktop_capture/win/dxgi_adapter_duplicator.h"
12
13 #include <comdef.h>
14 #include <DXGI.h>
15
16 #include <algorithm>
17
18 #include "webrtc/base/checks.h"
19 #include "webrtc/base/logging.h"
20
21 namespace webrtc {
22
23 using Microsoft::WRL::ComPtr;
24
25 namespace {
26
27 bool IsValidRect(const RECT& rect) {
28 return rect.left >= 0 && rect.top >= 0 && rect.right > rect.left &&
29 rect.bottom > rect.top;
30 }
31
32 } // namespace
33
34 DxgiAdapterDuplicator::DxgiAdapterDuplicator(const D3dDevice& device)
35 : device_(device) {}
36
37 DxgiAdapterDuplicator::DxgiAdapterDuplicator(DxgiAdapterDuplicator&&) = default;
38
39 bool DxgiAdapterDuplicator::Initialize() {
40 if (DoInitialize()) {
41 return true;
42 }
43 duplicators_.clear();
44 return false;
45 }
46
47 bool DxgiAdapterDuplicator::DoInitialize() {
48 for (int i = 0;; i++) {
49 ComPtr<IDXGIOutput> output;
50 _com_error error =
51 device_.dxgi_adapter()->EnumOutputs(i, output.GetAddressOf());
52 if (error.Error() == DXGI_ERROR_NOT_FOUND) {
53 break;
54 }
55
56 if (error.Error() != S_OK || !output) {
57 LOG(LS_WARNING) << "IDXGIAdapter::EnumOutputs returns an unexpected "
58 "result "
59 << error.ErrorMessage() << " with error code"
60 << error.Error();
61 return false;
62 }
63
64 DXGI_OUTPUT_DESC desc;
65 error = _com_error(output->GetDesc(&desc));
66 if (error.Error() == S_OK) {
67 if (desc.AttachedToDesktop && IsValidRect(desc.DesktopCoordinates)) {
68 ComPtr<IDXGIOutput1> output1;
69 error = _com_error(output.As(&output1));
70 if (error.Error() != S_OK || !output1) {
71 LOG(LS_WARNING) << "Failed to convert IDXGIOutput to IDXGIOutput1, "
72 "this usually means the system does not support "
73 "DirectX 11";
74 return false;
75 }
76 duplicators_.emplace_back(device_, output1, desc);
77 if (!duplicators_.back().Initialize()) {
78 return false;
79 }
80 if (desktop_rect_.is_empty()) {
81 desktop_rect_ = duplicators_.back().desktop_rect();
82 } else {
83 const DesktopRect& left = desktop_rect_;
84 const DesktopRect& right = duplicators_.back().desktop_rect();
85 desktop_rect_ =
86 DesktopRect::MakeLTRB(std::min(left.left(), right.left()),
87 std::min(left.top(), right.top()),
88 std::max(left.right(), right.right()),
89 std::max(left.bottom(), right.bottom()));
90 }
91 }
92 } else {
93 LOG(LS_WARNING) << "Failed to get output description of device " << i
94 << ", ignore.";
95 }
96 }
97 return true;
98 }
99
100 void DxgiAdapterDuplicator::Setup(Context* context) {
101 RTC_DCHECK(context->contexts.empty());
102 context->contexts.resize(duplicators_.size());
103 for (size_t i = 0; i < duplicators_.size(); i++) {
104 duplicators_[i].Setup(&context->contexts[i]);
105 }
106 }
107
108 void DxgiAdapterDuplicator::Unregister(const Context* const context) {
109 RTC_DCHECK_EQ(context->contexts.size(), duplicators_.size());
110 for (size_t i = 0; i < duplicators_.size(); i++) {
111 duplicators_[i].Unregister(&context->contexts[i]);
112 }
113 }
114
115 bool DxgiAdapterDuplicator::Duplicate(Context* context,
116 const DesktopFrame* last_frame,
117 DesktopFrame* target) {
118 RTC_DCHECK_EQ(context->contexts.size(), duplicators_.size());
119 for (size_t i = 0; i < duplicators_.size(); i++) {
120 if (!duplicators_[i].Duplicate(&context->contexts[i], last_frame,
121 duplicators_[i].desktop_rect().top_left(),
122 target)) {
123 return false;
124 }
125 }
126 return true;
127 }
128
129 bool DxgiAdapterDuplicator::DuplicateMonitor(Context* context,
130 int monitor_id,
131 const DesktopFrame* last_frame,
132 DesktopFrame* target) {
133 RTC_DCHECK(monitor_id >= 0 &&
134 monitor_id < static_cast<int>(duplicators_.size()) &&
135 context->contexts.size() == duplicators_.size());
136 return duplicators_[monitor_id].Duplicate(
137 &context->contexts[monitor_id], last_frame, DesktopVector(), target);
138 }
139
140 DesktopRect DxgiAdapterDuplicator::ScreenRect(int id) const {
141 RTC_DCHECK(id >= 0 && id < static_cast<int>(duplicators_.size()));
142 return duplicators_[id].desktop_rect();
143 }
144
145 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698