| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/renderer_host/render_widget_host_view_mac.h" | 5 #include "content/browser/renderer_host/render_widget_host_view_mac.h" |
| 6 | 6 |
| 7 #import <objc/runtime.h> | 7 #import <objc/runtime.h> |
| 8 #include <QuartzCore/QuartzCore.h> | 8 #include <QuartzCore/QuartzCore.h> |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| (...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 427 // goes away. Since we autorelease it, our caller must put | 427 // goes away. Since we autorelease it, our caller must put |
| 428 // |GetNativeView()| into the view hierarchy right after calling us. | 428 // |GetNativeView()| into the view hierarchy right after calling us. |
| 429 cocoa_view_ = [[[RenderWidgetHostViewCocoa alloc] | 429 cocoa_view_ = [[[RenderWidgetHostViewCocoa alloc] |
| 430 initWithRenderWidgetHostViewMac:this] autorelease]; | 430 initWithRenderWidgetHostViewMac:this] autorelease]; |
| 431 | 431 |
| 432 if (GetCoreAnimationStatus() == CORE_ANIMATION_ENABLED) { | 432 if (GetCoreAnimationStatus() == CORE_ANIMATION_ENABLED) { |
| 433 EnableCoreAnimation(); | 433 EnableCoreAnimation(); |
| 434 } | 434 } |
| 435 | 435 |
| 436 render_widget_host_->SetView(this); | 436 render_widget_host_->SetView(this); |
| 437 render_widget_host_->SetAboutToWaitForBackingStoreCallback( |
| 438 base::Bind(&RenderWidgetHostViewMac::SendPendingSwapAck, |
| 439 weak_factory_.GetWeakPtr())); |
| 437 } | 440 } |
| 438 | 441 |
| 439 RenderWidgetHostViewMac::~RenderWidgetHostViewMac() { | 442 RenderWidgetHostViewMac::~RenderWidgetHostViewMac() { |
| 440 // This is being called from |cocoa_view_|'s destructor, so invalidate the | 443 // This is being called from |cocoa_view_|'s destructor, so invalidate the |
| 441 // pointer. | 444 // pointer. |
| 442 cocoa_view_ = nil; | 445 cocoa_view_ = nil; |
| 443 | 446 |
| 444 UnlockMouse(); | 447 UnlockMouse(); |
| 445 | 448 |
| 446 // Make sure that the layer doesn't reach into the now-invalid object. | 449 // Make sure that the layer doesn't reach into the now-invalid object. |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 567 // Creating the CompositingIOSurfaceLayer may attempt to draw in setLayer, | 570 // Creating the CompositingIOSurfaceLayer may attempt to draw in setLayer, |
| 568 // which, if it fails, will promptly tear down everything that was just | 571 // which, if it fails, will promptly tear down everything that was just |
| 569 // created. If that happened, return failure. | 572 // created. If that happened, return failure. |
| 570 return compositing_iosurface_context_ && | 573 return compositing_iosurface_context_ && |
| 571 compositing_iosurface_ && | 574 compositing_iosurface_ && |
| 572 (compositing_iosurface_layer_ || !use_core_animation_); | 575 (compositing_iosurface_layer_ || !use_core_animation_); |
| 573 } | 576 } |
| 574 | 577 |
| 575 void RenderWidgetHostViewMac::DestroyCompositedIOSurfaceAndLayer( | 578 void RenderWidgetHostViewMac::DestroyCompositedIOSurfaceAndLayer( |
| 576 DestroyContextBehavior destroy_context_behavior) { | 579 DestroyContextBehavior destroy_context_behavior) { |
| 580 // Any pending frames will not be displayed, so ack them now. |
| 581 SendPendingSwapAck(); |
| 582 |
| 577 ScopedCAActionDisabler disabler; | 583 ScopedCAActionDisabler disabler; |
| 578 | 584 |
| 579 compositing_iosurface_.reset(); | 585 compositing_iosurface_.reset(); |
| 580 if (compositing_iosurface_layer_) { | 586 if (compositing_iosurface_layer_) { |
| 581 [software_layer_ setNeedsDisplay]; | 587 [software_layer_ setNeedsDisplay]; |
| 582 [compositing_iosurface_layer_ removeFromSuperlayer]; | 588 [compositing_iosurface_layer_ removeFromSuperlayer]; |
| 583 [compositing_iosurface_layer_ disableCompositing]; | 589 [compositing_iosurface_layer_ disableCompositing]; |
| 584 compositing_iosurface_layer_.reset(); | 590 compositing_iosurface_layer_.reset(); |
| 585 } | 591 } |
| 586 switch (destroy_context_behavior) { | 592 switch (destroy_context_behavior) { |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 741 if (!use_core_animation_) | 747 if (!use_core_animation_) |
| 742 [[cocoa_view_ window] disableScreenUpdatesUntilFlush]; | 748 [[cocoa_view_ window] disableScreenUpdatesUntilFlush]; |
| 743 | 749 |
| 744 [compositing_iosurface_layer_ setNeedsDisplay]; | 750 [compositing_iosurface_layer_ setNeedsDisplay]; |
| 745 } | 751 } |
| 746 | 752 |
| 747 void RenderWidgetHostViewMac::WasHidden() { | 753 void RenderWidgetHostViewMac::WasHidden() { |
| 748 if (render_widget_host_->is_hidden()) | 754 if (render_widget_host_->is_hidden()) |
| 749 return; | 755 return; |
| 750 | 756 |
| 757 // Any pending frames will not be displayed until this is shown again. Ack |
| 758 // them now. |
| 759 SendPendingSwapAck(); |
| 760 |
| 751 // If we have a renderer, then inform it that we are being hidden so it can | 761 // If we have a renderer, then inform it that we are being hidden so it can |
| 752 // reduce its resource utilization. | 762 // reduce its resource utilization. |
| 753 render_widget_host_->WasHidden(); | 763 render_widget_host_->WasHidden(); |
| 754 software_frame_manager_->SetVisibility(false); | 764 software_frame_manager_->SetVisibility(false); |
| 755 | 765 |
| 756 // There can be a transparent flash as this view is removed and the next is | 766 // There can be a transparent flash as this view is removed and the next is |
| 757 // added, because of OSX windowing races between displaying the contents of | 767 // added, because of OSX windowing races between displaying the contents of |
| 758 // the NSView and its corresponding OpenGL context. | 768 // the NSView and its corresponding OpenGL context. |
| 759 // disableScreenUpdatesUntilFlush prevents the transparent flash by avoiding | 769 // disableScreenUpdatesUntilFlush prevents the transparent flash by avoiding |
| 760 // screen updates until the next tab draws. | 770 // screen updates until the next tab draws. |
| (...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1314 if (frame_subscriber_->ShouldCaptureFrame(present_time, | 1324 if (frame_subscriber_->ShouldCaptureFrame(present_time, |
| 1315 &frame, &callback)) { | 1325 &frame, &callback)) { |
| 1316 gfx::ScopedCGLSetCurrentContext scoped_set_current_context( | 1326 gfx::ScopedCGLSetCurrentContext scoped_set_current_context( |
| 1317 compositing_iosurface_context_->cgl_context()); | 1327 compositing_iosurface_context_->cgl_context()); |
| 1318 compositing_iosurface_->SetIOSurfaceWithContextCurrent( | 1328 compositing_iosurface_->SetIOSurfaceWithContextCurrent( |
| 1319 compositing_iosurface_context_, surface_handle, size, | 1329 compositing_iosurface_context_, surface_handle, size, |
| 1320 surface_scale_factor); | 1330 surface_scale_factor); |
| 1321 compositing_iosurface_->CopyToVideoFrame( | 1331 compositing_iosurface_->CopyToVideoFrame( |
| 1322 gfx::Rect(size), frame, | 1332 gfx::Rect(size), frame, |
| 1323 base::Bind(callback, present_time)); | 1333 base::Bind(callback, present_time)); |
| 1334 SendPendingSwapAck(); |
| 1324 return; | 1335 return; |
| 1325 } | 1336 } |
| 1326 } | 1337 } |
| 1327 | 1338 |
| 1328 // TODO(shess) If the view does not have a window, or the window | 1339 // TODO(shess) If the view does not have a window, or the window |
| 1329 // does not have backing, the IOSurface will log "invalid drawable" | 1340 // does not have backing, the IOSurface will log "invalid drawable" |
| 1330 // in -setView:. It is not clear how this code is reached with such | 1341 // in -setView:. It is not clear how this code is reached with such |
| 1331 // a case, so record some info into breakpad (some subset of | 1342 // a case, so record some info into breakpad (some subset of |
| 1332 // browsers are likely to crash later for unrelated reasons). | 1343 // browsers are likely to crash later for unrelated reasons). |
| 1333 // http://crbug.com/148882 | 1344 // http://crbug.com/148882 |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1468 overlay_view_rect.height() - | 1479 overlay_view_rect.height() - |
| 1469 overlay_view_offset_.y()); | 1480 overlay_view_offset_.y()); |
| 1470 if (!overlay_view_->compositing_iosurface_->DrawIOSurface( | 1481 if (!overlay_view_->compositing_iosurface_->DrawIOSurface( |
| 1471 compositing_iosurface_context_, overlay_view_rect, | 1482 compositing_iosurface_context_, overlay_view_rect, |
| 1472 overlay_view_->scale_factor(), true)) { | 1483 overlay_view_->scale_factor(), true)) { |
| 1473 return false; | 1484 return false; |
| 1474 } | 1485 } |
| 1475 } | 1486 } |
| 1476 | 1487 |
| 1477 SendPendingLatencyInfoToHost(); | 1488 SendPendingLatencyInfoToHost(); |
| 1489 SendPendingSwapAck(); |
| 1478 return true; | 1490 return true; |
| 1479 } | 1491 } |
| 1480 | 1492 |
| 1481 void RenderWidgetHostViewMac::GotAcceleratedCompositingError() { | 1493 void RenderWidgetHostViewMac::GotAcceleratedCompositingError() { |
| 1482 DestroyCompositedIOSurfaceAndLayer(kDestroyContext); | 1494 DestroyCompositedIOSurfaceAndLayer(kDestroyContext); |
| 1483 // The existing GL contexts may be in a bad state, so don't re-use any of the | 1495 // The existing GL contexts may be in a bad state, so don't re-use any of the |
| 1484 // existing ones anymore, rather, allocate new ones. | 1496 // existing ones anymore, rather, allocate new ones. |
| 1485 CompositingIOSurfaceContext::MarkExistingContextsAsNotShareable(); | 1497 CompositingIOSurfaceContext::MarkExistingContextsAsNotShareable(); |
| 1486 // Request that a new frame be generated. | 1498 // Request that a new frame be generated. |
| 1487 if (render_widget_host_) | 1499 if (render_widget_host_) |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1645 return true; | 1657 return true; |
| 1646 } | 1658 } |
| 1647 | 1659 |
| 1648 void RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped( | 1660 void RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped( |
| 1649 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params, | 1661 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params, |
| 1650 int gpu_host_id) { | 1662 int gpu_host_id) { |
| 1651 TRACE_EVENT0("browser", | 1663 TRACE_EVENT0("browser", |
| 1652 "RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped"); | 1664 "RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped"); |
| 1653 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1665 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1654 | 1666 |
| 1667 AddPendingSwapAck(params.route_id, |
| 1668 gpu_host_id, |
| 1669 compositing_iosurface_ ? |
| 1670 compositing_iosurface_->GetRendererID() : 0); |
| 1655 CompositorSwapBuffers(params.surface_handle, | 1671 CompositorSwapBuffers(params.surface_handle, |
| 1656 params.size, | 1672 params.size, |
| 1657 params.scale_factor, | 1673 params.scale_factor, |
| 1658 params.latency_info); | 1674 params.latency_info); |
| 1659 | |
| 1660 AcceleratedSurfaceMsg_BufferPresented_Params ack_params; | |
| 1661 ack_params.sync_point = 0; | |
| 1662 ack_params.renderer_id = compositing_iosurface_ ? | |
| 1663 compositing_iosurface_->GetRendererID() : 0; | |
| 1664 RenderWidgetHostImpl::AcknowledgeBufferPresent(params.route_id, | |
| 1665 gpu_host_id, | |
| 1666 ack_params); | |
| 1667 render_widget_host_->AcknowledgeSwapBuffersToRenderer(); | |
| 1668 } | 1675 } |
| 1669 | 1676 |
| 1670 void RenderWidgetHostViewMac::AcceleratedSurfacePostSubBuffer( | 1677 void RenderWidgetHostViewMac::AcceleratedSurfacePostSubBuffer( |
| 1671 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params, | 1678 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params, |
| 1672 int gpu_host_id) { | 1679 int gpu_host_id) { |
| 1673 TRACE_EVENT0("browser", | 1680 TRACE_EVENT0("browser", |
| 1674 "RenderWidgetHostViewMac::AcceleratedSurfacePostSubBuffer"); | 1681 "RenderWidgetHostViewMac::AcceleratedSurfacePostSubBuffer"); |
| 1675 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1682 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1676 | 1683 |
| 1684 AddPendingSwapAck(params.route_id, |
| 1685 gpu_host_id, |
| 1686 compositing_iosurface_ ? |
| 1687 compositing_iosurface_->GetRendererID() : 0); |
| 1677 CompositorSwapBuffers(params.surface_handle, | 1688 CompositorSwapBuffers(params.surface_handle, |
| 1678 params.surface_size, | 1689 params.surface_size, |
| 1679 params.surface_scale_factor, | 1690 params.surface_scale_factor, |
| 1680 params.latency_info); | 1691 params.latency_info); |
| 1681 | |
| 1682 AcceleratedSurfaceMsg_BufferPresented_Params ack_params; | |
| 1683 ack_params.sync_point = 0; | |
| 1684 ack_params.renderer_id = compositing_iosurface_ ? | |
| 1685 compositing_iosurface_->GetRendererID() : 0; | |
| 1686 RenderWidgetHostImpl::AcknowledgeBufferPresent(params.route_id, | |
| 1687 gpu_host_id, | |
| 1688 ack_params); | |
| 1689 render_widget_host_->AcknowledgeSwapBuffersToRenderer(); | |
| 1690 } | 1692 } |
| 1691 | 1693 |
| 1692 void RenderWidgetHostViewMac::AcceleratedSurfaceSuspend() { | 1694 void RenderWidgetHostViewMac::AcceleratedSurfaceSuspend() { |
| 1693 if (compositing_iosurface_) | 1695 if (compositing_iosurface_) |
| 1694 compositing_iosurface_->UnrefIOSurface(); | 1696 compositing_iosurface_->UnrefIOSurface(); |
| 1695 } | 1697 } |
| 1696 | 1698 |
| 1697 void RenderWidgetHostViewMac::AcceleratedSurfaceRelease() { | 1699 void RenderWidgetHostViewMac::AcceleratedSurfaceRelease() { |
| 1698 DestroyCompositedIOSurfaceAndLayer(kDestroyContext); | 1700 DestroyCompositedIOSurfaceAndLayer(kDestroyContext); |
| 1699 } | 1701 } |
| (...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2053 | 2055 |
| 2054 void RenderWidgetHostViewMac::TickPendingLatencyInfoDelay() { | 2056 void RenderWidgetHostViewMac::TickPendingLatencyInfoDelay() { |
| 2055 // Keep calling setNeedsDisplay in a loop until enough display calls come in. | 2057 // Keep calling setNeedsDisplay in a loop until enough display calls come in. |
| 2056 base::MessageLoop::current()->PostTask(FROM_HERE, | 2058 base::MessageLoop::current()->PostTask(FROM_HERE, |
| 2057 base::Bind(&RenderWidgetHostViewMac::TickPendingLatencyInfoDelay, | 2059 base::Bind(&RenderWidgetHostViewMac::TickPendingLatencyInfoDelay, |
| 2058 pending_latency_info_delay_weak_ptr_factory_.GetWeakPtr())); | 2060 pending_latency_info_delay_weak_ptr_factory_.GetWeakPtr())); |
| 2059 [software_layer_ setNeedsDisplay]; | 2061 [software_layer_ setNeedsDisplay]; |
| 2060 [compositing_iosurface_layer_ setNeedsDisplay]; | 2062 [compositing_iosurface_layer_ setNeedsDisplay]; |
| 2061 } | 2063 } |
| 2062 | 2064 |
| 2065 void RenderWidgetHostViewMac::AddPendingSwapAck( |
| 2066 int32 route_id, int gpu_host_id, int32 renderer_id) { |
| 2067 DCHECK(!pending_swap_ack_); |
| 2068 pending_swap_ack_.reset(new PendingSwapAck( |
| 2069 route_id, gpu_host_id, renderer_id)); |
| 2070 } |
| 2071 |
| 2072 void RenderWidgetHostViewMac::SendPendingSwapAck() { |
| 2073 if (!pending_swap_ack_) |
| 2074 return; |
| 2075 |
| 2076 AcceleratedSurfaceMsg_BufferPresented_Params ack_params; |
| 2077 ack_params.sync_point = 0; |
| 2078 ack_params.renderer_id = pending_swap_ack_->renderer_id; |
| 2079 RenderWidgetHostImpl::AcknowledgeBufferPresent(pending_swap_ack_->route_id, |
| 2080 pending_swap_ack_->gpu_host_id, |
| 2081 ack_params); |
| 2082 if (render_widget_host_) |
| 2083 render_widget_host_->AcknowledgeSwapBuffersToRenderer(); |
| 2084 |
| 2085 pending_swap_ack_.reset(); |
| 2086 } |
| 2087 |
| 2063 } // namespace content | 2088 } // namespace content |
| 2064 | 2089 |
| 2065 // RenderWidgetHostViewCocoa --------------------------------------------------- | 2090 // RenderWidgetHostViewCocoa --------------------------------------------------- |
| 2066 | 2091 |
| 2067 @implementation RenderWidgetHostViewCocoa | 2092 @implementation RenderWidgetHostViewCocoa |
| 2068 @synthesize selectedRange = selectedRange_; | 2093 @synthesize selectedRange = selectedRange_; |
| 2069 @synthesize suppressNextEscapeKeyUp = suppressNextEscapeKeyUp_; | 2094 @synthesize suppressNextEscapeKeyUp = suppressNextEscapeKeyUp_; |
| 2070 @synthesize markedRange = markedRange_; | 2095 @synthesize markedRange = markedRange_; |
| 2071 | 2096 |
| 2072 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r { | 2097 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r { |
| (...skipping 2028 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4101 return YES; | 4126 return YES; |
| 4102 } | 4127 } |
| 4103 | 4128 |
| 4104 - (BOOL)isOpaque { | 4129 - (BOOL)isOpaque { |
| 4105 if (renderWidgetHostView_->use_core_animation_) | 4130 if (renderWidgetHostView_->use_core_animation_) |
| 4106 return YES; | 4131 return YES; |
| 4107 return [super isOpaque]; | 4132 return [super isOpaque]; |
| 4108 } | 4133 } |
| 4109 | 4134 |
| 4110 @end | 4135 @end |
| OLD | NEW |