| 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 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 } | 437 } |
| 438 | 438 |
| 439 RenderWidgetHostViewMac::~RenderWidgetHostViewMac() { | 439 RenderWidgetHostViewMac::~RenderWidgetHostViewMac() { |
| 440 // If a caller has set this, then when the caller tries to re-set it sometime | |
| 441 // in the future, we will crash. | |
| 442 DCHECK(!about_to_validate_and_paint_); | |
| 443 | |
| 444 // This is being called from |cocoa_view_|'s destructor, so invalidate the | 440 // This is being called from |cocoa_view_|'s destructor, so invalidate the |
| 445 // pointer. | 441 // pointer. |
| 446 cocoa_view_ = nil; | 442 cocoa_view_ = nil; |
| 447 | 443 |
| 448 UnlockMouse(); | 444 UnlockMouse(); |
| 449 | 445 |
| 450 // Make sure that the layer doesn't reach into the now-invalid object. | 446 // Make sure that the layer doesn't reach into the now-invalid object. |
| 451 DestroyCompositedIOSurfaceAndLayer(kDestroyContext); | 447 DestroyCompositedIOSurfaceAndLayer(kDestroyContext); |
| 452 software_layer_.reset(); | 448 software_layer_.reset(); |
| 453 | 449 |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 561 } | 557 } |
| 562 | 558 |
| 563 // Creating the CompositingIOSurfaceLayer may attempt to draw in setLayer, | 559 // Creating the CompositingIOSurfaceLayer may attempt to draw in setLayer, |
| 564 // which, if it fails, will promptly tear down everything that was just | 560 // which, if it fails, will promptly tear down everything that was just |
| 565 // created. If that happened, return failure. | 561 // created. If that happened, return failure. |
| 566 return compositing_iosurface_layer_; | 562 return compositing_iosurface_layer_; |
| 567 } | 563 } |
| 568 | 564 |
| 569 void RenderWidgetHostViewMac::DestroyCompositedIOSurfaceAndLayer( | 565 void RenderWidgetHostViewMac::DestroyCompositedIOSurfaceAndLayer( |
| 570 DestroyContextBehavior destroy_context_behavior) { | 566 DestroyContextBehavior destroy_context_behavior) { |
| 571 // Any pending frames will not be displayed, so ack them now. | |
| 572 SendPendingSwapAck(); | |
| 573 | |
| 574 ScopedCAActionDisabler disabler; | 567 ScopedCAActionDisabler disabler; |
| 575 | 568 |
| 576 compositing_iosurface_.reset(); | 569 compositing_iosurface_.reset(); |
| 577 if (compositing_iosurface_layer_) { | 570 if (compositing_iosurface_layer_) { |
| 578 [software_layer_ setNeedsDisplay]; | 571 [software_layer_ setNeedsDisplay]; |
| 579 [compositing_iosurface_layer_ removeFromSuperlayer]; | 572 [compositing_iosurface_layer_ removeFromSuperlayer]; |
| 580 [compositing_iosurface_layer_ disableCompositing]; | 573 [compositing_iosurface_layer_ disableCompositing]; |
| 581 compositing_iosurface_layer_.reset(); | 574 compositing_iosurface_layer_.reset(); |
| 582 } | 575 } |
| 583 switch (destroy_context_behavior) { | 576 switch (destroy_context_behavior) { |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 770 if (!use_core_animation_) | 763 if (!use_core_animation_) |
| 771 [[cocoa_view_ window] disableScreenUpdatesUntilFlush]; | 764 [[cocoa_view_ window] disableScreenUpdatesUntilFlush]; |
| 772 | 765 |
| 773 [compositing_iosurface_layer_ setNeedsDisplay]; | 766 [compositing_iosurface_layer_ setNeedsDisplay]; |
| 774 } | 767 } |
| 775 | 768 |
| 776 void RenderWidgetHostViewMac::WasHidden() { | 769 void RenderWidgetHostViewMac::WasHidden() { |
| 777 if (render_widget_host_->is_hidden()) | 770 if (render_widget_host_->is_hidden()) |
| 778 return; | 771 return; |
| 779 | 772 |
| 780 // Any pending frames will not be displayed until this is shown again. Ack | |
| 781 // them now. | |
| 782 SendPendingSwapAck(); | |
| 783 | |
| 784 // If we have a renderer, then inform it that we are being hidden so it can | 773 // If we have a renderer, then inform it that we are being hidden so it can |
| 785 // reduce its resource utilization. | 774 // reduce its resource utilization. |
| 786 render_widget_host_->WasHidden(); | 775 render_widget_host_->WasHidden(); |
| 787 software_frame_manager_->SetVisibility(false); | 776 software_frame_manager_->SetVisibility(false); |
| 788 | 777 |
| 789 // There can be a transparent flash as this view is removed and the next is | 778 // There can be a transparent flash as this view is removed and the next is |
| 790 // added, because of OSX windowing races between displaying the contents of | 779 // added, because of OSX windowing races between displaying the contents of |
| 791 // the NSView and its corresponding OpenGL context. | 780 // the NSView and its corresponding OpenGL context. |
| 792 // disableScreenUpdatesUntilFlush prevents the transparent flash by avoiding | 781 // disableScreenUpdatesUntilFlush prevents the transparent flash by avoiding |
| 793 // screen updates until the next tab draws. | 782 // screen updates until the next tab draws. |
| (...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1347 if (frame_subscriber_->ShouldCaptureFrame(present_time, | 1336 if (frame_subscriber_->ShouldCaptureFrame(present_time, |
| 1348 &frame, &callback)) { | 1337 &frame, &callback)) { |
| 1349 gfx::ScopedCGLSetCurrentContext scoped_set_current_context( | 1338 gfx::ScopedCGLSetCurrentContext scoped_set_current_context( |
| 1350 compositing_iosurface_context_->cgl_context()); | 1339 compositing_iosurface_context_->cgl_context()); |
| 1351 compositing_iosurface_->SetIOSurfaceWithContextCurrent( | 1340 compositing_iosurface_->SetIOSurfaceWithContextCurrent( |
| 1352 compositing_iosurface_context_, surface_handle, size, | 1341 compositing_iosurface_context_, surface_handle, size, |
| 1353 surface_scale_factor); | 1342 surface_scale_factor); |
| 1354 compositing_iosurface_->CopyToVideoFrame( | 1343 compositing_iosurface_->CopyToVideoFrame( |
| 1355 gfx::Rect(size), frame, | 1344 gfx::Rect(size), frame, |
| 1356 base::Bind(callback, present_time)); | 1345 base::Bind(callback, present_time)); |
| 1357 SendPendingSwapAck(); | |
| 1358 return; | 1346 return; |
| 1359 } | 1347 } |
| 1360 } | 1348 } |
| 1361 | 1349 |
| 1362 // TODO(shess) If the view does not have a window, or the window | 1350 // TODO(shess) If the view does not have a window, or the window |
| 1363 // does not have backing, the IOSurface will log "invalid drawable" | 1351 // does not have backing, the IOSurface will log "invalid drawable" |
| 1364 // in -setView:. It is not clear how this code is reached with such | 1352 // in -setView:. It is not clear how this code is reached with such |
| 1365 // a case, so record some info into breakpad (some subset of | 1353 // a case, so record some info into breakpad (some subset of |
| 1366 // browsers are likely to crash later for unrelated reasons). | 1354 // browsers are likely to crash later for unrelated reasons). |
| 1367 // http://crbug.com/148882 | 1355 // http://crbug.com/148882 |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1467 [compositing_iosurface_context_->nsgl_context() | 1455 [compositing_iosurface_context_->nsgl_context() |
| 1468 setValues:&new_gl_surface_order | 1456 setValues:&new_gl_surface_order |
| 1469 forParameter:NSOpenGLCPSurfaceOrder]; | 1457 forParameter:NSOpenGLCPSurfaceOrder]; |
| 1470 } | 1458 } |
| 1471 | 1459 |
| 1472 // Instead of drawing, request that underlay view redraws. | 1460 // Instead of drawing, request that underlay view redraws. |
| 1473 if (underlay_view_ && | 1461 if (underlay_view_ && |
| 1474 underlay_view_->compositing_iosurface_ && | 1462 underlay_view_->compositing_iosurface_ && |
| 1475 underlay_view_has_drawn_) { | 1463 underlay_view_has_drawn_) { |
| 1476 [underlay_view_->cocoa_view() setNeedsDisplay:YES]; | 1464 [underlay_view_->cocoa_view() setNeedsDisplay:YES]; |
| 1477 SendPendingSwapAck(); | |
| 1478 return true; | 1465 return true; |
| 1479 } | 1466 } |
| 1480 | 1467 |
| 1481 bool has_overlay = overlay_view_ && overlay_view_->compositing_iosurface_; | 1468 bool has_overlay = overlay_view_ && overlay_view_->compositing_iosurface_; |
| 1482 if (has_overlay) { | 1469 if (has_overlay) { |
| 1483 // Un-bind the overlay view's OpenGL context, since its content will be | 1470 // Un-bind the overlay view's OpenGL context, since its content will be |
| 1484 // drawn by this context. Not doing this can result in corruption. | 1471 // drawn by this context. Not doing this can result in corruption. |
| 1485 // http://crbug.com/330701 | 1472 // http://crbug.com/330701 |
| 1486 overlay_view_->ClearBoundContextDrawable(); | 1473 overlay_view_->ClearBoundContextDrawable(); |
| 1487 } | 1474 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1503 overlay_view_rect.height() - | 1490 overlay_view_rect.height() - |
| 1504 overlay_view_offset_.y()); | 1491 overlay_view_offset_.y()); |
| 1505 if (!overlay_view_->compositing_iosurface_->DrawIOSurface( | 1492 if (!overlay_view_->compositing_iosurface_->DrawIOSurface( |
| 1506 compositing_iosurface_context_, overlay_view_rect, | 1493 compositing_iosurface_context_, overlay_view_rect, |
| 1507 overlay_view_->ViewScaleFactor(), true)) { | 1494 overlay_view_->ViewScaleFactor(), true)) { |
| 1508 return false; | 1495 return false; |
| 1509 } | 1496 } |
| 1510 } | 1497 } |
| 1511 | 1498 |
| 1512 SendPendingLatencyInfoToHost(); | 1499 SendPendingLatencyInfoToHost(); |
| 1513 SendPendingSwapAck(); | |
| 1514 return true; | 1500 return true; |
| 1515 } | 1501 } |
| 1516 | 1502 |
| 1517 void RenderWidgetHostViewMac::GotAcceleratedCompositingError() { | 1503 void RenderWidgetHostViewMac::GotAcceleratedCompositingError() { |
| 1518 DestroyCompositedIOSurfaceAndLayer(kDestroyContext); | 1504 DestroyCompositedIOSurfaceAndLayer(kDestroyContext); |
| 1519 // The existing GL contexts may be in a bad state, so don't re-use any of the | 1505 // The existing GL contexts may be in a bad state, so don't re-use any of the |
| 1520 // existing ones anymore, rather, allocate new ones. | 1506 // existing ones anymore, rather, allocate new ones. |
| 1521 CompositingIOSurfaceContext::MarkExistingContextsAsNotShareable(); | 1507 CompositingIOSurfaceContext::MarkExistingContextsAsNotShareable(); |
| 1522 // Request that a new frame be generated. | 1508 // Request that a new frame be generated. |
| 1523 if (render_widget_host_) | 1509 if (render_widget_host_) |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1681 return true; | 1667 return true; |
| 1682 } | 1668 } |
| 1683 | 1669 |
| 1684 void RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped( | 1670 void RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped( |
| 1685 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params, | 1671 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params, |
| 1686 int gpu_host_id) { | 1672 int gpu_host_id) { |
| 1687 TRACE_EVENT0("browser", | 1673 TRACE_EVENT0("browser", |
| 1688 "RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped"); | 1674 "RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped"); |
| 1689 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1675 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1690 | 1676 |
| 1691 AddPendingSwapAck(params.route_id, | |
| 1692 gpu_host_id, | |
| 1693 compositing_iosurface_ ? | |
| 1694 compositing_iosurface_->GetRendererID() : 0); | |
| 1695 CompositorSwapBuffers(params.surface_handle, | 1677 CompositorSwapBuffers(params.surface_handle, |
| 1696 params.size, | 1678 params.size, |
| 1697 params.scale_factor, | 1679 params.scale_factor, |
| 1698 params.latency_info); | 1680 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(); |
| 1699 } | 1690 } |
| 1700 | 1691 |
| 1701 void RenderWidgetHostViewMac::AcceleratedSurfacePostSubBuffer( | 1692 void RenderWidgetHostViewMac::AcceleratedSurfacePostSubBuffer( |
| 1702 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params, | 1693 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params, |
| 1703 int gpu_host_id) { | 1694 int gpu_host_id) { |
| 1704 TRACE_EVENT0("browser", | 1695 TRACE_EVENT0("browser", |
| 1705 "RenderWidgetHostViewMac::AcceleratedSurfacePostSubBuffer"); | 1696 "RenderWidgetHostViewMac::AcceleratedSurfacePostSubBuffer"); |
| 1706 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1697 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1707 | 1698 |
| 1708 AddPendingSwapAck(params.route_id, | |
| 1709 gpu_host_id, | |
| 1710 compositing_iosurface_ ? | |
| 1711 compositing_iosurface_->GetRendererID() : 0); | |
| 1712 CompositorSwapBuffers(params.surface_handle, | 1699 CompositorSwapBuffers(params.surface_handle, |
| 1713 params.surface_size, | 1700 params.surface_size, |
| 1714 params.surface_scale_factor, | 1701 params.surface_scale_factor, |
| 1715 params.latency_info); | 1702 params.latency_info); |
| 1703 |
| 1704 AcceleratedSurfaceMsg_BufferPresented_Params ack_params; |
| 1705 ack_params.sync_point = 0; |
| 1706 ack_params.renderer_id = compositing_iosurface_ ? |
| 1707 compositing_iosurface_->GetRendererID() : 0; |
| 1708 RenderWidgetHostImpl::AcknowledgeBufferPresent(params.route_id, |
| 1709 gpu_host_id, |
| 1710 ack_params); |
| 1711 render_widget_host_->AcknowledgeSwapBuffersToRenderer(); |
| 1716 } | 1712 } |
| 1717 | 1713 |
| 1718 void RenderWidgetHostViewMac::AcceleratedSurfaceSuspend() { | 1714 void RenderWidgetHostViewMac::AcceleratedSurfaceSuspend() { |
| 1719 if (compositing_iosurface_) | 1715 if (compositing_iosurface_) |
| 1720 compositing_iosurface_->UnrefIOSurface(); | 1716 compositing_iosurface_->UnrefIOSurface(); |
| 1721 } | 1717 } |
| 1722 | 1718 |
| 1723 void RenderWidgetHostViewMac::AcceleratedSurfaceRelease() { | 1719 void RenderWidgetHostViewMac::AcceleratedSurfaceRelease() { |
| 1724 DestroyCompositedIOSurfaceAndLayer(kDestroyContext); | 1720 DestroyCompositedIOSurfaceAndLayer(kDestroyContext); |
| 1725 } | 1721 } |
| (...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2075 | 2071 |
| 2076 void RenderWidgetHostViewMac::TickPendingLatencyInfoDelay() { | 2072 void RenderWidgetHostViewMac::TickPendingLatencyInfoDelay() { |
| 2077 // Keep calling setNeedsDisplay in a loop until enough display calls come in. | 2073 // Keep calling setNeedsDisplay in a loop until enough display calls come in. |
| 2078 base::MessageLoop::current()->PostTask(FROM_HERE, | 2074 base::MessageLoop::current()->PostTask(FROM_HERE, |
| 2079 base::Bind(&RenderWidgetHostViewMac::TickPendingLatencyInfoDelay, | 2075 base::Bind(&RenderWidgetHostViewMac::TickPendingLatencyInfoDelay, |
| 2080 pending_latency_info_delay_weak_ptr_factory_.GetWeakPtr())); | 2076 pending_latency_info_delay_weak_ptr_factory_.GetWeakPtr())); |
| 2081 [software_layer_ setNeedsDisplay]; | 2077 [software_layer_ setNeedsDisplay]; |
| 2082 [compositing_iosurface_layer_ setNeedsDisplay]; | 2078 [compositing_iosurface_layer_ setNeedsDisplay]; |
| 2083 } | 2079 } |
| 2084 | 2080 |
| 2085 void RenderWidgetHostViewMac::AddPendingSwapAck( | |
| 2086 int32 route_id, int gpu_host_id, int32 renderer_id) { | |
| 2087 DCHECK(!pending_swap_ack_); | |
| 2088 pending_swap_ack_.reset(new PendingSwapAck( | |
| 2089 route_id, gpu_host_id, renderer_id)); | |
| 2090 // If we're about to paint, ack this immediatley. | |
| 2091 if (about_to_validate_and_paint_) | |
| 2092 SendPendingSwapAck(); | |
| 2093 } | |
| 2094 | |
| 2095 void RenderWidgetHostViewMac::SendPendingSwapAck() { | |
| 2096 if (!pending_swap_ack_) | |
| 2097 return; | |
| 2098 | |
| 2099 AcceleratedSurfaceMsg_BufferPresented_Params ack_params; | |
| 2100 ack_params.sync_point = 0; | |
| 2101 ack_params.renderer_id = pending_swap_ack_->renderer_id; | |
| 2102 RenderWidgetHostImpl::AcknowledgeBufferPresent(pending_swap_ack_->route_id, | |
| 2103 pending_swap_ack_->gpu_host_id, | |
| 2104 ack_params); | |
| 2105 if (render_widget_host_) | |
| 2106 render_widget_host_->AcknowledgeSwapBuffersToRenderer(); | |
| 2107 | |
| 2108 pending_swap_ack_.reset(); | |
| 2109 } | |
| 2110 | |
| 2111 } // namespace content | 2081 } // namespace content |
| 2112 | 2082 |
| 2113 // RenderWidgetHostViewCocoa --------------------------------------------------- | 2083 // RenderWidgetHostViewCocoa --------------------------------------------------- |
| 2114 | 2084 |
| 2115 @implementation RenderWidgetHostViewCocoa | 2085 @implementation RenderWidgetHostViewCocoa |
| 2116 @synthesize selectedRange = selectedRange_; | 2086 @synthesize selectedRange = selectedRange_; |
| 2117 @synthesize suppressNextEscapeKeyUp = suppressNextEscapeKeyUp_; | 2087 @synthesize suppressNextEscapeKeyUp = suppressNextEscapeKeyUp_; |
| 2118 @synthesize markedRange = markedRange_; | 2088 @synthesize markedRange = markedRange_; |
| 2119 | 2089 |
| 2120 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r { | 2090 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r { |
| (...skipping 2006 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4127 return YES; | 4097 return YES; |
| 4128 } | 4098 } |
| 4129 | 4099 |
| 4130 - (BOOL)isOpaque { | 4100 - (BOOL)isOpaque { |
| 4131 if (renderWidgetHostView_->use_core_animation_) | 4101 if (renderWidgetHostView_->use_core_animation_) |
| 4132 return YES; | 4102 return YES; |
| 4133 return [super isOpaque]; | 4103 return [super isOpaque]; |
| 4134 } | 4104 } |
| 4135 | 4105 |
| 4136 @end | 4106 @end |
| OLD | NEW |