diff options
4 files changed, 62 insertions, 1 deletions
diff --git a/content/browser/renderer_host/compositing_iosurface_layer_mac.h b/content/browser/renderer_host/compositing_iosurface_layer_mac.h index a03ab1c..af5d5b3 100644 --- a/content/browser/renderer_host/compositing_iosurface_layer_mac.h +++ b/content/browser/renderer_host/compositing_iosurface_layer_mac.h @@ -20,6 +20,11 @@ class RenderWidgetHostViewMac; @private content::RenderWidgetHostViewMac* renderWidgetHostView_; scoped_refptr<content::CompositingIOSurfaceContext> context_; + + // Used to track when canDrawInCGLContext should return YES. This can be + // in response to receiving a new compositor frame, or from any of the events + // that cause setNeedsDisplay to be called on the layer. + BOOL needsDisplay_; } @property(nonatomic, readonly) @@ -35,6 +40,13 @@ class RenderWidgetHostViewMac; // |renderWidgetHostView_| is no longer valid and may no longer be dereferenced. - (void)disableCompositing; +// Called when a new frame is received. +- (void)gotNewFrame; + +// Called when it has been a while since a new frame has been received, and the +// layer should become not-asynchronous. +- (void)timerSinceGotNewFrameFired; + @end #endif // CONTENT_BROWSER_RENDERER_HOST_COMPOSITING_IOSURFACE_LAYER_MAC_H_ diff --git a/content/browser/renderer_host/compositing_iosurface_layer_mac.mm b/content/browser/renderer_host/compositing_iosurface_layer_mac.mm index 38752b4..63f9ca3 100644 --- a/content/browser/renderer_host/compositing_iosurface_layer_mac.mm +++ b/content/browser/renderer_host/compositing_iosurface_layer_mac.mm @@ -26,6 +26,7 @@ context_ = content::CompositingIOSurfaceContext::Get( content::CompositingIOSurfaceContext::kOffscreenContextWindowNumber); DCHECK(context_); + needsDisplay_ = NO; ScopedCAActionDisabler disabler; [self setBackgroundColor:CGColorGetConstantColor(kCGColorWhite)]; @@ -64,6 +65,24 @@ renderWidgetHostView_ = nil; } +- (void)gotNewFrame { + if (![self isAsynchronous]) { + [self setNeedsDisplay]; + [self setAsynchronous:YES]; + } else { + needsDisplay_ = YES; + } +} + +- (void)timerSinceGotNewFrameFired { + if (![self isAsynchronous]) + return; + + [self setAsynchronous:NO]; + if (needsDisplay_) + [self setNeedsDisplay]; +} + // The remaining methods implement the CAOpenGLLayer interface. - (CGLPixelFormatObj)copyCGLPixelFormatForDisplayMask:(uint32_t)mask { @@ -78,6 +97,18 @@ return CGLRetainContext(context_->cgl_context()); } +- (void)setNeedsDisplay { + needsDisplay_ = YES; + [super setNeedsDisplay]; +} + +- (BOOL)canDrawInCGLContext:(CGLContextObj)glContext + pixelFormat:(CGLPixelFormatObj)pixelFormat + forLayerTime:(CFTimeInterval)timeInterval + displayTime:(const CVTimeStamp*)timeStamp { + return needsDisplay_; +} + - (void)drawInCGLContext:(CGLContextObj)glContext pixelFormat:(CGLPixelFormatObj)pixelFormat forLayerTime:(CFTimeInterval)timeInterval @@ -143,6 +174,7 @@ return; } + needsDisplay_ = NO; renderWidgetHostView_->SendPendingLatencyInfoToHost(); } diff --git a/content/browser/renderer_host/render_widget_host_view_mac.h b/content/browser/renderer_host/render_widget_host_view_mac.h index 2c3d44f..e141633 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.h +++ b/content/browser/renderer_host/render_widget_host_view_mac.h @@ -435,6 +435,11 @@ class RenderWidgetHostViewMac : public RenderWidgetHostViewBase, scoped_ptr<CompositingIOSurfaceMac> compositing_iosurface_; scoped_refptr<CompositingIOSurfaceContext> compositing_iosurface_context_; + // Timer used to dynamically transition the compositing layer in and out of + // asynchronous mode. + base::DelayTimer<RenderWidgetHostViewMac> + compositing_iosurface_layer_async_timer_; + // This holds the current software compositing framebuffer, if any. scoped_ptr<SoftwareFrameManager> software_frame_manager_; @@ -512,6 +517,10 @@ class RenderWidgetHostViewMac : public RenderWidgetHostViewBase, // Called when a software DIB is received. void GotSoftwareFrame(); + // Called if it has been a quarter-second since a GPU SwapBuffers has been + // received. In this case, switch from polling for frames to pushing them. + void TimerSinceGotAcceleratedFrameFired(); + void OnPluginFocusChanged(bool focused, int plugin_id); void OnStartPluginIme(); diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm index 510dec1..a2d991d 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac.mm @@ -408,6 +408,9 @@ RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget) last_frame_was_accelerated_(false), text_input_type_(ui::TEXT_INPUT_TYPE_NONE), can_compose_inline_(true), + compositing_iosurface_layer_async_timer_( + FROM_HERE, base::TimeDelta::FromMilliseconds(250), + this, &RenderWidgetHostViewMac::TimerSinceGotAcceleratedFrameFired), allow_overlapping_views_(false), use_core_animation_(false), pending_latency_info_delay_(0), @@ -1405,7 +1408,8 @@ void RenderWidgetHostViewMac::CompositorSwapBuffers( if (!about_to_validate_and_paint_) { if (use_core_animation_) { DCHECK(compositing_iosurface_layer_); - [compositing_iosurface_layer_ setNeedsDisplay]; + compositing_iosurface_layer_async_timer_.Reset(); + [compositing_iosurface_layer_ gotNewFrame]; } else { if (!DrawIOSurfaceWithoutCoreAnimation()) { [cocoa_view_ setNeedsDisplay:YES]; @@ -1903,6 +1907,10 @@ void RenderWidgetHostViewMac::GotSoftwareFrame() { } } +void RenderWidgetHostViewMac::TimerSinceGotAcceleratedFrameFired() { + [compositing_iosurface_layer_ timerSinceGotNewFrameFired]; +} + void RenderWidgetHostViewMac::SetActive(bool active) { if (render_widget_host_) { render_widget_host_->SetActive(active); |