| 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 a21f8c5bfc2aab7ce2c2e371887209255fd63bbf..cd6ed66cc6d539eb944ad2e7eadfff6f07b4b376 100644
|
| --- a/content/browser/compositor/browser_compositor_view_private_mac.mm
|
| +++ b/content/browser/compositor/browser_compositor_view_private_mac.mm
|
| @@ -15,6 +15,7 @@
|
| #include "content/browser/renderer_host/dip_util.h"
|
| #include "content/browser/renderer_host/render_widget_resize_helper.h"
|
| #include "content/browser/renderer_host/software_layer_mac.h"
|
| +#include "content/common/gpu/surface_handle_types_mac.h"
|
| #include "content/public/browser/context_factory.h"
|
| #include "ui/base/cocoa/animation_utils.h"
|
| #include "ui/gl/scoped_cgl.h"
|
| @@ -33,7 +34,7 @@ base::LazyInstance<WidgetToInternalsMap> g_widget_to_internals_map;
|
|
|
| BrowserCompositorViewMacInternal::BrowserCompositorViewMacInternal()
|
| : client_(NULL),
|
| - accelerated_layer_output_surface_id_(0) {
|
| + accelerated_output_surface_id_(0) {
|
| // Disable the fade-in animation as the layers are added.
|
| ScopedCAActionDisabler disabler;
|
|
|
| @@ -91,10 +92,10 @@ void BrowserCompositorViewMacInternal::ResetClient() {
|
|
|
| [flipped_layer_ removeFromSuperlayer];
|
|
|
| - [accelerated_layer_ removeFromSuperlayer];
|
| - [accelerated_layer_ resetClient];
|
| - accelerated_layer_.reset();
|
| - accelerated_layer_output_surface_id_ = 0;
|
| + [io_surface_layer_ removeFromSuperlayer];
|
| + [io_surface_layer_ resetClient];
|
| + io_surface_layer_.reset();
|
| + accelerated_output_surface_id_ = 0;
|
|
|
| [software_layer_ removeFromSuperlayer];
|
| software_layer_.reset();
|
| @@ -112,21 +113,20 @@ bool BrowserCompositorViewMacInternal::HasFrameOfSize(
|
| }
|
|
|
| void BrowserCompositorViewMacInternal::BeginPumpingFrames() {
|
| - [accelerated_layer_ beginPumpingFrames];
|
| + [io_surface_layer_ beginPumpingFrames];
|
| }
|
|
|
| void BrowserCompositorViewMacInternal::EndPumpingFrames() {
|
| - [accelerated_layer_ endPumpingFrames];
|
| + [io_surface_layer_ endPumpingFrames];
|
| }
|
|
|
| -void BrowserCompositorViewMacInternal::GotAcceleratedIOSurfaceFrame(
|
| - IOSurfaceID io_surface_id,
|
| - int output_surface_id,
|
| +void BrowserCompositorViewMacInternal::GotAcceleratedFrame(
|
| + uint64 surface_handle, 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_ = output_surface_id;
|
| + gfx::Size pixel_size, float scale_factor) {
|
| + // Record the surface and latency info to use when acknowledging this frame.
|
| + DCHECK(!accelerated_output_surface_id_);
|
| + accelerated_output_surface_id_ = output_surface_id;
|
| accelerated_latency_info_.insert(accelerated_latency_info_.end(),
|
| latency_info.begin(), latency_info.end());
|
|
|
| @@ -139,58 +139,127 @@ void BrowserCompositorViewMacInternal::GotAcceleratedIOSurfaceFrame(
|
| // 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
|
| - // factor or it was poisoned, remove the old layer and replace it.
|
| - base::scoped_nsobject<CompositingIOSurfaceLayer> old_accelerated_layer;
|
| - if (accelerated_layer_ && (
|
| - [accelerated_layer_ context]->HasBeenPoisoned() ||
|
| - [accelerated_layer_ iosurface]->scale_factor() != scale_factor)) {
|
| - old_accelerated_layer = accelerated_layer_;
|
| - accelerated_layer_.reset();
|
| + last_swap_size_dip_ = ConvertSizeToDIP(scale_factor, pixel_size);
|
| + switch (GetSurfaceHandleType(surface_handle)) {
|
| + case kSurfaceHandleTypeIOSurface: {
|
| + IOSurfaceID io_surface_id = IOSurfaceIDFromSurfaceHandle(surface_handle);
|
| + GotAcceleratedIOSurfaceFrame(io_surface_id, pixel_size, scale_factor);
|
| + break;
|
| + }
|
| + case kSurfaceHandleTypeCAContext: {
|
| + CAContextID ca_context_id = CAContextIDFromSurfaceHandle(surface_handle);
|
| + GotAcceleratedCAContextFrame(ca_context_id, pixel_size, scale_factor);
|
| + break;
|
| + }
|
| + default:
|
| + LOG(ERROR) << "Unrecognized accelerated frame type.";
|
| + return;
|
| + }
|
| +}
|
| +
|
| +void BrowserCompositorViewMacInternal::GotAcceleratedCAContextFrame(
|
| + CAContextID ca_context_id,
|
| + gfx::Size pixel_size,
|
| + float scale_factor) {
|
| + // In the layer is replaced, keep the old one around until after the new one
|
| + // is installed to avoid flashes.
|
| + base::scoped_nsobject<CALayerHost> old_ca_context_layer =
|
| + ca_context_layer_;
|
| +
|
| + // Create the layer to host the layer exported by the GPU process with this
|
| + // particular CAContext ID.
|
| + if ([ca_context_layer_ contextId] != ca_context_id) {
|
| + ca_context_layer_.reset([[CALayerHost alloc] init]);
|
| + [ca_context_layer_ setContextId:ca_context_id];
|
| + [ca_context_layer_
|
| + setAutoresizingMask:kCALayerMaxXMargin|kCALayerMaxYMargin];
|
| + [flipped_layer_ addSublayer:ca_context_layer_];
|
| + }
|
| +
|
| + // Acknowledge the frame to unblock the compositor immediately (the GPU
|
| + // process will do any required throttling).
|
| + AcceleratedLayerDidDrawFrame(true);
|
| +
|
| + // If this replacing a same-type layer, remove it now that the new layer is
|
| + // in the hierarchy.
|
| + if (old_ca_context_layer != ca_context_layer_)
|
| + [old_ca_context_layer removeFromSuperlayer];
|
| +
|
| + // Remove any different-type layers that this is replacing.
|
| + if (io_surface_layer_) {
|
| + [io_surface_layer_ resetClient];
|
| + [io_surface_layer_ removeFromSuperlayer];
|
| + io_surface_layer_.reset();
|
| + }
|
| + if (software_layer_) {
|
| + [software_layer_ removeFromSuperlayer];
|
| + software_layer_.reset();
|
| }
|
| +}
|
|
|
| - // If there is not a layer for accelerated frames, create one.
|
| - if (!accelerated_layer_) {
|
| +void BrowserCompositorViewMacInternal::GotAcceleratedIOSurfaceFrame(
|
| + IOSurfaceID io_surface_id,
|
| + gfx::Size pixel_size,
|
| + float scale_factor) {
|
| + // In the layer is replaced, keep the old one around until after the new one
|
| + // is installed to avoid flashes.
|
| + base::scoped_nsobject<CompositingIOSurfaceLayer> old_io_surface_layer =
|
| + io_surface_layer_;
|
| +
|
| + // Create or re-create an IOSurface layer if needed. If there already exists
|
| + // a layer but it has the wrong scale factor or it was poisoned, re-create the
|
| + // layer.
|
| + bool needs_new_layer =
|
| + !io_surface_layer_ ||
|
| + [io_surface_layer_ context]->HasBeenPoisoned() ||
|
| + [io_surface_layer_ iosurface]->scale_factor() != scale_factor;
|
| + if (needs_new_layer) {
|
| scoped_refptr<content::CompositingIOSurfaceMac> iosurface =
|
| content::CompositingIOSurfaceMac::Create();
|
| - accelerated_layer_.reset([[CompositingIOSurfaceLayer alloc]
|
| + io_surface_layer_.reset([[CompositingIOSurfaceLayer alloc]
|
| initWithIOSurface:iosurface
|
| withScaleFactor:scale_factor
|
| withClient:this]);
|
| - [flipped_layer_ addSublayer:accelerated_layer_];
|
| + [flipped_layer_ addSublayer:io_surface_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], io_surface_id, pixel_size, scale_factor);
|
| + [io_surface_layer_ context]->cgl_context());
|
| + result = [io_surface_layer_ iosurface]->SetIOSurfaceWithContextCurrent(
|
| + [io_surface_layer_ context], io_surface_id, pixel_size, scale_factor);
|
| if (!result)
|
| LOG(ERROR) << "Failed SetIOSurface on CompositingIOSurfaceMac";
|
| }
|
| - [accelerated_layer_ gotNewFrame];
|
| + [io_surface_layer_ gotNewFrame];
|
|
|
| // Set the bounds of the accelerated layer to match the size of the frame.
|
| // If the bounds changed, force the content to be displayed immediately.
|
| - last_swap_size_dip_ = [accelerated_layer_ iosurface]->dip_io_surface_size();
|
| CGRect new_layer_bounds = CGRectMake(
|
| 0, 0, last_swap_size_dip_.width(), last_swap_size_dip_.height());
|
| bool bounds_changed = !CGRectEqualToRect(
|
| - new_layer_bounds, [accelerated_layer_ bounds]);
|
| - [accelerated_layer_ setBounds:new_layer_bounds];
|
| + new_layer_bounds, [io_surface_layer_ bounds]);
|
| + [io_surface_layer_ setBounds:new_layer_bounds];
|
| if (bounds_changed)
|
| - [accelerated_layer_ setNeedsDisplayAndDisplayAndAck];
|
| + [io_surface_layer_ setNeedsDisplayAndDisplayAndAck];
|
|
|
| - // If there was a software layer or an old accelerated layer, remove it.
|
| - // Disable the fade-out animation as the layer is removed.
|
| - {
|
| + // If this replacing a same-type layer, remove it now that the new layer is
|
| + // in the hierarchy.
|
| + if (old_io_surface_layer != io_surface_layer_) {
|
| + [old_io_surface_layer resetClient];
|
| + [old_io_surface_layer removeFromSuperlayer];
|
| + }
|
| +
|
| + // Remove any different-type layers that this is replacing.
|
| + if (ca_context_layer_) {
|
| + [ca_context_layer_ removeFromSuperlayer];
|
| + ca_context_layer_.reset();
|
| + }
|
| + if (software_layer_) {
|
| [software_layer_ removeFromSuperlayer];
|
| software_layer_.reset();
|
| - [old_accelerated_layer resetClient];
|
| - [old_accelerated_layer removeFromSuperlayer];
|
| - old_accelerated_layer.reset();
|
| }
|
| }
|
|
|
| @@ -221,11 +290,15 @@ void BrowserCompositorViewMacInternal::GotSoftwareFrame(
|
| withScaleFactor:scale_factor];
|
| last_swap_size_dip_ = ConvertSizeToDIP(scale_factor, pixel_size);
|
|
|
| - // If there was an accelerated layer, remove it.
|
| - {
|
| - [accelerated_layer_ resetClient];
|
| - [accelerated_layer_ removeFromSuperlayer];
|
| - accelerated_layer_.reset();
|
| + // Remove any different-type layers that this is replacing.
|
| + if (ca_context_layer_) {
|
| + [ca_context_layer_ removeFromSuperlayer];
|
| + ca_context_layer_.reset();
|
| + }
|
| + if (io_surface_layer_) {
|
| + [io_surface_layer_ resetClient];
|
| + [io_surface_layer_ removeFromSuperlayer];
|
| + io_surface_layer_.reset();
|
| }
|
| }
|
|
|
| @@ -240,10 +313,10 @@ bool BrowserCompositorViewMacInternal::AcceleratedLayerShouldAckImmediately()
|
|
|
| void BrowserCompositorViewMacInternal::AcceleratedLayerDidDrawFrame(
|
| bool succeeded) {
|
| - if (accelerated_layer_output_surface_id_) {
|
| + if (accelerated_output_surface_id_) {
|
| content::ImageTransportFactory::GetInstance()->OnSurfaceDisplayed(
|
| - accelerated_layer_output_surface_id_);
|
| - accelerated_layer_output_surface_id_ = 0;
|
| + accelerated_output_surface_id_);
|
| + accelerated_output_surface_id_ = 0;
|
| }
|
|
|
| if (client_)
|
| @@ -252,8 +325,8 @@ void BrowserCompositorViewMacInternal::AcceleratedLayerDidDrawFrame(
|
| accelerated_latency_info_.clear();
|
|
|
| if (!succeeded) {
|
| - if (accelerated_layer_)
|
| - [accelerated_layer_ context]->PoisonContextAndSharegroup();
|
| + if (io_surface_layer_)
|
| + [io_surface_layer_ context]->PoisonContextAndSharegroup();
|
| compositor_->ScheduleFullRedraw();
|
| }
|
| }
|
| @@ -271,6 +344,4 @@ BrowserCompositorViewMacInternal* BrowserCompositorViewMacInternal::
|
| return found->second;
|
| }
|
|
|
| -
|
| } // namespace content
|
| -
|
|
|