| Index: content/browser/compositor/browser_compositor_view_private_mac.mm
|
| diff --git a/content/browser/compositor/browser_compositor_view_private_mac.mm b/content/browser/compositor/browser_compositor_view_private_mac.mm
|
| index f10960927681c3ac501a0aea76b104af5e21777a..a6ce4c2c664ba28cfe92164d4bb5159f975e8e5d 100644
|
| --- a/content/browser/compositor/browser_compositor_view_private_mac.mm
|
| +++ b/content/browser/compositor/browser_compositor_view_private_mac.mm
|
| @@ -14,87 +14,94 @@
|
| #include "ui/gl/scoped_cgl.h"
|
|
|
| ////////////////////////////////////////////////////////////////////////////////
|
| -// BrowserCompositorViewCocoa
|
| +// BrowserCompositorViewMacInternal
|
|
|
| -@implementation BrowserCompositorViewCocoa : NSView
|
| +namespace content {
|
|
|
| -- (id)init {
|
| - if (self = [super init]) {
|
| - accelerated_layer_output_surface_id_ = 0;
|
| - client_ = NULL;
|
| - helper_.reset(new content::BrowserCompositorViewCocoaHelper(self));
|
| -
|
| - // Disable the fade-in animation as the layer and view are added.
|
| - ScopedCAActionDisabler disabler;
|
| -
|
| - // Add a flipped transparent layer as a child, so that we don't need to
|
| - // fiddle with the position of sub-layers -- they will always be at the
|
| - // origin.
|
| - flipped_layer_.reset([[CALayer alloc] init]);
|
| - [flipped_layer_ setGeometryFlipped:YES];
|
| - [flipped_layer_ setAnchorPoint:CGPointMake(0, 0)];
|
| - [flipped_layer_
|
| - setAutoresizingMask:kCALayerWidthSizable|kCALayerHeightSizable];
|
| -
|
| - compositor_.reset(new ui::Compositor(self, content::GetContextFactory()));
|
| - }
|
| - return self;
|
| +BrowserCompositorViewMacInternal::BrowserCompositorViewMacInternal()
|
| + : client_(NULL),
|
| + accelerated_layer_output_surface_id_(0) {
|
| + // Disable the fade-in animation as the layers are added.
|
| + ScopedCAActionDisabler disabler;
|
| +
|
| + // Add a flipped transparent layer as a child, so that we don't need to
|
| + // fiddle with the position of sub-layers -- they will always be at the
|
| + // origin.
|
| + flipped_layer_.reset([[CALayer alloc] init]);
|
| + [flipped_layer_ setGeometryFlipped:YES];
|
| + [flipped_layer_ setAnchorPoint:CGPointMake(0, 0)];
|
| + [flipped_layer_
|
| + setAutoresizingMask:kCALayerWidthSizable|kCALayerHeightSizable];
|
| +
|
| + // Set the Cocoa view to be hosting the un-flipped background layer (hosting
|
| + // a flipped layer results in unpredictable behavior).
|
| + cocoa_view_.reset([[BrowserCompositorViewCocoa alloc] initWithClient:this]);
|
| +
|
| + // Create a compositor to draw the contents of |cocoa_view_|.
|
| + compositor_.reset(new ui::Compositor(
|
| + cocoa_view_, content::GetContextFactory()));
|
| +}
|
| +
|
| +BrowserCompositorViewMacInternal::~BrowserCompositorViewMacInternal() {
|
| + DCHECK(!client_);
|
| + [cocoa_view_ resetClient];
|
| +}
|
| +
|
| +void BrowserCompositorViewMacInternal::SetClient(
|
| + BrowserCompositorViewMacClient* client) {
|
| + // Disable the fade-in animation as the view is added.
|
| + ScopedCAActionDisabler disabler;
|
| +
|
| + DCHECK(client && !client_);
|
| + client_ = client;
|
| + compositor_->SetRootLayer(client_->BrowserCompositorRootLayer());
|
| +
|
| + CALayer* background_layer = [client_->BrowserCompositorSuperview() layer];
|
| + DCHECK(background_layer);
|
| + [flipped_layer_ setBounds:[background_layer bounds]];
|
| + [background_layer addSublayer:flipped_layer_];
|
| }
|
|
|
| -- (void)setClient:(content::BrowserCompositorViewMacClient*)client {
|
| - // Disable the fade-out as layers are removed.
|
| +void BrowserCompositorViewMacInternal::ResetClient() {
|
| + if (!client_)
|
| + return;
|
| +
|
| + // Disable the fade-out animation as the view is removed.
|
| ScopedCAActionDisabler disabler;
|
|
|
| - // Reset all state.
|
| [flipped_layer_ removeFromSuperlayer];
|
| +
|
| [accelerated_layer_ removeFromSuperlayer];
|
| [accelerated_layer_ resetClient];
|
| accelerated_layer_.reset();
|
| accelerated_layer_output_surface_id_ = 0;
|
| +
|
| [software_layer_ removeFromSuperlayer];
|
| software_layer_.reset();
|
| - compositor_->SetScaleAndSize(1.0, gfx::Size(0, 0));
|
| -
|
| - client_ = client;
|
| - if (client_) {
|
| - DCHECK(compositor_);
|
| - compositor_->SetRootLayer(client_->BrowserCompositorRootLayer());
|
| - CALayer* background_layer = [client_->BrowserCompositorSuperview() layer];
|
| - DCHECK(background_layer);
|
| - [flipped_layer_ setBounds:[background_layer bounds]];
|
| - [background_layer addSublayer:flipped_layer_];
|
| - } else {
|
| - compositor_->SetRootLayer(NULL);
|
| - }
|
| -}
|
|
|
| -- (void)destroyCompositor {
|
| - DCHECK(!client_);
|
| - compositor_.reset();
|
| -}
|
| -
|
| -- (void)gotAcceleratedLayerError {
|
| - if (!accelerated_layer_)
|
| - return;
|
| -
|
| - [accelerated_layer_ context]->PoisonContextAndSharegroup();
|
| - compositor_->ScheduleFullRedraw();
|
| -}
|
| -
|
| -- (ui::Compositor*)compositor {
|
| - return compositor_.get();
|
| + compositor_->SetScaleAndSize(1.0, gfx::Size(0, 0));
|
| + compositor_->SetRootLayer(NULL);
|
| + client_ = NULL;
|
| }
|
|
|
| -- (void)gotAcceleratedIOSurfaceFrame:(IOSurfaceID)surface_handle
|
| - withOutputSurfaceID:(int)surface_id
|
| - withLatencyInfo:(std::vector<ui::LatencyInfo>) latency_info
|
| - withPixelSize:(gfx::Size)pixel_size
|
| - withScaleFactor:(float)scale_factor {
|
| +void BrowserCompositorViewMacInternal::GotAcceleratedIOSurfaceFrame(
|
| + IOSurfaceID io_surface_id,
|
| + int output_surface_id,
|
| + const std::vector<ui::LatencyInfo>& latency_info,
|
| + gfx::Size pixel_size,
|
| + float scale_factor) {
|
| DCHECK(!accelerated_layer_output_surface_id_);
|
| - accelerated_layer_output_surface_id_ = surface_id;
|
| + accelerated_layer_output_surface_id_ = output_surface_id;
|
| 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_) {
|
| + AcceleratedLayerDidDrawFrame(true);
|
| + return;
|
| + }
|
| +
|
| + // Disable the fade-in or fade-out effect if we create or remove layers.
|
| ScopedCAActionDisabler disabler;
|
|
|
| // If there is already an accelerated layer, but it has the wrong scale
|
| @@ -109,23 +116,22 @@
|
|
|
| // If there is not a layer for accelerated frames, create one.
|
| if (!accelerated_layer_) {
|
| - // Disable the fade-in animation as the layer is added.
|
| - ScopedCAActionDisabler disabler;
|
| scoped_refptr<content::CompositingIOSurfaceMac> iosurface =
|
| content::CompositingIOSurfaceMac::Create();
|
| accelerated_layer_.reset([[CompositingIOSurfaceLayer alloc]
|
| initWithIOSurface:iosurface
|
| withScaleFactor:scale_factor
|
| - withClient:helper_.get()]);
|
| + withClient:this]);
|
| [flipped_layer_ addSublayer:accelerated_layer_];
|
| }
|
|
|
| + // Open the provided IOSurface.
|
| {
|
| bool result = true;
|
| gfx::ScopedCGLSetCurrentContext scoped_set_current_context(
|
| [accelerated_layer_ context]->cgl_context());
|
| result = [accelerated_layer_ iosurface]->SetIOSurfaceWithContextCurrent(
|
| - [accelerated_layer_ context], surface_handle, pixel_size, scale_factor);
|
| + [accelerated_layer_ context], io_surface_id, pixel_size, scale_factor);
|
| if (!result)
|
| LOG(ERROR) << "Failed SetIOSurface on CompositingIOSurfaceMac";
|
| }
|
| @@ -149,7 +155,6 @@
|
| // If there was a software layer or an old accelerated layer, remove it.
|
| // Disable the fade-out animation as the layer is removed.
|
| {
|
| - ScopedCAActionDisabler disabler;
|
| [software_layer_ removeFromSuperlayer];
|
| software_layer_.reset();
|
| [old_accelerated_layer resetClient];
|
| @@ -158,20 +163,23 @@
|
| }
|
| }
|
|
|
| -- (void)gotSoftwareFrame:(cc::SoftwareFrameData*)frame_data
|
| - withScaleFactor:(float)scale_factor
|
| - withCanvas:(SkCanvas*)canvas {
|
| - if (!frame_data || !canvas)
|
| +void BrowserCompositorViewMacInternal::GotSoftwareFrame(
|
| + cc::SoftwareFrameData* frame_data,
|
| + float scale_factor,
|
| + SkCanvas* canvas) {
|
| + if (!frame_data || !canvas || !client_)
|
| return;
|
|
|
| + // Disable the fade-in or fade-out effect if we create or remove layers.
|
| + ScopedCAActionDisabler disabler;
|
| +
|
| // If there is not a layer for software frames, create one.
|
| if (!software_layer_) {
|
| - // Disable the fade-in animation as the layer is added.
|
| - ScopedCAActionDisabler disabler;
|
| software_layer_.reset([[SoftwareLayer alloc] init]);
|
| [flipped_layer_ addSublayer:software_layer_];
|
| }
|
|
|
| + // Set the software layer to draw the provided canvas.
|
| SkImageInfo info;
|
| size_t row_bytes;
|
| const void* pixels = canvas->peekPixels(&info, &row_bytes);
|
| @@ -181,23 +189,15 @@
|
| withScaleFactor:scale_factor];
|
|
|
| // If there was an accelerated layer, remove it.
|
| - // Disable the fade-out animation as the layer is removed.
|
| {
|
| - ScopedCAActionDisabler disabler;
|
| [accelerated_layer_ resetClient];
|
| [accelerated_layer_ removeFromSuperlayer];
|
| accelerated_layer_.reset();
|
| }
|
| -
|
| - // This call can be nested insider ui::Compositor commit calls, and can also
|
| - // make additional ui::Compositor commit calls. Avoid the potential recursion
|
| - // by acknowledging the frame asynchronously.
|
| - [self performSelector:@selector(layerDidDrawFrame)
|
| - withObject:nil
|
| - afterDelay:0];
|
| }
|
|
|
| -- (void)layerDidDrawFrame {
|
| +void BrowserCompositorViewMacInternal::AcceleratedLayerDidDrawFrame(
|
| + bool succeeded) {
|
| if (accelerated_layer_output_surface_id_) {
|
| content::ImageTransportFactory::GetInstance()->OnSurfaceDisplayed(
|
| accelerated_layer_output_surface_id_);
|
| @@ -206,22 +206,57 @@
|
|
|
| if (client_)
|
| client_->BrowserCompositorViewFrameSwapped(accelerated_latency_info_);
|
| +
|
| accelerated_latency_info_.clear();
|
| +
|
| + if (!succeeded) {
|
| + if (accelerated_layer_)
|
| + [accelerated_layer_ context]->PoisonContextAndSharegroup();
|
| + compositor_->ScheduleFullRedraw();
|
| + }
|
| }
|
|
|
| -@end // BrowserCompositorViewCocoa
|
| +} // namespace content
|
|
|
| ////////////////////////////////////////////////////////////////////////////////
|
| -// BrowserCompositorViewCocoaHelper
|
| +// BrowserCompositorViewCocoa
|
|
|
| -namespace content {
|
| +@implementation BrowserCompositorViewCocoa
|
|
|
| -void BrowserCompositorViewCocoaHelper::AcceleratedLayerDidDrawFrame(
|
| - bool succeeded) {
|
| - [view_ layerDidDrawFrame];
|
| - if (!succeeded)
|
| - [view_ gotAcceleratedLayerError];
|
| +- (id)initWithClient:(content::BrowserCompositorViewCocoaClient*)client {
|
| + if (self = [super init]) {
|
| + client_ = client;
|
| + }
|
| + return self;
|
| }
|
|
|
| +- (void)dealloc {
|
| + DCHECK(!client_);
|
| + [super dealloc];
|
| }
|
|
|
| +- (void)resetClient {
|
| + client_ = NULL;
|
| +}
|
| +
|
| +- (void)gotAcceleratedIOSurfaceFrame:(IOSurfaceID)surface_handle
|
| + withOutputSurfaceID:(int)surface_id
|
| + withLatencyInfo:(std::vector<ui::LatencyInfo>)latency_info
|
| + withPixelSize:(gfx::Size)pixel_size
|
| + withScaleFactor:(float)scale_factor {
|
| + if (!client_)
|
| + return;
|
| + client_->GotAcceleratedIOSurfaceFrame(
|
| + surface_handle, surface_id, latency_info, pixel_size, scale_factor);
|
| +}
|
| +
|
| +- (void)gotSoftwareFrame:(cc::SoftwareFrameData*)frame_data
|
| + withScaleFactor:(float)scale_factor
|
| + withCanvas:(SkCanvas*)canvas {
|
| + if (!client_)
|
| + return;
|
| + client_->GotSoftwareFrame(frame_data, scale_factor, canvas);
|
| +}
|
| +
|
| +@end // BrowserCompositorViewCocoa
|
| +
|
|
|