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

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: Add reference counter for DxgiDuplicatorController 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 <atomic>
16 #include <memory> 17 #include <memory>
17 #include <vector> 18 #include <vector>
18 19
19 #include "webrtc/base/criticalsection.h" 20 #include "webrtc/base/criticalsection.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 {
45 void operator()(DxgiDuplicatorController* instance) const;
46 };
47
42 public: 48 public:
43 using Context = DxgiFrameContext; 49 using Context = DxgiFrameContext;
50 using Reference =
51 std::unique_ptr<DxgiDuplicatorController, ReferenceReleaser>;
Do not use (sergeyu) 2017/06/15 19:25:19 Do we really need this instead of scoped_refptr<>?
Hzj_jie 2017/06/15 20:32:02 I can imagine three solutions by using scoped_refp
Sergey Ulanov 2017/06/16 05:59:58 I was thinking about (3), but I think (1) may work
44 52
45 // A collection of D3d information we are interested on, which may impact 53 // A collection of D3d information we are interested on, which may impact
46 // capturer performance or reliability. 54 // capturer performance or reliability.
47 struct D3dInfo { 55 struct D3dInfo {
48 // Each video adapter has its own D3D_FEATURE_LEVEL, so this structure 56 // Each video adapter has its own D3D_FEATURE_LEVEL, so this structure
49 // contains the minimum and maximium D3D_FEATURE_LEVELs current system 57 // contains the minimum and maximium D3D_FEATURE_LEVELs current system
50 // supports. 58 // supports.
51 // Both fields can be 0, which is the default value to indicate no valid 59 // 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. 60 // D3D_FEATURE_LEVEL has been retrieved from underlying OS APIs.
53 D3D_FEATURE_LEVEL min_feature_level; 61 D3D_FEATURE_LEVEL min_feature_level;
54 D3D_FEATURE_LEVEL max_feature_level; 62 D3D_FEATURE_LEVEL max_feature_level;
55 63
56 // TODO(zijiehe): Add more fields, such as manufacturer name, mode, driver 64 // TODO(zijiehe): Add more fields, such as manufacturer name, mode, driver
57 // version. 65 // version.
58 }; 66 };
59 67
60 enum class Result { 68 enum class Result {
61 SUCCEEDED, 69 SUCCEEDED,
62 FRAME_PREPARE_FAILED, 70 FRAME_PREPARE_FAILED,
63 INITIALIZATION_FAILED, 71 INITIALIZATION_FAILED,
64 DUPLICATION_FAILED, 72 DUPLICATION_FAILED,
65 INVALID_MONITOR_ID, 73 INVALID_MONITOR_ID,
66 }; 74 };
67 75
76 // Deprecated: use "GetRefence()" instead.
68 // Returns the singleton instance of DxgiDuplicatorController. 77 // Returns the singleton instance of DxgiDuplicatorController.
69 static DxgiDuplicatorController* Instance(); 78 static DxgiDuplicatorController* Instance();
70 79
71 // Destructs current instance. We need to make sure COM components and their 80 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. 81 // All the following public functions implicitly call Initialize() function.
77 82
78 // Detects whether the system supports DXGI based capturer. 83 // Detects whether the system supports DXGI based capturer.
79 bool IsSupported(); 84 bool IsSupported();
80 85
81 // Returns a copy of D3dInfo composed by last Initialize() function call. 86 // Returns a copy of D3dInfo composed by last Initialize() function call.
82 bool RetrieveD3dInfo(D3dInfo* info); 87 bool RetrieveD3dInfo(D3dInfo* info);
83 88
84 // Captures current screen and writes into |frame|. 89 // Captures current screen and writes into |frame|.
85 // TODO(zijiehe): Windows cannot guarantee the frames returned by each 90 // TODO(zijiehe): Windows cannot guarantee the frames returned by each
(...skipping 15 matching lines...) Expand all
101 // by an integer in the range of [0, ScreenCount()). If system does not 106 // by an integer in the range of [0, ScreenCount()). If system does not
102 // support DXGI based capturer, this function returns 0. 107 // support DXGI based capturer, this function returns 0.
103 int ScreenCount(); 108 int ScreenCount();
104 109
105 private: 110 private:
106 // DxgiFrameContext calls private Unregister(Context*) function during 111 // DxgiFrameContext calls private Unregister(Context*) function during
107 // destructing. 112 // destructing.
108 friend DxgiFrameContext::~DxgiFrameContext(); 113 friend DxgiFrameContext::~DxgiFrameContext();
109 114
110 // A private constructor to ensure consumers to use 115 // A private constructor to ensure consumers to use
111 // DxgiDuplicatorController::Instance(). 116 // DxgiDuplicatorController::GetReference().
112 DxgiDuplicatorController(); 117 DxgiDuplicatorController();
113 118
119 // Not implemented: The singleton DxgiDuplicatorController instance should not
120 // be deleted.
121 ~DxgiDuplicatorController();
122
114 // Does the real duplication work. Setting |monitor_id| < 0 to capture entire 123 // Does the real duplication work. Setting |monitor_id| < 0 to capture entire
115 // screen. This function calls Initialize(). And if the duplication failed, 124 // screen. This function calls Initialize(). And if the duplication failed,
116 // this function calls Deinitialize() to ensure the Dxgi components can be 125 // this function calls Deinitialize() to ensure the Dxgi components can be
117 // reinitialized next time. 126 // reinitialized next time.
118 Result DoDuplicate(DxgiFrame* frame, int monitor_id); 127 Result DoDuplicate(DxgiFrame* frame, int monitor_id);
119 128
129 // Unload all the DXGI components and releases the resources. This function
130 // wraps Deinitialize() with |lock_|.
131 void Unload();
132
120 // Unregisters Context from this instance and all DxgiAdapterDuplicator(s) 133 // Unregisters Context from this instance and all DxgiAdapterDuplicator(s)
121 // it owns. 134 // it owns.
122 void Unregister(const Context* const context); 135 void Unregister(const Context* const context);
123 136
124 // All functions below should be called in |lock_| locked scope and should be 137 // All functions below should be called in |lock_| locked scope and should be
125 // after a successful Initialize(). 138 // after a successful Initialize().
126 139
127 // If current instance has not been initialized, executes DoInitialize() 140 // If current instance has not been initialized, executes DoInitialize()
128 // function, and returns initialize result. Otherwise directly returns true. 141 // function, and returns initialize result. Otherwise directly returns true.
129 // This function may calls Deinitialize() if initialization failed. 142 // 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 191 // According to http://crbug.com/682112, dxgi capturer returns a black frame
179 // during first several capture attempts. 192 // during first several capture attempts.
180 bool EnsureFrameCaptured(Context* context, SharedDesktopFrame* target); 193 bool EnsureFrameCaptured(Context* context, SharedDesktopFrame* target);
181 194
182 // Moves |desktop_rect_| and all underlying |duplicators_|, putting top left 195 // 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 196 // corner of the desktop at (0, 0). This is necessary because DXGI_OUTPUT_DESC
184 // may return negative coordinates. Called from DoInitialize() after all 197 // may return negative coordinates. Called from DoInitialize() after all
185 // DxgiAdapterDuplicator and DxgiOutputDuplicator instances are initialized. 198 // DxgiAdapterDuplicator and DxgiOutputDuplicator instances are initialized.
186 void TranslateRect(); 199 void TranslateRect();
187 200
201 // The count of references which are now "living".
202 static std::atomic_int refcount_;
203
188 // This lock must be locked whenever accessing any of the following objects. 204 // This lock must be locked whenever accessing any of the following objects.
189 rtc::CriticalSection lock_; 205 rtc::CriticalSection lock_;
190 206
191 // A self-incremented integer to compare with the one in Context. It ensures 207 // A self-incremented integer to compare with the one in Context. It ensures
192 // a Context instance is always initialized after DxgiDuplicatorController. 208 // a Context instance is always initialized after DxgiDuplicatorController.
193 int identity_ = 0; 209 int identity_ = 0;
194 DesktopRect desktop_rect_; 210 DesktopRect desktop_rect_;
195 DesktopVector dpi_; 211 DesktopVector dpi_;
196 std::vector<DxgiAdapterDuplicator> duplicators_; 212 std::vector<DxgiAdapterDuplicator> duplicators_;
197 D3dInfo d3d_info_; 213 D3dInfo d3d_info_;
198 ResolutionChangeDetector resolution_change_detector_; 214 ResolutionChangeDetector resolution_change_detector_;
199 }; 215 };
200 216
201 } // namespace webrtc 217 } // namespace webrtc
202 218
203 #endif // WEBRTC_MODULES_DESKTOP_CAPTURE_WIN_DXGI_DUPLICATOR_CONTROLLER_H_ 219 #endif // WEBRTC_MODULES_DESKTOP_CAPTURE_WIN_DXGI_DUPLICATOR_CONTROLLER_H_
OLDNEW
« no previous file with comments | « webrtc/modules/desktop_capture/win/dxgi_context.cc ('k') | webrtc/modules/desktop_capture/win/dxgi_duplicator_controller.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698