summaryrefslogtreecommitdiffstats
path: root/cc
diff options
context:
space:
mode:
authorskyostil@chromium.org <skyostil@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-26 22:28:45 +0000
committerskyostil@chromium.org <skyostil@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-26 22:28:45 +0000
commit7ed4751b7860f7248ae7042465d3051867632c56 (patch)
tree4d2fc3b6525453b48461ceeae0611e21c4759648 /cc
parent5b409ba35802ce8eba4b3056c5787cf73f81c745 (diff)
downloadchromium_src-7ed4751b7860f7248ae7042465d3051867632c56.zip
chromium_src-7ed4751b7860f7248ae7042465d3051867632c56.tar.gz
chromium_src-7ed4751b7860f7248ae7042465d3051867632c56.tar.bz2
cc: Hook vsync time source to output surface
Let the output surface generate a vsync signal for the vsync time source. This will be used to drive rendering based on a vsync notification from the browser process. BUG=149227 TEST=LayerTreeHostTestVSyncNotification Review URL: https://chromiumcodereview.appspot.com/12674030 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@190780 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r--cc/output/output_surface.h5
-rw-r--r--cc/output/output_surface_client.h1
-rw-r--r--cc/scheduler/vsync_time_source.cc2
-rw-r--r--cc/scheduler/vsync_time_source.h2
-rw-r--r--cc/scheduler/vsync_time_source_unittest.cc2
-rw-r--r--cc/test/fake_layer_tree_host_impl_client.h1
-rw-r--r--cc/test/fake_output_surface.cc13
-rw-r--r--cc/test/fake_output_surface.h8
-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
15 files changed, 133 insertions, 8 deletions
diff --git a/cc/output/output_surface.h b/cc/output/output_surface.h
index ce425ed..bb473e2 100644
--- a/cc/output/output_surface.h
+++ b/cc/output/output_surface.h
@@ -91,6 +91,11 @@ class CC_EXPORT OutputSurface {
// processing should be stopped, or lowered in priority.
virtual void UpdateSmoothnessTakesPriority(bool prefer_smoothness) {}
+ // Requests a vsync notification from the output surface. The notification
+ // will be delivered by calling OutputSurfaceClient::DidVSync for all future
+ // vsync events until the callback is disabled.
+ virtual void EnableVSyncNotification(bool enable_vsync) {}
+
protected:
OutputSurfaceClient* client_;
struct cc::OutputSurface::Capabilities capabilities_;
diff --git a/cc/output/output_surface_client.h b/cc/output/output_surface_client.h
index b8d0ad7..1ba5a43 100644
--- a/cc/output/output_surface_client.h
+++ b/cc/output/output_surface_client.h
@@ -16,6 +16,7 @@ class CC_EXPORT OutputSurfaceClient {
public:
virtual void OnVSyncParametersChanged(base::TimeTicks timebase,
base::TimeDelta interval) = 0;
+ virtual void DidVSync(base::TimeTicks frame_time) = 0;
virtual void OnSendFrameToParentCompositorAck(const CompositorFrameAck&) = 0;
protected:
diff --git a/cc/scheduler/vsync_time_source.cc b/cc/scheduler/vsync_time_source.cc
index 5f2992e..1483478 100644
--- a/cc/scheduler/vsync_time_source.cc
+++ b/cc/scheduler/vsync_time_source.cc
@@ -6,7 +6,7 @@
namespace cc {
-scoped_refptr<VSyncTimeSource> VSyncTimeSource::create(
+scoped_refptr<VSyncTimeSource> VSyncTimeSource::Create(
VSyncProvider* vsync_provider) {
return make_scoped_refptr(new VSyncTimeSource(vsync_provider));
}
diff --git a/cc/scheduler/vsync_time_source.h b/cc/scheduler/vsync_time_source.h
index e62e0fb..910168f 100644
--- a/cc/scheduler/vsync_time_source.h
+++ b/cc/scheduler/vsync_time_source.h
@@ -33,7 +33,7 @@ class VSyncProvider {
// external vsync signal.
class CC_EXPORT VSyncTimeSource : public TimeSource, public VSyncClient {
public:
- static scoped_refptr<VSyncTimeSource> create(VSyncProvider* vsync_provider);
+ static scoped_refptr<VSyncTimeSource> Create(VSyncProvider* vsync_provider);
// TimeSource implementation
virtual void SetClient(TimeSourceClient* client) OVERRIDE;
diff --git a/cc/scheduler/vsync_time_source_unittest.cc b/cc/scheduler/vsync_time_source_unittest.cc
index 334dde7..d652017 100644
--- a/cc/scheduler/vsync_time_source_unittest.cc
+++ b/cc/scheduler/vsync_time_source_unittest.cc
@@ -32,7 +32,7 @@ class FakeVSyncProvider : public VSyncProvider {
class VSyncTimeSourceTest : public testing::Test {
public:
- VSyncTimeSourceTest() : timer_(VSyncTimeSource::create(&provider_)) {
+ VSyncTimeSourceTest() : timer_(VSyncTimeSource::Create(&provider_)) {
timer_->SetClient(&client_);
}
diff --git a/cc/test/fake_layer_tree_host_impl_client.h b/cc/test/fake_layer_tree_host_impl_client.h
index 4ed6442..61555bb 100644
--- a/cc/test/fake_layer_tree_host_impl_client.h
+++ b/cc/test/fake_layer_tree_host_impl_client.h
@@ -17,6 +17,7 @@ class FakeLayerTreeHostImplClient : public LayerTreeHostImplClient {
virtual void OnVSyncParametersChanged(
base::TimeTicks,
base::TimeDelta) 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 {}
diff --git a/cc/test/fake_output_surface.cc b/cc/test/fake_output_surface.cc
index 0b9a6d3..6369f61 100644
--- a/cc/test/fake_output_surface.cc
+++ b/cc/test/fake_output_surface.cc
@@ -4,12 +4,15 @@
#include "cc/test/fake_output_surface.h"
+#include "cc/output/output_surface_client.h"
+
namespace cc {
FakeOutputSurface::FakeOutputSurface(
scoped_ptr<WebKit::WebGraphicsContext3D> context3d, bool has_parent)
: OutputSurface(context3d.Pass()),
- num_sent_frames_(0) {
+ num_sent_frames_(0),
+ vsync_notification_enabled_(false) {
capabilities_.has_parent_compositor = has_parent;
}
@@ -37,4 +40,12 @@ void FakeOutputSurface::SendFrameToParentCompositor(
++num_sent_frames_;
}
+void FakeOutputSurface::EnableVSyncNotification(bool enable) {
+ vsync_notification_enabled_ = enable;
+}
+
+void FakeOutputSurface::DidVSync(base::TimeTicks frame_time) {
+ client_->DidVSync(frame_time);
+}
+
} // namespace cc
diff --git a/cc/test/fake_output_surface.h b/cc/test/fake_output_surface.h
index 8a2217b..e23f8cb 100644
--- a/cc/test/fake_output_surface.h
+++ b/cc/test/fake_output_surface.h
@@ -5,6 +5,7 @@
#ifndef CC_TEST_FAKE_OUTPUT_SURFACE_H_
#define CC_TEST_FAKE_OUTPUT_SURFACE_H_
+#include "base/time.h"
#include "cc/output/compositor_frame.h"
#include "cc/output/output_surface.h"
#include "cc/output/software_output_device.h"
@@ -61,6 +62,12 @@ class FakeOutputSurface : public OutputSurface {
CompositorFrame& last_sent_frame() { return last_sent_frame_; }
size_t num_sent_frames() { return num_sent_frames_; }
+ virtual void EnableVSyncNotification(bool enable) OVERRIDE;
+ bool vsync_notification_enabled() const {
+ return vsync_notification_enabled_;
+ }
+ void DidVSync(base::TimeTicks frame_time);
+
private:
FakeOutputSurface(
scoped_ptr<WebKit::WebGraphicsContext3D> context3d,
@@ -72,6 +79,7 @@ class FakeOutputSurface : public OutputSurface {
CompositorFrame last_sent_frame_;
size_t num_sent_frames_;
+ bool vsync_notification_enabled_;
};
static inline scoped_ptr<cc::OutputSurface> CreateFakeOutputSurface() {
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_;