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

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 #include "webrtc/modules/desktop_capture/win/dxgi_context.h"
23
24 namespace webrtc {
25
26 // A controller for all the objects we need to call Windows DirectX based
27 // capture APIs. Note, one application can only have one IDXGIOutputDuplication
28 // instance per output, so this class should be singleton.
29 //
30 // Consumers should create a DxgiContext and keep it through their lifetime.
31 // Calls Duplicate() function with the DxgiContext. Consumers can also call
32 // Prepare() to determine whether the system supports DXGI duplicator or not. If
33 // a previous Prepare() function call returns true, but a later Duplicate()
34 // returns false, this usually means the display mode is changing. Consumers
35 // should retry after a while. (Typically 50 milliseconds, but according to
36 // hardware performance, this time may be various.)
37 //
38 // This implementation is typically for ScreenCapturer(s) with double buffering,
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
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 DxgiContext instance to Duplicate() function to force duplicator
46 // to treat it as a new consumer.
47 class DxgiDuplicatorController {
48 public:
49 // Creates or retrieves the singleton instance of DxgiDuplicatorController.
50 static DxgiDuplicatorController* Instance();
51
52 // Destructs current instance. We need to make sure COM components and their
53 // containers are destructed in correct order.
54 ~DxgiDuplicatorController();
55
56 // Detects whether the system supports DXGI based capturer.
57 bool IsSupported();
58
59 // Captures current screen and writes into target. Since we are using double
60 // buffering, |last_frame|.updated_region() is used to represent the not
61 // updated regions in current |target| frame, which should also be copied this
62 // time.
63 // TODO(zijiehe): Windows cannot guarantee the frames returned by each
64 // IDXGIOutputDuplication are synchronized. But we are using a totally
65 // different threading model than the way Windows suggested, it's hard to
66 // synchronize them manually. But we should find a way to do it.
67 bool Duplicate(DxgiContext* context,
68 const DesktopFrame* last_frame,
69 DesktopFrame* target);
70
71 // Captures one monitor and writes into target. |monitor_id| should >= 0. If
72 // |monitor_id| is greater than the total screen count of all the Duplicators,
73 // this function returns false.
74 bool DuplicateMonitor(DxgiContext* context,
75 int monitor_id,
76 const DesktopFrame* last_frame,
77 DesktopFrame* target);
78
79 // Returns dpi of current system. Returns an empty DesktopVector if system
80 // does not support DXGI based capturer.
81 DesktopVector dpi();
82
83 // Returns entire desktop size. Returns an empty DesktopRect if system does
84 // not support DXGI based capturer.
85 DesktopRect desktop_rect();
86
87 // Returns a DesktopSize to cover entire desktop_rect. This may be different
88 // than desktop_rect().size(), since top-left screen does not need to start
89 // from (0, 0).
90 DesktopSize desktop_size();
91
92 // Returns the size of one screen. |monitor_id| should be >= 0. If system does
93 // not support DXGI based capturer, or |monitor_id| is greater than the total
94 // screen count of all the Duplicators, this function returns an empty
95 // DesktopRect.
96 DesktopRect ScreenRect(int id);
97
98 // Returns the count of screens on the system. These screens can be retrieved
99 // by an integer in the range of [0, ScreenCount()). If system does not
100 // support DXGI based capturer, this function returns 0.
101 int ScreenCount();
102
103 private:
104 // DxgiContext calls private Unregister(DxgiContext*) function during
105 // destructing.
106 friend class DxgiContext;
107
108 // A private constructor to ensure consumers to use
109 // DxgiDuplicatorController::Instance().
110 DxgiDuplicatorController();
111
112 // Unregisters DxgiContext from this instance and all DxgiAdapterDuplicator(s)
113 // it owns.
114 void Unregister(const DxgiContext* const context);
115
116 /*** All functions below should be called in lock_ locked scope. ***/
117
118 // If current instance has not been initialized, executes DoInitialize
119 // function, and returns initialize result. Otherwise directly returns true.
120 bool Initialize();
121
122 // Does the real initialization work.
123 bool DoInitialize();
124
125 // Clears all COM components referred by this instance. So next Duplicate()
126 // call will eventually initialize this instance again.
127 void Deinitialize();
128
129 // A helper function to check whether a DxgiContext has been expired.
130 bool DxgiContextExpired(const DxgiContext* const context) const;
131
132 // Updates DxgiContext if needed.
133 void Setup(DxgiContext* context);
134
135 // Do the real duplication work. |monitor_id < 0| to capture entire screen.
136 bool DoDuplicate(DxgiContext* context,
137 int monitor_id,
138 const DesktopFrame* last_frame,
139 DesktopFrame* target);
140
141 rtc::CriticalSection lock_;
142
143 // A self-incremented integer to compare with the one in DxgiContext, to
144 // ensure a DxgiContext has been initialized after DxgiDuplicatorController.
145 int identity_ = 0;
146 DesktopRect desktop_rect_;
147 DesktopVector dpi_;
148 std::vector<DxgiAdapterDuplicator> duplicators_;
149 };
150
151 } // namespace webrtc
152
153 #endif // MODULES_DESKTOP_CAPTURE_WIN_DXGI_DUPLICATOR_CONTROLLER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698