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

Side by Side Diff: webrtc/modules/desktop_capture/window_capturer_win.cc

Issue 1705183002: Fix screen flickering for Windows platform… (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 4 years, 10 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2013 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 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 Callback* callback_; 96 Callback* callback_;
97 97
98 // HWND and HDC for the currently selected window or NULL if window is not 98 // HWND and HDC for the currently selected window or NULL if window is not
99 // selected. 99 // selected.
100 HWND window_; 100 HWND window_;
101 101
102 DesktopSize previous_size_; 102 DesktopSize previous_size_;
103 103
104 AeroChecker aero_checker_; 104 AeroChecker aero_checker_;
105 105
106 // This map is used to avoid flickering for the case when SelectWindow() calls
107 // are interleaved with Capture() calls.
108 std::map<HWND, DesktopSize> window_size_map_;
109
106 RTC_DISALLOW_COPY_AND_ASSIGN(WindowCapturerWin); 110 RTC_DISALLOW_COPY_AND_ASSIGN(WindowCapturerWin);
107 }; 111 };
108 112
109 WindowCapturerWin::WindowCapturerWin() 113 WindowCapturerWin::WindowCapturerWin()
110 : callback_(NULL), 114 : callback_(NULL),
111 window_(NULL) { 115 window_(NULL) {
112 } 116 }
113 117
114 WindowCapturerWin::~WindowCapturerWin() { 118 WindowCapturerWin::~WindowCapturerWin() {
115 } 119 }
116 120
117 bool WindowCapturerWin::GetWindowList(WindowList* windows) { 121 bool WindowCapturerWin::GetWindowList(WindowList* windows) {
118 WindowList result; 122 WindowList result;
119 LPARAM param = reinterpret_cast<LPARAM>(&result); 123 LPARAM param = reinterpret_cast<LPARAM>(&result);
120 if (!EnumWindows(&WindowsEnumerationHandler, param)) 124 if (!EnumWindows(&WindowsEnumerationHandler, param))
121 return false; 125 return false;
122 windows->swap(result); 126 windows->swap(result);
127
128 std::map<HWND, DesktopSize> new_map;
129 for (const auto& item : *windows) {
130 HWND hwnd = reinterpret_cast<HWND>(item.id);
131 new_map[hwnd] = window_size_map_[hwnd];
132 }
133 window_size_map_.swap(new_map);
134
123 return true; 135 return true;
124 } 136 }
125 137
126 bool WindowCapturerWin::SelectWindow(WindowId id) { 138 bool WindowCapturerWin::SelectWindow(WindowId id) {
127 HWND window = reinterpret_cast<HWND>(id); 139 HWND window = reinterpret_cast<HWND>(id);
128 if (!IsWindow(window) || !IsWindowVisible(window) || IsIconic(window)) 140 if (!IsWindow(window) || !IsWindowVisible(window) || IsIconic(window))
129 return false; 141 return false;
130 window_ = window; 142 window_ = window;
131 previous_size_.set(0, 0); 143 // When a window is not in the map, window_size_map_[window] will create an
144 // item with DesktopSize (0, 0).
145 previous_size_ = window_size_map_[window];
132 return true; 146 return true;
133 } 147 }
134 148
135 bool WindowCapturerWin::BringSelectedWindowToFront() { 149 bool WindowCapturerWin::BringSelectedWindowToFront() {
136 if (!window_) 150 if (!window_)
137 return false; 151 return false;
138 152
139 if (!IsWindow(window_) || !IsWindowVisible(window_) || IsIconic(window_)) 153 if (!IsWindow(window_) || !IsWindowVisible(window_) || IsIconic(window_))
140 return false; 154 return false;
141 155
(...skipping 21 matching lines...) Expand all
163 } 177 }
164 178
165 // Return a 1x1 black frame if the window is minimized or invisible, to match 179 // Return a 1x1 black frame if the window is minimized or invisible, to match
166 // behavior on mace. Window can be temporarily invisible during the 180 // behavior on mace. Window can be temporarily invisible during the
167 // transition of full screen mode on/off. 181 // transition of full screen mode on/off.
168 if (IsIconic(window_) || !IsWindowVisible(window_)) { 182 if (IsIconic(window_) || !IsWindowVisible(window_)) {
169 BasicDesktopFrame* frame = new BasicDesktopFrame(DesktopSize(1, 1)); 183 BasicDesktopFrame* frame = new BasicDesktopFrame(DesktopSize(1, 1));
170 memset(frame->data(), 0, frame->stride() * frame->size().height()); 184 memset(frame->data(), 0, frame->stride() * frame->size().height());
171 185
172 previous_size_ = frame->size(); 186 previous_size_ = frame->size();
187 window_size_map_[window_] = previous_size_;
173 callback_->OnCaptureCompleted(frame); 188 callback_->OnCaptureCompleted(frame);
174 return; 189 return;
175 } 190 }
176 191
177 DesktopRect original_rect; 192 DesktopRect original_rect;
178 DesktopRect cropped_rect; 193 DesktopRect cropped_rect;
179 if (!GetCroppedWindowRect(window_, &cropped_rect, &original_rect)) { 194 if (!GetCroppedWindowRect(window_, &cropped_rect, &original_rect)) {
180 LOG(LS_WARNING) << "Failed to get window info: " << GetLastError(); 195 LOG(LS_WARNING) << "Failed to get window info: " << GetLastError();
181 callback_->OnCaptureCompleted(NULL); 196 callback_->OnCaptureCompleted(NULL);
182 return; 197 return;
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 cropped_rect.left() - original_rect.left(), 244 cropped_rect.left() - original_rect.left(),
230 cropped_rect.top() - original_rect.top(), 245 cropped_rect.top() - original_rect.top(),
231 SRCCOPY); 246 SRCCOPY);
232 } 247 }
233 248
234 SelectObject(mem_dc, previous_object); 249 SelectObject(mem_dc, previous_object);
235 DeleteDC(mem_dc); 250 DeleteDC(mem_dc);
236 ReleaseDC(window_, window_dc); 251 ReleaseDC(window_, window_dc);
237 252
238 previous_size_ = frame->size(); 253 previous_size_ = frame->size();
254 window_size_map_[window_] = previous_size_;
239 255
240 frame->mutable_updated_region()->SetRect( 256 frame->mutable_updated_region()->SetRect(
241 DesktopRect::MakeSize(frame->size())); 257 DesktopRect::MakeSize(frame->size()));
242 258
243 if (!result) { 259 if (!result) {
244 LOG(LS_ERROR) << "Both PrintWindow() and BitBlt() failed."; 260 LOG(LS_ERROR) << "Both PrintWindow() and BitBlt() failed.";
245 frame.reset(); 261 frame.reset();
246 } 262 }
247 263
248 callback_->OnCaptureCompleted(frame.release()); 264 callback_->OnCaptureCompleted(frame.release());
249 } 265 }
250 266
251 } // namespace 267 } // namespace
252 268
253 // static 269 // static
254 WindowCapturer* WindowCapturer::Create(const DesktopCaptureOptions& options) { 270 WindowCapturer* WindowCapturer::Create(const DesktopCaptureOptions& options) {
255 return new WindowCapturerWin(); 271 return new WindowCapturerWin();
256 } 272 }
257 273
258 } // namespace webrtc 274 } // namespace webrtc
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698