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 1ae110cfaf49c4e269e8c10c3efd00159d101958..7525c53acd79febf73756cfbe4afe4dd68e8493a 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" |
@@ -530,7 +531,11 @@ RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget) |
is_loading_(false), |
allow_pause_for_resize_or_repaint_(true), |
weak_factory_(this), |
- fullscreen_parent_host_view_(NULL) { |
+ fullscreen_parent_host_view_(NULL), |
+ needs_begin_frame_(false), |
+ software_frame_weak_ptr_factory_(this) { |
+ software_frame_manager_.reset( |
+ new SoftwareFrameManager(software_frame_weak_ptr_factory_.GetWeakPtr())); |
// |cocoa_view_| owns us and we will be deleted when |cocoa_view_| |
// goes away. Since we autorelease it, our caller must put |
// |GetNativeView()| into the view hierarchy right after calling us. |
@@ -556,6 +561,10 @@ RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget) |
} |
RenderWidgetHostViewMac::~RenderWidgetHostViewMac() { |
+ if (display_link_) { |
+ 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 |
@@ -596,6 +605,9 @@ void RenderWidgetHostViewMac::EnsureBrowserCompositorView() { |
browser_compositor_view_.reset(new BrowserCompositorViewMac(this)); |
delegated_frame_host_->AddedToWindow(); |
delegated_frame_host_->WasShown(ui::LatencyInfo()); |
+ |
+ if (needs_begin_frame_) |
+ GetCompositor()->AddBeginFrameObserver(this, last_begin_frame_args_); |
} |
void RenderWidgetHostViewMac::DestroyBrowserCompositorView() { |
@@ -609,6 +621,11 @@ void RenderWidgetHostViewMac::DestroyBrowserCompositorView() { |
delegated_frame_host_->WasHidden(); |
delegated_frame_host_->RemovingFromWindow(); |
browser_compositor_view_.reset(); |
+ |
+ if (needs_begin_frame_) { |
+ GetCompositor()->RemoveBeginFrameObserver(this); |
+ needs_begin_frame_ = false; |
+ } |
} |
bool RenderWidgetHostViewMac::OnMessageReceived(const IPC::Message& message) { |
@@ -618,6 +635,7 @@ bool RenderWidgetHostViewMac::OnMessageReceived(const IPC::Message& message) { |
IPC_MESSAGE_HANDLER(ViewHostMsg_StartPluginIme, OnStartPluginIme) |
IPC_MESSAGE_HANDLER(ViewMsg_GetRenderedTextCompleted, |
OnGetRenderedTextCompleted) |
+ IPC_MESSAGE_HANDLER(ViewHostMsg_SetNeedsBeginFrame, OnSetNeedsBeginFrame) |
IPC_MESSAGE_UNHANDLED(handled = false) |
IPC_END_MESSAGE_MAP() |
return handled; |
@@ -743,20 +761,29 @@ void RenderWidgetHostViewMac::UpdateDisplayLink() { |
// Note that on some headless systems, the display link will fail to be |
// created, so this should not be a fatal error. |
LOG(ERROR) << "Failed to create display link."; |
+ return; |
} |
+ |
+ display_link_->AddObserver(this); |
} |
-void RenderWidgetHostViewMac::SendVSyncParametersToRenderer() { |
- if (!render_widget_host_ || !display_link_) |
- return; |
+void RenderWidgetHostViewMac::OnSetNeedsBeginFrame(bool enabled) { |
+ DCHECK(display_link_); |
- if (!display_link_->GetVSyncParameters(&vsync_timebase_, &vsync_interval_)) { |
- vsync_timebase_ = base::TimeTicks(); |
- vsync_interval_ = base::TimeDelta(); |
+ if (needs_begin_frame_ == enabled) |
return; |
- } |
- render_widget_host_->UpdateVSyncParameters(vsync_timebase_, vsync_interval_); |
+ TRACE_EVENT1("cc", |
+ "RenderWidgetHostViewMac::OnSetNeedsBeginFrame", |
+ "enabled", |
+ enabled); |
+ |
+ needs_begin_frame_ = enabled; |
+ |
+ if (enabled) |
+ GetCompositor()->AddBeginFrameObserver(this, last_begin_frame_args_); |
+ else |
+ DCHECK(!GetCompsoitr()); |
} |
void RenderWidgetHostViewMac::SpeakText(const std::string& text) { |
@@ -1410,8 +1437,6 @@ void RenderWidgetHostViewMac::OnSwapCompositorFrame( |
scale_factor, pixel_size); |
} |
- SendVSyncParametersToRenderer(); |
- |
delegated_frame_host_->SwapDelegatedFrame( |
output_surface_id, |
frame->delegated_frame_data.Pass(), |
@@ -1657,6 +1682,31 @@ void RenderWidgetHostViewMac::OnDisplayMetricsChanged( |
UpdateScreenInfo(cocoa_view_); |
} |
+void RenderWidgetHostViewMac::OnSendBeginFrame(const cc::BeginFrameArgs& args) { |
+ DCHECK(display_link_); |
+ DCHECK(render_widget_host_); |
+ TRACE_EVENT0("cc", "RenderWidgetHostViewMac::OnSendBeginFrame"); |
+ |
+ delegated_frame_host_->UpdateVSyncParameters(args); |
+ |
+ render_widget_host_->Send( |
+ new ViewMsg_BeginFrame(render_widget_host_->GetRoutingID(), args)); |
+ last_begin_frame_args_ = args; |
+ vsync_timebase_ = args.frame_time; |
+ vsync_interval_ = args.interval; |
+} |
+ |
+void RenderWidgetHostViewMac::OnVSync(base::TimeTicks timebase, |
+ base::TimeDelta interval) { |
+ DCHECK(display_link_); |
+ |
+ if (!GetCompositor()) |
+ return; |
+ |
+ GetCompositor()->StartBeginFrame( |
+ cc::BeginFrameArgs::Create(timebase, timebase + interval, interval)); |
+} |
+ |
} // namespace content |
// RenderWidgetHostViewCocoa --------------------------------------------------- |