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

Side by Side Diff: webrtc/modules/desktop_capture/win/screen_capturer_win_gdi.cc

Issue 2030333003: Revert of Use std::unique_ptr<> to pass frame ownership in DesktopCapturer impls. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 4 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) 2014 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2014 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
(...skipping 21 matching lines...) Expand all
32 namespace { 32 namespace {
33 33
34 // Constants from dwmapi.h. 34 // Constants from dwmapi.h.
35 const UINT DWM_EC_DISABLECOMPOSITION = 0; 35 const UINT DWM_EC_DISABLECOMPOSITION = 0;
36 const UINT DWM_EC_ENABLECOMPOSITION = 1; 36 const UINT DWM_EC_ENABLECOMPOSITION = 1;
37 37
38 const wchar_t kDwmapiLibraryName[] = L"dwmapi.dll"; 38 const wchar_t kDwmapiLibraryName[] = L"dwmapi.dll";
39 39
40 } // namespace 40 } // namespace
41 41
42 ScreenCapturerWinGdi::ScreenCapturerWinGdi( 42 ScreenCapturerWinGdi::ScreenCapturerWinGdi(const DesktopCaptureOptions& options)
43 const DesktopCaptureOptions& options) { 43 : callback_(NULL),
44 current_screen_id_(kFullDesktopScreenId),
45 desktop_dc_(NULL),
46 memory_dc_(NULL),
47 dwmapi_library_(NULL),
48 composition_func_(NULL),
49 set_thread_execution_state_failed_(false) {
44 if (options.disable_effects()) { 50 if (options.disable_effects()) {
45 // Load dwmapi.dll dynamically since it is not available on XP. 51 // Load dwmapi.dll dynamically since it is not available on XP.
46 if (!dwmapi_library_) 52 if (!dwmapi_library_)
47 dwmapi_library_ = LoadLibrary(kDwmapiLibraryName); 53 dwmapi_library_ = LoadLibrary(kDwmapiLibraryName);
48 54
49 if (dwmapi_library_) { 55 if (dwmapi_library_) {
50 composition_func_ = reinterpret_cast<DwmEnableCompositionFunc>( 56 composition_func_ = reinterpret_cast<DwmEnableCompositionFunc>(
51 GetProcAddress(dwmapi_library_, "DwmEnableComposition")); 57 GetProcAddress(dwmapi_library_, "DwmEnableComposition"));
52 } 58 }
53 } 59 }
(...skipping 30 matching lines...) Expand all
84 set_thread_execution_state_failed_ = true; 90 set_thread_execution_state_failed_ = true;
85 LOG_F(LS_WARNING) << "Failed to make system & display power assertion: " 91 LOG_F(LS_WARNING) << "Failed to make system & display power assertion: "
86 << GetLastError(); 92 << GetLastError();
87 } 93 }
88 } 94 }
89 95
90 // Make sure the GDI capture resources are up-to-date. 96 // Make sure the GDI capture resources are up-to-date.
91 PrepareCaptureResources(); 97 PrepareCaptureResources();
92 98
93 if (!CaptureImage()) { 99 if (!CaptureImage()) {
94 callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr); 100 callback_->OnCaptureCompleted(NULL);
95 return; 101 return;
96 } 102 }
97 103
98 const DesktopFrame* current_frame = queue_.current_frame(); 104 const DesktopFrame* current_frame = queue_.current_frame();
99 const DesktopFrame* last_frame = queue_.previous_frame(); 105 const DesktopFrame* last_frame = queue_.previous_frame();
100 if (last_frame && last_frame->size().equals(current_frame->size())) { 106 if (last_frame && last_frame->size().equals(current_frame->size())) {
101 // Make sure the differencer is set up correctly for these previous and 107 // Make sure the differencer is set up correctly for these previous and
102 // current screens. 108 // current screens.
103 if (!differ_.get() || 109 if (!differ_.get() ||
104 (differ_->width() != current_frame->size().width()) || 110 (differ_->width() != current_frame->size().width()) ||
(...skipping 12 matching lines...) Expand all
117 helper_.InvalidateRegion(region); 123 helper_.InvalidateRegion(region);
118 } else { 124 } else {
119 // No previous frame is available, or the screen is resized. Invalidate the 125 // No previous frame is available, or the screen is resized. Invalidate the
120 // whole screen. 126 // whole screen.
121 helper_.InvalidateScreen(current_frame->size()); 127 helper_.InvalidateScreen(current_frame->size());
122 } 128 }
123 129
124 helper_.set_size_most_recent(current_frame->size()); 130 helper_.set_size_most_recent(current_frame->size());
125 131
126 // Emit the current frame. 132 // Emit the current frame.
127 std::unique_ptr<DesktopFrame> frame = queue_.current_frame()->Share(); 133 DesktopFrame* frame = queue_.current_frame()->Share();
128 frame->set_dpi(DesktopVector( 134 frame->set_dpi(DesktopVector(
129 GetDeviceCaps(desktop_dc_, LOGPIXELSX), 135 GetDeviceCaps(desktop_dc_, LOGPIXELSX),
130 GetDeviceCaps(desktop_dc_, LOGPIXELSY))); 136 GetDeviceCaps(desktop_dc_, LOGPIXELSY)));
131 frame->mutable_updated_region()->Clear(); 137 frame->mutable_updated_region()->Clear();
132 helper_.TakeInvalidRegion(frame->mutable_updated_region()); 138 helper_.TakeInvalidRegion(frame->mutable_updated_region());
133 frame->set_capture_time_ms( 139 frame->set_capture_time_ms(
134 (rtc::TimeNanos() - capture_start_time_nanos) / 140 (rtc::TimeNanos() - capture_start_time_nanos) /
135 rtc::kNumNanosecsPerMillisec); 141 rtc::kNumNanosecsPerMillisec);
136 callback_->OnCaptureResult(Result::SUCCESS, std::move(frame)); 142 callback_->OnCaptureCompleted(frame);
137 } 143 }
138 144
139 bool ScreenCapturerWinGdi::GetScreenList(ScreenList* screens) { 145 bool ScreenCapturerWinGdi::GetScreenList(ScreenList* screens) {
140 return webrtc::GetScreenList(screens); 146 return webrtc::GetScreenList(screens);
141 } 147 }
142 148
143 bool ScreenCapturerWinGdi::SelectScreen(ScreenId id) { 149 bool ScreenCapturerWinGdi::SelectScreen(ScreenId id) {
144 bool valid = IsScreenValid(id, &current_device_key_); 150 bool valid = IsScreenValid(id, &current_device_key_);
145 if (valid) 151 if (valid)
146 current_screen_id_ = id; 152 current_screen_id_ = id;
(...skipping 10 matching lines...) Expand all
157 // will restore Aero automatically if the process exits. This has no effect 163 // will restore Aero automatically if the process exits. This has no effect
158 // under Windows 8 or higher. See crbug.com/124018. 164 // under Windows 8 or higher. See crbug.com/124018.
159 if (composition_func_) 165 if (composition_func_)
160 (*composition_func_)(DWM_EC_DISABLECOMPOSITION); 166 (*composition_func_)(DWM_EC_DISABLECOMPOSITION);
161 } 167 }
162 168
163 void ScreenCapturerWinGdi::PrepareCaptureResources() { 169 void ScreenCapturerWinGdi::PrepareCaptureResources() {
164 // Switch to the desktop receiving user input if different from the current 170 // Switch to the desktop receiving user input if different from the current
165 // one. 171 // one.
166 std::unique_ptr<Desktop> input_desktop(Desktop::GetInputDesktop()); 172 std::unique_ptr<Desktop> input_desktop(Desktop::GetInputDesktop());
167 if (input_desktop && !desktop_.IsSame(*input_desktop)) { 173 if (input_desktop.get() != NULL && !desktop_.IsSame(*input_desktop)) {
168 // Release GDI resources otherwise SetThreadDesktop will fail. 174 // Release GDI resources otherwise SetThreadDesktop will fail.
169 if (desktop_dc_) { 175 if (desktop_dc_) {
170 ReleaseDC(NULL, desktop_dc_); 176 ReleaseDC(NULL, desktop_dc_);
171 desktop_dc_ = nullptr; 177 desktop_dc_ = NULL;
172 } 178 }
173 179
174 if (memory_dc_) { 180 if (memory_dc_) {
175 DeleteDC(memory_dc_); 181 DeleteDC(memory_dc_);
176 memory_dc_ = nullptr; 182 memory_dc_ = NULL;
177 } 183 }
178 184
179 // If SetThreadDesktop() fails, the thread is still assigned a desktop. 185 // If SetThreadDesktop() fails, the thread is still assigned a desktop.
180 // So we can continue capture screen bits, just from the wrong desktop. 186 // So we can continue capture screen bits, just from the wrong desktop.
181 desktop_.SetThreadDesktop(input_desktop.release()); 187 desktop_.SetThreadDesktop(input_desktop.release());
182 188
183 // Re-assert our vote to disable Aero. 189 // Re-assert our vote to disable Aero.
184 // See crbug.com/124018 and crbug.com/129906. 190 // See crbug.com/124018 and crbug.com/129906.
185 if (composition_func_) { 191 if (composition_func_ != NULL) {
186 (*composition_func_)(DWM_EC_DISABLECOMPOSITION); 192 (*composition_func_)(DWM_EC_DISABLECOMPOSITION);
187 } 193 }
188 } 194 }
189 195
190 // If the display bounds have changed then recreate GDI resources. 196 // If the display bounds have changed then recreate GDI resources.
191 // TODO(wez): Also check for pixel format changes. 197 // TODO(wez): Also check for pixel format changes.
192 DesktopRect screen_rect(DesktopRect::MakeXYWH( 198 DesktopRect screen_rect(DesktopRect::MakeXYWH(
193 GetSystemMetrics(SM_XVIRTUALSCREEN), 199 GetSystemMetrics(SM_XVIRTUALSCREEN),
194 GetSystemMetrics(SM_YVIRTUALSCREEN), 200 GetSystemMetrics(SM_YVIRTUALSCREEN),
195 GetSystemMetrics(SM_CXVIRTUALSCREEN), 201 GetSystemMetrics(SM_CXVIRTUALSCREEN),
196 GetSystemMetrics(SM_CYVIRTUALSCREEN))); 202 GetSystemMetrics(SM_CYVIRTUALSCREEN)));
197 if (!screen_rect.equals(desktop_dc_rect_)) { 203 if (!screen_rect.equals(desktop_dc_rect_)) {
198 if (desktop_dc_) { 204 if (desktop_dc_) {
199 ReleaseDC(NULL, desktop_dc_); 205 ReleaseDC(NULL, desktop_dc_);
200 desktop_dc_ = nullptr; 206 desktop_dc_ = NULL;
201 } 207 }
202 if (memory_dc_) { 208 if (memory_dc_) {
203 DeleteDC(memory_dc_); 209 DeleteDC(memory_dc_);
204 memory_dc_ = nullptr; 210 memory_dc_ = NULL;
205 } 211 }
206 desktop_dc_rect_ = DesktopRect(); 212 desktop_dc_rect_ = DesktopRect();
207 } 213 }
208 214
209 if (!desktop_dc_) { 215 if (desktop_dc_ == NULL) {
210 assert(!memory_dc_); 216 assert(memory_dc_ == NULL);
211 217
212 // Create GDI device contexts to capture from the desktop into memory. 218 // Create GDI device contexts to capture from the desktop into memory.
213 desktop_dc_ = GetDC(nullptr); 219 desktop_dc_ = GetDC(NULL);
214 if (!desktop_dc_) 220 if (!desktop_dc_)
215 abort(); 221 abort();
216 memory_dc_ = CreateCompatibleDC(desktop_dc_); 222 memory_dc_ = CreateCompatibleDC(desktop_dc_);
217 if (!memory_dc_) 223 if (!memory_dc_)
218 abort(); 224 abort();
219 225
220 desktop_dc_rect_ = screen_rect; 226 desktop_dc_rect_ = screen_rect;
221 227
222 // Make sure the frame buffers will be reallocated. 228 // Make sure the frame buffers will be reallocated.
223 queue_.Reset(); 229 queue_.Reset();
224 230
225 helper_.ClearInvalidRegion(); 231 helper_.ClearInvalidRegion();
226 } 232 }
227 } 233 }
228 234
229 bool ScreenCapturerWinGdi::CaptureImage() { 235 bool ScreenCapturerWinGdi::CaptureImage() {
230 DesktopRect screen_rect = 236 DesktopRect screen_rect =
231 GetScreenRect(current_screen_id_, current_device_key_); 237 GetScreenRect(current_screen_id_, current_device_key_);
232 if (screen_rect.is_empty()) 238 if (screen_rect.is_empty())
233 return false; 239 return false;
234 240
235 DesktopSize size = screen_rect.size(); 241 DesktopSize size = screen_rect.size();
236 // If the current buffer is from an older generation then allocate a new one. 242 // If the current buffer is from an older generation then allocate a new one.
237 // Note that we can't reallocate other buffers at this point, since the caller 243 // Note that we can't reallocate other buffers at this point, since the caller
238 // may still be reading from them. 244 // may still be reading from them.
239 if (!queue_.current_frame() || 245 if (!queue_.current_frame() ||
240 !queue_.current_frame()->size().equals(screen_rect.size())) { 246 !queue_.current_frame()->size().equals(screen_rect.size())) {
241 assert(desktop_dc_); 247 assert(desktop_dc_ != NULL);
242 assert(memory_dc_); 248 assert(memory_dc_ != NULL);
243 249
244 std::unique_ptr<DesktopFrame> buffer = DesktopFrameWin::Create( 250 std::unique_ptr<DesktopFrame> buffer(DesktopFrameWin::Create(
245 size, shared_memory_factory_.get(), desktop_dc_); 251 size, shared_memory_factory_.get(), desktop_dc_));
246 if (!buffer) 252 if (!buffer)
247 return false; 253 return false;
248 queue_.ReplaceCurrentFrame(SharedDesktopFrame::Wrap(std::move(buffer))); 254 queue_.ReplaceCurrentFrame(SharedDesktopFrame::Wrap(buffer.release()));
249 } 255 }
250 256
251 // Select the target bitmap into the memory dc and copy the rect from desktop 257 // Select the target bitmap into the memory dc and copy the rect from desktop
252 // to memory. 258 // to memory.
253 DesktopFrameWin* current = static_cast<DesktopFrameWin*>( 259 DesktopFrameWin* current = static_cast<DesktopFrameWin*>(
254 queue_.current_frame()->GetUnderlyingFrame()); 260 queue_.current_frame()->GetUnderlyingFrame());
255 HGDIOBJ previous_object = SelectObject(memory_dc_, current->bitmap()); 261 HGDIOBJ previous_object = SelectObject(memory_dc_, current->bitmap());
256 if (previous_object) { 262 if (previous_object != NULL) {
257 BitBlt(memory_dc_, 0, 0, screen_rect.width(), screen_rect.height(), 263 BitBlt(memory_dc_,
258 desktop_dc_, screen_rect.left(), screen_rect.top(), 264 0, 0, screen_rect.width(), screen_rect.height(),
265 desktop_dc_,
266 screen_rect.left(), screen_rect.top(),
259 SRCCOPY | CAPTUREBLT); 267 SRCCOPY | CAPTUREBLT);
260 268
261 // Select back the previously selected object to that the device contect 269 // Select back the previously selected object to that the device contect
262 // could be destroyed independently of the bitmap if needed. 270 // could be destroyed independently of the bitmap if needed.
263 SelectObject(memory_dc_, previous_object); 271 SelectObject(memory_dc_, previous_object);
264 } 272 }
265 return true; 273 return true;
266 } 274 }
267 275
268 } // namespace webrtc 276 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698