| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/compositor/browser_compositor_view_private_mac.h" | 5 #include "content/browser/compositor/browser_compositor_view_private_mac.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 | 8 |
| 9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
| 10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
| 11 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
| 12 #include "content/browser/compositor/gpu_process_transport_factory.h" | 12 #include "content/browser/compositor/gpu_process_transport_factory.h" |
| 13 #include "content/browser/renderer_host/compositing_iosurface_context_mac.h" | 13 #include "content/browser/compositor/io_surface_layer_mac.h" |
| 14 #include "content/browser/renderer_host/compositing_iosurface_mac.h" | 14 #include "content/browser/compositor/software_layer_mac.h" |
| 15 #include "content/browser/renderer_host/dip_util.h" | 15 #include "content/browser/renderer_host/dip_util.h" |
| 16 #include "content/browser/renderer_host/render_widget_resize_helper.h" | 16 #include "content/browser/renderer_host/render_widget_resize_helper.h" |
| 17 #include "content/browser/renderer_host/software_layer_mac.h" | |
| 18 #include "content/common/gpu/surface_handle_types_mac.h" | 17 #include "content/common/gpu/surface_handle_types_mac.h" |
| 19 #include "content/public/browser/context_factory.h" | 18 #include "content/public/browser/context_factory.h" |
| 20 #include "ui/base/cocoa/animation_utils.h" | 19 #include "ui/base/cocoa/animation_utils.h" |
| 21 #include "ui/gl/scoped_cgl.h" | 20 #include "ui/gl/scoped_cgl.h" |
| 22 | 21 |
| 23 namespace content { | 22 namespace content { |
| 24 namespace { | 23 namespace { |
| 25 | 24 |
| 26 typedef std::map<gfx::AcceleratedWidget,BrowserCompositorViewMacInternal*> | 25 typedef std::map<gfx::AcceleratedWidget,BrowserCompositorViewMacInternal*> |
| 27 WidgetToInternalsMap; | 26 WidgetToInternalsMap; |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 106 client_ = NULL; | 105 client_ = NULL; |
| 107 } | 106 } |
| 108 | 107 |
| 109 bool BrowserCompositorViewMacInternal::HasFrameOfSize( | 108 bool BrowserCompositorViewMacInternal::HasFrameOfSize( |
| 110 const gfx::Size& dip_size) const { | 109 const gfx::Size& dip_size) const { |
| 111 return last_swap_size_dip_ == dip_size; | 110 return last_swap_size_dip_ == dip_size; |
| 112 } | 111 } |
| 113 | 112 |
| 114 int BrowserCompositorViewMacInternal::GetRendererID() const { | 113 int BrowserCompositorViewMacInternal::GetRendererID() const { |
| 115 if (io_surface_layer_) | 114 if (io_surface_layer_) |
| 116 return [io_surface_layer_ iosurface]->GetRendererID(); | 115 return [io_surface_layer_ rendererID]; |
| 117 return 0; | 116 return 0; |
| 118 } | 117 } |
| 119 | 118 |
| 120 void BrowserCompositorViewMacInternal::BeginPumpingFrames() { | 119 void BrowserCompositorViewMacInternal::BeginPumpingFrames() { |
| 121 [io_surface_layer_ beginPumpingFrames]; | 120 [io_surface_layer_ beginPumpingFrames]; |
| 122 } | 121 } |
| 123 | 122 |
| 124 void BrowserCompositorViewMacInternal::EndPumpingFrames() { | 123 void BrowserCompositorViewMacInternal::EndPumpingFrames() { |
| 125 [io_surface_layer_ endPumpingFrames]; | 124 [io_surface_layer_ endPumpingFrames]; |
| 126 } | 125 } |
| 127 | 126 |
| 128 void BrowserCompositorViewMacInternal::GotAcceleratedFrame( | 127 void BrowserCompositorViewMacInternal::GotAcceleratedFrame( |
| 129 uint64 surface_handle, int output_surface_id, | 128 uint64 surface_handle, int output_surface_id, |
| 130 const std::vector<ui::LatencyInfo>& latency_info, | 129 const std::vector<ui::LatencyInfo>& latency_info, |
| 131 gfx::Size pixel_size, float scale_factor) { | 130 gfx::Size pixel_size, float scale_factor) { |
| 132 // Record the surface and latency info to use when acknowledging this frame. | 131 // Record the surface and latency info to use when acknowledging this frame. |
| 133 DCHECK(!accelerated_output_surface_id_); | 132 DCHECK(!accelerated_output_surface_id_); |
| 134 accelerated_output_surface_id_ = output_surface_id; | 133 accelerated_output_surface_id_ = output_surface_id; |
| 135 accelerated_latency_info_.insert(accelerated_latency_info_.end(), | 134 accelerated_latency_info_.insert(accelerated_latency_info_.end(), |
| 136 latency_info.begin(), latency_info.end()); | 135 latency_info.begin(), latency_info.end()); |
| 137 | 136 |
| 138 // If there is no client and therefore no superview to draw into, early-out. | 137 // If there is no client and therefore no superview to draw into, early-out. |
| 139 if (!client_) { | 138 if (!client_) { |
| 140 AcceleratedLayerDidDrawFrame(); | 139 IOSurfaceLayerDidDrawFrame(); |
| 141 return; | 140 return; |
| 142 } | 141 } |
| 143 | 142 |
| 144 // Disable the fade-in or fade-out effect if we create or remove layers. | 143 // Disable the fade-in or fade-out effect if we create or remove layers. |
| 145 ScopedCAActionDisabler disabler; | 144 ScopedCAActionDisabler disabler; |
| 146 | 145 |
| 147 last_swap_size_dip_ = ConvertSizeToDIP(scale_factor, pixel_size); | 146 last_swap_size_dip_ = ConvertSizeToDIP(scale_factor, pixel_size); |
| 148 switch (GetSurfaceHandleType(surface_handle)) { | 147 switch (GetSurfaceHandleType(surface_handle)) { |
| 149 case kSurfaceHandleTypeIOSurface: { | 148 case kSurfaceHandleTypeIOSurface: { |
| 150 IOSurfaceID io_surface_id = IOSurfaceIDFromSurfaceHandle(surface_handle); | 149 IOSurfaceID io_surface_id = IOSurfaceIDFromSurfaceHandle(surface_handle); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 176 if ([ca_context_layer_ contextId] != ca_context_id) { | 175 if ([ca_context_layer_ contextId] != ca_context_id) { |
| 177 ca_context_layer_.reset([[CALayerHost alloc] init]); | 176 ca_context_layer_.reset([[CALayerHost alloc] init]); |
| 178 [ca_context_layer_ setContextId:ca_context_id]; | 177 [ca_context_layer_ setContextId:ca_context_id]; |
| 179 [ca_context_layer_ | 178 [ca_context_layer_ |
| 180 setAutoresizingMask:kCALayerMaxXMargin|kCALayerMaxYMargin]; | 179 setAutoresizingMask:kCALayerMaxXMargin|kCALayerMaxYMargin]; |
| 181 [flipped_layer_ addSublayer:ca_context_layer_]; | 180 [flipped_layer_ addSublayer:ca_context_layer_]; |
| 182 } | 181 } |
| 183 | 182 |
| 184 // Acknowledge the frame to unblock the compositor immediately (the GPU | 183 // Acknowledge the frame to unblock the compositor immediately (the GPU |
| 185 // process will do any required throttling). | 184 // process will do any required throttling). |
| 186 AcceleratedLayerDidDrawFrame(); | 185 IOSurfaceLayerDidDrawFrame(); |
| 187 | 186 |
| 188 // If this replacing a same-type layer, remove it now that the new layer is | 187 // If this replacing a same-type layer, remove it now that the new layer is |
| 189 // in the hierarchy. | 188 // in the hierarchy. |
| 190 if (old_ca_context_layer != ca_context_layer_) | 189 if (old_ca_context_layer != ca_context_layer_) |
| 191 DestroyCAContextLayer(old_ca_context_layer); | 190 DestroyCAContextLayer(old_ca_context_layer); |
| 192 | 191 |
| 193 // Remove any different-type layers that this is replacing. | 192 // Remove any different-type layers that this is replacing. |
| 194 DestroyIOSurfaceLayer(io_surface_layer_); | 193 DestroyIOSurfaceLayer(io_surface_layer_); |
| 195 DestroySoftwareLayer(); | 194 DestroySoftwareLayer(); |
| 196 } | 195 } |
| 197 | 196 |
| 198 void BrowserCompositorViewMacInternal::GotAcceleratedIOSurfaceFrame( | 197 void BrowserCompositorViewMacInternal::GotAcceleratedIOSurfaceFrame( |
| 199 IOSurfaceID io_surface_id, | 198 IOSurfaceID io_surface_id, |
| 200 gfx::Size pixel_size, | 199 gfx::Size pixel_size, |
| 201 float scale_factor) { | 200 float scale_factor) { |
| 202 // In the layer is replaced, keep the old one around until after the new one | 201 // In the layer is replaced, keep the old one around until after the new one |
| 203 // is installed to avoid flashes. | 202 // is installed to avoid flashes. |
| 204 base::scoped_nsobject<CompositingIOSurfaceLayer> old_io_surface_layer = | 203 base::scoped_nsobject<IOSurfaceLayer> old_io_surface_layer = |
| 205 io_surface_layer_; | 204 io_surface_layer_; |
| 206 | 205 |
| 207 // Create or re-create an IOSurface layer if needed. If there already exists | 206 // Create or re-create an IOSurface layer if needed. If there already exists |
| 208 // a layer but it has the wrong scale factor or it was poisoned, re-create the | 207 // a layer but it has the wrong scale factor or it was poisoned, re-create the |
| 209 // layer. | 208 // layer. |
| 210 bool needs_new_layer = | 209 bool needs_new_layer = |
| 211 !io_surface_layer_ || | 210 !io_surface_layer_ || |
| 212 [io_surface_layer_ context]->HasBeenPoisoned() || | 211 [io_surface_layer_ hasBeenPoisoned] || |
| 213 [io_surface_layer_ iosurface]->scale_factor() != scale_factor; | 212 [io_surface_layer_ scaleFactor] != scale_factor; |
| 214 if (needs_new_layer) { | 213 if (needs_new_layer) { |
| 215 scoped_refptr<content::CompositingIOSurfaceMac> iosurface = | 214 io_surface_layer_.reset( |
| 216 content::CompositingIOSurfaceMac::Create(); | 215 [[IOSurfaceLayer alloc] initWithClient:this |
| 217 if (!iosurface) { | 216 withScaleFactor:scale_factor]); |
| 218 LOG(ERROR) << "Failed to create CompositingIOSurfaceMac"; | 217 if (io_surface_layer_) |
| 219 } else { | 218 [flipped_layer_ addSublayer:io_surface_layer_]; |
| 220 io_surface_layer_.reset([[CompositingIOSurfaceLayer alloc] | 219 else |
| 221 initWithIOSurface:iosurface | 220 LOG(ERROR) << "Failed to create IOSurfaceLayer"; |
| 222 withScaleFactor:scale_factor | |
| 223 withClient:this]); | |
| 224 if (io_surface_layer_) | |
| 225 [flipped_layer_ addSublayer:io_surface_layer_]; | |
| 226 else | |
| 227 LOG(ERROR) << "Failed to create CompositingIOSurfaceLayer"; | |
| 228 } | |
| 229 } | 221 } |
| 230 | 222 |
| 231 // Open the provided IOSurface. | 223 // Open the provided IOSurface. |
| 232 if (io_surface_layer_) { | 224 if (io_surface_layer_) { |
| 233 bool result = true; | 225 bool result = [io_surface_layer_ gotFrameWithIOSurface:io_surface_id |
| 234 gfx::ScopedCGLSetCurrentContext scoped_set_current_context( | 226 withPixelSize:pixel_size |
| 235 [io_surface_layer_ context]->cgl_context()); | 227 withScaleFactor:scale_factor]; |
| 236 result = [io_surface_layer_ iosurface]->SetIOSurfaceWithContextCurrent( | |
| 237 [io_surface_layer_ context], io_surface_id, pixel_size, scale_factor); | |
| 238 if (!result) { | 228 if (!result) { |
| 239 DestroyIOSurfaceLayer(io_surface_layer_); | 229 DestroyIOSurfaceLayer(io_surface_layer_); |
| 240 LOG(ERROR) << "Failed open IOSurface in CompositingIOSurfaceLayer"; | 230 LOG(ERROR) << "Failed open IOSurface in IOSurfaceLayer"; |
| 241 } | 231 } |
| 242 } | 232 } |
| 243 | 233 |
| 244 // Give a final complaint if anything with the layer's creation went wrong. | 234 // Give a final complaint if anything with the layer's creation went wrong. |
| 245 // This frame will appear blank, the compositor will try to create another, | 235 // This frame will appear blank, the compositor will try to create another, |
| 246 // and maybe that will go better. | 236 // and maybe that will go better. |
| 247 if (!io_surface_layer_) { | 237 if (!io_surface_layer_) { |
| 248 LOG(ERROR) << "CompositingIOSurfaceLayer is nil, tab will be blank"; | 238 LOG(ERROR) << "IOSurfaceLayer is nil, tab will be blank"; |
| 249 AcceleratedLayerHitError(); | 239 IOSurfaceLayerHitError(); |
| 250 } | 240 } |
| 251 | 241 |
| 252 // Make the CALayer draw and set its size appropriately. | 242 // Make the CALayer draw and set its size appropriately. |
| 253 if (io_surface_layer_) { | 243 if (io_surface_layer_) { |
| 254 [io_surface_layer_ gotNewFrame]; | 244 [io_surface_layer_ gotNewFrame]; |
| 255 | 245 |
| 256 // Set the bounds of the accelerated layer to match the size of the frame. | 246 // Set the bounds of the accelerated layer to match the size of the frame. |
| 257 // If the bounds changed, force the content to be displayed immediately. | 247 // If the bounds changed, force the content to be displayed immediately. |
| 258 CGRect new_layer_bounds = CGRectMake( | 248 CGRect new_layer_bounds = CGRectMake( |
| 259 0, 0, last_swap_size_dip_.width(), last_swap_size_dip_.height()); | 249 0, 0, last_swap_size_dip_.width(), last_swap_size_dip_.height()); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 309 void BrowserCompositorViewMacInternal::DestroyCAContextLayer( | 299 void BrowserCompositorViewMacInternal::DestroyCAContextLayer( |
| 310 base::scoped_nsobject<CALayerHost> ca_context_layer) { | 300 base::scoped_nsobject<CALayerHost> ca_context_layer) { |
| 311 if (!ca_context_layer) | 301 if (!ca_context_layer) |
| 312 return; | 302 return; |
| 313 [ca_context_layer removeFromSuperlayer]; | 303 [ca_context_layer removeFromSuperlayer]; |
| 314 if (ca_context_layer == ca_context_layer_) | 304 if (ca_context_layer == ca_context_layer_) |
| 315 ca_context_layer_.reset(); | 305 ca_context_layer_.reset(); |
| 316 } | 306 } |
| 317 | 307 |
| 318 void BrowserCompositorViewMacInternal::DestroyIOSurfaceLayer( | 308 void BrowserCompositorViewMacInternal::DestroyIOSurfaceLayer( |
| 319 base::scoped_nsobject<CompositingIOSurfaceLayer> io_surface_layer) { | 309 base::scoped_nsobject<IOSurfaceLayer> io_surface_layer) { |
| 320 if (!io_surface_layer) | 310 if (!io_surface_layer) |
| 321 return; | 311 return; |
| 322 [io_surface_layer resetClient]; | 312 [io_surface_layer resetClient]; |
| 323 [io_surface_layer removeFromSuperlayer]; | 313 [io_surface_layer removeFromSuperlayer]; |
| 324 if (io_surface_layer == io_surface_layer_) | 314 if (io_surface_layer == io_surface_layer_) |
| 325 io_surface_layer_.reset(); | 315 io_surface_layer_.reset(); |
| 326 } | 316 } |
| 327 | 317 |
| 328 void BrowserCompositorViewMacInternal::DestroySoftwareLayer() { | 318 void BrowserCompositorViewMacInternal::DestroySoftwareLayer() { |
| 329 if (!software_layer_) | 319 if (!software_layer_) |
| 330 return; | 320 return; |
| 331 [software_layer_ removeFromSuperlayer]; | 321 [software_layer_ removeFromSuperlayer]; |
| 332 software_layer_.reset(); | 322 software_layer_.reset(); |
| 333 } | 323 } |
| 334 | 324 |
| 335 bool BrowserCompositorViewMacInternal::AcceleratedLayerShouldAckImmediately() | 325 bool BrowserCompositorViewMacInternal::IOSurfaceLayerShouldAckImmediately() |
| 336 const { | 326 const { |
| 337 // If there is no client then the accelerated layer is not in the hierarchy | 327 // If there is no client then the accelerated layer is not in the hierarchy |
| 338 // and will never draw. | 328 // and will never draw. |
| 339 if (!client_) | 329 if (!client_) |
| 340 return true; | 330 return true; |
| 341 return client_->BrowserCompositorViewShouldAckImmediately(); | 331 return client_->BrowserCompositorViewShouldAckImmediately(); |
| 342 } | 332 } |
| 343 | 333 |
| 344 void BrowserCompositorViewMacInternal::AcceleratedLayerDidDrawFrame() { | 334 void BrowserCompositorViewMacInternal::IOSurfaceLayerDidDrawFrame() { |
| 345 if (accelerated_output_surface_id_) { | 335 if (accelerated_output_surface_id_) { |
| 346 content::ImageTransportFactory::GetInstance()->OnSurfaceDisplayed( | 336 content::ImageTransportFactory::GetInstance()->OnSurfaceDisplayed( |
| 347 accelerated_output_surface_id_); | 337 accelerated_output_surface_id_); |
| 348 accelerated_output_surface_id_ = 0; | 338 accelerated_output_surface_id_ = 0; |
| 349 } | 339 } |
| 350 | 340 |
| 351 if (client_) | 341 if (client_) |
| 352 client_->BrowserCompositorViewFrameSwapped(accelerated_latency_info_); | 342 client_->BrowserCompositorViewFrameSwapped(accelerated_latency_info_); |
| 353 | 343 |
| 354 accelerated_latency_info_.clear(); | 344 accelerated_latency_info_.clear(); |
| 355 } | 345 } |
| 356 | 346 |
| 357 void BrowserCompositorViewMacInternal::AcceleratedLayerHitError() { | 347 void BrowserCompositorViewMacInternal::IOSurfaceLayerHitError() { |
| 358 // Perform all acks that would have been done if the frame had succeeded, to | 348 // Perform all acks that would have been done if the frame had succeeded, to |
| 359 // un-block the compositor and renderer. | 349 // un-block the compositor and renderer. |
| 360 AcceleratedLayerDidDrawFrame(); | 350 IOSurfaceLayerDidDrawFrame(); |
| 361 | 351 |
| 362 // Poison the context being used and request a mulligan. | 352 // Poison the context being used and request a mulligan. |
| 363 if (io_surface_layer_) | 353 [io_surface_layer_ poisonContextAndSharegroup]; |
| 364 [io_surface_layer_ context]->PoisonContextAndSharegroup(); | |
| 365 compositor_->ScheduleFullRedraw(); | 354 compositor_->ScheduleFullRedraw(); |
| 366 } | 355 } |
| 367 | 356 |
| 368 // static | 357 // static |
| 369 BrowserCompositorViewMacInternal* BrowserCompositorViewMacInternal:: | 358 BrowserCompositorViewMacInternal* BrowserCompositorViewMacInternal:: |
| 370 FromAcceleratedWidget(gfx::AcceleratedWidget widget) { | 359 FromAcceleratedWidget(gfx::AcceleratedWidget widget) { |
| 371 WidgetToInternalsMap::const_iterator found = | 360 WidgetToInternalsMap::const_iterator found = |
| 372 g_widget_to_internals_map.Pointer()->find(widget); | 361 g_widget_to_internals_map.Pointer()->find(widget); |
| 373 // This can end up being accessed after the underlying widget has been | 362 // This can end up being accessed after the underlying widget has been |
| 374 // destroyed, but while the ui::Compositor is still being destroyed. | 363 // destroyed, but while the ui::Compositor is still being destroyed. |
| 375 // Return NULL in these cases. | 364 // Return NULL in these cases. |
| 376 if (found == g_widget_to_internals_map.Pointer()->end()) | 365 if (found == g_widget_to_internals_map.Pointer()->end()) |
| 377 return NULL; | 366 return NULL; |
| 378 return found->second; | 367 return found->second; |
| 379 } | 368 } |
| 380 | 369 |
| 381 } // namespace content | 370 } // namespace content |
| OLD | NEW |