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

MacViews: Don't draw blank windows after de-miniturize

Whenever the ui::Layer for BridgedNativeWidgetMac is hidden, also lock
the ui::Compositor ("lock" in this sense means "disable drawing new
frames").

This ensure that we won't draw any blank frames (which is what would
result in a blank frame).

Bug: 712244
Change-Id: Ia8c17742e6a48190b9a3aead6443102a585d1f7d
Reviewed-on: https://chromium-review.googlesource.com/1129320
Commit-Queue: ccameron <ccameron@chromium.org>
Reviewed-by: default avatarTrent Apted <tapted@chromium.org>
Cr-Commit-Position: refs/heads/master@{#574187}
parent 009cee5a
......@@ -287,6 +287,11 @@ class VIEWS_EXPORT BridgedNativeWidget
// DialogObserver:
void OnDialogModelChanged() override;
// Set |layer()| to be visible or not visible based on |window_visible_|. If
// the layer is not visible, then lock the compositor, so we don't draw any
// new frames.
void UpdateLayerVisibility();
views::NativeWidgetMac* native_widget_mac_; // Weak. Owns this.
base::scoped_nsobject<NSWindow> window_;
base::scoped_nsobject<ViewsNSWindowDelegate> window_delegate_;
......@@ -307,6 +312,8 @@ class VIEWS_EXPORT BridgedNativeWidget
std::unique_ptr<ui::AcceleratedWidgetMac> compositor_widget_;
std::unique_ptr<ui::DisplayCALayerTree> display_ca_layer_tree_;
std::unique_ptr<ui::Compositor> compositor_;
std::unique_ptr<ui::CompositorLock> compositor_lock_;
viz::ParentLocalSurfaceIdAllocator parent_local_surface_id_allocator_;
// Tracks the bounds when the window last started entering fullscreen. Used to
......
......@@ -796,12 +796,11 @@ void BridgedNativeWidget::OnVisibilityChanged() {
// TODO(tapted): Investigate whether we want this for Mac. This is what Aura
// does, and it is what tests expect. However, because layer drawing is
// asynchronous (and things like deminiaturize in AppKit are not), it can
// result in a CALayer appearing on screen before it has been redrawn in the
// GPU process. This is a general problem. In content, a helper class,
// RenderWidgetResizeHelper, blocks the UI thread in -[NSView setFrameSize:]
// and RenderWidgetHostView::Show() until a frame is ready.
// result in the compositor producing a blank frame during the time that the
// layer is not visible. Avoid this by locking the compositor (preventing any
// new frames) in UpdateLayerVisibility whenever the layer is hidden.
if (layer()) {
layer()->SetVisible(window_visible_);
UpdateLayerVisibility();
layer()->SchedulePaint(gfx::Rect(GetClientAreaSize()));
// For translucent windows which are made visible, recalculate shadow when
......@@ -904,7 +903,7 @@ void BridgedNativeWidget::CreateLayer(ui::LayerType layer_type,
SetLayer(std::make_unique<ui::Layer>(layer_type));
// Note, except for controls, this will set the layer to be hidden, since it
// is only called during Init().
layer()->SetVisible(window_visible_);
UpdateLayerVisibility();
layer()->set_delegate(this);
InitCompositor();
......@@ -1347,7 +1346,7 @@ void BridgedNativeWidget::ShowAsModalSheet() {
// So that it doesn't animate a fully transparent window, first wait for a
// frame. The first step is to pretend that the window is already visible.
window_visible_ = true;
layer()->SetVisible(true);
UpdateLayerVisibility();
native_widget_mac_->GetWidget()->OnNativeWidgetVisibilityChanged(true);
MaybeWaitForFrame(GetClientAreaSize());
......@@ -1376,4 +1375,16 @@ NSMutableDictionary* BridgedNativeWidget::GetWindowProperties() const {
return properties;
}
void BridgedNativeWidget::UpdateLayerVisibility() {
layer()->SetVisible(window_visible_);
if (window_visible_) {
compositor_lock_.reset();
} else if (!compositor_lock_) {
// Assume that GetCompositorLock always succeeds (if it does not, then a
// flicker may be seen).
compositor_lock_ =
compositor_->GetCompositorLock(nullptr, base::TimeDelta());
}
}
} // namespace views
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