Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/common/gpu/image_transport_surface_overlay_mac.h" | 5 #include "content/common/gpu/image_transport_surface_overlay_mac.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <IOSurface/IOSurface.h> | 8 #include <IOSurface/IOSurface.h> |
| 9 #include <OpenGL/CGLRenderers.h> | 9 #include <OpenGL/CGLRenderers.h> |
| 10 #include <OpenGL/CGLTypes.h> | 10 #include <OpenGL/CGLTypes.h> |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 79 } | 79 } |
| 80 | 80 |
| 81 } // namespace | 81 } // namespace |
| 82 | 82 |
| 83 @interface CALayer(Private) | 83 @interface CALayer(Private) |
| 84 -(void)setContentsChanged; | 84 -(void)setContentsChanged; |
| 85 @end | 85 @end |
| 86 | 86 |
| 87 namespace content { | 87 namespace content { |
| 88 | 88 |
| 89 scoped_refptr<gfx::GLSurface> ImageTransportSurfaceCreateNativeSurface( | |
| 90 GpuChannelManager* manager, | |
| 91 GpuCommandBufferStub* stub, | |
| 92 gfx::PluginWindowHandle handle) { | |
| 93 return new ImageTransportSurfaceOverlayMac(manager, stub, handle); | |
| 94 } | |
| 95 | |
| 89 class ImageTransportSurfaceOverlayMac::OverlayPlane { | 96 class ImageTransportSurfaceOverlayMac::OverlayPlane { |
| 90 public: | 97 public: |
| 91 OverlayPlane(int z_order, | 98 OverlayPlane(int z_order, |
| 99 int io_surface_id, | |
| 92 base::ScopedCFTypeRef<IOSurfaceRef> io_surface, | 100 base::ScopedCFTypeRef<IOSurfaceRef> io_surface, |
| 93 const gfx::RectF& dip_frame_rect, | 101 const gfx::RectF& dip_frame_rect, |
| 94 const gfx::RectF& contents_rect) | 102 const gfx::RectF& contents_rect) |
| 95 : z_order(z_order), | 103 : z_order(z_order), |
| 104 io_surface_id(io_surface_id), | |
| 96 io_surface(io_surface), | 105 io_surface(io_surface), |
| 97 dip_frame_rect(dip_frame_rect), | 106 dip_frame_rect(dip_frame_rect), |
| 98 contents_rect(contents_rect), | 107 contents_rect(contents_rect), |
| 99 layer_needs_update(true) {} | 108 layer_needs_update(true) {} |
| 100 ~OverlayPlane() { DCHECK(!ca_layer); } | 109 ~OverlayPlane() { DCHECK(!ca_layer); } |
| 101 | 110 |
| 102 const int z_order; | 111 const int z_order; |
| 103 base::scoped_nsobject<CALayer> ca_layer; | 112 base::scoped_nsobject<CALayer> ca_layer; |
| 104 | 113 |
| 105 // The IOSurface to set the CALayer's contents to. | 114 // The IOSurface to set the CALayer's contents to. |
| 115 const int io_surface_id; | |
| 106 const base::ScopedCFTypeRef<IOSurfaceRef> io_surface; | 116 const base::ScopedCFTypeRef<IOSurfaceRef> io_surface; |
| 107 const gfx::RectF dip_frame_rect; | 117 const gfx::RectF dip_frame_rect; |
| 108 const gfx::RectF contents_rect; | 118 const gfx::RectF contents_rect; |
| 109 | 119 |
| 110 bool layer_needs_update; | 120 bool layer_needs_update; |
| 111 | 121 |
| 112 static bool Compare(const linked_ptr<OverlayPlane>& a, | 122 static bool Compare(const linked_ptr<OverlayPlane>& a, |
| 113 const linked_ptr<OverlayPlane>& b) { | 123 const linked_ptr<OverlayPlane>& b) { |
| 114 return (a->z_order < b->z_order); | 124 return (a->z_order < b->z_order); |
| 115 } | 125 } |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 184 | 194 |
| 185 // The time that this will wake up and draw, if a following swap does not | 195 // The time that this will wake up and draw, if a following swap does not |
| 186 // cause it to draw earlier. | 196 // cause it to draw earlier. |
| 187 base::TimeTicks target_display_time; | 197 base::TimeTicks target_display_time; |
| 188 }; | 198 }; |
| 189 | 199 |
| 190 ImageTransportSurfaceOverlayMac::ImageTransportSurfaceOverlayMac( | 200 ImageTransportSurfaceOverlayMac::ImageTransportSurfaceOverlayMac( |
| 191 GpuChannelManager* manager, | 201 GpuChannelManager* manager, |
| 192 GpuCommandBufferStub* stub, | 202 GpuCommandBufferStub* stub, |
| 193 gfx::PluginWindowHandle handle) | 203 gfx::PluginWindowHandle handle) |
| 194 : scale_factor_(1), gl_renderer_id_(0), vsync_parameters_valid_(false), | 204 : use_remote_layer_api_(ui::RemoteLayerAPISupported()), |
| 195 display_pending_swap_timer_(true, false), weak_factory_(this) { | 205 scale_factor_(1), |
| 206 gl_renderer_id_(0), | |
| 207 vsync_parameters_valid_(false), | |
| 208 display_pending_swap_timer_(true, false), | |
| 209 weak_factory_(this) { | |
| 196 helper_.reset(new ImageTransportHelper(this, manager, stub, handle)); | 210 helper_.reset(new ImageTransportHelper(this, manager, stub, handle)); |
| 197 ui::GpuSwitchingManager::GetInstance()->AddObserver(this); | 211 ui::GpuSwitchingManager::GetInstance()->AddObserver(this); |
| 198 } | 212 } |
| 199 | 213 |
| 200 ImageTransportSurfaceOverlayMac::~ImageTransportSurfaceOverlayMac() { | 214 ImageTransportSurfaceOverlayMac::~ImageTransportSurfaceOverlayMac() { |
| 201 ui::GpuSwitchingManager::GetInstance()->RemoveObserver(this); | 215 ui::GpuSwitchingManager::GetInstance()->RemoveObserver(this); |
| 202 Destroy(); | 216 Destroy(); |
| 203 } | 217 } |
| 204 | 218 |
| 205 bool ImageTransportSurfaceOverlayMac::Initialize() { | 219 bool ImageTransportSurfaceOverlayMac::Initialize() { |
| 206 if (!helper_->Initialize()) | 220 if (!helper_->Initialize()) |
| 207 return false; | 221 return false; |
| 208 | 222 |
| 209 // Create the CAContext to send this to the GPU process, and the layer for | 223 // Create the CAContext to send this to the GPU process, and the layer for |
| 210 // the context. | 224 // the context. |
| 211 CGSConnectionID connection_id = CGSMainConnectionID(); | 225 if (use_remote_layer_api_) { |
| 212 ca_context_.reset( | 226 CGSConnectionID connection_id = CGSMainConnectionID(); |
| 213 [[CAContext contextWithCGSConnection:connection_id options:@{}] retain]); | 227 ca_context_.reset([ |
| 214 ca_root_layer_.reset([[CALayer alloc] init]); | 228 [CAContext contextWithCGSConnection:connection_id options:@{}] retain]); |
| 215 [ca_root_layer_ setGeometryFlipped:YES]; | 229 ca_root_layer_.reset([[CALayer alloc] init]); |
| 216 [ca_root_layer_ setOpaque:YES]; | 230 [ca_root_layer_ setGeometryFlipped:YES]; |
| 217 [ca_context_ setLayer:ca_root_layer_]; | 231 [ca_root_layer_ setOpaque:YES]; |
| 232 [ca_context_ setLayer:ca_root_layer_]; | |
| 233 } | |
| 218 return true; | 234 return true; |
| 219 } | 235 } |
| 220 | 236 |
| 221 void ImageTransportSurfaceOverlayMac::Destroy() { | 237 void ImageTransportSurfaceOverlayMac::Destroy() { |
| 222 DisplayAndClearAllPendingSwaps(); | 238 DisplayAndClearAllPendingSwaps(); |
| 223 | 239 |
| 224 if (current_root_plane_.get()) | 240 if (current_root_plane_.get()) |
| 225 current_root_plane_->Destroy(); | 241 current_root_plane_->Destroy(); |
| 226 current_root_plane_.reset(); | 242 current_root_plane_.reset(); |
| 227 for (auto& plane : current_partial_damage_planes_) | 243 for (auto& plane : current_partial_damage_planes_) |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 363 | 379 |
| 364 ScopedCAActionDisabler disabler; | 380 ScopedCAActionDisabler disabler; |
| 365 UpdateRootAndPartialDamagePlanes(swap->root_plane, dip_damage_rect); | 381 UpdateRootAndPartialDamagePlanes(swap->root_plane, dip_damage_rect); |
| 366 UpdateOverlayPlanes(swap->overlay_planes); | 382 UpdateOverlayPlanes(swap->overlay_planes); |
| 367 UpdateCALayerTree(); | 383 UpdateCALayerTree(); |
| 368 swap->overlay_planes.clear(); | 384 swap->overlay_planes.clear(); |
| 369 } | 385 } |
| 370 | 386 |
| 371 // Send acknowledgement to the browser. | 387 // Send acknowledgement to the browser. |
| 372 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params; | 388 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params; |
| 373 params.surface_handle = | 389 if (use_remote_layer_api_) { |
| 374 ui::SurfaceHandleFromCAContextID([ca_context_ contextId]); | 390 params.surface_handle = |
| 391 ui::SurfaceHandleFromCAContextID([ca_context_ contextId]); | |
| 392 } else { | |
| 393 params.surface_handle = | |
| 394 ui::SurfaceHandleFromIOSurfaceID(current_root_plane_->io_surface_id); | |
| 395 } | |
| 375 params.size = swap->pixel_size; | 396 params.size = swap->pixel_size; |
| 376 params.scale_factor = swap->scale_factor; | 397 params.scale_factor = swap->scale_factor; |
| 377 params.latency_info.swap(swap->latency_info); | 398 params.latency_info.swap(swap->latency_info); |
| 378 helper_->SendAcceleratedSurfaceBuffersSwapped(params); | 399 helper_->SendAcceleratedSurfaceBuffersSwapped(params); |
| 379 | 400 |
| 380 // Remove this from the queue, and reset any callback timers. | 401 // Remove this from the queue, and reset any callback timers. |
| 381 pending_swaps_.pop_front(); | 402 pending_swaps_.pop_front(); |
| 382 } | 403 } |
| 383 | 404 |
| 384 void ImageTransportSurfaceOverlayMac::UpdateOverlayPlanes( | 405 void ImageTransportSurfaceOverlayMac::UpdateOverlayPlanes( |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 412 // If there is no new root plane, destroy the old one. | 433 // If there is no new root plane, destroy the old one. |
| 413 if (!new_root_plane.get()) { | 434 if (!new_root_plane.get()) { |
| 414 for (auto& old_plane : old_partial_damage_planes) | 435 for (auto& old_plane : old_partial_damage_planes) |
| 415 old_plane->Destroy(); | 436 old_plane->Destroy(); |
| 416 if (current_root_plane_.get()) | 437 if (current_root_plane_.get()) |
| 417 current_root_plane_->Destroy(); | 438 current_root_plane_->Destroy(); |
| 418 current_root_plane_.reset(); | 439 current_root_plane_.reset(); |
| 419 return; | 440 return; |
| 420 } | 441 } |
| 421 | 442 |
| 422 // If the frame's size changed, if we haven't updated the root layer, or if | 443 // If the frame's size changed, if we haven't updated the root layer, if |
| 423 // we have full damage, then use the root layer directly. | 444 // we have full damage, or if we don't support remote layers, then use the |
| 424 if (!current_root_plane_.get() || | 445 // root layer directly. |
| 446 if (!use_remote_layer_api_ || !current_root_plane_.get() || | |
| 425 current_root_plane_->dip_frame_rect != new_root_plane->dip_frame_rect || | 447 current_root_plane_->dip_frame_rect != new_root_plane->dip_frame_rect || |
| 426 dip_damage_rect == new_root_plane->dip_frame_rect) { | 448 dip_damage_rect == new_root_plane->dip_frame_rect) { |
| 427 plane_for_swap = new_root_plane; | 449 plane_for_swap = new_root_plane; |
| 428 } | 450 } |
| 429 | 451 |
| 430 // Walk though the existing partial damage layers and see if there is one that | 452 // Walk though the existing partial damage layers and see if there is one that |
| 431 // is appropriate to re-use. | 453 // is appropriate to re-use. |
| 432 if (!plane_for_swap.get() && !dip_damage_rect.IsEmpty()) { | 454 if (!plane_for_swap.get() && !dip_damage_rect.IsEmpty()) { |
| 433 gfx::RectF plane_to_reuse_dip_enlarged_rect; | 455 gfx::RectF plane_to_reuse_dip_enlarged_rect; |
| 434 | 456 |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 451 plane_to_reuse_dip_enlarged_rect.Union(dip_enlarged_rect); | 473 plane_to_reuse_dip_enlarged_rect.Union(dip_enlarged_rect); |
| 452 } | 474 } |
| 453 | 475 |
| 454 if (plane_to_reuse.get()) { | 476 if (plane_to_reuse.get()) { |
| 455 gfx::RectF enlarged_contents_rect = plane_to_reuse_dip_enlarged_rect; | 477 gfx::RectF enlarged_contents_rect = plane_to_reuse_dip_enlarged_rect; |
| 456 enlarged_contents_rect.Scale( | 478 enlarged_contents_rect.Scale( |
| 457 1. / new_root_plane->dip_frame_rect.width(), | 479 1. / new_root_plane->dip_frame_rect.width(), |
| 458 1. / new_root_plane->dip_frame_rect.height()); | 480 1. / new_root_plane->dip_frame_rect.height()); |
| 459 | 481 |
| 460 plane_for_swap = linked_ptr<OverlayPlane>(new OverlayPlane( | 482 plane_for_swap = linked_ptr<OverlayPlane>(new OverlayPlane( |
| 461 0, new_root_plane->io_surface, plane_to_reuse_dip_enlarged_rect, | 483 0, new_root_plane->io_surface_id, new_root_plane->io_surface, |
| 462 enlarged_contents_rect)); | 484 plane_to_reuse_dip_enlarged_rect, enlarged_contents_rect)); |
| 463 | 485 |
| 464 plane_for_swap->TakeCALayerFrom(plane_to_reuse.get()); | 486 plane_for_swap->TakeCALayerFrom(plane_to_reuse.get()); |
| 465 if (plane_to_reuse != old_partial_damage_planes.back()) | 487 if (plane_to_reuse != old_partial_damage_planes.back()) |
| 466 [plane_for_swap->ca_layer removeFromSuperlayer]; | 488 [plane_for_swap->ca_layer removeFromSuperlayer]; |
| 467 } | 489 } |
| 468 } | 490 } |
| 469 | 491 |
| 470 // If we haven't found an appropriate layer to re-use, create a new one, if | 492 // If we haven't found an appropriate layer to re-use, create a new one, if |
| 471 // we haven't already created too many. | 493 // we haven't already created too many. |
| 472 if (!plane_for_swap.get() && !dip_damage_rect.IsEmpty() && | 494 if (!plane_for_swap.get() && !dip_damage_rect.IsEmpty() && |
| 473 old_partial_damage_planes.size() < kMaximumPartialDamageLayers) { | 495 old_partial_damage_planes.size() < kMaximumPartialDamageLayers) { |
| 474 gfx::RectF contents_rect = gfx::RectF(dip_damage_rect); | 496 gfx::RectF contents_rect = gfx::RectF(dip_damage_rect); |
| 475 contents_rect.Scale(1. / new_root_plane->dip_frame_rect.width(), | 497 contents_rect.Scale(1. / new_root_plane->dip_frame_rect.width(), |
| 476 1. / new_root_plane->dip_frame_rect.height()); | 498 1. / new_root_plane->dip_frame_rect.height()); |
| 477 plane_for_swap = linked_ptr<OverlayPlane>(new OverlayPlane( | 499 plane_for_swap = linked_ptr<OverlayPlane>(new OverlayPlane( |
| 478 0, new_root_plane->io_surface, dip_damage_rect, contents_rect)); | 500 0, new_root_plane->io_surface_id, new_root_plane->io_surface, |
| 501 dip_damage_rect, contents_rect)); | |
| 479 } | 502 } |
| 480 | 503 |
| 481 // And if we still don't have a layer, use the root layer. | 504 // And if we still don't have a layer, use the root layer. |
| 482 if (!plane_for_swap.get() && !dip_damage_rect.IsEmpty()) | 505 if (!plane_for_swap.get() && !dip_damage_rect.IsEmpty()) |
| 483 plane_for_swap = new_root_plane; | 506 plane_for_swap = new_root_plane; |
| 484 | 507 |
| 485 // Walk all old partial damage planes. Remove anything that is now completely | 508 // Walk all old partial damage planes. Remove anything that is now completely |
| 486 // covered, and move everything else into the new | 509 // covered, and move everything else into the new |
| 487 // |current_partial_damage_planes_|. | 510 // |current_partial_damage_planes_|. |
| 488 for (auto& old_plane : old_partial_damage_planes) { | 511 for (auto& old_plane : old_partial_damage_planes) { |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 507 } else { | 530 } else { |
| 508 plane_for_swap->ca_layer = ca_root_layer_; | 531 plane_for_swap->ca_layer = ca_root_layer_; |
| 509 } | 532 } |
| 510 current_root_plane_ = new_root_plane; | 533 current_root_plane_ = new_root_plane; |
| 511 } else if (plane_for_swap.get()) { | 534 } else if (plane_for_swap.get()) { |
| 512 current_partial_damage_planes_.push_back(plane_for_swap); | 535 current_partial_damage_planes_.push_back(plane_for_swap); |
| 513 } | 536 } |
| 514 } | 537 } |
| 515 | 538 |
| 516 void ImageTransportSurfaceOverlayMac::UpdateCALayerTree() { | 539 void ImageTransportSurfaceOverlayMac::UpdateCALayerTree() { |
| 540 if (!use_remote_layer_api_) { | |
| 541 DCHECK(current_overlay_planes_.empty()); | |
| 542 DCHECK(current_partial_damage_planes_.empty()); | |
| 543 return; | |
| 544 } | |
| 545 | |
| 517 // Allocate new CALayers as needed. Overlay layers are always added to the | 546 // Allocate new CALayers as needed. Overlay layers are always added to the |
| 518 // back of the list. | 547 // back of the list. |
| 519 CALayer* first_overlay_ca_layer = nil; | 548 CALayer* first_overlay_ca_layer = nil; |
| 520 for (auto& plane : current_overlay_planes_) { | 549 for (auto& plane : current_overlay_planes_) { |
| 521 if (!plane->ca_layer) { | 550 if (!plane->ca_layer) { |
| 522 plane->ca_layer.reset([[CALayer alloc] init]); | 551 plane->ca_layer.reset([[CALayer alloc] init]); |
| 523 [ca_root_layer_ addSublayer:plane->ca_layer]; | 552 [ca_root_layer_ addSublayer:plane->ca_layer]; |
| 524 } | 553 } |
| 525 if (!first_overlay_ca_layer) | 554 if (!first_overlay_ca_layer) |
| 526 first_overlay_ca_layer = plane->ca_layer; | 555 first_overlay_ca_layer = plane->ca_layer; |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 624 } | 653 } |
| 625 | 654 |
| 626 bool ImageTransportSurfaceOverlayMac::SetBackbufferAllocation(bool allocated) { | 655 bool ImageTransportSurfaceOverlayMac::SetBackbufferAllocation(bool allocated) { |
| 627 if (!allocated) { | 656 if (!allocated) { |
| 628 DisplayAndClearAllPendingSwaps(); | 657 DisplayAndClearAllPendingSwaps(); |
| 629 last_swap_time_ = base::TimeTicks(); | 658 last_swap_time_ = base::TimeTicks(); |
| 630 } | 659 } |
| 631 return true; | 660 return true; |
| 632 } | 661 } |
| 633 | 662 |
| 634 bool ImageTransportSurfaceOverlayMac::ScheduleOverlayPlane( | 663 bool ImageTransportSurfaceOverlayMac::ScheduleOverlayPlane( |
|
reveman
2015/10/23 20:44:40
Can you remind me what the call stack for this fun
ccameron
2015/10/26 22:28:11
I think that this needs to be made safer as well -
| |
| 635 int z_order, | 664 int z_order, |
| 636 gfx::OverlayTransform transform, | 665 gfx::OverlayTransform transform, |
| 637 gfx::GLImage* image, | 666 gfx::GLImage* image, |
| 638 const gfx::Rect& bounds_rect, | 667 const gfx::Rect& bounds_rect, |
| 639 const gfx::RectF& crop_rect) { | 668 const gfx::RectF& crop_rect) { |
| 640 DCHECK_EQ(transform, gfx::OVERLAY_TRANSFORM_NONE); | 669 DCHECK_EQ(transform, gfx::OVERLAY_TRANSFORM_NONE); |
| 641 if (transform != gfx::OVERLAY_TRANSFORM_NONE) | 670 if (transform != gfx::OVERLAY_TRANSFORM_NONE) |
| 642 return false; | 671 return false; |
| 643 | 672 |
| 644 linked_ptr<OverlayPlane> plane( | 673 linked_ptr<OverlayPlane> plane(new OverlayPlane( |
| 645 new OverlayPlane(z_order, | 674 z_order, static_cast<gfx::GLImageIOSurface*>(image)->io_surface_id().id, |
| 646 static_cast<gfx::GLImageIOSurface*>(image)->io_surface(), | 675 static_cast<gfx::GLImageIOSurface*>(image)->io_surface(), |
| 647 ConvertRectToDIPF(scale_factor_, bounds_rect), | 676 ConvertRectToDIPF(scale_factor_, bounds_rect), crop_rect)); |
| 648 crop_rect)); | |
| 649 if (z_order == 0) | 677 if (z_order == 0) |
| 650 pending_root_plane_ = plane; | 678 pending_root_plane_ = plane; |
| 651 else | 679 else |
| 652 pending_overlay_planes_.push_back(plane); | 680 pending_overlay_planes_.push_back(plane); |
| 653 | 681 |
| 654 return true; | 682 return true; |
| 655 } | 683 } |
| 656 | 684 |
| 657 bool ImageTransportSurfaceOverlayMac::IsSurfaceless() const { | 685 bool ImageTransportSurfaceOverlayMac::IsSurfaceless() const { |
| 658 return true; | 686 return true; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 716 // Compute the previous vsync time. | 744 // Compute the previous vsync time. |
| 717 base::TimeTicks previous_vsync = | 745 base::TimeTicks previous_vsync = |
| 718 vsync_interval_ * ((from - vsync_timebase_) / vsync_interval_) + | 746 vsync_interval_ * ((from - vsync_timebase_) / vsync_interval_) + |
| 719 vsync_timebase_; | 747 vsync_timebase_; |
| 720 | 748 |
| 721 // Return |interval_fraction| through the next vsync. | 749 // Return |interval_fraction| through the next vsync. |
| 722 return previous_vsync + (1 + interval_fraction) * vsync_interval_; | 750 return previous_vsync + (1 + interval_fraction) * vsync_interval_; |
| 723 } | 751 } |
| 724 | 752 |
| 725 } // namespace content | 753 } // namespace content |
| OLD | NEW |