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

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: Resolve review comments Created 4 years, 5 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 &&
29 rect.right > rect.left && rect.bottom > rect.top;
30 }
31
32 } // namespace
33
34 bool DxgiAdapterDuplicator::Initialize(const D3dDevice& device) {
35 if (DoInitialize(device)) {
36 return true;
37 }
38 duplicators_.clear();
39 return false;
40 }
41
42 bool DxgiAdapterDuplicator::DoInitialize(const D3dDevice& device) {
43 for (int i = 0;; i++) {
44 ComPtr<IDXGIOutput> output;
45 _com_error error = device.dxgi_adapter()->EnumOutputs(
46 i, output.GetAddressOf());
47 if (error.Error() == DXGI_ERROR_NOT_FOUND) {
48 break;
49 }
50
51 if (error.Error() != S_OK || !output) {
52 LOG(LS_WARNING) << "IDXGIAdapter::EnumOutputs returns an unexpected "
53 "result " << error.ErrorMessage() << " with error code"
54 << error.Error();
55 return false;
56 }
57
58 DXGI_OUTPUT_DESC desc;
59 error = _com_error(output->GetDesc(&desc));
60 if (error.Error() == S_OK) {
61 if (desc.AttachedToDesktop && IsValidRect(desc.DesktopCoordinates)) {
62 ComPtr<IDXGIOutput1> output1;
63 error = _com_error(output.As(&output1));
64 if (error.Error() != S_OK || !output1) {
65 LOG(LS_WARNING) << "Failed to convert IDXGIOutput to IDXGIOutput1, "
66 "this usually means the system does not support "
67 "DirectX 11";
68 return false;
69 }
70 duplicators_.emplace_back(device, output1, desc);
71 if (!duplicators_.back().Initialize()) {
72 return false;
73 }
74 if (desktop_rect_.is_empty()) {
75 desktop_rect_ = duplicators_.back().desktop_rect();
76 } else {
77 const DesktopRect& left = desktop_rect_;
78 const DesktopRect& right = duplicators_.back().desktop_rect();
79 desktop_rect_ = DesktopRect::MakeLTRB(
80 std::min(left.left(), right.left()),
81 std::min(left.top(), right.top()),
82 std::max(left.right(), right.right()),
83 std::max(left.bottom(), right.bottom()));
84 }
85 }
86 } else {
87 LOG(LS_WARNING) << "Failed to get output description of device " << i
88 << ", ignore.";
89 }
90 }
91 return true;
92 }
93
94 bool DxgiAdapterDuplicator::Duplicate(DxgiContext* context,
95 DesktopFrame* target,
96 const DesktopFrame* last_frame) {
97 for (size_t i = 0; i < duplicators_.size(); i++) {
98 if (!duplicators_[i].Duplicate(&context->contexts_[i],
99 target,
100 last_frame,
101 duplicators_[i].desktop_rect().top_left())) {
102 return false;
103 }
104 }
105 return true;
106 }
107
108 bool DxgiAdapterDuplicator::Duplicate(DxgiContext* context,
109 int id,
110 DesktopFrame* target,
111 const DesktopFrame* last_frame) {
112 if (id < 0 ||
113 id >= static_cast<int>(duplicators_.size()) ||
114 context->contexts_.size() != duplicators_.size()) {
115 return false;
116 }
117 return duplicators_[id].Duplicate(
118 &context->contexts_[id], target, last_frame, DesktopVector());
119 }
120
121 DesktopRect DxgiAdapterDuplicator::ScreenRect(int id) const {
122 if (id < 0 || id >= static_cast<int>(duplicators_.size())) {
123 return DesktopRect();
124 }
125 return duplicators_[id].desktop_rect();
126 }
127
128 void DxgiAdapterDuplicator::Setup(DxgiContext* context) {
129 RTC_DCHECK(context->contexts_.empty());
130 context->contexts_.resize(duplicators_.size());
131 for (size_t i = 0; i < duplicators_.size(); i++) {
132 duplicators_[i].Setup(&context->contexts_[i]);
133 }
134 }
135
136 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698