summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--content/browser/renderer_host/compositing_iosurface_layer_mac.h12
-rw-r--r--content/browser/renderer_host/compositing_iosurface_layer_mac.mm32
-rw-r--r--content/browser/renderer_host/render_widget_host_view_mac.h9
-rw-r--r--content/browser/renderer_host/render_widget_host_view_mac.mm10
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);