summaryrefslogtreecommitdiffstats
path: root/cc/trees
diff options
context:
space:
mode:
Diffstat (limited to 'cc/trees')
-rw-r--r--cc/trees/layer_tree_host_impl.cc9
-rw-r--r--cc/trees/layer_tree_host_impl.h3
-rw-r--r--cc/trees/layer_tree_host_impl_unittest.cc1
-rw-r--r--cc/trees/layer_tree_host_unittest.cc51
-rw-r--r--cc/trees/single_thread_proxy.h1
-rw-r--r--cc/trees/thread_proxy.cc32
-rw-r--r--cc/trees/thread_proxy.h10
7 files changed, 103 insertions, 4 deletions
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index a6f15db..3332839 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -915,6 +915,10 @@ void LayerTreeHostImpl::OnVSyncParametersChanged(base::TimeTicks timebase,
client_->OnVSyncParametersChanged(timebase, interval);
}
+void LayerTreeHostImpl::DidVSync(base::TimeTicks frame_time) {
+ client_->DidVSync(frame_time);
+}
+
void LayerTreeHostImpl::OnSendFrameToParentCompositorAck(
const CompositorFrameAck& ack) {
if (!renderer_)
@@ -1039,6 +1043,11 @@ bool LayerTreeHostImpl::SwapBuffers() {
return renderer_->SwapBuffers();
}
+void LayerTreeHostImpl::EnableVSyncNotification(bool enable) {
+ if (output_surface_)
+ output_surface_->EnableVSyncNotification(enable);
+}
+
gfx::Size LayerTreeHostImpl::DeviceViewportSize() const {
return device_viewport_size();
}
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h
index 6ef2f64..3025832 100644
--- a/cc/trees/layer_tree_host_impl.h
+++ b/cc/trees/layer_tree_host_impl.h
@@ -51,6 +51,7 @@ class LayerTreeHostImplClient {
virtual void OnSwapBuffersCompleteOnImplThread() = 0;
virtual void OnVSyncParametersChanged(base::TimeTicks timebase,
base::TimeDelta interval) = 0;
+ virtual void DidVSync(base::TimeTicks frame_time) = 0;
virtual void OnCanDrawStateChanged(bool can_draw) = 0;
virtual void OnHasPendingTreeStateChanged(bool has_pending_tree) = 0;
virtual void SetNeedsRedrawOnImplThread() = 0;
@@ -182,6 +183,7 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandlerClient,
// OutputSurfaceClient implementation.
virtual void OnVSyncParametersChanged(base::TimeTicks timebase,
base::TimeDelta interval) OVERRIDE;
+ virtual void DidVSync(base::TimeTicks frame_time) OVERRIDE;
virtual void OnSendFrameToParentCompositorAck(const CompositorFrameAck& ack)
OVERRIDE;
@@ -205,6 +207,7 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandlerClient,
const RendererCapabilities& GetRendererCapabilities() const;
virtual bool SwapBuffers();
+ void EnableVSyncNotification(bool enable);
void Readback(void* pixels, gfx::Rect rect_in_device_viewport);
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index e47e311..aeca5de 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -91,6 +91,7 @@ class LayerTreeHostImplTest : public testing::Test,
virtual void OnSwapBuffersCompleteOnImplThread() OVERRIDE {}
virtual void OnVSyncParametersChanged(base::TimeTicks timebase,
base::TimeDelta interval) OVERRIDE {}
+ virtual void DidVSync(base::TimeTicks frame_time) OVERRIDE {}
virtual void OnCanDrawStateChanged(bool can_draw) OVERRIDE {
on_can_draw_state_changed_called_ = true;
}
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc
index 4f7d2d6..eeddab3 100644
--- a/cc/trees/layer_tree_host_unittest.cc
+++ b/cc/trees/layer_tree_host_unittest.cc
@@ -2164,5 +2164,56 @@ class LayerTreeHostTestLCDNotification : public LayerTreeHostTest {
SINGLE_THREAD_TEST_F(LayerTreeHostTestLCDNotification);
+// Verify that the vsync notification is used to initiate rendering.
+class LayerTreeHostTestVSyncNotification : public LayerTreeHostTest {
+ public:
+ virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
+ settings->render_vsync_notification_enabled = true;
+ }
+
+ virtual void BeginTest() OVERRIDE {
+ PostSetNeedsCommitToMainThread();
+ }
+
+ virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
+ FakeOutputSurface* fake_output_surface =
+ reinterpret_cast<FakeOutputSurface*>(host_impl->output_surface());
+
+ // The vsync notification is turned off now but will get enabled once we
+ // return, so post a task to trigger it.
+ ASSERT_FALSE(fake_output_surface->vsync_notification_enabled());
+ PostVSyncOnImplThread(fake_output_surface);
+ }
+
+ void PostVSyncOnImplThread(FakeOutputSurface* fake_output_surface) {
+ DCHECK(ImplThread());
+ ImplThread()->PostTask(
+ base::Bind(&LayerTreeHostTestVSyncNotification::DidVSync,
+ base::Unretained(this),
+ base::Unretained(fake_output_surface)));
+ }
+
+ void DidVSync(FakeOutputSurface* fake_output_surface) {
+ ASSERT_TRUE(fake_output_surface->vsync_notification_enabled());
+ fake_output_surface->DidVSync(frame_time_);
+ }
+
+ virtual bool PrepareToDrawOnThread(
+ LayerTreeHostImpl* host_impl,
+ LayerTreeHostImpl::FrameData* frame,
+ bool result) OVERRIDE {
+ EndTest();
+ return true;
+ }
+
+ virtual void AfterTest() OVERRIDE {
+ }
+
+ private:
+ base::TimeTicks frame_time_;
+};
+
+MULTI_THREAD_TEST_F(LayerTreeHostTestVSyncNotification);
+
} // namespace
} // namespace cc
diff --git a/cc/trees/single_thread_proxy.h b/cc/trees/single_thread_proxy.h
index ea6b549..2322d76 100644
--- a/cc/trees/single_thread_proxy.h
+++ b/cc/trees/single_thread_proxy.h
@@ -56,6 +56,7 @@ class SingleThreadProxy : public Proxy, LayerTreeHostImplClient {
virtual void OnSwapBuffersCompleteOnImplThread() OVERRIDE;
virtual void OnVSyncParametersChanged(base::TimeTicks timebase,
base::TimeDelta interval) OVERRIDE {}
+ virtual void DidVSync(base::TimeTicks frame_time) OVERRIDE {}
virtual void OnCanDrawStateChanged(bool can_draw) OVERRIDE {}
virtual void OnHasPendingTreeStateChanged(bool have_pending_tree) OVERRIDE;
virtual void SetNeedsRedrawOnImplThread() OVERRIDE;
diff --git a/cc/trees/thread_proxy.cc b/cc/trees/thread_proxy.cc
index c49527d..8c7d9de 100644
--- a/cc/trees/thread_proxy.cc
+++ b/cc/trees/thread_proxy.cc
@@ -16,6 +16,7 @@
#include "cc/scheduler/delay_based_time_source.h"
#include "cc/scheduler/frame_rate_controller.h"
#include "cc/scheduler/scheduler.h"
+#include "cc/scheduler/vsync_time_source.h"
#include "cc/trees/layer_tree_host.h"
#include "cc/trees/layer_tree_impl.h"
@@ -59,6 +60,9 @@ ThreadProxy::ThreadProxy(LayerTreeHost* layer_tree_host,
texture_acquisition_completion_event_on_impl_thread_(NULL),
next_frame_is_newly_committed_frame_on_impl_thread_(false),
render_vsync_enabled_(layer_tree_host->settings().render_vsync_enabled),
+ render_vsync_notification_enabled_(
+ layer_tree_host->settings().render_vsync_notification_enabled),
+ vsync_client_(NULL),
inside_draw_(false),
defer_commits_(false),
renew_tree_priority_on_impl_thread_pending_(false) {
@@ -350,6 +354,21 @@ void ThreadProxy::OnVSyncParametersChanged(base::TimeTicks timebase,
scheduler_on_impl_thread_->SetTimebaseAndInterval(timebase, interval);
}
+void ThreadProxy::DidVSync(base::TimeTicks frame_time) {
+ DCHECK(IsImplThread());
+ TRACE_EVENT0("cc", "ThreadProxy::DidVSync");
+ if (vsync_client_)
+ vsync_client_->DidVSync(frame_time);
+}
+
+void ThreadProxy::RequestVSyncNotification(VSyncClient* client) {
+ DCHECK(IsImplThread());
+ TRACE_EVENT1(
+ "cc", "ThreadProxy::RequestVSyncNotification", "enable", !!client);
+ vsync_client_ = client;
+ layer_tree_host_impl_->EnableVSyncNotification(client);
+}
+
void ThreadProxy::OnCanDrawStateChanged(bool can_draw) {
DCHECK(IsImplThread());
TRACE_EVENT1(
@@ -1067,9 +1086,14 @@ void ThreadProxy::InitializeImplOnImplThread(CompletionEvent* completion,
60);
scoped_ptr<FrameRateController> frame_rate_controller;
if (render_vsync_enabled_) {
- frame_rate_controller.reset(
- new FrameRateController(DelayBasedTimeSource::Create(
- display_refresh_interval, Proxy::ImplThread())));
+ if (render_vsync_notification_enabled_) {
+ frame_rate_controller.reset(
+ new FrameRateController(VSyncTimeSource::Create(this)));
+ } else {
+ frame_rate_controller.reset(
+ new FrameRateController(DelayBasedTimeSource::Create(
+ display_refresh_interval, Proxy::ImplThread())));
+ }
} else {
frame_rate_controller.reset(new FrameRateController(Proxy::ImplThread()));
}
@@ -1128,10 +1152,12 @@ void ThreadProxy::LayerTreeHostClosedOnImplThread(CompletionEvent* completion) {
DCHECK(IsImplThread());
layer_tree_host_->DeleteContentsTexturesOnImplThread(
layer_tree_host_impl_->resource_provider());
+ layer_tree_host_impl_->EnableVSyncNotification(false);
input_handler_on_impl_thread_.reset();
layer_tree_host_impl_.reset();
scheduler_on_impl_thread_.reset();
weak_factory_on_impl_thread_.InvalidateWeakPtrs();
+ vsync_client_ = NULL;
completion->Signal();
}
diff --git a/cc/trees/thread_proxy.h b/cc/trees/thread_proxy.h
index 67084a6..73193aa 100644
--- a/cc/trees/thread_proxy.h
+++ b/cc/trees/thread_proxy.h
@@ -12,6 +12,7 @@
#include "cc/base/completion_event.h"
#include "cc/resources/resource_update_controller.h"
#include "cc/scheduler/scheduler.h"
+#include "cc/scheduler/vsync_time_source.h"
#include "cc/trees/layer_tree_host_impl.h"
#include "cc/trees/proxy.h"
@@ -28,7 +29,8 @@ class Thread;
class ThreadProxy : public Proxy,
LayerTreeHostImplClient,
SchedulerClient,
- ResourceUpdateControllerClient {
+ ResourceUpdateControllerClient,
+ VSyncProvider {
public:
static scoped_ptr<Proxy> Create(LayerTreeHost* layer_tree_host,
scoped_ptr<Thread> impl_thread);
@@ -69,6 +71,7 @@ class ThreadProxy : public Proxy,
virtual void OnSwapBuffersCompleteOnImplThread() OVERRIDE;
virtual void OnVSyncParametersChanged(base::TimeTicks timebase,
base::TimeDelta interval) OVERRIDE;
+ virtual void DidVSync(base::TimeTicks frame_time) OVERRIDE;
virtual void OnCanDrawStateChanged(bool can_draw) OVERRIDE;
virtual void OnHasPendingTreeStateChanged(bool has_pending_tree) OVERRIDE;
virtual void SetNeedsRedrawOnImplThread() OVERRIDE;
@@ -104,6 +107,9 @@ class ThreadProxy : public Proxy,
// ResourceUpdateControllerClient implementation
virtual void ReadyToFinalizeTextureUpdates() OVERRIDE;
+ // VSyncProvider implementation
+ virtual void RequestVSyncNotification(VSyncClient* client) OVERRIDE;
+
int MaxFramesPendingForTesting() const {
return scheduler_on_impl_thread_->MaxFramesPending();
}
@@ -248,6 +254,8 @@ class ThreadProxy : public Proxy,
bool next_frame_is_newly_committed_frame_on_impl_thread_;
bool render_vsync_enabled_;
+ bool render_vsync_notification_enabled_;
+ VSyncClient* vsync_client_;
bool inside_draw_;