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 1313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1324 render_widget_host_->Send(new ViewMsg_PluginImeCompositionCompleted( | 1324 render_widget_host_->Send(new ViewMsg_PluginImeCompositionCompleted( |
1325 render_widget_host_->GetRoutingID(), text, plugin_id)); | 1325 render_widget_host_->GetRoutingID(), text, plugin_id)); |
1326 } | 1326 } |
1327 } | 1327 } |
1328 | 1328 |
1329 void RenderWidgetHostViewMac::CompositorSwapBuffers( | 1329 void RenderWidgetHostViewMac::CompositorSwapBuffers( |
1330 uint64 surface_handle, | 1330 uint64 surface_handle, |
1331 const gfx::Size& size, | 1331 const gfx::Size& size, |
1332 float surface_scale_factor, | 1332 float surface_scale_factor, |
1333 const std::vector<ui::LatencyInfo>& latency_info) { | 1333 const std::vector<ui::LatencyInfo>& latency_info) { |
| 1334 // Ensure that the frame be acked unless it is explicitly passed to a |
| 1335 // display function. |
| 1336 base::ScopedClosureRunner scoped_ack( |
| 1337 base::Bind(&RenderWidgetHostViewMac::SendPendingSwapAck, |
| 1338 weak_factory_.GetWeakPtr())); |
| 1339 |
1334 if (render_widget_host_->is_hidden()) | 1340 if (render_widget_host_->is_hidden()) |
1335 return; | 1341 return; |
1336 | 1342 |
1337 AddPendingLatencyInfo(latency_info); | 1343 AddPendingLatencyInfo(latency_info); |
1338 | 1344 |
1339 NSWindow* window = [cocoa_view_ window]; | 1345 NSWindow* window = [cocoa_view_ window]; |
1340 if (window_number() <= 0) { | 1346 if (window_number() <= 0) { |
1341 // There is no window to present so capturing during present won't work. | 1347 // There is no window to present so capturing during present won't work. |
1342 // We check if frame subscriber wants this frame and capture manually. | 1348 // We check if frame subscriber wants this frame and capture manually. |
1343 if (compositing_iosurface_ && frame_subscriber_) { | 1349 if (compositing_iosurface_ && frame_subscriber_) { |
1344 const base::TimeTicks present_time = base::TimeTicks::Now(); | 1350 const base::TimeTicks present_time = base::TimeTicks::Now(); |
1345 scoped_refptr<media::VideoFrame> frame; | 1351 scoped_refptr<media::VideoFrame> frame; |
1346 RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback callback; | 1352 RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback callback; |
1347 if (frame_subscriber_->ShouldCaptureFrame(present_time, | 1353 if (frame_subscriber_->ShouldCaptureFrame(present_time, |
1348 &frame, &callback)) { | 1354 &frame, &callback)) { |
1349 gfx::ScopedCGLSetCurrentContext scoped_set_current_context( | 1355 gfx::ScopedCGLSetCurrentContext scoped_set_current_context( |
1350 compositing_iosurface_context_->cgl_context()); | 1356 compositing_iosurface_context_->cgl_context()); |
1351 compositing_iosurface_->SetIOSurfaceWithContextCurrent( | 1357 compositing_iosurface_->SetIOSurfaceWithContextCurrent( |
1352 compositing_iosurface_context_, surface_handle, size, | 1358 compositing_iosurface_context_, surface_handle, size, |
1353 surface_scale_factor); | 1359 surface_scale_factor); |
1354 compositing_iosurface_->CopyToVideoFrame( | 1360 compositing_iosurface_->CopyToVideoFrame( |
1355 gfx::Rect(size), frame, | 1361 gfx::Rect(size), frame, |
1356 base::Bind(callback, present_time)); | 1362 base::Bind(callback, present_time)); |
1357 SendPendingSwapAck(); | |
1358 return; | 1363 return; |
1359 } | 1364 } |
1360 } | 1365 } |
1361 | 1366 |
1362 // TODO(shess) If the view does not have a window, or the window | 1367 // TODO(shess) If the view does not have a window, or the window |
1363 // does not have backing, the IOSurface will log "invalid drawable" | 1368 // does not have backing, the IOSurface will log "invalid drawable" |
1364 // in -setView:. It is not clear how this code is reached with such | 1369 // 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 | 1370 // a case, so record some info into breakpad (some subset of |
1366 // browsers are likely to crash later for unrelated reasons). | 1371 // browsers are likely to crash later for unrelated reasons). |
1367 // http://crbug.com/148882 | 1372 // http://crbug.com/148882 |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1433 gfx::Size window_size(NSSizeToCGSize([cocoa_view_ frame].size)); | 1438 gfx::Size window_size(NSSizeToCGSize([cocoa_view_ frame].size)); |
1434 if (window_size.IsEmpty()) { | 1439 if (window_size.IsEmpty()) { |
1435 // setNeedsDisplay will never display and we'll never ack if the window is | 1440 // setNeedsDisplay will never display and we'll never ack if the window is |
1436 // empty, so ack now and don't bother calling setNeedsDisplay below. | 1441 // empty, so ack now and don't bother calling setNeedsDisplay below. |
1437 return; | 1442 return; |
1438 } | 1443 } |
1439 | 1444 |
1440 // No need to draw the surface if we are inside a drawRect. It will be done | 1445 // No need to draw the surface if we are inside a drawRect. It will be done |
1441 // later. | 1446 // later. |
1442 if (!about_to_validate_and_paint_) { | 1447 if (!about_to_validate_and_paint_) { |
| 1448 scoped_ack.Reset(); |
1443 if (use_core_animation_) { | 1449 if (use_core_animation_) { |
1444 DCHECK(compositing_iosurface_layer_); | 1450 DCHECK(compositing_iosurface_layer_); |
1445 compositing_iosurface_layer_async_timer_.Reset(); | 1451 compositing_iosurface_layer_async_timer_.Reset(); |
1446 [compositing_iosurface_layer_ gotNewFrame]; | 1452 [compositing_iosurface_layer_ gotNewFrame]; |
1447 } else { | 1453 } else { |
1448 if (!DrawIOSurfaceWithoutCoreAnimation()) { | 1454 if (!DrawIOSurfaceWithoutCoreAnimation()) { |
1449 [cocoa_view_ setNeedsDisplay:YES]; | 1455 [cocoa_view_ setNeedsDisplay:YES]; |
1450 GotAcceleratedCompositingError(); | 1456 GotAcceleratedCompositingError(); |
1451 return; | 1457 return; |
1452 } | 1458 } |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1689 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1695 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
1690 | 1696 |
1691 AddPendingSwapAck(params.route_id, | 1697 AddPendingSwapAck(params.route_id, |
1692 gpu_host_id, | 1698 gpu_host_id, |
1693 compositing_iosurface_ ? | 1699 compositing_iosurface_ ? |
1694 compositing_iosurface_->GetRendererID() : 0); | 1700 compositing_iosurface_->GetRendererID() : 0); |
1695 CompositorSwapBuffers(params.surface_handle, | 1701 CompositorSwapBuffers(params.surface_handle, |
1696 params.size, | 1702 params.size, |
1697 params.scale_factor, | 1703 params.scale_factor, |
1698 params.latency_info); | 1704 params.latency_info); |
1699 // TODO(ccameron): This ack should not be needed, and will inappropriately | |
1700 // remove GPU back-pressure. Remove this. | |
1701 SendPendingSwapAck(); | |
1702 } | 1705 } |
1703 | 1706 |
1704 void RenderWidgetHostViewMac::AcceleratedSurfacePostSubBuffer( | 1707 void RenderWidgetHostViewMac::AcceleratedSurfacePostSubBuffer( |
1705 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params, | 1708 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params, |
1706 int gpu_host_id) { | 1709 int gpu_host_id) { |
1707 TRACE_EVENT0("browser", | 1710 TRACE_EVENT0("browser", |
1708 "RenderWidgetHostViewMac::AcceleratedSurfacePostSubBuffer"); | 1711 "RenderWidgetHostViewMac::AcceleratedSurfacePostSubBuffer"); |
1709 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1712 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
1710 | 1713 |
1711 AddPendingSwapAck(params.route_id, | 1714 AddPendingSwapAck(params.route_id, |
1712 gpu_host_id, | 1715 gpu_host_id, |
1713 compositing_iosurface_ ? | 1716 compositing_iosurface_ ? |
1714 compositing_iosurface_->GetRendererID() : 0); | 1717 compositing_iosurface_->GetRendererID() : 0); |
1715 CompositorSwapBuffers(params.surface_handle, | 1718 CompositorSwapBuffers(params.surface_handle, |
1716 params.surface_size, | 1719 params.surface_size, |
1717 params.surface_scale_factor, | 1720 params.surface_scale_factor, |
1718 params.latency_info); | 1721 params.latency_info); |
1719 // TODO(ccameron): This ack should not be needed, and will inappropriately | |
1720 // remove GPU back-pressure. Remove this. | |
1721 SendPendingSwapAck(); | |
1722 } | 1722 } |
1723 | 1723 |
1724 void RenderWidgetHostViewMac::AcceleratedSurfaceSuspend() { | 1724 void RenderWidgetHostViewMac::AcceleratedSurfaceSuspend() { |
1725 if (compositing_iosurface_) | 1725 if (compositing_iosurface_) |
1726 compositing_iosurface_->UnrefIOSurface(); | 1726 compositing_iosurface_->UnrefIOSurface(); |
1727 } | 1727 } |
1728 | 1728 |
1729 void RenderWidgetHostViewMac::AcceleratedSurfaceRelease() { | 1729 void RenderWidgetHostViewMac::AcceleratedSurfaceRelease() { |
1730 DestroyCompositedIOSurfaceAndLayer(kDestroyContext); | 1730 DestroyCompositedIOSurfaceAndLayer(kDestroyContext); |
1731 } | 1731 } |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1884 weak_factory_.InvalidateWeakPtrs(); | 1884 weak_factory_.InvalidateWeakPtrs(); |
1885 render_widget_host_->Shutdown(); | 1885 render_widget_host_->Shutdown(); |
1886 // Do not touch any members at this point, |this| has been deleted. | 1886 // Do not touch any members at this point, |this| has been deleted. |
1887 } | 1887 } |
1888 | 1888 |
1889 void RenderWidgetHostViewMac::GotAcceleratedFrame() { | 1889 void RenderWidgetHostViewMac::GotAcceleratedFrame() { |
1890 // Update the host with VSync parametrs. | 1890 // Update the host with VSync parametrs. |
1891 base::TimeTicks timebase; | 1891 base::TimeTicks timebase; |
1892 base::TimeDelta interval; | 1892 base::TimeDelta interval; |
1893 if (compositing_iosurface_context_ && | 1893 if (compositing_iosurface_context_ && |
| 1894 compositing_iosurface_context_->display_link() && |
1894 compositing_iosurface_context_->display_link()->GetVSyncParameters( | 1895 compositing_iosurface_context_->display_link()->GetVSyncParameters( |
1895 &timebase, &interval)) { | 1896 &timebase, &interval)) { |
1896 render_widget_host_->UpdateVSyncParameters(timebase, interval); | 1897 render_widget_host_->UpdateVSyncParameters(timebase, interval); |
1897 } | 1898 } |
1898 | 1899 |
1899 if (!last_frame_was_accelerated_) { | 1900 if (!last_frame_was_accelerated_) { |
1900 last_frame_was_accelerated_ = true; | 1901 last_frame_was_accelerated_ = true; |
1901 | 1902 |
1902 if (!use_core_animation_) { | 1903 if (!use_core_animation_) { |
1903 // Need to wipe the software view with transparency to expose the GL | 1904 // Need to wipe the software view with transparency to expose the GL |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2087 [software_layer_ setNeedsDisplay]; | 2088 [software_layer_ setNeedsDisplay]; |
2088 [compositing_iosurface_layer_ setNeedsDisplay]; | 2089 [compositing_iosurface_layer_ setNeedsDisplay]; |
2089 } | 2090 } |
2090 | 2091 |
2091 void RenderWidgetHostViewMac::AddPendingSwapAck( | 2092 void RenderWidgetHostViewMac::AddPendingSwapAck( |
2092 int32 route_id, int gpu_host_id, int32 renderer_id) { | 2093 int32 route_id, int gpu_host_id, int32 renderer_id) { |
2093 // Note that multiple un-acked swaps can come in the event of a GPU process | 2094 // Note that multiple un-acked swaps can come in the event of a GPU process |
2094 // loss. Drop the old acks. | 2095 // loss. Drop the old acks. |
2095 pending_swap_ack_.reset(new PendingSwapAck( | 2096 pending_swap_ack_.reset(new PendingSwapAck( |
2096 route_id, gpu_host_id, renderer_id)); | 2097 route_id, gpu_host_id, renderer_id)); |
2097 // Ack this immediately if we're already inside a paint call, or if we're | |
2098 // hidden and this may not paint for a long time. | |
2099 if (about_to_validate_and_paint_ || render_widget_host_->is_hidden()) | |
2100 SendPendingSwapAck(); | |
2101 } | 2098 } |
2102 | 2099 |
2103 void RenderWidgetHostViewMac::SendPendingSwapAck() { | 2100 void RenderWidgetHostViewMac::SendPendingSwapAck() { |
2104 if (!pending_swap_ack_) | 2101 if (!pending_swap_ack_) |
2105 return; | 2102 return; |
2106 | 2103 |
2107 AcceleratedSurfaceMsg_BufferPresented_Params ack_params; | 2104 AcceleratedSurfaceMsg_BufferPresented_Params ack_params; |
2108 ack_params.sync_point = 0; | 2105 ack_params.sync_point = 0; |
2109 ack_params.renderer_id = pending_swap_ack_->renderer_id; | 2106 ack_params.renderer_id = pending_swap_ack_->renderer_id; |
2110 RenderWidgetHostImpl::AcknowledgeBufferPresent(pending_swap_ack_->route_id, | 2107 RenderWidgetHostImpl::AcknowledgeBufferPresent(pending_swap_ack_->route_id, |
(...skipping 2024 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4135 return YES; | 4132 return YES; |
4136 } | 4133 } |
4137 | 4134 |
4138 - (BOOL)isOpaque { | 4135 - (BOOL)isOpaque { |
4139 if (renderWidgetHostView_->use_core_animation_) | 4136 if (renderWidgetHostView_->use_core_animation_) |
4140 return YES; | 4137 return YES; |
4141 return [super isOpaque]; | 4138 return [super isOpaque]; |
4142 } | 4139 } |
4143 | 4140 |
4144 @end | 4141 @end |
OLD | NEW |