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

Side by Side Diff: ui/views/win/hwnd_message_handler.cc

Issue 2562613002: Disable redraw lock when using DirectComposition. (Closed)
Patch Set: Created 4 years 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 | « ui/views/win/hwnd_message_handler.h ('k') | 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 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/views/win/hwnd_message_handler.h" 5 #include "ui/views/win/hwnd_message_handler.h"
6 6
7 #include <dwmapi.h> 7 #include <dwmapi.h>
8 #include <oleacc.h> 8 #include <oleacc.h>
9 #include <shellapi.h> 9 #include <shellapi.h>
10 #include <tchar.h> 10 #include <tchar.h>
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 // The solution is to handle these messages and call DefWindowProc ourselves, 250 // The solution is to handle these messages and call DefWindowProc ourselves,
251 // but prevent the window from being able to update itself for the duration of 251 // but prevent the window from being able to update itself for the duration of
252 // the call. We do this with this class, which automatically calls its 252 // the call. We do this with this class, which automatically calls its
253 // associated Window's lock and unlock functions as it is created and destroyed. 253 // associated Window's lock and unlock functions as it is created and destroyed.
254 // See documentation in those methods for the technique used. 254 // See documentation in those methods for the technique used.
255 // 255 //
256 // The lock only has an effect if the window was visible upon lock creation, as 256 // The lock only has an effect if the window was visible upon lock creation, as
257 // it doesn't guard against direct visiblility changes, and multiple locks may 257 // it doesn't guard against direct visiblility changes, and multiple locks may
258 // exist simultaneously to handle certain nested Windows messages. 258 // exist simultaneously to handle certain nested Windows messages.
259 // 259 //
260 // This lock is disabled when DirectComposition is used and there's a child
261 // rendering window, as the WS_CLIPCHILDREN on the parent window should
262 // prevent the glitched rendering and making the window contents non-visible
263 // can cause a them to disappear for a frame.
264 //
265 // We normally skip locked updates when Aero is on for two reasons:
266 // 1. Because it isn't necessary. However, for windows without WS_CAPTION a
267 // close button may still be drawn, so the resize lock remains enabled for
268 // them. See http://crrev.com/130323
269 // 2. Because toggling the WS_VISIBLE flag may occur while the GPU process is
270 // attempting to present a child window's backbuffer onscreen. When these
271 // two actions race with one another, the child window will either flicker
272 // or will simply stop updating entirely.
273 //
260 // IMPORTANT: Do not use this scoping object for large scopes or periods of 274 // IMPORTANT: Do not use this scoping object for large scopes or periods of
261 // time! IT WILL PREVENT THE WINDOW FROM BEING REDRAWN! (duh). 275 // time! IT WILL PREVENT THE WINDOW FROM BEING REDRAWN! (duh).
262 // 276 //
263 // I would love to hear Raymond Chen's explanation for all this. And maybe a 277 // I would love to hear Raymond Chen's explanation for all this. And maybe a
264 // list of other messages that this applies to ;-) 278 // list of other messages that this applies to ;-)
265 class HWNDMessageHandler::ScopedRedrawLock { 279 class HWNDMessageHandler::ScopedRedrawLock {
266 public: 280 public:
267 explicit ScopedRedrawLock(HWNDMessageHandler* owner) 281 explicit ScopedRedrawLock(HWNDMessageHandler* owner)
268 : owner_(owner), 282 : owner_(owner),
269 hwnd_(owner_->hwnd()), 283 hwnd_(owner_->hwnd()),
270 was_visible_(owner_->IsVisible()), 284 cancel_unlock_(false),
271 cancel_unlock_(false), 285 should_lock_(owner_->IsVisible() && !owner->HasChildRenderingWindow() &&
272 force_(!(GetWindowLong(hwnd_, GWL_STYLE) & WS_CAPTION)) { 286 ::IsWindow(hwnd_) &&
273 if (was_visible_ && ::IsWindow(hwnd_)) 287 (!(GetWindowLong(hwnd_, GWL_STYLE) & WS_CAPTION) ||
274 owner_->LockUpdates(force_); 288 !ui::win::IsAeroGlassEnabled())) {
289 if (should_lock_)
290 owner_->LockUpdates();
275 } 291 }
276 292
277 ~ScopedRedrawLock() { 293 ~ScopedRedrawLock() {
278 if (!cancel_unlock_ && was_visible_ && ::IsWindow(hwnd_)) 294 if (!cancel_unlock_ && should_lock_ && ::IsWindow(hwnd_))
279 owner_->UnlockUpdates(force_); 295 owner_->UnlockUpdates();
280 } 296 }
281 297
282 // Cancel the unlock operation, call this if the Widget is being destroyed. 298 // Cancel the unlock operation, call this if the Widget is being destroyed.
283 void CancelUnlockOperation() { cancel_unlock_ = true; } 299 void CancelUnlockOperation() { cancel_unlock_ = true; }
284 300
285 private: 301 private:
286 // The owner having its style changed. 302 // The owner having its style changed.
287 HWNDMessageHandler* owner_; 303 HWNDMessageHandler* owner_;
288 // The owner's HWND, cached to avoid action after window destruction. 304 // The owner's HWND, cached to avoid action after window destruction.
289 HWND hwnd_; 305 HWND hwnd_;
290 // Records the HWND visibility at the time of creation.
291 bool was_visible_;
292 // A flag indicating that the unlock operation was canceled. 306 // A flag indicating that the unlock operation was canceled.
293 bool cancel_unlock_; 307 bool cancel_unlock_;
294 // If true, perform the redraw lock regardless of Aero state. 308 // If false, don't use redraw lock.
295 bool force_; 309 const bool should_lock_;
296 310
297 DISALLOW_COPY_AND_ASSIGN(ScopedRedrawLock); 311 DISALLOW_COPY_AND_ASSIGN(ScopedRedrawLock);
298 }; 312 };
299 313
300 // static HWNDMessageHandler member initialization. 314 // static HWNDMessageHandler member initialization.
301 base::LazyInstance<HWNDMessageHandler::FullscreenWindowMonitorMap> 315 base::LazyInstance<HWNDMessageHandler::FullscreenWindowMonitorMap>
302 HWNDMessageHandler::fullscreen_monitor_map_ = LAZY_INSTANCE_INITIALIZER; 316 HWNDMessageHandler::fullscreen_monitor_map_ = LAZY_INSTANCE_INITIALIZER;
303 317
304 //////////////////////////////////////////////////////////////////////////////// 318 ////////////////////////////////////////////////////////////////////////////////
305 // HWNDMessageHandler, public: 319 // HWNDMessageHandler, public:
(...skipping 912 matching lines...) Expand 10 before | Expand all | Expand 10 after
1218 ScopedRedrawLock lock(this); 1232 ScopedRedrawLock lock(this);
1219 // The Widget and HWND can be destroyed in the call to DefWindowProc, so use 1233 // The Widget and HWND can be destroyed in the call to DefWindowProc, so use
1220 // the WeakPtrFactory to avoid unlocking (and crashing) after destruction. 1234 // the WeakPtrFactory to avoid unlocking (and crashing) after destruction.
1221 base::WeakPtr<HWNDMessageHandler> ref(weak_factory_.GetWeakPtr()); 1235 base::WeakPtr<HWNDMessageHandler> ref(weak_factory_.GetWeakPtr());
1222 LRESULT result = DefWindowProc(hwnd(), message, w_param, l_param); 1236 LRESULT result = DefWindowProc(hwnd(), message, w_param, l_param);
1223 if (!ref) 1237 if (!ref)
1224 lock.CancelUnlockOperation(); 1238 lock.CancelUnlockOperation();
1225 return result; 1239 return result;
1226 } 1240 }
1227 1241
1228 void HWNDMessageHandler::LockUpdates(bool force) { 1242 void HWNDMessageHandler::LockUpdates() {
1229 // We skip locked updates when Aero is on for two reasons: 1243 if (++lock_updates_count_ == 1) {
1230 // 1. Because it isn't necessary
1231 // 2. Because toggling the WS_VISIBLE flag may occur while the GPU process is
1232 // attempting to present a child window's backbuffer onscreen. When these
1233 // two actions race with one another, the child window will either flicker
1234 // or will simply stop updating entirely.
1235 if ((force || !ui::win::IsAeroGlassEnabled()) && ++lock_updates_count_ == 1) {
1236 SetWindowLong(hwnd(), GWL_STYLE, 1244 SetWindowLong(hwnd(), GWL_STYLE,
1237 GetWindowLong(hwnd(), GWL_STYLE) & ~WS_VISIBLE); 1245 GetWindowLong(hwnd(), GWL_STYLE) & ~WS_VISIBLE);
1238 } 1246 }
1239 } 1247 }
1240 1248
1241 void HWNDMessageHandler::UnlockUpdates(bool force) { 1249 void HWNDMessageHandler::UnlockUpdates() {
1242 if ((force || !ui::win::IsAeroGlassEnabled()) && --lock_updates_count_ <= 0) { 1250 if (--lock_updates_count_ <= 0) {
1243 SetWindowLong(hwnd(), GWL_STYLE, 1251 SetWindowLong(hwnd(), GWL_STYLE,
1244 GetWindowLong(hwnd(), GWL_STYLE) | WS_VISIBLE); 1252 GetWindowLong(hwnd(), GWL_STYLE) | WS_VISIBLE);
1245 lock_updates_count_ = 0; 1253 lock_updates_count_ = 0;
1246 } 1254 }
1247 } 1255 }
1248 1256
1249 void HWNDMessageHandler::ForceRedrawWindow(int attempts) { 1257 void HWNDMessageHandler::ForceRedrawWindow(int attempts) {
1250 if (ui::IsWorkstationLocked()) { 1258 if (ui::IsWorkstationLocked()) {
1251 // Presents will continue to fail as long as the input desktop is 1259 // Presents will continue to fail as long as the input desktop is
1252 // unavailable. 1260 // unavailable.
(...skipping 1496 matching lines...) Expand 10 before | Expand all | Expand 10 after
2749 MONITORINFO monitor_info = {sizeof(monitor_info)}; 2757 MONITORINFO monitor_info = {sizeof(monitor_info)};
2750 GetMonitorInfo(MonitorFromWindow(hwnd(), MONITOR_DEFAULTTOPRIMARY), 2758 GetMonitorInfo(MonitorFromWindow(hwnd(), MONITOR_DEFAULTTOPRIMARY),
2751 &monitor_info); 2759 &monitor_info);
2752 gfx::Rect shrunk_rect(monitor_info.rcMonitor); 2760 gfx::Rect shrunk_rect(monitor_info.rcMonitor);
2753 shrunk_rect.set_height(shrunk_rect.height() - 1); 2761 shrunk_rect.set_height(shrunk_rect.height() - 1);
2754 background_fullscreen_hack_ = true; 2762 background_fullscreen_hack_ = true;
2755 SetBoundsInternal(shrunk_rect, false); 2763 SetBoundsInternal(shrunk_rect, false);
2756 } 2764 }
2757 2765
2758 } // namespace views 2766 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/win/hwnd_message_handler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698