Commit 6be8acd7 authored by Christopher Cameron's avatar Christopher Cameron Committed by Commit Bot

MacViews: Lazily enable using a single ui::Compositor

It is not possible to know ahead of time whether or not a
WebContentsView will be embedded in an NSView or a views::View, even
when MacViewsBrowser is enabled (content_shell, for instance, uses the
NSView display path).

Lazily determine if a WebContentsView is to display via its parent
views::View's compositor. When attaching to a views::View for the first
time, clear all content that is being displayed in the NSView (because
it will occlude the views::View) and disable displaying through Cocoa
for the lifetime of the WebContentsView.

When all code that expects to display through Cocoa is updated or
deleted, this lazy determination may be removed.

Bug: 840173
Change-Id: I36c7054ba7c71e6fe94e496e677a9a9be4fb790a
Reviewed-on: https://chromium-review.googlesource.com/1075563Reviewed-by: default avatarSidney San Martín <sdy@chromium.org>
Commit-Queue: ccameron <ccameron@chromium.org>
Cr-Commit-Position: refs/heads/master@{#563008}
parent 1e665d5f
......@@ -54,6 +54,10 @@ class RenderWidgetHostNSViewBridge {
virtual void InitAsPopup(const gfx::Rect& content_rect,
blink::WebPopupType popup_type) = 0;
// Disable displaying any content (including the background color). This is
// to be called on views that are to be displayed via a parent ui::Compositor.
virtual void DisableDisplay() = 0;
// Make the NSView be the first responder of its NSWindow.
virtual void MakeFirstResponder() = 0;
......
......@@ -38,6 +38,7 @@ class RenderWidgetHostViewNSViewBridgeLocal
void InitAsPopup(const gfx::Rect& content_rect,
blink::WebPopupType popup_type) override;
void DisableDisplay() override;
void MakeFirstResponder() override;
void SetBounds(const gfx::Rect& rect) override;
void SetCALayerParams(const gfx::CALayerParams& ca_layer_params) override;
......@@ -74,6 +75,10 @@ class RenderWidgetHostViewNSViewBridgeLocal
// The NSView used for input and display.
base::scoped_nsobject<RenderWidgetHostViewCocoa> cocoa_view_;
// Once set, all calls to set the background color or CALayer content will
// be ignored.
bool display_disabled_ = false;
// The window used for popup widgets, and its helper.
std::unique_ptr<PopupWindowMac> popup_window_;
blink::WebPopupType popup_type_ = blink::kWebPopupTypeNone;
......@@ -134,6 +139,14 @@ void RenderWidgetHostViewNSViewBridgeLocal::MakeFirstResponder() {
[[cocoa_view_ window] makeFirstResponder:cocoa_view_];
}
void RenderWidgetHostViewNSViewBridgeLocal::DisableDisplay() {
if (display_disabled_)
return;
SetBackgroundColor(SK_ColorTRANSPARENT);
display_ca_layer_tree_.reset();
display_disabled_ = true;
}
void RenderWidgetHostViewNSViewBridgeLocal::SetBounds(const gfx::Rect& rect) {
// |rect.size()| is view coordinates, |rect.origin| is screen coordinates,
// TODO(thakis): fix, http://crbug.com/73362
......@@ -177,10 +190,14 @@ void RenderWidgetHostViewNSViewBridgeLocal::SetBounds(const gfx::Rect& rect) {
void RenderWidgetHostViewNSViewBridgeLocal::SetCALayerParams(
const gfx::CALayerParams& ca_layer_params) {
if (display_disabled_)
return;
display_ca_layer_tree_->UpdateCALayerTree(ca_layer_params);
}
void RenderWidgetHostViewNSViewBridgeLocal::SetBackgroundColor(SkColor color) {
if (display_disabled_)
return;
ScopedCAActionDisabler disabler;
base::ScopedCFTypeRef<CGColorRef> cg_color(
skia::CGColorCreateFromSkColor(color));
......
......@@ -110,11 +110,6 @@ NSView* RenderWidgetHostViewMac::AcceleratedWidgetGetNSView() const {
}
void RenderWidgetHostViewMac::AcceleratedWidgetCALayerParamsUpdated() {
// This may be called when we do not have a parent ui::Layer (e.g, when tab
// capturing a background layer). Do not update the NSView in this case.
if (display_only_using_parent_ui_layer_)
return;
// Set the background color for the root layer from the frame that just
// swapped. See RenderWidgetHostViewAura for more details. Note that this is
// done only after the swap has completed, so that the background is not set
......@@ -146,11 +141,6 @@ RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget,
ui::GestureProviderConfigType::CURRENT_PLATFORM),
this),
weak_factory_(this) {
display_only_using_parent_ui_layer_ = !features::IsViewsBrowserCocoa();
// TODO(ccameron): This path breaks content_shell because content_shell does
// not display using ui::Views, even when !features::IsViewsBrowserCocoa.
display_only_using_parent_ui_layer_ = false;
// The NSView is on the other side of |ns_view_bridge_|.
ns_view_bridge_ = RenderWidgetHostNSViewBridge::Create(this);
......@@ -209,8 +199,16 @@ RenderWidgetHostViewMac::~RenderWidgetHostViewMac() {
}
void RenderWidgetHostViewMac::SetParentUiLayer(ui::Layer* parent_ui_layer) {
if (!display_only_using_parent_ui_layer_)
return;
if (!display_only_using_parent_ui_layer_) {
// The first time that we display using a parent ui::Layer, permanently
// switch from drawing using Cocoa to only drawing using ui::Views. Erase
// the existing content being drawn by Cocoa (which may have been set due
// to races, e.g, in https://crbug.com/845807). Note that this transition
// must be done lazily because not all code has been updated to use
// ui::Views (e.g, content_shell).
display_only_using_parent_ui_layer_ = true;
ns_view_bridge_->DisableDisplay();
}
if (browser_compositor_)
browser_compositor_->SetParentUiLayer(parent_ui_layer);
}
......@@ -1245,11 +1243,6 @@ base::Optional<SkColor> RenderWidgetHostViewMac::GetBackgroundColor() const {
}
void RenderWidgetHostViewMac::SetBackgroundLayerColor(SkColor color) {
// If displaying via a ui::Layer, leave the background color of the NSView
// as transparent (it is to be used for input handling only).
if (display_only_using_parent_ui_layer_)
return;
if (color == background_layer_color_)
return;
background_layer_color_ = color;
......
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