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

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

Powered by Google App Engine
This is Rietveld 408576698