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 |
- |