Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(13)

Side by Side Diff: content/browser/renderer_host/render_widget_host_view_mac.mm

Issue 165703002: Do not send a frame swap ack from the browser until the frame is drawn (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@dynamic_async
Patch Set: Add swap ack missed with devtools overlays Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « content/browser/renderer_host/render_widget_host_view_mac.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « content/browser/renderer_host/render_widget_host_view_mac.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698