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 |
440 // This is being called from |cocoa_view_|'s destructor, so invalidate the | 444 // This is being called from |cocoa_view_|'s destructor, so invalidate the |
441 // pointer. | 445 // pointer. |
442 cocoa_view_ = nil; | 446 cocoa_view_ = nil; |
443 | 447 |
444 UnlockMouse(); | 448 UnlockMouse(); |
445 | 449 |
446 // Make sure that the layer doesn't reach into the now-invalid object. | 450 // Make sure that the layer doesn't reach into the now-invalid object. |
447 DestroyCompositedIOSurfaceAndLayer(kDestroyContext); | 451 DestroyCompositedIOSurfaceAndLayer(kDestroyContext); |
448 software_layer_.reset(); | 452 software_layer_.reset(); |
449 | 453 |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
567 // Creating the CompositingIOSurfaceLayer may attempt to draw in setLayer, | 571 // Creating the CompositingIOSurfaceLayer may attempt to draw in setLayer, |
568 // which, if it fails, will promptly tear down everything that was just | 572 // which, if it fails, will promptly tear down everything that was just |
569 // created. If that happened, return failure. | 573 // created. If that happened, return failure. |
570 return compositing_iosurface_context_ && | 574 return compositing_iosurface_context_ && |
571 compositing_iosurface_ && | 575 compositing_iosurface_ && |
572 (compositing_iosurface_layer_ || !use_core_animation_); | 576 (compositing_iosurface_layer_ || !use_core_animation_); |
573 } | 577 } |
574 | 578 |
575 void RenderWidgetHostViewMac::DestroyCompositedIOSurfaceAndLayer( | 579 void RenderWidgetHostViewMac::DestroyCompositedIOSurfaceAndLayer( |
576 DestroyContextBehavior destroy_context_behavior) { | 580 DestroyContextBehavior destroy_context_behavior) { |
| 581 // Any pending frames will not be displayed, so ack them now. |
| 582 SendPendingSwapAck(); |
| 583 |
577 ScopedCAActionDisabler disabler; | 584 ScopedCAActionDisabler disabler; |
578 | 585 |
579 compositing_iosurface_.reset(); | 586 compositing_iosurface_.reset(); |
580 if (compositing_iosurface_layer_) { | 587 if (compositing_iosurface_layer_) { |
581 [software_layer_ setNeedsDisplay]; | 588 [software_layer_ setNeedsDisplay]; |
582 [compositing_iosurface_layer_ removeFromSuperlayer]; | 589 [compositing_iosurface_layer_ removeFromSuperlayer]; |
583 [compositing_iosurface_layer_ disableCompositing]; | 590 [compositing_iosurface_layer_ disableCompositing]; |
584 compositing_iosurface_layer_.reset(); | 591 compositing_iosurface_layer_.reset(); |
585 } | 592 } |
586 switch (destroy_context_behavior) { | 593 switch (destroy_context_behavior) { |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
741 if (!use_core_animation_) | 748 if (!use_core_animation_) |
742 [[cocoa_view_ window] disableScreenUpdatesUntilFlush]; | 749 [[cocoa_view_ window] disableScreenUpdatesUntilFlush]; |
743 | 750 |
744 [compositing_iosurface_layer_ setNeedsDisplay]; | 751 [compositing_iosurface_layer_ setNeedsDisplay]; |
745 } | 752 } |
746 | 753 |
747 void RenderWidgetHostViewMac::WasHidden() { | 754 void RenderWidgetHostViewMac::WasHidden() { |
748 if (render_widget_host_->is_hidden()) | 755 if (render_widget_host_->is_hidden()) |
749 return; | 756 return; |
750 | 757 |
| 758 // Any pending frames will not be displayed until this is shown again. Ack |
| 759 // them now. |
| 760 SendPendingSwapAck(); |
| 761 |
751 // If we have a renderer, then inform it that we are being hidden so it can | 762 // If we have a renderer, then inform it that we are being hidden so it can |
752 // reduce its resource utilization. | 763 // reduce its resource utilization. |
753 render_widget_host_->WasHidden(); | 764 render_widget_host_->WasHidden(); |
754 software_frame_manager_->SetVisibility(false); | 765 software_frame_manager_->SetVisibility(false); |
755 | 766 |
756 // There can be a transparent flash as this view is removed and the next is | 767 // 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 | 768 // added, because of OSX windowing races between displaying the contents of |
758 // the NSView and its corresponding OpenGL context. | 769 // the NSView and its corresponding OpenGL context. |
759 // disableScreenUpdatesUntilFlush prevents the transparent flash by avoiding | 770 // disableScreenUpdatesUntilFlush prevents the transparent flash by avoiding |
760 // screen updates until the next tab draws. | 771 // 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, | 1325 if (frame_subscriber_->ShouldCaptureFrame(present_time, |
1315 &frame, &callback)) { | 1326 &frame, &callback)) { |
1316 gfx::ScopedCGLSetCurrentContext scoped_set_current_context( | 1327 gfx::ScopedCGLSetCurrentContext scoped_set_current_context( |
1317 compositing_iosurface_context_->cgl_context()); | 1328 compositing_iosurface_context_->cgl_context()); |
1318 compositing_iosurface_->SetIOSurfaceWithContextCurrent( | 1329 compositing_iosurface_->SetIOSurfaceWithContextCurrent( |
1319 compositing_iosurface_context_, surface_handle, size, | 1330 compositing_iosurface_context_, surface_handle, size, |
1320 surface_scale_factor); | 1331 surface_scale_factor); |
1321 compositing_iosurface_->CopyToVideoFrame( | 1332 compositing_iosurface_->CopyToVideoFrame( |
1322 gfx::Rect(size), frame, | 1333 gfx::Rect(size), frame, |
1323 base::Bind(callback, present_time)); | 1334 base::Bind(callback, present_time)); |
| 1335 SendPendingSwapAck(); |
1324 return; | 1336 return; |
1325 } | 1337 } |
1326 } | 1338 } |
1327 | 1339 |
1328 // TODO(shess) If the view does not have a window, or the window | 1340 // TODO(shess) If the view does not have a window, or the window |
1329 // does not have backing, the IOSurface will log "invalid drawable" | 1341 // does not have backing, the IOSurface will log "invalid drawable" |
1330 // in -setView:. It is not clear how this code is reached with such | 1342 // 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 | 1343 // a case, so record some info into breakpad (some subset of |
1332 // browsers are likely to crash later for unrelated reasons). | 1344 // browsers are likely to crash later for unrelated reasons). |
1333 // http://crbug.com/148882 | 1345 // http://crbug.com/148882 |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1433 [compositing_iosurface_context_->nsgl_context() | 1445 [compositing_iosurface_context_->nsgl_context() |
1434 setValues:&new_gl_surface_order | 1446 setValues:&new_gl_surface_order |
1435 forParameter:NSOpenGLCPSurfaceOrder]; | 1447 forParameter:NSOpenGLCPSurfaceOrder]; |
1436 } | 1448 } |
1437 | 1449 |
1438 // Instead of drawing, request that underlay view redraws. | 1450 // Instead of drawing, request that underlay view redraws. |
1439 if (underlay_view_ && | 1451 if (underlay_view_ && |
1440 underlay_view_->compositing_iosurface_ && | 1452 underlay_view_->compositing_iosurface_ && |
1441 underlay_view_has_drawn_) { | 1453 underlay_view_has_drawn_) { |
1442 [underlay_view_->cocoa_view() setNeedsDisplay:YES]; | 1454 [underlay_view_->cocoa_view() setNeedsDisplay:YES]; |
| 1455 SendPendingSwapAck(); |
1443 return true; | 1456 return true; |
1444 } | 1457 } |
1445 | 1458 |
1446 bool has_overlay = overlay_view_ && overlay_view_->compositing_iosurface_; | 1459 bool has_overlay = overlay_view_ && overlay_view_->compositing_iosurface_; |
1447 if (has_overlay) { | 1460 if (has_overlay) { |
1448 // Un-bind the overlay view's OpenGL context, since its content will be | 1461 // Un-bind the overlay view's OpenGL context, since its content will be |
1449 // drawn by this context. Not doing this can result in corruption. | 1462 // drawn by this context. Not doing this can result in corruption. |
1450 // http://crbug.com/330701 | 1463 // http://crbug.com/330701 |
1451 overlay_view_->ClearBoundContextDrawable(); | 1464 overlay_view_->ClearBoundContextDrawable(); |
1452 } | 1465 } |
(...skipping 15 matching lines...) Expand all Loading... |
1468 overlay_view_rect.height() - | 1481 overlay_view_rect.height() - |
1469 overlay_view_offset_.y()); | 1482 overlay_view_offset_.y()); |
1470 if (!overlay_view_->compositing_iosurface_->DrawIOSurface( | 1483 if (!overlay_view_->compositing_iosurface_->DrawIOSurface( |
1471 compositing_iosurface_context_, overlay_view_rect, | 1484 compositing_iosurface_context_, overlay_view_rect, |
1472 overlay_view_->scale_factor(), true)) { | 1485 overlay_view_->scale_factor(), true)) { |
1473 return false; | 1486 return false; |
1474 } | 1487 } |
1475 } | 1488 } |
1476 | 1489 |
1477 SendPendingLatencyInfoToHost(); | 1490 SendPendingLatencyInfoToHost(); |
| 1491 SendPendingSwapAck(); |
1478 return true; | 1492 return true; |
1479 } | 1493 } |
1480 | 1494 |
1481 void RenderWidgetHostViewMac::GotAcceleratedCompositingError() { | 1495 void RenderWidgetHostViewMac::GotAcceleratedCompositingError() { |
1482 DestroyCompositedIOSurfaceAndLayer(kDestroyContext); | 1496 DestroyCompositedIOSurfaceAndLayer(kDestroyContext); |
1483 // The existing GL contexts may be in a bad state, so don't re-use any of the | 1497 // 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. | 1498 // existing ones anymore, rather, allocate new ones. |
1485 CompositingIOSurfaceContext::MarkExistingContextsAsNotShareable(); | 1499 CompositingIOSurfaceContext::MarkExistingContextsAsNotShareable(); |
1486 // Request that a new frame be generated. | 1500 // Request that a new frame be generated. |
1487 if (render_widget_host_) | 1501 if (render_widget_host_) |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1645 return true; | 1659 return true; |
1646 } | 1660 } |
1647 | 1661 |
1648 void RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped( | 1662 void RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped( |
1649 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params, | 1663 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params, |
1650 int gpu_host_id) { | 1664 int gpu_host_id) { |
1651 TRACE_EVENT0("browser", | 1665 TRACE_EVENT0("browser", |
1652 "RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped"); | 1666 "RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped"); |
1653 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1667 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
1654 | 1668 |
| 1669 AddPendingSwapAck(params.route_id, |
| 1670 gpu_host_id, |
| 1671 compositing_iosurface_ ? |
| 1672 compositing_iosurface_->GetRendererID() : 0); |
1655 CompositorSwapBuffers(params.surface_handle, | 1673 CompositorSwapBuffers(params.surface_handle, |
1656 params.size, | 1674 params.size, |
1657 params.scale_factor, | 1675 params.scale_factor, |
1658 params.latency_info); | 1676 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 } | 1677 } |
1669 | 1678 |
1670 void RenderWidgetHostViewMac::AcceleratedSurfacePostSubBuffer( | 1679 void RenderWidgetHostViewMac::AcceleratedSurfacePostSubBuffer( |
1671 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params, | 1680 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params, |
1672 int gpu_host_id) { | 1681 int gpu_host_id) { |
1673 TRACE_EVENT0("browser", | 1682 TRACE_EVENT0("browser", |
1674 "RenderWidgetHostViewMac::AcceleratedSurfacePostSubBuffer"); | 1683 "RenderWidgetHostViewMac::AcceleratedSurfacePostSubBuffer"); |
1675 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1684 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
1676 | 1685 |
| 1686 AddPendingSwapAck(params.route_id, |
| 1687 gpu_host_id, |
| 1688 compositing_iosurface_ ? |
| 1689 compositing_iosurface_->GetRendererID() : 0); |
1677 CompositorSwapBuffers(params.surface_handle, | 1690 CompositorSwapBuffers(params.surface_handle, |
1678 params.surface_size, | 1691 params.surface_size, |
1679 params.surface_scale_factor, | 1692 params.surface_scale_factor, |
1680 params.latency_info); | 1693 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 } | 1694 } |
1691 | 1695 |
1692 void RenderWidgetHostViewMac::AcceleratedSurfaceSuspend() { | 1696 void RenderWidgetHostViewMac::AcceleratedSurfaceSuspend() { |
1693 if (compositing_iosurface_) | 1697 if (compositing_iosurface_) |
1694 compositing_iosurface_->UnrefIOSurface(); | 1698 compositing_iosurface_->UnrefIOSurface(); |
1695 } | 1699 } |
1696 | 1700 |
1697 void RenderWidgetHostViewMac::AcceleratedSurfaceRelease() { | 1701 void RenderWidgetHostViewMac::AcceleratedSurfaceRelease() { |
1698 DestroyCompositedIOSurfaceAndLayer(kDestroyContext); | 1702 DestroyCompositedIOSurfaceAndLayer(kDestroyContext); |
1699 } | 1703 } |
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2053 | 2057 |
2054 void RenderWidgetHostViewMac::TickPendingLatencyInfoDelay() { | 2058 void RenderWidgetHostViewMac::TickPendingLatencyInfoDelay() { |
2055 // Keep calling setNeedsDisplay in a loop until enough display calls come in. | 2059 // Keep calling setNeedsDisplay in a loop until enough display calls come in. |
2056 base::MessageLoop::current()->PostTask(FROM_HERE, | 2060 base::MessageLoop::current()->PostTask(FROM_HERE, |
2057 base::Bind(&RenderWidgetHostViewMac::TickPendingLatencyInfoDelay, | 2061 base::Bind(&RenderWidgetHostViewMac::TickPendingLatencyInfoDelay, |
2058 pending_latency_info_delay_weak_ptr_factory_.GetWeakPtr())); | 2062 pending_latency_info_delay_weak_ptr_factory_.GetWeakPtr())); |
2059 [software_layer_ setNeedsDisplay]; | 2063 [software_layer_ setNeedsDisplay]; |
2060 [compositing_iosurface_layer_ setNeedsDisplay]; | 2064 [compositing_iosurface_layer_ setNeedsDisplay]; |
2061 } | 2065 } |
2062 | 2066 |
| 2067 void RenderWidgetHostViewMac::AddPendingSwapAck( |
| 2068 int32 route_id, int gpu_host_id, int32 renderer_id) { |
| 2069 DCHECK(!pending_swap_ack_); |
| 2070 pending_swap_ack_.reset(new PendingSwapAck( |
| 2071 route_id, gpu_host_id, renderer_id)); |
| 2072 // If we're about to paint, ack this immediatley. |
| 2073 if (about_to_validate_and_paint_) |
| 2074 SendPendingSwapAck(); |
| 2075 } |
| 2076 |
| 2077 void RenderWidgetHostViewMac::SendPendingSwapAck() { |
| 2078 if (!pending_swap_ack_) |
| 2079 return; |
| 2080 |
| 2081 AcceleratedSurfaceMsg_BufferPresented_Params ack_params; |
| 2082 ack_params.sync_point = 0; |
| 2083 ack_params.renderer_id = pending_swap_ack_->renderer_id; |
| 2084 RenderWidgetHostImpl::AcknowledgeBufferPresent(pending_swap_ack_->route_id, |
| 2085 pending_swap_ack_->gpu_host_id, |
| 2086 ack_params); |
| 2087 if (render_widget_host_) |
| 2088 render_widget_host_->AcknowledgeSwapBuffersToRenderer(); |
| 2089 |
| 2090 pending_swap_ack_.reset(); |
| 2091 } |
| 2092 |
2063 } // namespace content | 2093 } // namespace content |
2064 | 2094 |
2065 // RenderWidgetHostViewCocoa --------------------------------------------------- | 2095 // RenderWidgetHostViewCocoa --------------------------------------------------- |
2066 | 2096 |
2067 @implementation RenderWidgetHostViewCocoa | 2097 @implementation RenderWidgetHostViewCocoa |
2068 @synthesize selectedRange = selectedRange_; | 2098 @synthesize selectedRange = selectedRange_; |
2069 @synthesize suppressNextEscapeKeyUp = suppressNextEscapeKeyUp_; | 2099 @synthesize suppressNextEscapeKeyUp = suppressNextEscapeKeyUp_; |
2070 @synthesize markedRange = markedRange_; | 2100 @synthesize markedRange = markedRange_; |
2071 | 2101 |
2072 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r { | 2102 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r { |
(...skipping 2028 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4101 return YES; | 4131 return YES; |
4102 } | 4132 } |
4103 | 4133 |
4104 - (BOOL)isOpaque { | 4134 - (BOOL)isOpaque { |
4105 if (renderWidgetHostView_->use_core_animation_) | 4135 if (renderWidgetHostView_->use_core_animation_) |
4106 return YES; | 4136 return YES; |
4107 return [super isOpaque]; | 4137 return [super isOpaque]; |
4108 } | 4138 } |
4109 | 4139 |
4110 @end | 4140 @end |
OLD | NEW |