Commit d2f3e593 authored by Sidney San Martín's avatar Sidney San Martín Committed by Commit Bot

[Mac] Make synchronized content resize/repaint visually atomic.

NSDisableScreenUpdates() is advertised for making visually atomic changes that
affect multiple windows, but it it's also effective when multiple processes
have layers in the same window. macOS uses it to synchronize resizing of
out-of-process views like NSOpenPanel.

Leaving screen updates disabled for too long can create funky visual artifacts
within and behind Chrome windows if left on for too long. This waits to flip it
until a frame has been produced of the new size, and it's only on during the
(very brief) compositor swap.

Bug: 617824, 741478
Change-Id: Id6ddfb8848342d6e4b148207a3f76125774081d6
Reviewed-on: https://chromium-review.googlesource.com/798774
Commit-Queue: Sidney San Martín <sdy@chromium.org>
Reviewed-by: default avatarccameron <ccameron@chromium.org>
Cr-Commit-Position: refs/heads/master@{#523982}
parent c31b374d
......@@ -629,6 +629,17 @@ class CONTENT_EXPORT RenderWidgetHostViewMac
// The size associated with the current LocalSurfaceId if any.
gfx::Size last_size_;
enum class RepaintState {
// No repaint in progress.
None,
// Synchronously waiting for a new frame.
Paused,
// Screen updates are disabled while a new frame is swapped in.
ScreenUpdatesDisabled,
} repaint_state_ = RepaintState::None;
// The last device scale factor associated with the current
// LocalSurfaceId if any.
float last_device_scale_factor_ = 0.f;
......
......@@ -1435,6 +1435,16 @@ void RenderWidgetHostViewMac::SubmitCompositorFrame(
viz::mojom::HitTestRegionListPtr hit_test_region_list) {
TRACE_EVENT0("browser", "RenderWidgetHostViewMac::OnSwapCompositorFrame");
if (repaint_state_ == RepaintState::Paused) {
gfx::Size frame_size = gfx::ConvertSizeToDIP(
frame.metadata.device_scale_factor, frame.size_in_pixels());
gfx::Size view_size = gfx::Size(cocoa_view_.bounds.size);
if (frame_size == view_size || render_widget_host_->auto_resize_enabled()) {
NSDisableScreenUpdates();
repaint_state_ = RepaintState::ScreenUpdatesDisabled;
}
}
last_frame_root_background_color_ = frame.metadata.root_background_color;
last_scroll_offset_ = frame.metadata.root_scroll_offset;
......@@ -1754,7 +1764,11 @@ void RenderWidgetHostViewMac::PauseForPendingResizeOrRepaintsAndDraw() {
return;
// Wait for a frame of the right size to come in.
repaint_state_ = RepaintState::Paused;
render_widget_host_->PauseForPendingResizeOrRepaints();
if (repaint_state_ == RepaintState::ScreenUpdatesDisabled)
NSEnableScreenUpdates();
repaint_state_ = RepaintState::None;
}
////////////////////////////////////////////////////////////////////////////////
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment