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

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

Issue 2933893003: Add reference counter of DxgiDuplicatorController to unload DXGI components (Closed)
Patch Set: unique_ptr -> scoped_refptr Created 3 years, 6 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
1 /* 1 /*
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #ifndef WEBRTC_MODULES_DESKTOP_CAPTURE_WIN_DXGI_DUPLICATOR_CONTROLLER_H_ 11 #ifndef WEBRTC_MODULES_DESKTOP_CAPTURE_WIN_DXGI_DUPLICATOR_CONTROLLER_H_
12 #define WEBRTC_MODULES_DESKTOP_CAPTURE_WIN_DXGI_DUPLICATOR_CONTROLLER_H_ 12 #define WEBRTC_MODULES_DESKTOP_CAPTURE_WIN_DXGI_DUPLICATOR_CONTROLLER_H_
13 13
14 #include <D3DCommon.h> 14 #include <D3DCommon.h>
15 15
16 #include <memory> 16 #include <atomic>
17 #include <vector> 17 #include <vector>
18 18
19 #include "webrtc/base/criticalsection.h" 19 #include "webrtc/base/criticalsection.h"
20 #include "webrtc/base/scoped_ref_ptr.h"
20 #include "webrtc/modules/desktop_capture/desktop_geometry.h" 21 #include "webrtc/modules/desktop_capture/desktop_geometry.h"
21 #include "webrtc/modules/desktop_capture/resolution_change_detector.h" 22 #include "webrtc/modules/desktop_capture/resolution_change_detector.h"
22 #include "webrtc/modules/desktop_capture/shared_desktop_frame.h" 23 #include "webrtc/modules/desktop_capture/shared_desktop_frame.h"
23 #include "webrtc/modules/desktop_capture/win/d3d_device.h" 24 #include "webrtc/modules/desktop_capture/win/d3d_device.h"
24 #include "webrtc/modules/desktop_capture/win/dxgi_adapter_duplicator.h" 25 #include "webrtc/modules/desktop_capture/win/dxgi_adapter_duplicator.h"
25 #include "webrtc/modules/desktop_capture/win/dxgi_context.h" 26 #include "webrtc/modules/desktop_capture/win/dxgi_context.h"
26 #include "webrtc/modules/desktop_capture/win/dxgi_frame.h" 27 #include "webrtc/modules/desktop_capture/win/dxgi_frame.h"
27 28
28 namespace webrtc { 29 namespace webrtc {
29 30
30 // A controller for all the objects we need to call Windows DirectX capture APIs 31 // A controller for all the objects we need to call Windows DirectX capture APIs
31 // It's a singleton because only one IDXGIOutputDuplication instance per monitor 32 // It's a singleton because only one IDXGIOutputDuplication instance per monitor
32 // is allowed per application. 33 // is allowed per application.
33 // 34 //
34 // Consumers should create a DxgiDuplicatorController::Context and keep it 35 // Consumers should create a DxgiDuplicatorController::Context and keep it
35 // throughout their lifetime, and pass it when calling Duplicate(). Consumers 36 // throughout their lifetime, and pass it when calling Duplicate(). Consumers
36 // can also call IsSupported() to determine whether the system supports DXGI 37 // can also call IsSupported() to determine whether the system supports DXGI
37 // duplicator or not. If a previous IsSupported() function call returns true, 38 // duplicator or not. If a previous IsSupported() function call returns true,
38 // but a later Duplicate() returns false, this usually means the display mode is 39 // but a later Duplicate() returns false, this usually means the display mode is
39 // changing. Consumers should retry after a while. (Typically 50 milliseconds, 40 // changing. Consumers should retry after a while. (Typically 50 milliseconds,
40 // but according to hardware performance, this time may vary.) 41 // but according to hardware performance, this time may vary.)
41 class DxgiDuplicatorController { 42 class DxgiDuplicatorController {
43 private:
44 struct ReferenceReleaser final {
Sergey Ulanov 2017/06/19 18:52:43 I don't think you need this anymore
Hzj_jie 2017/06/19 20:19:46 Done.
45 void operator()(DxgiDuplicatorController* instance) const;
46 };
47
42 public: 48 public:
43 using Context = DxgiFrameContext; 49 using Context = DxgiFrameContext;
50 using Reference = rtc::scoped_refptr<DxgiDuplicatorController>;
Sergey Ulanov 2017/06/19 18:52:43 I'd prefer to use scoped_refptr<> directly. It won
Hzj_jie 2017/06/19 20:19:47 Done.
44 51
45 // A collection of D3d information we are interested on, which may impact 52 // A collection of D3d information we are interested on, which may impact
46 // capturer performance or reliability. 53 // capturer performance or reliability.
47 struct D3dInfo { 54 struct D3dInfo {
48 // Each video adapter has its own D3D_FEATURE_LEVEL, so this structure 55 // Each video adapter has its own D3D_FEATURE_LEVEL, so this structure
49 // contains the minimum and maximium D3D_FEATURE_LEVELs current system 56 // contains the minimum and maximium D3D_FEATURE_LEVELs current system
50 // supports. 57 // supports.
51 // Both fields can be 0, which is the default value to indicate no valid 58 // Both fields can be 0, which is the default value to indicate no valid
52 // D3D_FEATURE_LEVEL has been retrieved from underlying OS APIs. 59 // D3D_FEATURE_LEVEL has been retrieved from underlying OS APIs.
53 D3D_FEATURE_LEVEL min_feature_level; 60 D3D_FEATURE_LEVEL min_feature_level;
54 D3D_FEATURE_LEVEL max_feature_level; 61 D3D_FEATURE_LEVEL max_feature_level;
55 62
56 // TODO(zijiehe): Add more fields, such as manufacturer name, mode, driver 63 // TODO(zijiehe): Add more fields, such as manufacturer name, mode, driver
57 // version. 64 // version.
58 }; 65 };
59 66
60 enum class Result { 67 enum class Result {
61 SUCCEEDED, 68 SUCCEEDED,
62 FRAME_PREPARE_FAILED, 69 FRAME_PREPARE_FAILED,
63 INITIALIZATION_FAILED, 70 INITIALIZATION_FAILED,
64 DUPLICATION_FAILED, 71 DUPLICATION_FAILED,
65 INVALID_MONITOR_ID, 72 INVALID_MONITOR_ID,
66 }; 73 };
67 74
75 // Deprecated: use "GetRefence()" instead.
Sergey Ulanov 2017/06/19 18:52:43 Maybe just update this function to return scoped_r
Hzj_jie 2017/06/19 20:19:46 Done. The only concern is the name "Instance()" do
Do not use (sergeyu) 2017/06/19 20:54:44 I think Instance() is still fine. We still have on
68 // Returns the singleton instance of DxgiDuplicatorController. 76 // Returns the singleton instance of DxgiDuplicatorController.
69 static DxgiDuplicatorController* Instance(); 77 static DxgiDuplicatorController* Instance();
70 78
71 // Destructs current instance. We need to make sure COM components and their 79 static Reference GetReference();
72 // containers are destructed in correct order. This function calls
73 // Deinitialize() to do the real work.
74 ~DxgiDuplicatorController();
75
76 // All the following public functions implicitly call Initialize() function. 80 // All the following public functions implicitly call Initialize() function.
77 81
78 // Detects whether the system supports DXGI based capturer. 82 // Detects whether the system supports DXGI based capturer.
79 bool IsSupported(); 83 bool IsSupported();
80 84
81 // Returns a copy of D3dInfo composed by last Initialize() function call. 85 // Returns a copy of D3dInfo composed by last Initialize() function call.
82 bool RetrieveD3dInfo(D3dInfo* info); 86 bool RetrieveD3dInfo(D3dInfo* info);
83 87
84 // Captures current screen and writes into |frame|. 88 // Captures current screen and writes into |frame|.
85 // TODO(zijiehe): Windows cannot guarantee the frames returned by each 89 // TODO(zijiehe): Windows cannot guarantee the frames returned by each
(...skipping 14 matching lines...) Expand all
100 // Returns the count of screens on the system. These screens can be retrieved 104 // Returns the count of screens on the system. These screens can be retrieved
101 // by an integer in the range of [0, ScreenCount()). If system does not 105 // by an integer in the range of [0, ScreenCount()). If system does not
102 // support DXGI based capturer, this function returns 0. 106 // support DXGI based capturer, this function returns 0.
103 int ScreenCount(); 107 int ScreenCount();
104 108
105 private: 109 private:
106 // DxgiFrameContext calls private Unregister(Context*) function during 110 // DxgiFrameContext calls private Unregister(Context*) function during
107 // destructing. 111 // destructing.
108 friend DxgiFrameContext::~DxgiFrameContext(); 112 friend DxgiFrameContext::~DxgiFrameContext();
109 113
114 // scoped_refptr<DxgiDuplicatorController> accesses private AddRef() and
115 // Release() functions.
116 friend class rtc::scoped_refptr<DxgiDuplicatorController>;
117
110 // A private constructor to ensure consumers to use 118 // A private constructor to ensure consumers to use
111 // DxgiDuplicatorController::Instance(). 119 // DxgiDuplicatorController::GetReference().
112 DxgiDuplicatorController(); 120 DxgiDuplicatorController();
113 121
122 // Not implemented: The singleton DxgiDuplicatorController instance should not
123 // be deleted.
124 ~DxgiDuplicatorController();
125
126 // RefCountedInterface implementations.
127 void AddRef() const;
128 void Release();
129
114 // Does the real duplication work. Setting |monitor_id| < 0 to capture entire 130 // Does the real duplication work. Setting |monitor_id| < 0 to capture entire
115 // screen. This function calls Initialize(). And if the duplication failed, 131 // screen. This function calls Initialize(). And if the duplication failed,
116 // this function calls Deinitialize() to ensure the Dxgi components can be 132 // this function calls Deinitialize() to ensure the Dxgi components can be
117 // reinitialized next time. 133 // reinitialized next time.
118 Result DoDuplicate(DxgiFrame* frame, int monitor_id); 134 Result DoDuplicate(DxgiFrame* frame, int monitor_id);
119 135
136 // Unload all the DXGI components and releases the resources. This function
137 // wraps Deinitialize() with |lock_|.
138 void Unload();
139
120 // Unregisters Context from this instance and all DxgiAdapterDuplicator(s) 140 // Unregisters Context from this instance and all DxgiAdapterDuplicator(s)
121 // it owns. 141 // it owns.
122 void Unregister(const Context* const context); 142 void Unregister(const Context* const context);
123 143
124 // All functions below should be called in |lock_| locked scope and should be 144 // All functions below should be called in |lock_| locked scope and should be
125 // after a successful Initialize(). 145 // after a successful Initialize().
126 146
127 // If current instance has not been initialized, executes DoInitialize() 147 // If current instance has not been initialized, executes DoInitialize()
128 // function, and returns initialize result. Otherwise directly returns true. 148 // function, and returns initialize result. Otherwise directly returns true.
129 // This function may calls Deinitialize() if initialization failed. 149 // This function may calls Deinitialize() if initialization failed.
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 // According to http://crbug.com/682112, dxgi capturer returns a black frame 198 // According to http://crbug.com/682112, dxgi capturer returns a black frame
179 // during first several capture attempts. 199 // during first several capture attempts.
180 bool EnsureFrameCaptured(Context* context, SharedDesktopFrame* target); 200 bool EnsureFrameCaptured(Context* context, SharedDesktopFrame* target);
181 201
182 // Moves |desktop_rect_| and all underlying |duplicators_|, putting top left 202 // Moves |desktop_rect_| and all underlying |duplicators_|, putting top left
183 // corner of the desktop at (0, 0). This is necessary because DXGI_OUTPUT_DESC 203 // corner of the desktop at (0, 0). This is necessary because DXGI_OUTPUT_DESC
184 // may return negative coordinates. Called from DoInitialize() after all 204 // may return negative coordinates. Called from DoInitialize() after all
185 // DxgiAdapterDuplicator and DxgiOutputDuplicator instances are initialized. 205 // DxgiAdapterDuplicator and DxgiOutputDuplicator instances are initialized.
186 void TranslateRect(); 206 void TranslateRect();
187 207
208 // The count of references which are now "living".
209 static std::atomic_int refcount_;
210
188 // This lock must be locked whenever accessing any of the following objects. 211 // This lock must be locked whenever accessing any of the following objects.
189 rtc::CriticalSection lock_; 212 rtc::CriticalSection lock_;
190 213
191 // A self-incremented integer to compare with the one in Context. It ensures 214 // A self-incremented integer to compare with the one in Context. It ensures
192 // a Context instance is always initialized after DxgiDuplicatorController. 215 // a Context instance is always initialized after DxgiDuplicatorController.
193 int identity_ = 0; 216 int identity_ = 0;
194 DesktopRect desktop_rect_; 217 DesktopRect desktop_rect_;
195 DesktopVector dpi_; 218 DesktopVector dpi_;
196 std::vector<DxgiAdapterDuplicator> duplicators_; 219 std::vector<DxgiAdapterDuplicator> duplicators_;
197 D3dInfo d3d_info_; 220 D3dInfo d3d_info_;
198 ResolutionChangeDetector resolution_change_detector_; 221 ResolutionChangeDetector resolution_change_detector_;
199 }; 222 };
200 223
201 } // namespace webrtc 224 } // namespace webrtc
202 225
203 #endif // WEBRTC_MODULES_DESKTOP_CAPTURE_WIN_DXGI_DUPLICATOR_CONTROLLER_H_ 226 #endif // WEBRTC_MODULES_DESKTOP_CAPTURE_WIN_DXGI_DUPLICATOR_CONTROLLER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698