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

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

Issue 2099123002: [Chromoting] Improve DirectX capturer to support multiple outputs (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Use a self-incremented integer to identify a DxgiDuplicatorContaienr::Initialize 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_CONTAINER_H_
12 #define MODULES_DESKTOP_CAPTURE_WIN_DXGI_DUPLICATOR_CONTAINER_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 container for all the objects we need to call Windows DirectX based capture
27 // APIs. Note, one application can only have one IDXGIOutputDuplication instance
28 // per output, so this class should be singleton.
29 //
30 // Consumers should create a DxgiContext and keep it through their lifetime.
31 // Calls Prepare() function with the DxgiContext before each Duplicate()
32 // function calls. If a previous Prepare() function call returns true, but a
33 // later one returns false, this usually means the display mode is changing.
34 // Consumers should retry after a while. (Typically 50 milliseconds, but
35 // according to hardware performance, this time may be various.)
36 //
37 // This implementation is typically for ScreenCapturer(s) with double buffering,
38 // such as ScreenCapturerWinDirectx. And it should work with consumers with one
39 // buffer, i.e. Consumers can always send nullptr for |last_frame|. Some minor
40 // changes in DxgiOutputDuplicator class are nice to have to reduce size of data
41 // to copy (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.
44 class DxgiDuplicatorContainer {
Sergey Ulanov 2016/07/28 22:15:32 Maybe call this DxgiDuplicatorController to make t
Hzj_jie 2016/07/29 02:12:23 Done.
45 public:
46 // Creates or retrieves the singleton instance of DxgiDuplicatorContainer.
47 static DxgiDuplicatorContainer* Instance();
48
49 // Destructs current instance. We need to make sure COM components and their
50 // containers are destructed in correct order.
51 ~DxgiDuplicatorContainer();
52
53 // Initializes all the components and updates |context|. This function equals
54 // to call Prepare() and Setup(DxgiContext*) sequentially.
55 bool Prepare(DxgiContext* context);
56
57 // Initializes all the components. Returns false if system does not support
58 // DirectX based capture, or system resource is not enough to support to
59 // capture all monitors. By default, only four applications can capture the
60 // screen with DirectX based capture simultaneously. Returns true if this
61 // instance has been initialized already.
62 bool Prepare();
63
64 // Captures current screen and writes into target. Since we are using double
65 // buffering, |last_frame|.updated_region() is used to represent the not
66 // updated regions in current |target| frame, which should also be copied this
67 // time.
68 // TODO(zijiehe): Windows cannot guarantee the frames returned by each
69 // IDXGIOutputDuplication are synchronized. But we are using a totally
70 // different threading model than the way Windows suggested, it's hard to
71 // synchronize them manually. But we should find a way to do it.
72 bool Duplicate(DxgiContext* context,
73 DesktopFrame* target,
74 const DesktopFrame* last_frame);
75
76 // Captures one screen and writes into target. If id < 0 or greater than
77 // the total screen count of all the Duplicators, this function returns false.
78 bool Duplicate(DxgiContext* context,
79 int id,
80 DesktopFrame* target,
81 const DesktopFrame* last_frame);
82
83 DesktopVector dpi() const { return dpi_; }
84
85 // Returns entire desktop size.
86 DesktopRect desktop_rect() const { return desktop_rect_; }
87
88 // Returns a DesktopSize to cover entire desktop_rect. This may be different
89 // than desktop_rect().size(), since top-left screen does not need to start
90 // from (0, 0).
91 DesktopSize desktop_size() const {
92 return DesktopSize(desktop_rect_.right(), desktop_rect_.bottom());
93 }
94
95 // Returns the size of one screen. If id < 0 or greater than the total screen
96 // count of all the Duplicators, this function returns an empty DesktopRect.
97 DesktopRect ScreenRect(int id) const;
98
99 // Returns the count of screens on the system. These screens can be retrieved
100 // by an integer in the range of [0, ScreenCount()).
101 int ScreenCount() const;
102
103 private:
104 // DxgiContext calls private Unregister(DxgiContext*) function during
105 // destructing.
106 friend class DxgiContext;
107
108 // A class to allow only one thread to enter. This class is used to make sure
109 // only one Initialize function call is being performed.
110 class SingleEntry {
111 public:
112 bool Enter();
113 void Exit();
114 bool Hold() const;
115
116 private:
117 rtc::CriticalSection lock_;
118 bool entered_ = false;
119 };
120
121 // A helper class to execute SingleEntry::Exit in its destructor.
122 class AutoExit;
123
124 // A private constructor to ensure consumers to use
125 // DxgiDuplicatorContainer::Instance().
126 DxgiDuplicatorContainer();
127
128 // A helper function to check whether a DxgiContext has been expired. This
129 // function should be called in lock_ locked scope.
130 bool DxgiContextExpired(const DxgiContext* const context) const;
131
132 // Updates DxgiContext if needed.
133 void Setup(DxgiContext* context);
134
135 // Unregisters DxgiContext from this instance and all DxgiAdapterDuplicator(s)
136 // it owns.
137 void Unregister(const DxgiContext* const context);
138
139 // Does the real initialization work.
140 bool DoInitialize();
141
142 // Clears all COM components referred by this instance. So next Prepare()
143 // call will eventually initialize this instance again.
144 void Deinitialize();
145
146 rtc::CriticalSection lock_;
147 SingleEntry initializing_;
148
149 // A self-incremented integer to compare with the one in DxgiContext, to
150 // ensure a DxgiContext has been initialized after DxgiDuplicatorContainer.
151 int identity_ = 0;
152 DesktopRect desktop_rect_;
153 DesktopVector dpi_;
154 std::vector<DxgiAdapterDuplicator> duplicators_;
155 };
156
157 } // namespace webrtc
158
159 #endif // MODULES_DESKTOP_CAPTURE_WIN_DXGI_DUPLICATOR_CONTAINER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698