Commit faae3909 authored by Christopher Cameron's avatar Christopher Cameron Committed by Commit Bot

mac: Eliminate remaining flashes during navigation

During navigation, in RenderFrameHostManager::CommitPending, when the
navigation results in creation of a new RenderWidgetHostView, the
sequence of events in that function is that
- the old RenderWidgetHostView is hidden
- the new RenderWidgetHostView takes content from the old one
- the new RenderWidgetHostView is shown

On macOS, this can result in a one-frame flicker where there is no
content present (between the hide and the show). Fix this by adding
a ScopedCocoaDisableScreenUpdates for the duration of CommitPending.
This will make all Cocoa changes in the function be atomic.

In order to include ScopedCocoaDisableScreenUpdates in a non-objective-C
file, move its ScopedCocoaDisableScreenUpdates implementation out of
the header file.

Bug: 829523
Change-Id: If541ef8985cf7990d63a79435b179f84339a9372
Reviewed-on: https://chromium-review.googlesource.com/1024968Reviewed-by: default avatarccameron <ccameron@chromium.org>
Reviewed-by: default avatarSaman Sami <samans@chromium.org>
Reviewed-by: default avatarAntoine Labour <piman@chromium.org>
Commit-Queue: ccameron <ccameron@chromium.org>
Cr-Commit-Position: refs/heads/master@{#553628}
parent 03212fef
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "base/memory/ptr_util.h" #include "base/memory/ptr_util.h"
#include "base/stl_util.h" #include "base/stl_util.h"
#include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "content/browser/child_process_security_policy_impl.h" #include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/devtools/render_frame_devtools_agent_host.h" #include "content/browser/devtools/render_frame_devtools_agent_host.h"
#include "content/browser/frame_host/debug_urls.h" #include "content/browser/frame_host/debug_urls.h"
...@@ -51,6 +52,10 @@ ...@@ -51,6 +52,10 @@
#include "content/public/common/url_constants.h" #include "content/public/common/url_constants.h"
#include "content/public/common/url_utils.h" #include "content/public/common/url_utils.h"
#if defined(OS_MACOSX)
#include "ui/gfx/mac/scoped_cocoa_disable_screen_updates.h"
#endif // defined(OS_MACOSX)
namespace content { namespace content {
RenderFrameHostManager::RenderFrameHostManager( RenderFrameHostManager::RenderFrameHostManager(
...@@ -2078,6 +2083,17 @@ void RenderFrameHostManager::CommitPending() { ...@@ -2078,6 +2083,17 @@ void RenderFrameHostManager::CommitPending() {
"FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); "FrameTreeNode id", frame_tree_node_->frame_tree_node_id());
DCHECK(speculative_render_frame_host_); DCHECK(speculative_render_frame_host_);
#if defined(OS_MACOSX)
// The old RenderWidgetHostView will be hidden before the new
// RenderWidgetHostView takes its contents. Ensure that Cocoa sees this as
// a single transaction.
// https://crbug.com/829523
// TODO(ccameron): This can be removed when the RenderWidgetHostViewMac uses
// the same ui::Compositor as MacViews.
// https://crbug.com/331669
gfx::ScopedCocoaDisableScreenUpdates disabler;
#endif // defined(OS_MACOSX)
bool is_main_frame = frame_tree_node_->IsMainFrame(); bool is_main_frame = frame_tree_node_->IsMainFrame();
// First check whether we're going to want to focus the location bar after // First check whether we're going to want to focus the location bar after
......
...@@ -125,6 +125,7 @@ jumbo_component("gfx") { ...@@ -125,6 +125,7 @@ jumbo_component("gfx") {
"mac/nswindow_frame_controls.h", "mac/nswindow_frame_controls.h",
"mac/nswindow_frame_controls.mm", "mac/nswindow_frame_controls.mm",
"mac/scoped_cocoa_disable_screen_updates.h", "mac/scoped_cocoa_disable_screen_updates.h",
"mac/scoped_cocoa_disable_screen_updates.mm",
"nine_image_painter.cc", "nine_image_painter.cc",
"nine_image_painter.h", "nine_image_painter.h",
"path.cc", "path.cc",
......
...@@ -5,10 +5,8 @@ ...@@ -5,10 +5,8 @@
#ifndef UI_GFX_MAC_SCOPED_COCOA_DISABLE_SCREEN_UPDATES_H_ #ifndef UI_GFX_MAC_SCOPED_COCOA_DISABLE_SCREEN_UPDATES_H_
#define UI_GFX_MAC_SCOPED_COCOA_DISABLE_SCREEN_UPDATES_H_ #define UI_GFX_MAC_SCOPED_COCOA_DISABLE_SCREEN_UPDATES_H_
#import <Cocoa/Cocoa.h>
#include "base/mac/mac_util.h"
#include "base/macros.h" #include "base/macros.h"
#include "ui/gfx/gfx_export.h"
namespace gfx { namespace gfx {
...@@ -17,25 +15,10 @@ namespace gfx { ...@@ -17,25 +15,10 @@ namespace gfx {
// can be nested, and there is a time-maximum (about 1 second) after which // can be nested, and there is a time-maximum (about 1 second) after which
// Cocoa will automatically re-enable updating. This class doesn't attempt to // Cocoa will automatically re-enable updating. This class doesn't attempt to
// overrule that. // overrule that.
class ScopedCocoaDisableScreenUpdates { class GFX_EXPORT ScopedCocoaDisableScreenUpdates {
public: public:
ScopedCocoaDisableScreenUpdates() { ScopedCocoaDisableScreenUpdates();
if (base::mac::IsAtLeastOS10_11()) { ~ScopedCocoaDisableScreenUpdates();
// Beginning with OS X 10.11, [NSAnimationContext beginGrouping] is the
// preferred way of disabling screen updates. Use of
// NSDisableScreenUpdates() is discouraged.
[NSAnimationContext beginGrouping];
} else {
NSDisableScreenUpdates();
}
}
~ScopedCocoaDisableScreenUpdates() {
if (base::mac::IsAtLeastOS10_11()) {
[NSAnimationContext endGrouping];
} else {
NSEnableScreenUpdates();
}
}
private: private:
DISALLOW_COPY_AND_ASSIGN(ScopedCocoaDisableScreenUpdates); DISALLOW_COPY_AND_ASSIGN(ScopedCocoaDisableScreenUpdates);
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/gfx/mac/scoped_cocoa_disable_screen_updates.h"
#import <Cocoa/Cocoa.h>
#include "base/mac/mac_util.h"
namespace gfx {
ScopedCocoaDisableScreenUpdates::ScopedCocoaDisableScreenUpdates() {
if (base::mac::IsAtLeastOS10_11()) {
// Beginning with OS X 10.11, [NSAnimationContext beginGrouping] is the
// preferred way of disabling screen updates. Use of
// NSDisableScreenUpdates() is discouraged.
[NSAnimationContext beginGrouping];
} else {
NSDisableScreenUpdates();
}
}
ScopedCocoaDisableScreenUpdates::~ScopedCocoaDisableScreenUpdates() {
if (base::mac::IsAtLeastOS10_11()) {
[NSAnimationContext endGrouping];
} else {
NSEnableScreenUpdates();
}
}
} // namespace gfx
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