Commit c0e0e0ff authored by ccameron's avatar ccameron Committed by Commit bot

Prepare to move BrowserCompositorViewMac to ui

This cleans up the the interface to BrowserCompositorViewMac to
prepare for moving it closer to ui::views.

BUG=424058

Review URL: https://codereview.chromium.org/638123003

Cr-Commit-Position: refs/heads/master@{#300300}
parent 5893f9aa
......@@ -7,14 +7,20 @@
#include <IOSurface/IOSurfaceAPI.h>
#include "base/mac/scoped_nsobject.h"
#include "content/browser/compositor/browser_compositor_view_mac.h"
#if defined(__OBJC__)
#include <Cocoa/Cocoa.h>
#include "base/mac/scoped_nsobject.h"
#include "content/browser/compositor/io_surface_layer_mac.h"
#include "content/browser/compositor/software_layer_mac.h"
#include "ui/base/cocoa/remote_layer_api.h"
#endif // __OBJC__
namespace content {
#if defined(__OBJC__)
// BrowserCompositorCALayerTreeMac owns tree of CALayer and a ui::Compositor
// that is used to draw the layers. The CALayer tree can be attached to the
// NSView of a BrowserCompositorViewMac
......@@ -26,8 +32,8 @@ class BrowserCompositorCALayerTreeMac
static BrowserCompositorCALayerTreeMac* FromAcceleratedWidget(
gfx::AcceleratedWidget widget);
void SetClient(BrowserCompositorViewMacClient* client);
void ResetClient();
void SetView(BrowserCompositorViewMac* view);
void ResetView();
ui::Compositor* compositor() const { return compositor_.get(); }
......@@ -75,9 +81,8 @@ private:
base::scoped_nsobject<IOSurfaceLayer> io_surface_layer);
void DestroySoftwareLayer();
// The client of the BrowserCompositorViewMac that is using this as its
// internals.
BrowserCompositorViewMacClient* client_;
// The BrowserCompositorViewMac that is using this as its internals.
BrowserCompositorViewMac* view_;
// A phony NSView handle used to identify this.
gfx::AcceleratedWidget native_widget_;
......@@ -113,6 +118,19 @@ private:
gfx::Size last_swap_size_dip_;
};
#endif // __OBJC__
void BrowserCompositorCALayerTreeMacGotAcceleratedFrame(
gfx::AcceleratedWidget widget,
uint64 surface_handle, int surface_id,
const std::vector<ui::LatencyInfo>& latency_info,
gfx::Size pixel_size, float scale_factor,
bool* disable_throttling, int* renderer_id);
void BrowserCompositorCALayerTreeMacGotSoftwareFrame(
gfx::AcceleratedWidget widget,
cc::SoftwareFrameData* frame_data, float scale_factor, SkCanvas* canvas);
} // namespace content
#endif // CONTENT_BROWSER_COMPOSITOR_BROWSER_COMPOSITOR_CA_LAYER_TREE_MAC_H_
......@@ -32,7 +32,7 @@ base::LazyInstance<WidgetToInternalsMap> g_widget_to_internals_map;
// BrowserCompositorCALayerTreeMac
BrowserCompositorCALayerTreeMac::BrowserCompositorCALayerTreeMac()
: client_(NULL),
: view_(NULL),
accelerated_output_surface_id_(0) {
// Disable the fade-in animation as the layers are added.
ScopedCAActionDisabler disabler;
......@@ -64,28 +64,28 @@ BrowserCompositorCALayerTreeMac::BrowserCompositorCALayerTreeMac()
}
BrowserCompositorCALayerTreeMac::~BrowserCompositorCALayerTreeMac() {
DCHECK(!client_);
DCHECK(!view_);
g_widget_to_internals_map.Pointer()->erase(native_widget_);
}
void BrowserCompositorCALayerTreeMac::SetClient(
BrowserCompositorViewMacClient* client) {
void BrowserCompositorCALayerTreeMac::SetView(
BrowserCompositorViewMac* view) {
// Disable the fade-in animation as the view is added.
ScopedCAActionDisabler disabler;
DCHECK(client && !client_);
client_ = client;
compositor_->SetRootLayer(client_->BrowserCompositorRootLayer());
DCHECK(view && !view_);
view_ = view;
compositor_->SetRootLayer(view_->ui_root_layer());
CALayer* background_layer = [client_->BrowserCompositorSuperview() layer];
CALayer* background_layer = [view_->native_view() layer];
DCHECK(background_layer);
[flipped_layer_ setBounds:[background_layer bounds]];
[background_layer addSublayer:flipped_layer_];
compositor_->SetVisible(true);
}
void BrowserCompositorCALayerTreeMac::ResetClient() {
if (!client_)
void BrowserCompositorCALayerTreeMac::ResetView() {
if (!view_)
return;
// Disable the fade-out animation as the view is removed.
......@@ -102,7 +102,7 @@ void BrowserCompositorCALayerTreeMac::ResetClient() {
compositor_->SetVisible(false);
compositor_->SetScaleAndSize(1.0, gfx::Size(0, 0));
compositor_->SetRootLayer(NULL);
client_ = NULL;
view_ = NULL;
}
bool BrowserCompositorCALayerTreeMac::HasFrameOfSize(
......@@ -117,8 +117,8 @@ int BrowserCompositorCALayerTreeMac::GetRendererID() const {
}
bool BrowserCompositorCALayerTreeMac::IsRendererThrottlingDisabled() const {
if (client_)
return client_->BrowserCompositorViewShouldAckImmediately();
if (view_)
return view_->client()->BrowserCompositorViewShouldAckImmediately();
return false;
}
......@@ -140,8 +140,8 @@ void BrowserCompositorCALayerTreeMac::GotAcceleratedFrame(
accelerated_latency_info_.insert(accelerated_latency_info_.end(),
latency_info.begin(), latency_info.end());
// If there is no client and therefore no superview to draw into, early-out.
if (!client_) {
// If there is no view and therefore no superview to draw into, early-out.
if (!view_) {
IOSurfaceLayerDidDrawFrame();
return;
}
......@@ -274,7 +274,7 @@ void BrowserCompositorCALayerTreeMac::GotSoftwareFrame(
cc::SoftwareFrameData* frame_data,
float scale_factor,
SkCanvas* canvas) {
if (!frame_data || !canvas || !client_)
if (!frame_data || !canvas || !view_)
return;
// Disable the fade-in or fade-out effect if we create or remove layers.
......@@ -330,11 +330,11 @@ void BrowserCompositorCALayerTreeMac::DestroySoftwareLayer() {
bool BrowserCompositorCALayerTreeMac::IOSurfaceLayerShouldAckImmediately()
const {
// If there is no client then the accelerated layer is not in the hierarchy
// If there is no view then the accelerated layer is not in the hierarchy
// and will never draw.
if (!client_)
if (!view_)
return true;
return client_->BrowserCompositorViewShouldAckImmediately();
return view_->client()->BrowserCompositorViewShouldAckImmediately();
}
void BrowserCompositorCALayerTreeMac::IOSurfaceLayerDidDrawFrame() {
......@@ -344,8 +344,10 @@ void BrowserCompositorCALayerTreeMac::IOSurfaceLayerDidDrawFrame() {
accelerated_output_surface_id_ = 0;
}
if (client_)
client_->BrowserCompositorViewFrameSwapped(accelerated_latency_info_);
if (view_) {
view_->client()->BrowserCompositorViewFrameSwapped(
accelerated_latency_info_);
}
accelerated_latency_info_.clear();
}
......@@ -373,4 +375,32 @@ BrowserCompositorCALayerTreeMac* BrowserCompositorCALayerTreeMac::
return found->second;
}
void BrowserCompositorCALayerTreeMacGotAcceleratedFrame(
gfx::AcceleratedWidget widget,
uint64 surface_handle, int surface_id,
const std::vector<ui::LatencyInfo>& latency_info,
gfx::Size pixel_size, float scale_factor,
bool* disable_throttling, int* renderer_id) {
BrowserCompositorCALayerTreeMac* ca_layer_tree =
BrowserCompositorCALayerTreeMac::FromAcceleratedWidget(widget);
if (ca_layer_tree) {
ca_layer_tree->GotAcceleratedFrame(
surface_handle, surface_id, latency_info, pixel_size, scale_factor);
*disable_throttling = ca_layer_tree->IsRendererThrottlingDisabled();
*renderer_id = ca_layer_tree->GetRendererID();
} else {
*disable_throttling = false;
*renderer_id = 0;
}
}
void BrowserCompositorCALayerTreeMacGotSoftwareFrame(
gfx::AcceleratedWidget widget,
cc::SoftwareFrameData* frame_data, float scale_factor, SkCanvas* canvas) {
BrowserCompositorCALayerTreeMac* ca_layer_tree =
BrowserCompositorCALayerTreeMac::FromAcceleratedWidget(widget);
if (ca_layer_tree)
ca_layer_tree->GotSoftwareFrame(frame_data, scale_factor, canvas);
}
} // namespace content
......@@ -20,6 +20,7 @@ class BrowserCompositorCALayerTreeMac;
// The interface through which BrowserCompositorViewMac calls back into
// RenderWidgetHostViewMac (or any other structure that wishes to draw a
// NSView backed by a ui::Compositor).
// TODO(ccameron): This interface should be in the ui namespace.
class BrowserCompositorViewMacClient {
public:
// Drawing is usually throttled by the rate at which CoreAnimation draws
......@@ -30,33 +31,29 @@ class BrowserCompositorViewMacClient {
// renderer (if any).
virtual void BrowserCompositorViewFrameSwapped(
const std::vector<ui::LatencyInfo>& latency_info) = 0;
// Used to install the ui::Compositor-backed NSView as a child of its parent
// view.
virtual NSView* BrowserCompositorSuperview() = 0;
// Used to install the root ui::Layer into the ui::Compositor.
virtual ui::Layer* BrowserCompositorRootLayer() = 0;
};
// The class to hold a ui::Compositor-backed NSView. Because a ui::Compositor
// is expensive in terms of resources and re-allocating a ui::Compositor is
// expensive in terms of work, this class is largely used to manage recycled
// instances of BrowserCompositorViewCocoa, which actually is a NSView and
// has a ui::Compositor instance.
// The class to hold the ui::Compositor which is used to draw a NSView.
// TODO(ccameron): This should implement an interface in the ui namespace.
class BrowserCompositorViewMac {
public:
// This will install the NSView which is drawn by the ui::Compositor into
// the NSView provided by the client.
explicit BrowserCompositorViewMac(BrowserCompositorViewMacClient* client);
// the NSView provided by the client. Note that |client|, |native_view|, and
// |ui_root_layer| outlive their BrowserCompositorViewMac object.
BrowserCompositorViewMac(
BrowserCompositorViewMacClient* client,
NSView* native_view,
ui::Layer* ui_root_layer);
~BrowserCompositorViewMac();
BrowserCompositorViewMacClient* client() const { return client_; }
NSView* native_view() const { return native_view_; }
ui::Layer* ui_root_layer() const { return ui_root_layer_; }
// The ui::Compositor being used to render the NSView.
// TODO(ccameron): This should be in the ui namespace interface.
ui::Compositor* GetCompositor() const;
// The client (used by the BrowserCompositorViewCocoa to access the client).
BrowserCompositorViewMacClient* GetClient() const { return client_; }
// Return true if the last frame swapped has a size in DIP of |dip_size|.
bool HasFrameOfSize(const gfx::Size& dip_size) const;
......@@ -66,19 +63,16 @@ class BrowserCompositorViewMac {
void BeginPumpingFrames();
void EndPumpingFrames();
static void GotAcceleratedFrame(
gfx::AcceleratedWidget widget,
uint64 surface_handle, int surface_id,
const std::vector<ui::LatencyInfo>& latency_info,
gfx::Size pixel_size, float scale_factor,
int gpu_host_id, int gpu_route_id);
static void GotSoftwareFrame(
gfx::AcceleratedWidget widget,
cc::SoftwareFrameData* frame_data, float scale_factor, SkCanvas* canvas);
private:
BrowserCompositorViewMacClient* client_;
NSView* native_view_;
ui::Layer* ui_root_layer_;
// Because a ui::Compositor is expensive in terms of resources and
// re-allocating a ui::Compositor is expensive in terms of work, this class
// is largely used to manage recycled instances of
// BrowserCompositorCALayerTreeMac, which actually has a ui::Compositor
// instance and modifies the CALayers used to draw the NSView.
scoped_ptr<BrowserCompositorCALayerTreeMac> ca_layer_tree_;
};
......
......@@ -28,7 +28,12 @@ base::LazyInstance<scoped_ptr<BrowserCompositorCALayerTreeMac>>
} // namespace
BrowserCompositorViewMac::BrowserCompositorViewMac(
BrowserCompositorViewMacClient* client) : client_(client) {
BrowserCompositorViewMacClient* client,
NSView* native_view,
ui::Layer* ui_root_layer)
: client_(client),
native_view_(native_view),
ui_root_layer_(ui_root_layer) {
// Try to use the recyclable BrowserCompositorCALayerTreeMac if there is one,
// otherwise allocate a new one.
// TODO(ccameron): If there exists a frame in flight (swap has been called
......@@ -37,12 +42,12 @@ BrowserCompositorViewMac::BrowserCompositorViewMac(
ca_layer_tree_ = g_recyclable_ca_layer_tree.Get().Pass();
if (!ca_layer_tree_)
ca_layer_tree_.reset(new BrowserCompositorCALayerTreeMac);
ca_layer_tree_->SetClient(client_);
ca_layer_tree_->SetView(this);
}
BrowserCompositorViewMac::~BrowserCompositorViewMac() {
// Make this BrowserCompositorCALayerTreeMac recyclable for future instances.
ca_layer_tree_->ResetClient();
ca_layer_tree_->ResetView();
g_recyclable_ca_layer_tree.Get() = ca_layer_tree_.Pass();
// If there are no placeholders allocated, destroy the recyclable
......@@ -73,45 +78,6 @@ void BrowserCompositorViewMac::EndPumpingFrames() {
ca_layer_tree_->EndPumpingFrames();
}
// static
void BrowserCompositorViewMac::GotAcceleratedFrame(
gfx::AcceleratedWidget widget,
uint64 surface_handle, int surface_id,
const std::vector<ui::LatencyInfo>& latency_info,
gfx::Size pixel_size, float scale_factor,
int gpu_host_id, int gpu_route_id) {
BrowserCompositorCALayerTreeMac* ca_layer_tree =
BrowserCompositorCALayerTreeMac::FromAcceleratedWidget(widget);
bool disable_throttling = false;
int renderer_id = 0;
if (ca_layer_tree) {
ca_layer_tree->GotAcceleratedFrame(
surface_handle, surface_id, latency_info, pixel_size, scale_factor);
disable_throttling = ca_layer_tree->IsRendererThrottlingDisabled();
renderer_id = ca_layer_tree->GetRendererID();
}
// Acknowledge the swap, now that it has been processed.
AcceleratedSurfaceMsg_BufferPresented_Params ack_params;
ack_params.disable_throttling = disable_throttling;
ack_params.renderer_id = renderer_id;
GpuProcessHostUIShim* ui_shim = GpuProcessHostUIShim::FromID(gpu_host_id);
if (ui_shim) {
ui_shim->Send(new AcceleratedSurfaceMsg_BufferPresented(
gpu_route_id, ack_params));
}
}
// static
void BrowserCompositorViewMac::GotSoftwareFrame(
gfx::AcceleratedWidget widget,
cc::SoftwareFrameData* frame_data, float scale_factor, SkCanvas* canvas) {
BrowserCompositorCALayerTreeMac* ca_layer_tree =
BrowserCompositorCALayerTreeMac::FromAcceleratedWidget(widget);
if (ca_layer_tree)
ca_layer_tree->GotSoftwareFrame(frame_data, scale_factor, canvas);
}
////////////////////////////////////////////////////////////////////////////////
// BrowserCompositorViewPlaceholderMac
......
......@@ -6,7 +6,7 @@
#include "content/browser/compositor/software_output_device_mac.h"
#include "content/browser/compositor/browser_compositor_view_mac.h"
#include "content/browser/compositor/browser_compositor_ca_layer_tree_mac.h"
#include "ui/compositor/compositor.h"
namespace content {
......@@ -20,7 +20,7 @@ SoftwareOutputDeviceMac::~SoftwareOutputDeviceMac() {
void SoftwareOutputDeviceMac::EndPaint(cc::SoftwareFrameData* frame_data) {
SoftwareOutputDevice::EndPaint(frame_data);
BrowserCompositorViewMac::GotSoftwareFrame(
BrowserCompositorCALayerTreeMacGotSoftwareFrame(
compositor_->widget(), frame_data, scale_factor_, canvas_.get());
}
......
......@@ -23,7 +23,7 @@
#include "content/public/browser/browser_thread.h"
#if defined(OS_MACOSX)
#include "content/browser/compositor/browser_compositor_view_mac.h"
#include "content/browser/compositor/browser_compositor_ca_layer_tree_mac.h"
#endif
#if defined(USE_OZONE)
......@@ -257,17 +257,20 @@ void GpuProcessHostUIShim::OnAcceleratedSurfaceBuffersSwapped(
// On Mac with delegated rendering, accelerated surfaces are not necessarily
// associated with a RenderWidgetHostViewBase.
AcceleratedSurfaceMsg_BufferPresented_Params ack_params;
DCHECK(IsDelegatedRendererEnabled());
gfx::AcceleratedWidget native_widget =
content::GpuSurfaceTracker::Get()->AcquireNativeWidget(params.surface_id);
BrowserCompositorViewMac::GotAcceleratedFrame(native_widget,
params.surface_handle,
params.surface_id,
params.latency_info,
params.size,
params.scale_factor,
host_id_,
params.route_id);
BrowserCompositorCALayerTreeMacGotAcceleratedFrame(
native_widget,
params.surface_handle,
params.surface_id,
params.latency_info,
params.size,
params.scale_factor,
&ack_params.disable_throttling,
&ack_params.renderer_id);
Send(new AcceleratedSurfaceMsg_BufferPresented(params.route_id, ack_params));
#else
NOTREACHED();
#endif
......
......@@ -434,8 +434,6 @@ class CONTENT_EXPORT RenderWidgetHostViewMac
virtual bool BrowserCompositorViewShouldAckImmediately() const override;
virtual void BrowserCompositorViewFrameSwapped(
const std::vector<ui::LatencyInfo>& latency_info) override;
virtual NSView* BrowserCompositorSuperview() override;
virtual ui::Layer* BrowserCompositorRootLayer() override;
private:
friend class RenderWidgetHostViewMacTest;
......
......@@ -501,14 +501,6 @@ void RenderWidgetHostViewMac::BrowserCompositorViewFrameSwapped(
}
}
NSView* RenderWidgetHostViewMac::BrowserCompositorSuperview() {
return cocoa_view_;
}
ui::Layer* RenderWidgetHostViewMac::BrowserCompositorRootLayer() {
return root_layer_.get();
}
///////////////////////////////////////////////////////////////////////////////
// RenderWidgetHostViewBase, public:
......@@ -601,7 +593,8 @@ void RenderWidgetHostViewMac::EnsureBrowserCompositorView() {
TRACE_EVENT0("browser",
"RenderWidgetHostViewMac::EnsureBrowserCompositorView");
browser_compositor_view_.reset(new BrowserCompositorViewMac(this));
browser_compositor_view_.reset(
new BrowserCompositorViewMac(this, cocoa_view_, root_layer_.get()));
delegated_frame_host_->AddedToWindow();
delegated_frame_host_->WasShown(ui::LatencyInfo());
}
......
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