Index: content/browser/renderer_host/render_widget_host_view_mac.mm |
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 f80585a0f84bda8df033495a7f234670204f27c7..22dd88aae8bfd1e3fa0b6151348ab2937d7ac6e6 100644 |
--- a/content/browser/renderer_host/render_widget_host_view_mac.mm |
+++ b/content/browser/renderer_host/render_widget_host_view_mac.mm |
@@ -26,6 +26,7 @@ |
#include "base/strings/sys_string_conversions.h" |
#include "base/strings/utf_string_conversions.h" |
#include "base/sys_info.h" |
+#include "cc/base/switches.h" |
#import "content/browser/accessibility/browser_accessibility_cocoa.h" |
#include "content/browser/accessibility/browser_accessibility_manager_mac.h" |
#import "content/browser/cocoa/system_hotkey_helper_mac.h" |
@@ -511,6 +512,8 @@ RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget) |
allow_pause_for_resize_or_repaint_(true), |
weak_factory_(this), |
fullscreen_parent_host_view_(NULL), |
+ needs_begin_frame_(false), |
+ begin_frame_scheduling_is_enabled_(false), |
software_frame_weak_ptr_factory_(this) { |
software_frame_manager_.reset(new SoftwareFrameManager( |
software_frame_weak_ptr_factory_.GetWeakPtr())); |
@@ -547,9 +550,19 @@ RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget) |
gfx::Screen::GetScreenFor(cocoa_view_)->AddObserver(this); |
render_widget_host_->SetView(this); |
+ |
+ if (CommandLine::ForCurrentProcess()->HasSwitch( |
+ cc::switches::kEnableBeginFrameScheduling) && |
+ !CommandLIne::HasSwitch(switches::kDisableGpuVsync)) |
+ begin_frame_scheduling_is_enabled_ = true; |
} |
RenderWidgetHostViewMac::~RenderWidgetHostViewMac() { |
+ // |this| should be removed from BeginFrameManger's observer list cleanly. |
+ if (begin_frame_scheduling_is_enalbed_) { |
+ DCHECK(needs_begin_frame_); |
+ display_link_->RemoveObserver(this); |
+ } |
gfx::Screen::GetScreenFor(cocoa_view_)->RemoveObserver(this); |
// This is being called from |cocoa_view_|'s destructor, so invalidate the |
@@ -652,6 +665,9 @@ void RenderWidgetHostViewMac::EnsureBrowserCompositorView() { |
browser_compositor_view_.reset(new BrowserCompositorViewMac(this)); |
delegated_frame_host_->AddedToWindow(); |
delegated_frame_host_->WasShown(); |
+ |
+ if (needs_begin_frame_) |
+ GetCompositor()->begin_frame_manager()->AddObserver(this); |
} |
void RenderWidgetHostViewMac::DestroyBrowserCompositorView() { |
@@ -660,6 +676,9 @@ void RenderWidgetHostViewMac::DestroyBrowserCompositorView() { |
if (!browser_compositor_view_) |
return; |
+ if (needs_begin_frame_) |
+ GetCompositor()->begin_frame_manager()->RemoveObserver(this); |
+ |
delegated_frame_host_->WasHidden(); |
delegated_frame_host_->RemovingFromWindow(); |
browser_compositor_view_.reset(); |
@@ -734,6 +753,7 @@ bool RenderWidgetHostViewMac::OnMessageReceived(const IPC::Message& message) { |
IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewMac, message) |
IPC_MESSAGE_HANDLER(ViewHostMsg_PluginFocusChanged, OnPluginFocusChanged) |
IPC_MESSAGE_HANDLER(ViewHostMsg_StartPluginIme, OnStartPluginIme) |
+ IPC_MESSAGE_HANDLER(ViewHostMsg_SetNeedsBeginFrame, OnSetNeedsBeginFrame) |
IPC_MESSAGE_UNHANDLED(handled = false) |
IPC_END_MESSAGE_MAP() |
return handled; |
@@ -859,9 +879,15 @@ void RenderWidgetHostViewMac::UpdateDisplayLink() { |
// created, so this should not be a fatal error. |
LOG(ERROR) << "Failed to create display link."; |
} |
+ |
+ if (begin_frame_scheduling_is_enabled_) |
+ display_link_->AddObserver(this); |
} |
void RenderWidgetHostViewMac::SendVSyncParametersToRenderer() { |
+ if (begin_frame_scheduling_is_enabled_) |
+ return; |
+ |
if (!render_widget_host_ || !display_link_) |
return; |
@@ -874,6 +900,24 @@ void RenderWidgetHostViewMac::SendVSyncParametersToRenderer() { |
render_widget_host_->UpdateVSyncParameters(vsync_timebase_, vsync_interval_); |
} |
+void RenderWidgetHostViewMac::OnSetNeedsBeginFrame(bool enabled) { |
+ DCHECK(begin_frame_scheduling_is_enabled_); |
+ |
+ if (needs_begin_frame_ == enabled) |
+ return; |
+ |
+ TRACE_EVENT1("cc", "RenderWidgetHostViewMac::OnSetNeedsBeginFrame", |
+ "enabled", enabled); |
+ |
+ if (enabled) |
+ GetCompositor()->begin_frame_manager()->AddObserver(this, |
+ last_begin_frame_args_); |
+ else |
+ GetCompositor()->begin_frame_manager()->RemoveObserver(this); |
+ |
+ needs_begin_frame_ = enabled; |
+} |
+ |
void RenderWidgetHostViewMac::UpdateBackingStoreScaleFactor() { |
if (!render_widget_host_) |
return; |
@@ -2342,6 +2386,39 @@ void RenderWidgetHostViewMac::OnDisplayMetricsChanged( |
UpdateScreenInfo(cocoa_view_); |
} |
+void RenderWidgetHostViewMac::OnSendBeginFrame( |
+ const cc::BeginFrameArgs& args) { |
+ DCHECK(begin_frame_scheduling_is_enabled_); |
+ DCHECK(render_widget_host_); |
+ TRACE_EVENT0("cc", "RenderWidgetHostViewMac::OnSendBeginFrame"); |
+ |
+ cc::BeginFrameArgs adjusted_args(args); |
+ |
+ delegated_frame_host_->UpdateVSyncParameters(adjusted_args); |
+ |
+ // TODO(brianderson): Use adaptive draw-time estimation. |
+ base::TimeDelta estimated_browser_composite_time = |
+ base::TimeDelta::FromMicroseconds( |
+ (1.0f * base::Time::kMicrosecondsPerSecond) / (3.0f * 60)); |
+ |
+ adjusted_args.deadline -= estimated_browser_composite_time; |
+ |
+ render_widget_host_->Send(new ViewMsg_BeginFrame( |
+ render_widget_host_->GetRoutingID(), |
+ adjusted_args)); |
+ last_begin_frame_args_ = args; |
+} |
+ |
+void RenderWidgetHostViewMac::OnVSync(base::TimeTicks timebase, |
+ base::TimeDelta interval) { |
+ DCHECK(begin_frame_scheduling_is_enabled_); |
+ |
+ GetCompositor()->begin_frame_manager()->StartBeginFrame( |
+ cc::BeginFrameArgs::Create(timebase, |
+ timebase + interval, |
+ interval)); |
+} |
+ |
} // namespace content |
// RenderWidgetHostViewCocoa --------------------------------------------------- |