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

Side by Side Diff: webrtc/modules/desktop_capture/win/dxgi_duplicator_controller.h

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 #ifndef WEBRTC_MODULES_DESKTOP_CAPTURE_WIN_DXGI_DUPLICATOR_CONTROLLER_H_
12 #define WEBRTC_MODULES_DESKTOP_CAPTURE_WIN_DXGI_DUPLICATOR_CONTROLLER_H_
13
14 #include <vector>
15
16 #include "webrtc/base/criticalsection.h"
17 #include "webrtc/modules/desktop_capture/desktop_frame.h"
18 #include "webrtc/modules/desktop_capture/desktop_geometry.h"
19 #include "webrtc/modules/desktop_capture/desktop_region.h"
20 #include "webrtc/modules/desktop_capture/win/d3d_device.h"
21 #include "webrtc/modules/desktop_capture/win/dxgi_adapter_duplicator.h"
22
23 namespace webrtc {
24
25 // A controller for all the objects we need to call Windows DirectX capture APIs
26 // It's a singleton because, only one IDXGIOutputDuplication instance per
27 // monitor is allowed per application.
28 //
29 // Consumers should create a DxgiDuplicatorController::Context and keep it
30 // throughout their lifetime, and pass it when calling Duplicate(). Consumers
31 // can also call IsSupported() to determine whether the system supports DXGI
32 // duplicator or not. If a previous IsSupported() function call returns true,
33 // but a later Duplicate() returns false, this usually means the display mode is
34 // changing. Consumers should retry after a while. (Typically 50 milliseconds,
35 // but according to hardware performance, this time may vary.)
36 //
37 // This class is normally used with double buffering, e.g. as in
38 // ScreenCapturerWinDirectx, but it should work with consumers with one buffer,
39 // i.e. consumers can always send nullptr for |last_frame|. Some minor changes
40 // in DxgiOutputDuplicator class are nice to have to reduce size of data to copy
41 // (Commented in dxgi_output_duplicator.cc). But this class won't work
42 // with three or more buffers, the updated region merging logic will be broken
43 // in such scenarios. If a consumer does have this requirement, one can always
44 // send a new Context instance to Duplicate() function to force duplicator to
45 // treat it as a new consumer.
46 class DxgiDuplicatorController {
47 public:
48 // A context to store the status of a single consumer of
49 // DxgiDuplicatorController.
50 class Context {
51 public:
52 // Unregister this Context instance from all Dxgi duplicators during
53 // destructing.
54 ~Context();
55
56 private:
57 friend class DxgiDuplicatorController;
58
59 // A Context will have an exactly same |identity_| as
60 // DxgiDuplicatorController, to ensure it has been correctly setted up after
61 // each DxgiDuplicatorController::Initialize().
62 int identity_ = 0;
63
64 // Child DxgiAdapterDuplicator::Context belongs to this Context.
65 std::vector<DxgiAdapterDuplicator::Context> contexts_;
66 };
67
68 // Returns the singleton instance of DxgiDuplicatorController.
69 static DxgiDuplicatorController* Instance();
70
71 // Destructs current instance. We need to make sure COM components and their
72 // containers are destructed in correct order.
73 ~DxgiDuplicatorController();
74
75 // Detects whether the system supports DXGI based capturer.
76 bool IsSupported();
77
78 // Captures current screen and writes into target. Since we are using double
79 // buffering, |last_frame|.updated_region() is used to represent the not
80 // updated regions in current |target| frame, which should also be copied this
81 // time.
82 // TODO(zijiehe): Windows cannot guarantee the frames returned by each
83 // IDXGIOutputDuplication are synchronized. But we are using a totally
84 // different threading model than the way Windows suggested, it's hard to
85 // synchronize them manually. But we should find a way to do it.
86 bool Duplicate(Context* context,
87 const DesktopFrame* last_frame,
88 DesktopFrame* target);
89
90 // Captures one monitor and writes into target. |monitor_id| should >= 0. If
91 // |monitor_id| is greater than the total screen count of all the Duplicators,
92 // this function returns false.
93 bool DuplicateMonitor(Context* context,
94 int monitor_id,
95 const DesktopFrame* last_frame,
96 DesktopFrame* target);
97
98 // Returns dpi of current system. Returns an empty DesktopVector if system
99 // does not support DXGI based capturer.
100 DesktopVector dpi();
101
102 // Returns entire desktop size. Returns an empty DesktopRect if system does
103 // not support DXGI based capturer.
104 DesktopRect desktop_rect();
105
106 // Returns a DesktopSize to cover entire desktop_rect. This may be different
107 // than desktop_rect().size(), since top-left screen does not need to start
108 // from (0, 0).
109 DesktopSize desktop_size();
110
111 // Returns the size of one screen. |monitor_id| should be >= 0. If system does
112 // not support DXGI based capturer, or |monitor_id| is greater than the total
113 // screen count of all the Duplicators, this function returns an empty
114 // DesktopRect.
115 DesktopRect ScreenRect(int id);
116
117 // Returns the count of screens on the system. These screens can be retrieved
118 // by an integer in the range of [0, ScreenCount()). If system does not
119 // support DXGI based capturer, this function returns 0.
120 int ScreenCount();
121
122 private:
123 // Context calls private Unregister(Context*) function during
124 // destructing.
125 friend class Context;
126
127 // A private constructor to ensure consumers to use
128 // DxgiDuplicatorController::Instance().
129 DxgiDuplicatorController();
130
131 // Unregisters Context from this instance and all DxgiAdapterDuplicator(s)
132 // it owns.
133 void Unregister(const Context* const context);
134
135 // All functions below should be called in |lock_| locked scope.
136
137 // If current instance has not been initialized, executes DoInitialize
138 // function, and returns initialize result. Otherwise directly returns true.
139 bool Initialize();
140
141 bool DoInitialize();
142
143 // Clears all COM components referred by this instance. So next Duplicate()
144 // call will eventually initialize this instance again.
145 void Deinitialize();
146
147 // A helper function to check whether a Context has been expired.
148 bool ContextExpired(const Context* const context) const;
149
150 // Updates Context if needed.
151 void Setup(Context* context);
152
153 // Do the real duplication work. |monitor_id < 0| to capture entire screen.
154 bool DoDuplicate(Context* context,
155 int monitor_id,
156 const DesktopFrame* last_frame,
157 DesktopFrame* target);
158
159 // This lock must be locked whenever accessing any of the following objects.
160 rtc::CriticalSection lock_;
161
162 // A self-incremented integer to compare with the one in Context, to
163 // ensure a Context has been initialized after DxgiDuplicatorController.
164 int identity_ = 0;
165 DesktopRect desktop_rect_;
166 DesktopVector dpi_;
167 std::vector<DxgiAdapterDuplicator> duplicators_;
168 };
169
170 } // namespace webrtc
171
172 #endif // WEBRTC_MODULES_DESKTOP_CAPTURE_WIN_DXGI_DUPLICATOR_CONTROLLER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698