| 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_ca_layer_tree_mac.h" | 5 #include "content/browser/compositor/browser_compositor_ca_layer_tree_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" |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 typedef std::map<gfx::AcceleratedWidget,BrowserCompositorCALayerTreeMac*> | 25 typedef std::map<gfx::AcceleratedWidget,BrowserCompositorCALayerTreeMac*> |
| 26 WidgetToInternalsMap; | 26 WidgetToInternalsMap; |
| 27 base::LazyInstance<WidgetToInternalsMap> g_widget_to_internals_map; | 27 base::LazyInstance<WidgetToInternalsMap> g_widget_to_internals_map; |
| 28 | 28 |
| 29 } | 29 } |
| 30 | 30 |
| 31 //////////////////////////////////////////////////////////////////////////////// | 31 //////////////////////////////////////////////////////////////////////////////// |
| 32 // BrowserCompositorCALayerTreeMac | 32 // BrowserCompositorCALayerTreeMac |
| 33 | 33 |
| 34 BrowserCompositorCALayerTreeMac::BrowserCompositorCALayerTreeMac() | 34 BrowserCompositorCALayerTreeMac::BrowserCompositorCALayerTreeMac() |
| 35 : client_(NULL), | 35 : view_(NULL), |
| 36 accelerated_output_surface_id_(0) { | 36 accelerated_output_surface_id_(0) { |
| 37 // Disable the fade-in animation as the layers are added. | 37 // Disable the fade-in animation as the layers are added. |
| 38 ScopedCAActionDisabler disabler; | 38 ScopedCAActionDisabler disabler; |
| 39 | 39 |
| 40 // Add a flipped transparent layer as a child, so that we don't need to | 40 // Add a flipped transparent layer as a child, so that we don't need to |
| 41 // fiddle with the position of sub-layers -- they will always be at the | 41 // fiddle with the position of sub-layers -- they will always be at the |
| 42 // origin. | 42 // origin. |
| 43 flipped_layer_.reset([[CALayer alloc] init]); | 43 flipped_layer_.reset([[CALayer alloc] init]); |
| 44 [flipped_layer_ setGeometryFlipped:YES]; | 44 [flipped_layer_ setGeometryFlipped:YES]; |
| 45 [flipped_layer_ setAnchorPoint:CGPointMake(0, 0)]; | 45 [flipped_layer_ setAnchorPoint:CGPointMake(0, 0)]; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 57 | 57 |
| 58 // Create a compositor to draw the contents of this view. | 58 // Create a compositor to draw the contents of this view. |
| 59 compositor_.reset(new ui::Compositor( | 59 compositor_.reset(new ui::Compositor( |
| 60 native_widget_, | 60 native_widget_, |
| 61 content::GetContextFactory(), | 61 content::GetContextFactory(), |
| 62 RenderWidgetResizeHelper::Get()->task_runner())); | 62 RenderWidgetResizeHelper::Get()->task_runner())); |
| 63 compositor_->SetVisible(false); | 63 compositor_->SetVisible(false); |
| 64 } | 64 } |
| 65 | 65 |
| 66 BrowserCompositorCALayerTreeMac::~BrowserCompositorCALayerTreeMac() { | 66 BrowserCompositorCALayerTreeMac::~BrowserCompositorCALayerTreeMac() { |
| 67 DCHECK(!client_); | 67 DCHECK(!view_); |
| 68 g_widget_to_internals_map.Pointer()->erase(native_widget_); | 68 g_widget_to_internals_map.Pointer()->erase(native_widget_); |
| 69 } | 69 } |
| 70 | 70 |
| 71 void BrowserCompositorCALayerTreeMac::SetClient( | 71 void BrowserCompositorCALayerTreeMac::SetView( |
| 72 BrowserCompositorViewMacClient* client) { | 72 BrowserCompositorViewMac* view) { |
| 73 // Disable the fade-in animation as the view is added. | 73 // Disable the fade-in animation as the view is added. |
| 74 ScopedCAActionDisabler disabler; | 74 ScopedCAActionDisabler disabler; |
| 75 | 75 |
| 76 DCHECK(client && !client_); | 76 DCHECK(view && !view_); |
| 77 client_ = client; | 77 view_ = view; |
| 78 compositor_->SetRootLayer(client_->BrowserCompositorRootLayer()); | 78 compositor_->SetRootLayer(view_->ui_root_layer()); |
| 79 | 79 |
| 80 CALayer* background_layer = [client_->BrowserCompositorSuperview() layer]; | 80 CALayer* background_layer = [view_->native_view() layer]; |
| 81 DCHECK(background_layer); | 81 DCHECK(background_layer); |
| 82 [flipped_layer_ setBounds:[background_layer bounds]]; | 82 [flipped_layer_ setBounds:[background_layer bounds]]; |
| 83 [background_layer addSublayer:flipped_layer_]; | 83 [background_layer addSublayer:flipped_layer_]; |
| 84 compositor_->SetVisible(true); | 84 compositor_->SetVisible(true); |
| 85 } | 85 } |
| 86 | 86 |
| 87 void BrowserCompositorCALayerTreeMac::ResetClient() { | 87 void BrowserCompositorCALayerTreeMac::ResetView() { |
| 88 if (!client_) | 88 if (!view_) |
| 89 return; | 89 return; |
| 90 | 90 |
| 91 // Disable the fade-out animation as the view is removed. | 91 // Disable the fade-out animation as the view is removed. |
| 92 ScopedCAActionDisabler disabler; | 92 ScopedCAActionDisabler disabler; |
| 93 | 93 |
| 94 [flipped_layer_ removeFromSuperlayer]; | 94 [flipped_layer_ removeFromSuperlayer]; |
| 95 DestroyIOSurfaceLayer(io_surface_layer_); | 95 DestroyIOSurfaceLayer(io_surface_layer_); |
| 96 DestroyCAContextLayer(ca_context_layer_); | 96 DestroyCAContextLayer(ca_context_layer_); |
| 97 DestroySoftwareLayer(); | 97 DestroySoftwareLayer(); |
| 98 | 98 |
| 99 accelerated_output_surface_id_ = 0; | 99 accelerated_output_surface_id_ = 0; |
| 100 last_swap_size_dip_ = gfx::Size(); | 100 last_swap_size_dip_ = gfx::Size(); |
| 101 | 101 |
| 102 compositor_->SetVisible(false); | 102 compositor_->SetVisible(false); |
| 103 compositor_->SetScaleAndSize(1.0, gfx::Size(0, 0)); | 103 compositor_->SetScaleAndSize(1.0, gfx::Size(0, 0)); |
| 104 compositor_->SetRootLayer(NULL); | 104 compositor_->SetRootLayer(NULL); |
| 105 client_ = NULL; | 105 view_ = NULL; |
| 106 } | 106 } |
| 107 | 107 |
| 108 bool BrowserCompositorCALayerTreeMac::HasFrameOfSize( | 108 bool BrowserCompositorCALayerTreeMac::HasFrameOfSize( |
| 109 const gfx::Size& dip_size) const { | 109 const gfx::Size& dip_size) const { |
| 110 return last_swap_size_dip_ == dip_size; | 110 return last_swap_size_dip_ == dip_size; |
| 111 } | 111 } |
| 112 | 112 |
| 113 int BrowserCompositorCALayerTreeMac::GetRendererID() const { | 113 int BrowserCompositorCALayerTreeMac::GetRendererID() const { |
| 114 if (io_surface_layer_) | 114 if (io_surface_layer_) |
| 115 return [io_surface_layer_ rendererID]; | 115 return [io_surface_layer_ rendererID]; |
| 116 return 0; | 116 return 0; |
| 117 } | 117 } |
| 118 | 118 |
| 119 bool BrowserCompositorCALayerTreeMac::IsRendererThrottlingDisabled() const { | 119 bool BrowserCompositorCALayerTreeMac::IsRendererThrottlingDisabled() const { |
| 120 if (client_) | 120 if (view_) |
| 121 return client_->BrowserCompositorViewShouldAckImmediately(); | 121 return view_->client()->BrowserCompositorViewShouldAckImmediately(); |
| 122 return false; | 122 return false; |
| 123 } | 123 } |
| 124 | 124 |
| 125 void BrowserCompositorCALayerTreeMac::BeginPumpingFrames() { | 125 void BrowserCompositorCALayerTreeMac::BeginPumpingFrames() { |
| 126 [io_surface_layer_ beginPumpingFrames]; | 126 [io_surface_layer_ beginPumpingFrames]; |
| 127 } | 127 } |
| 128 | 128 |
| 129 void BrowserCompositorCALayerTreeMac::EndPumpingFrames() { | 129 void BrowserCompositorCALayerTreeMac::EndPumpingFrames() { |
| 130 [io_surface_layer_ endPumpingFrames]; | 130 [io_surface_layer_ endPumpingFrames]; |
| 131 } | 131 } |
| 132 | 132 |
| 133 void BrowserCompositorCALayerTreeMac::GotAcceleratedFrame( | 133 void BrowserCompositorCALayerTreeMac::GotAcceleratedFrame( |
| 134 uint64 surface_handle, int output_surface_id, | 134 uint64 surface_handle, int output_surface_id, |
| 135 const std::vector<ui::LatencyInfo>& latency_info, | 135 const std::vector<ui::LatencyInfo>& latency_info, |
| 136 gfx::Size pixel_size, float scale_factor) { | 136 gfx::Size pixel_size, float scale_factor) { |
| 137 // Record the surface and latency info to use when acknowledging this frame. | 137 // Record the surface and latency info to use when acknowledging this frame. |
| 138 DCHECK(!accelerated_output_surface_id_); | 138 DCHECK(!accelerated_output_surface_id_); |
| 139 accelerated_output_surface_id_ = output_surface_id; | 139 accelerated_output_surface_id_ = output_surface_id; |
| 140 accelerated_latency_info_.insert(accelerated_latency_info_.end(), | 140 accelerated_latency_info_.insert(accelerated_latency_info_.end(), |
| 141 latency_info.begin(), latency_info.end()); | 141 latency_info.begin(), latency_info.end()); |
| 142 | 142 |
| 143 // If there is no client and therefore no superview to draw into, early-out. | 143 // If there is no view and therefore no superview to draw into, early-out. |
| 144 if (!client_) { | 144 if (!view_) { |
| 145 IOSurfaceLayerDidDrawFrame(); | 145 IOSurfaceLayerDidDrawFrame(); |
| 146 return; | 146 return; |
| 147 } | 147 } |
| 148 | 148 |
| 149 // Disable the fade-in or fade-out effect if we create or remove layers. | 149 // Disable the fade-in or fade-out effect if we create or remove layers. |
| 150 ScopedCAActionDisabler disabler; | 150 ScopedCAActionDisabler disabler; |
| 151 | 151 |
| 152 last_swap_size_dip_ = ConvertSizeToDIP(scale_factor, pixel_size); | 152 last_swap_size_dip_ = ConvertSizeToDIP(scale_factor, pixel_size); |
| 153 switch (GetSurfaceHandleType(surface_handle)) { | 153 switch (GetSurfaceHandleType(surface_handle)) { |
| 154 case kSurfaceHandleTypeIOSurface: { | 154 case kSurfaceHandleTypeIOSurface: { |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 267 | 267 |
| 268 // Remove any different-type layers that this is replacing. | 268 // Remove any different-type layers that this is replacing. |
| 269 DestroyCAContextLayer(ca_context_layer_); | 269 DestroyCAContextLayer(ca_context_layer_); |
| 270 DestroySoftwareLayer(); | 270 DestroySoftwareLayer(); |
| 271 } | 271 } |
| 272 | 272 |
| 273 void BrowserCompositorCALayerTreeMac::GotSoftwareFrame( | 273 void BrowserCompositorCALayerTreeMac::GotSoftwareFrame( |
| 274 cc::SoftwareFrameData* frame_data, | 274 cc::SoftwareFrameData* frame_data, |
| 275 float scale_factor, | 275 float scale_factor, |
| 276 SkCanvas* canvas) { | 276 SkCanvas* canvas) { |
| 277 if (!frame_data || !canvas || !client_) | 277 if (!frame_data || !canvas || !view_) |
| 278 return; | 278 return; |
| 279 | 279 |
| 280 // Disable the fade-in or fade-out effect if we create or remove layers. | 280 // Disable the fade-in or fade-out effect if we create or remove layers. |
| 281 ScopedCAActionDisabler disabler; | 281 ScopedCAActionDisabler disabler; |
| 282 | 282 |
| 283 // If there is not a layer for software frames, create one. | 283 // If there is not a layer for software frames, create one. |
| 284 if (!software_layer_) { | 284 if (!software_layer_) { |
| 285 software_layer_.reset([[SoftwareLayer alloc] init]); | 285 software_layer_.reset([[SoftwareLayer alloc] init]); |
| 286 [flipped_layer_ addSublayer:software_layer_]; | 286 [flipped_layer_ addSublayer:software_layer_]; |
| 287 } | 287 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 323 | 323 |
| 324 void BrowserCompositorCALayerTreeMac::DestroySoftwareLayer() { | 324 void BrowserCompositorCALayerTreeMac::DestroySoftwareLayer() { |
| 325 if (!software_layer_) | 325 if (!software_layer_) |
| 326 return; | 326 return; |
| 327 [software_layer_ removeFromSuperlayer]; | 327 [software_layer_ removeFromSuperlayer]; |
| 328 software_layer_.reset(); | 328 software_layer_.reset(); |
| 329 } | 329 } |
| 330 | 330 |
| 331 bool BrowserCompositorCALayerTreeMac::IOSurfaceLayerShouldAckImmediately() | 331 bool BrowserCompositorCALayerTreeMac::IOSurfaceLayerShouldAckImmediately() |
| 332 const { | 332 const { |
| 333 // If there is no client then the accelerated layer is not in the hierarchy | 333 // If there is no view then the accelerated layer is not in the hierarchy |
| 334 // and will never draw. | 334 // and will never draw. |
| 335 if (!client_) | 335 if (!view_) |
| 336 return true; | 336 return true; |
| 337 return client_->BrowserCompositorViewShouldAckImmediately(); | 337 return view_->client()->BrowserCompositorViewShouldAckImmediately(); |
| 338 } | 338 } |
| 339 | 339 |
| 340 void BrowserCompositorCALayerTreeMac::IOSurfaceLayerDidDrawFrame() { | 340 void BrowserCompositorCALayerTreeMac::IOSurfaceLayerDidDrawFrame() { |
| 341 if (accelerated_output_surface_id_) { | 341 if (accelerated_output_surface_id_) { |
| 342 content::ImageTransportFactory::GetInstance()->OnSurfaceDisplayed( | 342 content::ImageTransportFactory::GetInstance()->OnSurfaceDisplayed( |
| 343 accelerated_output_surface_id_); | 343 accelerated_output_surface_id_); |
| 344 accelerated_output_surface_id_ = 0; | 344 accelerated_output_surface_id_ = 0; |
| 345 } | 345 } |
| 346 | 346 |
| 347 if (client_) | 347 if (view_) { |
| 348 client_->BrowserCompositorViewFrameSwapped(accelerated_latency_info_); | 348 view_->client()->BrowserCompositorViewFrameSwapped( |
| 349 accelerated_latency_info_); |
| 350 } |
| 349 | 351 |
| 350 accelerated_latency_info_.clear(); | 352 accelerated_latency_info_.clear(); |
| 351 } | 353 } |
| 352 | 354 |
| 353 void BrowserCompositorCALayerTreeMac::IOSurfaceLayerHitError() { | 355 void BrowserCompositorCALayerTreeMac::IOSurfaceLayerHitError() { |
| 354 // Perform all acks that would have been done if the frame had succeeded, to | 356 // Perform all acks that would have been done if the frame had succeeded, to |
| 355 // un-block the compositor and renderer. | 357 // un-block the compositor and renderer. |
| 356 IOSurfaceLayerDidDrawFrame(); | 358 IOSurfaceLayerDidDrawFrame(); |
| 357 | 359 |
| 358 // Poison the context being used and request a mulligan. | 360 // Poison the context being used and request a mulligan. |
| 359 [io_surface_layer_ poisonContextAndSharegroup]; | 361 [io_surface_layer_ poisonContextAndSharegroup]; |
| 360 compositor_->ScheduleFullRedraw(); | 362 compositor_->ScheduleFullRedraw(); |
| 361 } | 363 } |
| 362 | 364 |
| 363 // static | 365 // static |
| 364 BrowserCompositorCALayerTreeMac* BrowserCompositorCALayerTreeMac:: | 366 BrowserCompositorCALayerTreeMac* BrowserCompositorCALayerTreeMac:: |
| 365 FromAcceleratedWidget(gfx::AcceleratedWidget widget) { | 367 FromAcceleratedWidget(gfx::AcceleratedWidget widget) { |
| 366 WidgetToInternalsMap::const_iterator found = | 368 WidgetToInternalsMap::const_iterator found = |
| 367 g_widget_to_internals_map.Pointer()->find(widget); | 369 g_widget_to_internals_map.Pointer()->find(widget); |
| 368 // This can end up being accessed after the underlying widget has been | 370 // This can end up being accessed after the underlying widget has been |
| 369 // destroyed, but while the ui::Compositor is still being destroyed. | 371 // destroyed, but while the ui::Compositor is still being destroyed. |
| 370 // Return NULL in these cases. | 372 // Return NULL in these cases. |
| 371 if (found == g_widget_to_internals_map.Pointer()->end()) | 373 if (found == g_widget_to_internals_map.Pointer()->end()) |
| 372 return NULL; | 374 return NULL; |
| 373 return found->second; | 375 return found->second; |
| 374 } | 376 } |
| 375 | 377 |
| 378 // static |
| 379 void BrowserCompositorCALayerTreeMac::GotAcceleratedFrame( |
| 380 gfx::AcceleratedWidget widget, |
| 381 uint64 surface_handle, int surface_id, |
| 382 const std::vector<ui::LatencyInfo>& latency_info, |
| 383 gfx::Size pixel_size, float scale_factor, |
| 384 bool* disable_throttling, int* renderer_id) { |
| 385 BrowserCompositorCALayerTreeMac* ca_layer_tree = |
| 386 FromAcceleratedWidget(widget); |
| 387 if (ca_layer_tree) { |
| 388 ca_layer_tree->GotAcceleratedFrame( |
| 389 surface_handle, surface_id, latency_info, pixel_size, scale_factor); |
| 390 *disable_throttling = ca_layer_tree->IsRendererThrottlingDisabled(); |
| 391 *renderer_id = ca_layer_tree->GetRendererID(); |
| 392 } else { |
| 393 *disable_throttling = false; |
| 394 *renderer_id = 0; |
| 395 } |
| 396 } |
| 397 |
| 398 // static |
| 399 void BrowserCompositorCALayerTreeMac::GotSoftwareFrame( |
| 400 gfx::AcceleratedWidget widget, |
| 401 cc::SoftwareFrameData* frame_data, float scale_factor, SkCanvas* canvas) { |
| 402 BrowserCompositorCALayerTreeMac* ca_layer_tree = |
| 403 FromAcceleratedWidget(widget); |
| 404 if (ca_layer_tree) |
| 405 ca_layer_tree->GotSoftwareFrame(frame_data, scale_factor, canvas); |
| 406 } |
| 407 |
| 376 } // namespace content | 408 } // namespace content |
| OLD | NEW |