summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbrianderson@chromium.org <brianderson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-12 01:07:15 +0000
committerbrianderson@chromium.org <brianderson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-12 01:07:15 +0000
commit97e9ccd6a43b365d11972c81aeb3faa0c3aa3503 (patch)
tree37185307ead88a0267b40c4379a64d7db1da5cb8
parentb4c49028da217cbf78d1876e69cbf7af07aa385d (diff)
downloadchromium_src-97e9ccd6a43b365d11972c81aeb3faa0c3aa3503.zip
chromium_src-97e9ccd6a43b365d11972c81aeb3faa0c3aa3503.tar.gz
chromium_src-97e9ccd6a43b365d11972c81aeb3faa0c3aa3503.tar.bz2
cc: Handle retroactive BeginFrames in the Scheduler.
This will be the first step allowing us to pull logic out of the OutputSurface. Initially, the retroactive logic will exist in both the OutputSurface and the scheduler. Then, as all logic that depends on the retroactive logic has moved to the scheduler, I will remove the retroactive logic in OutputSurface. There are now 4 BeginFrames in the scheduler: 1) BeginFrame: from the OutputSurface. 2) BeginRetroFrame: a deferred BeginFrame. 3) BeginImplFrame: starts a compositor frame. 4) BeginMainFrame: starts a main frame. BUG=358409 Review URL: https://codereview.chromium.org/218633010 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@263435 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--cc/output/output_surface.cc103
-rw-r--r--cc/output/output_surface.h39
-rw-r--r--cc/output/output_surface_client.h2
-rw-r--r--cc/output/output_surface_unittest.cc193
-rw-r--r--cc/scheduler/scheduler.cc204
-rw-r--r--cc/scheduler/scheduler.h21
-rw-r--r--cc/scheduler/scheduler_state_machine.cc54
-rw-r--r--cc/scheduler/scheduler_state_machine.h10
-rw-r--r--cc/scheduler/scheduler_state_machine_unittest.cc42
-rw-r--r--cc/scheduler/scheduler_unittest.cc281
-rw-r--r--cc/test/fake_layer_tree_host_impl_client.h3
-rw-r--r--cc/test/fake_output_surface.cc21
-rw-r--r--cc/test/fake_output_surface.h10
-rw-r--r--cc/test/fake_output_surface_client.cc4
-rw-r--r--cc/test/fake_output_surface_client.h10
-rw-r--r--cc/test/layer_tree_test.cc7
-rw-r--r--cc/test/layer_tree_test.h2
-rw-r--r--cc/trees/layer_tree_host_impl.cc18
-rw-r--r--cc/trees/layer_tree_host_impl.h7
-rw-r--r--cc/trees/layer_tree_host_impl_unittest.cc2
-rw-r--r--cc/trees/layer_tree_host_unittest.cc26
-rw-r--r--cc/trees/single_thread_proxy.h3
-rw-r--r--cc/trees/thread_proxy.cc22
-rw-r--r--cc/trees/thread_proxy.h5
-rw-r--r--content/browser/android/in_process/synchronous_compositor_output_surface.cc18
-rw-r--r--content/browser/android/in_process/synchronous_compositor_output_surface.h4
-rw-r--r--content/public/common/content_switches.cc2
-rw-r--r--content/renderer/gpu/compositor_output_surface.cc14
-rw-r--r--content/renderer/gpu/compositor_output_surface.h4
29 files changed, 645 insertions, 486 deletions
diff --git a/cc/output/output_surface.cc b/cc/output/output_surface.cc
index 9c52bcb..3aaa1a1 100644
--- a/cc/output/output_surface.cc
+++ b/cc/output/output_surface.cc
@@ -48,10 +48,10 @@ OutputSurface::OutputSurface(scoped_refptr<ContextProvider> context_provider)
device_scale_factor_(-1),
max_frames_pending_(0),
pending_swap_buffers_(0),
- needs_begin_impl_frame_(false),
- client_ready_for_begin_impl_frame_(true),
+ needs_begin_frame_(false),
+ client_ready_for_begin_frame_(true),
client_(NULL),
- check_for_retroactive_begin_impl_frame_pending_(false),
+ check_for_retroactive_begin_frame_pending_(false),
external_stencil_test_enabled_(false),
weak_ptr_factory_(this),
gpu_latency_history_(kGpuLatencyHistorySize) {}
@@ -61,10 +61,10 @@ OutputSurface::OutputSurface(scoped_ptr<SoftwareOutputDevice> software_device)
device_scale_factor_(-1),
max_frames_pending_(0),
pending_swap_buffers_(0),
- needs_begin_impl_frame_(false),
- client_ready_for_begin_impl_frame_(true),
+ needs_begin_frame_(false),
+ client_ready_for_begin_frame_(true),
client_(NULL),
- check_for_retroactive_begin_impl_frame_pending_(false),
+ check_for_retroactive_begin_frame_pending_(false),
external_stencil_test_enabled_(false),
weak_ptr_factory_(this),
gpu_latency_history_(kGpuLatencyHistorySize) {}
@@ -76,15 +76,15 @@ OutputSurface::OutputSurface(scoped_refptr<ContextProvider> context_provider,
device_scale_factor_(-1),
max_frames_pending_(0),
pending_swap_buffers_(0),
- needs_begin_impl_frame_(false),
- client_ready_for_begin_impl_frame_(true),
+ needs_begin_frame_(false),
+ client_ready_for_begin_frame_(true),
client_(NULL),
- check_for_retroactive_begin_impl_frame_pending_(false),
+ check_for_retroactive_begin_frame_pending_(false),
external_stencil_test_enabled_(false),
weak_ptr_factory_(this),
gpu_latency_history_(kGpuLatencyHistorySize) {}
-void OutputSurface::InitializeBeginImplFrameEmulation(
+void OutputSurface::InitializeBeginFrameEmulation(
base::SingleThreadTaskRunner* task_runner,
bool throttle_frame_production,
base::TimeDelta interval) {
@@ -133,9 +133,9 @@ void OutputSurface::FrameRateControllerTick(bool throttled,
const BeginFrameArgs& args) {
DCHECK(frame_rate_controller_);
if (throttled)
- skipped_begin_impl_frame_args_ = args;
+ skipped_begin_frame_args_ = args;
else
- BeginImplFrame(args);
+ BeginFrame(args);
}
// Forwarded to OutputSurfaceClient
@@ -144,64 +144,65 @@ void OutputSurface::SetNeedsRedrawRect(const gfx::Rect& damage_rect) {
client_->SetNeedsRedrawRect(damage_rect);
}
-void OutputSurface::SetNeedsBeginImplFrame(bool enable) {
- TRACE_EVENT1("cc", "OutputSurface::SetNeedsBeginImplFrame", "enable", enable);
- needs_begin_impl_frame_ = enable;
- client_ready_for_begin_impl_frame_ = true;
+void OutputSurface::SetNeedsBeginFrame(bool enable) {
+ TRACE_EVENT1("cc", "OutputSurface::SetNeedsBeginFrame", "enable", enable);
+ needs_begin_frame_ = enable;
+ client_ready_for_begin_frame_ = true;
if (frame_rate_controller_) {
BeginFrameArgs skipped = frame_rate_controller_->SetActive(enable);
if (skipped.IsValid())
- skipped_begin_impl_frame_args_ = skipped;
+ skipped_begin_frame_args_ = skipped;
}
- if (needs_begin_impl_frame_)
- PostCheckForRetroactiveBeginImplFrame();
+ if (needs_begin_frame_)
+ PostCheckForRetroactiveBeginFrame();
}
-void OutputSurface::BeginImplFrame(const BeginFrameArgs& args) {
- TRACE_EVENT2("cc", "OutputSurface::BeginImplFrame",
- "client_ready_for_begin_impl_frame_",
- client_ready_for_begin_impl_frame_,
- "pending_swap_buffers_", pending_swap_buffers_);
- if (!needs_begin_impl_frame_ || !client_ready_for_begin_impl_frame_ ||
+void OutputSurface::BeginFrame(const BeginFrameArgs& args) {
+ TRACE_EVENT2("cc",
+ "OutputSurface::BeginFrame",
+ "client_ready_for_begin_frame_",
+ client_ready_for_begin_frame_,
+ "pending_swap_buffers_",
+ pending_swap_buffers_);
+ if (!needs_begin_frame_ || !client_ready_for_begin_frame_ ||
(pending_swap_buffers_ >= max_frames_pending_ &&
max_frames_pending_ > 0)) {
- skipped_begin_impl_frame_args_ = args;
+ skipped_begin_frame_args_ = args;
} else {
- client_ready_for_begin_impl_frame_ = false;
- client_->BeginImplFrame(args);
- // args might be an alias for skipped_begin_impl_frame_args_.
- // Do not reset it before calling BeginImplFrame!
- skipped_begin_impl_frame_args_ = BeginFrameArgs();
+ client_ready_for_begin_frame_ = false;
+ client_->BeginFrame(args);
+ // args might be an alias for skipped_begin_frame_args_.
+ // Do not reset it before calling BeginFrame!
+ skipped_begin_frame_args_ = BeginFrameArgs();
}
}
-base::TimeTicks OutputSurface::RetroactiveBeginImplFrameDeadline() {
+base::TimeTicks OutputSurface::RetroactiveBeginFrameDeadline() {
// TODO(brianderson): Remove the alternative deadline once we have better
// deadline estimations.
base::TimeTicks alternative_deadline =
- skipped_begin_impl_frame_args_.frame_time +
+ skipped_begin_frame_args_.frame_time +
BeginFrameArgs::DefaultRetroactiveBeginFramePeriod();
- return std::max(skipped_begin_impl_frame_args_.deadline,
- alternative_deadline);
+ return std::max(skipped_begin_frame_args_.deadline, alternative_deadline);
}
-void OutputSurface::PostCheckForRetroactiveBeginImplFrame() {
- if (!skipped_begin_impl_frame_args_.IsValid() ||
- check_for_retroactive_begin_impl_frame_pending_)
+void OutputSurface::PostCheckForRetroactiveBeginFrame() {
+ if (!skipped_begin_frame_args_.IsValid() ||
+ check_for_retroactive_begin_frame_pending_)
return;
base::MessageLoop::current()->PostTask(
- FROM_HERE,
- base::Bind(&OutputSurface::CheckForRetroactiveBeginImplFrame,
- weak_ptr_factory_.GetWeakPtr()));
- check_for_retroactive_begin_impl_frame_pending_ = true;
+ FROM_HERE,
+ base::Bind(&OutputSurface::CheckForRetroactiveBeginFrame,
+ weak_ptr_factory_.GetWeakPtr()));
+ check_for_retroactive_begin_frame_pending_ = true;
}
-void OutputSurface::CheckForRetroactiveBeginImplFrame() {
- TRACE_EVENT0("cc", "OutputSurface::CheckForRetroactiveBeginImplFrame");
- check_for_retroactive_begin_impl_frame_pending_ = false;
- if (gfx::FrameTime::Now() < RetroactiveBeginImplFrameDeadline())
- BeginImplFrame(skipped_begin_impl_frame_args_);
+void OutputSurface::CheckForRetroactiveBeginFrame() {
+ TRACE_EVENT0("cc", "OutputSurface::CheckForRetroactiveBeginFrame");
+ check_for_retroactive_begin_frame_pending_ = false;
+ if (gfx::FrameTime::Now() < RetroactiveBeginFrameDeadline())
+ BeginFrame(skipped_begin_frame_args_);
}
void OutputSurface::DidSwapBuffers() {
@@ -211,7 +212,7 @@ void OutputSurface::DidSwapBuffers() {
client_->DidSwapBuffers();
if (frame_rate_controller_)
frame_rate_controller_->DidSwapBuffers();
- PostCheckForRetroactiveBeginImplFrame();
+ PostCheckForRetroactiveBeginFrame();
}
void OutputSurface::OnSwapBuffersComplete() {
@@ -221,7 +222,7 @@ void OutputSurface::OnSwapBuffersComplete() {
client_->OnSwapBuffersComplete();
if (frame_rate_controller_)
frame_rate_controller_->DidSwapBuffersComplete();
- PostCheckForRetroactiveBeginImplFrame();
+ PostCheckForRetroactiveBeginFrame();
}
void OutputSurface::ReclaimResources(const CompositorFrameAck* ack) {
@@ -230,9 +231,9 @@ void OutputSurface::ReclaimResources(const CompositorFrameAck* ack) {
void OutputSurface::DidLoseOutputSurface() {
TRACE_EVENT0("cc", "OutputSurface::DidLoseOutputSurface");
- client_ready_for_begin_impl_frame_ = true;
+ client_ready_for_begin_frame_ = true;
pending_swap_buffers_ = 0;
- skipped_begin_impl_frame_args_ = BeginFrameArgs();
+ skipped_begin_frame_args_ = BeginFrameArgs();
if (frame_rate_controller_)
frame_rate_controller_->SetActive(false);
pending_gpu_latency_query_ids_.clear();
diff --git a/cc/output/output_surface.h b/cc/output/output_surface.h
index 5bec9d1..a5d4d7b 100644
--- a/cc/output/output_surface.h
+++ b/cc/output/output_surface.h
@@ -69,7 +69,7 @@ class CC_EXPORT OutputSurface : public FrameRateControllerClient {
int max_frames_pending;
bool deferred_gl_initialization;
bool draw_and_swap_full_viewport_every_frame;
- // This doesn't handle the <webview> case, but once BeginImplFrame is
+ // This doesn't handle the <webview> case, but once BeginFrame is
// supported natively, we shouldn't need adjust_deadline_for_parent.
bool adjust_deadline_for_parent;
// Whether this output surface renders to the default OpenGL zero
@@ -105,10 +105,9 @@ class CC_EXPORT OutputSurface : public FrameRateControllerClient {
// thread.
virtual bool BindToClient(OutputSurfaceClient* client);
- void InitializeBeginImplFrameEmulation(
- base::SingleThreadTaskRunner* task_runner,
- bool throttle_frame_production,
- base::TimeDelta interval);
+ void InitializeBeginFrameEmulation(base::SingleThreadTaskRunner* task_runner,
+ bool throttle_frame_production,
+ base::TimeDelta interval);
void SetMaxFramesPending(int max_frames_pending);
@@ -129,10 +128,10 @@ class CC_EXPORT OutputSurface : public FrameRateControllerClient {
// processing should be stopped, or lowered in priority.
virtual void UpdateSmoothnessTakesPriority(bool prefer_smoothness) {}
- // Requests a BeginImplFrame notification from the output surface. The
+ // Requests a BeginFrame notification from the output surface. The
// notification will be delivered by calling
- // OutputSurfaceClient::BeginImplFrame until the callback is disabled.
- virtual void SetNeedsBeginImplFrame(bool enable);
+ // OutputSurfaceClient::BeginFrame until the callback is disabled.
+ virtual void SetNeedsBeginFrame(bool enable);
bool HasClient() { return !!client_; }
@@ -165,7 +164,7 @@ class CC_EXPORT OutputSurface : public FrameRateControllerClient {
float device_scale_factor_;
// The FrameRateController is deprecated.
- // Platforms should move to native BeginImplFrames instead.
+ // Platforms should move to native BeginFrames instead.
void CommitVSyncParameters(base::TimeTicks timebase,
base::TimeDelta interval);
virtual void FrameRateControllerTick(bool throttled,
@@ -173,17 +172,17 @@ class CC_EXPORT OutputSurface : public FrameRateControllerClient {
scoped_ptr<FrameRateController> frame_rate_controller_;
int max_frames_pending_;
int pending_swap_buffers_;
- bool needs_begin_impl_frame_;
- bool client_ready_for_begin_impl_frame_;
+ bool needs_begin_frame_;
+ bool client_ready_for_begin_frame_;
- // This stores a BeginImplFrame that we couldn't process immediately,
+ // This stores a BeginFrame that we couldn't process immediately,
// but might process retroactively in the near future.
- BeginFrameArgs skipped_begin_impl_frame_args_;
+ BeginFrameArgs skipped_begin_frame_args_;
// Forwarded to OutputSurfaceClient but threaded through OutputSurface
// first so OutputSurface has a chance to update the FrameRateController
void SetNeedsRedrawRect(const gfx::Rect& damage_rect);
- void BeginImplFrame(const BeginFrameArgs& args);
+ void BeginFrame(const BeginFrameArgs& args);
void DidSwapBuffers();
void OnSwapBuffersComplete();
void ReclaimResources(const CompositorFrameAck* ack);
@@ -195,9 +194,9 @@ class CC_EXPORT OutputSurface : public FrameRateControllerClient {
bool valid_for_tile_management);
// virtual for testing.
- virtual base::TimeTicks RetroactiveBeginImplFrameDeadline();
- virtual void PostCheckForRetroactiveBeginImplFrame();
- void CheckForRetroactiveBeginImplFrame();
+ virtual base::TimeTicks RetroactiveBeginFrameDeadline();
+ virtual void PostCheckForRetroactiveBeginFrame();
+ void CheckForRetroactiveBeginFrame();
private:
OutputSurfaceClient* client_;
@@ -207,9 +206,9 @@ class CC_EXPORT OutputSurface : public FrameRateControllerClient {
void SetMemoryPolicy(const ManagedMemoryPolicy& policy);
void UpdateAndMeasureGpuLatency();
- // check_for_retroactive_begin_impl_frame_pending_ is used to avoid posting
- // redundant checks for a retroactive BeginImplFrame.
- bool check_for_retroactive_begin_impl_frame_pending_;
+ // check_for_retroactive_begin_frame_pending_ is used to avoid posting
+ // redundant checks for a retroactive BeginFrame.
+ bool check_for_retroactive_begin_frame_pending_;
bool external_stencil_test_enabled_;
diff --git a/cc/output/output_surface_client.h b/cc/output/output_surface_client.h
index 7e509a8..08d9b62 100644
--- a/cc/output/output_surface_client.h
+++ b/cc/output/output_surface_client.h
@@ -31,7 +31,7 @@ class CC_EXPORT OutputSurfaceClient {
scoped_refptr<ContextProvider> offscreen_context_provider) = 0;
virtual void ReleaseGL() = 0;
virtual void SetNeedsRedrawRect(const gfx::Rect& damage_rect) = 0;
- virtual void BeginImplFrame(const BeginFrameArgs& args) = 0;
+ virtual void BeginFrame(const BeginFrameArgs& args) = 0;
virtual void DidSwapBuffers() = 0;
virtual void OnSwapBuffersComplete() = 0;
virtual void ReclaimResources(const CompositorFrameAck* ack) = 0;
diff --git a/cc/output/output_surface_unittest.cc b/cc/output/output_surface_unittest.cc
index b0220fb..d40feb1 100644
--- a/cc/output/output_surface_unittest.cc
+++ b/cc/output/output_surface_unittest.cc
@@ -24,18 +24,18 @@ class TestOutputSurface : public OutputSurface {
public:
explicit TestOutputSurface(scoped_refptr<ContextProvider> context_provider)
: OutputSurface(context_provider),
- retroactive_begin_impl_frame_deadline_enabled_(false),
+ retroactive_begin_frame_deadline_enabled_(false),
override_retroactive_period_(false) {}
explicit TestOutputSurface(scoped_ptr<SoftwareOutputDevice> software_device)
: OutputSurface(software_device.Pass()),
- retroactive_begin_impl_frame_deadline_enabled_(false),
+ retroactive_begin_frame_deadline_enabled_(false),
override_retroactive_period_(false) {}
TestOutputSurface(scoped_refptr<ContextProvider> context_provider,
scoped_ptr<SoftwareOutputDevice> software_device)
: OutputSurface(context_provider, software_device.Pass()),
- retroactive_begin_impl_frame_deadline_enabled_(false),
+ retroactive_begin_frame_deadline_enabled_(false),
override_retroactive_period_(false) {}
bool InitializeNewContext3d(
@@ -51,8 +51,8 @@ class TestOutputSurface : public OutputSurface {
CommitVSyncParameters(timebase, interval);
}
- void BeginImplFrameForTesting() {
- OutputSurface::BeginImplFrame(BeginFrameArgs::CreateExpiredForTesting());
+ void BeginFrameForTesting() {
+ OutputSurface::BeginFrame(BeginFrameArgs::CreateExpiredForTesting());
}
void DidSwapBuffersForTesting() {
@@ -67,34 +67,33 @@ class TestOutputSurface : public OutputSurface {
OnSwapBuffersComplete();
}
- void EnableRetroactiveBeginImplFrameDeadline(
- bool enable,
- bool override_retroactive_period,
- base::TimeDelta period_override) {
- retroactive_begin_impl_frame_deadline_enabled_ = enable;
+ void EnableRetroactiveBeginFrameDeadline(bool enable,
+ bool override_retroactive_period,
+ base::TimeDelta period_override) {
+ retroactive_begin_frame_deadline_enabled_ = enable;
override_retroactive_period_ = override_retroactive_period;
retroactive_period_override_ = period_override;
}
protected:
- virtual void PostCheckForRetroactiveBeginImplFrame() OVERRIDE {
+ virtual void PostCheckForRetroactiveBeginFrame() OVERRIDE {
// For testing purposes, we check immediately rather than posting a task.
- CheckForRetroactiveBeginImplFrame();
+ CheckForRetroactiveBeginFrame();
}
- virtual base::TimeTicks RetroactiveBeginImplFrameDeadline() OVERRIDE {
- if (retroactive_begin_impl_frame_deadline_enabled_) {
+ virtual base::TimeTicks RetroactiveBeginFrameDeadline() OVERRIDE {
+ if (retroactive_begin_frame_deadline_enabled_) {
if (override_retroactive_period_) {
- return skipped_begin_impl_frame_args_.frame_time +
+ return skipped_begin_frame_args_.frame_time +
retroactive_period_override_;
} else {
- return OutputSurface::RetroactiveBeginImplFrameDeadline();
+ return OutputSurface::RetroactiveBeginFrameDeadline();
}
}
return base::TimeTicks();
}
- bool retroactive_begin_impl_frame_deadline_enabled_;
+ bool retroactive_begin_frame_deadline_enabled_;
bool override_retroactive_period_;
base::TimeDelta retroactive_period_override_;
};
@@ -221,7 +220,7 @@ TEST_F(OutputSurfaceTestInitializeNewContext3d, ClientDeferredInitializeFails) {
InitializeNewContextExpectFail();
}
-TEST(OutputSurfaceTest, BeginImplFrameEmulation) {
+TEST(OutputSurfaceTest, BeginFrameEmulation) {
TestOutputSurface output_surface(TestContextProvider::Create());
EXPECT_FALSE(output_surface.HasClient());
@@ -230,86 +229,84 @@ TEST(OutputSurfaceTest, BeginImplFrameEmulation) {
EXPECT_TRUE(output_surface.HasClient());
EXPECT_FALSE(client.deferred_initialize_called());
- // Initialize BeginImplFrame emulation
+ // Initialize BeginFrame emulation
scoped_refptr<base::TestSimpleTaskRunner> task_runner =
new base::TestSimpleTaskRunner;
bool throttle_frame_production = true;
const base::TimeDelta display_refresh_interval =
BeginFrameArgs::DefaultInterval();
- output_surface.InitializeBeginImplFrameEmulation(
- task_runner.get(),
- throttle_frame_production,
- display_refresh_interval);
+ output_surface.InitializeBeginFrameEmulation(
+ task_runner.get(), throttle_frame_production, display_refresh_interval);
output_surface.SetMaxFramesPending(2);
- output_surface.EnableRetroactiveBeginImplFrameDeadline(
+ output_surface.EnableRetroactiveBeginFrameDeadline(
false, false, base::TimeDelta());
- // We should start off with 0 BeginImplFrames
- EXPECT_EQ(client.begin_impl_frame_count(), 0);
+ // We should start off with 0 BeginFrames
+ EXPECT_EQ(client.begin_frame_count(), 0);
EXPECT_EQ(output_surface.pending_swap_buffers(), 0);
- // We should not have a pending task until a BeginImplFrame has been
+ // We should not have a pending task until a BeginFrame has been
// requested.
EXPECT_FALSE(task_runner->HasPendingTask());
- output_surface.SetNeedsBeginImplFrame(true);
+ output_surface.SetNeedsBeginFrame(true);
EXPECT_TRUE(task_runner->HasPendingTask());
- // BeginImplFrame should be called on the first tick.
+ // BeginFrame should be called on the first tick.
task_runner->RunPendingTasks();
- EXPECT_EQ(client.begin_impl_frame_count(), 1);
+ EXPECT_EQ(client.begin_frame_count(), 1);
EXPECT_EQ(output_surface.pending_swap_buffers(), 0);
- // BeginImplFrame should not be called when there is a pending BeginImplFrame.
+ // BeginFrame should not be called when there is a pending BeginFrame.
task_runner->RunPendingTasks();
- EXPECT_EQ(client.begin_impl_frame_count(), 1);
+ EXPECT_EQ(client.begin_frame_count(), 1);
EXPECT_EQ(output_surface.pending_swap_buffers(), 0);
- // SetNeedsBeginImplFrame should clear the pending BeginImplFrame after
+ // SetNeedsBeginFrame should clear the pending BeginFrame after
// a SwapBuffers.
output_surface.DidSwapBuffersForTesting();
- output_surface.SetNeedsBeginImplFrame(true);
- EXPECT_EQ(client.begin_impl_frame_count(), 1);
+ output_surface.SetNeedsBeginFrame(true);
+ EXPECT_EQ(client.begin_frame_count(), 1);
EXPECT_EQ(output_surface.pending_swap_buffers(), 1);
task_runner->RunPendingTasks();
- EXPECT_EQ(client.begin_impl_frame_count(), 2);
+ EXPECT_EQ(client.begin_frame_count(), 2);
EXPECT_EQ(output_surface.pending_swap_buffers(), 1);
- // BeginImplFrame should be throttled by pending swap buffers.
+ // BeginFrame should be throttled by pending swap buffers.
output_surface.DidSwapBuffersForTesting();
- output_surface.SetNeedsBeginImplFrame(true);
- EXPECT_EQ(client.begin_impl_frame_count(), 2);
+ output_surface.SetNeedsBeginFrame(true);
+ EXPECT_EQ(client.begin_frame_count(), 2);
EXPECT_EQ(output_surface.pending_swap_buffers(), 2);
task_runner->RunPendingTasks();
- EXPECT_EQ(client.begin_impl_frame_count(), 2);
+ EXPECT_EQ(client.begin_frame_count(), 2);
EXPECT_EQ(output_surface.pending_swap_buffers(), 2);
- // SwapAck should decrement pending swap buffers and unblock BeginImplFrame
+ // SwapAck should decrement pending swap buffers and unblock BeginFrame
// again.
output_surface.OnSwapBuffersCompleteForTesting();
- EXPECT_EQ(client.begin_impl_frame_count(), 2);
+ EXPECT_EQ(client.begin_frame_count(), 2);
EXPECT_EQ(output_surface.pending_swap_buffers(), 1);
task_runner->RunPendingTasks();
- EXPECT_EQ(client.begin_impl_frame_count(), 3);
+ EXPECT_EQ(client.begin_frame_count(), 3);
EXPECT_EQ(output_surface.pending_swap_buffers(), 1);
- // Calling SetNeedsBeginImplFrame again indicates a swap did not occur but
- // the client still wants another BeginImplFrame.
- output_surface.SetNeedsBeginImplFrame(true);
+ // Calling SetNeedsBeginFrame again indicates a swap did not occur but
+ // the client still wants another BeginFrame.
+ output_surface.SetNeedsBeginFrame(true);
task_runner->RunPendingTasks();
- EXPECT_EQ(client.begin_impl_frame_count(), 4);
+ EXPECT_EQ(client.begin_frame_count(), 4);
EXPECT_EQ(output_surface.pending_swap_buffers(), 1);
- // Disabling SetNeedsBeginImplFrame should prevent further BeginImplFrames.
- output_surface.SetNeedsBeginImplFrame(false);
+ // Disabling SetNeedsBeginFrame should prevent further BeginFrames.
+ output_surface.SetNeedsBeginFrame(false);
task_runner->RunPendingTasks();
EXPECT_FALSE(task_runner->HasPendingTask());
- EXPECT_EQ(client.begin_impl_frame_count(), 4);
+ EXPECT_EQ(client.begin_frame_count(), 4);
EXPECT_EQ(output_surface.pending_swap_buffers(), 1);
}
-TEST(OutputSurfaceTest, OptimisticAndRetroactiveBeginImplFrames) {
+TEST(OutputSurfaceTest, OptimisticAndRetroactiveBeginFrames) {
TestOutputSurface output_surface(TestContextProvider::Create());
EXPECT_FALSE(output_surface.HasClient());
@@ -319,48 +316,47 @@ TEST(OutputSurfaceTest, OptimisticAndRetroactiveBeginImplFrames) {
EXPECT_FALSE(client.deferred_initialize_called());
output_surface.SetMaxFramesPending(2);
- output_surface.EnableRetroactiveBeginImplFrameDeadline(
+ output_surface.EnableRetroactiveBeginFrameDeadline(
true, false, base::TimeDelta());
- // Optimistically injected BeginImplFrames should be throttled if
- // SetNeedsBeginImplFrame is false...
- output_surface.SetNeedsBeginImplFrame(false);
- output_surface.BeginImplFrameForTesting();
- EXPECT_EQ(client.begin_impl_frame_count(), 0);
- // ...and retroactively triggered by a SetNeedsBeginImplFrame.
- output_surface.SetNeedsBeginImplFrame(true);
- EXPECT_EQ(client.begin_impl_frame_count(), 1);
-
- // Optimistically injected BeginImplFrames should be throttled by pending
- // BeginImplFrames...
- output_surface.BeginImplFrameForTesting();
- EXPECT_EQ(client.begin_impl_frame_count(), 1);
- // ...and retroactively triggered by a SetNeedsBeginImplFrame.
- output_surface.SetNeedsBeginImplFrame(true);
- EXPECT_EQ(client.begin_impl_frame_count(), 2);
+ // Optimistically injected BeginFrames should be throttled if
+ // SetNeedsBeginFrame is false...
+ output_surface.SetNeedsBeginFrame(false);
+ output_surface.BeginFrameForTesting();
+ EXPECT_EQ(client.begin_frame_count(), 0);
+ // ...and retroactively triggered by a SetNeedsBeginFrame.
+ output_surface.SetNeedsBeginFrame(true);
+ EXPECT_EQ(client.begin_frame_count(), 1);
+
+ // Optimistically injected BeginFrames should be throttled by pending
+ // BeginFrames...
+ output_surface.BeginFrameForTesting();
+ EXPECT_EQ(client.begin_frame_count(), 1);
+ // ...and retroactively triggered by a SetNeedsBeginFrame.
+ output_surface.SetNeedsBeginFrame(true);
+ EXPECT_EQ(client.begin_frame_count(), 2);
// ...or retroactively triggered by a Swap.
- output_surface.BeginImplFrameForTesting();
- EXPECT_EQ(client.begin_impl_frame_count(), 2);
+ output_surface.BeginFrameForTesting();
+ EXPECT_EQ(client.begin_frame_count(), 2);
output_surface.DidSwapBuffersForTesting();
- output_surface.SetNeedsBeginImplFrame(true);
- EXPECT_EQ(client.begin_impl_frame_count(), 3);
+ output_surface.SetNeedsBeginFrame(true);
+ EXPECT_EQ(client.begin_frame_count(), 3);
EXPECT_EQ(output_surface.pending_swap_buffers(), 1);
- // Optimistically injected BeginImplFrames should be by throttled by pending
+ // Optimistically injected BeginFrames should be by throttled by pending
// swap buffers...
output_surface.DidSwapBuffersForTesting();
- output_surface.SetNeedsBeginImplFrame(true);
- EXPECT_EQ(client.begin_impl_frame_count(), 3);
+ output_surface.SetNeedsBeginFrame(true);
+ EXPECT_EQ(client.begin_frame_count(), 3);
EXPECT_EQ(output_surface.pending_swap_buffers(), 2);
- output_surface.BeginImplFrameForTesting();
- EXPECT_EQ(client.begin_impl_frame_count(), 3);
+ output_surface.BeginFrameForTesting();
+ EXPECT_EQ(client.begin_frame_count(), 3);
// ...and retroactively triggered by OnSwapBuffersComplete
output_surface.OnSwapBuffersCompleteForTesting();
- EXPECT_EQ(client.begin_impl_frame_count(), 4);
+ EXPECT_EQ(client.begin_frame_count(), 4);
}
-TEST(OutputSurfaceTest,
- RetroactiveBeginImplFrameDoesNotDoubleTickWhenEmulating) {
+TEST(OutputSurfaceTest, RetroactiveBeginFrameDoesNotDoubleTickWhenEmulating) {
scoped_refptr<TestContextProvider> context_provider =
TestContextProvider::Create();
@@ -374,16 +370,14 @@ TEST(OutputSurfaceTest,
base::TimeDelta big_interval = base::TimeDelta::FromSeconds(10);
- // Initialize BeginImplFrame emulation
+ // Initialize BeginFrame emulation
scoped_refptr<base::TestSimpleTaskRunner> task_runner =
new base::TestSimpleTaskRunner;
bool throttle_frame_production = true;
const base::TimeDelta display_refresh_interval = big_interval;
- output_surface.InitializeBeginImplFrameEmulation(
- task_runner.get(),
- throttle_frame_production,
- display_refresh_interval);
+ output_surface.InitializeBeginFrameEmulation(
+ task_runner.get(), throttle_frame_production, display_refresh_interval);
// We need to subtract an epsilon from Now() because some platforms have
// a slow clock.
@@ -391,31 +385,30 @@ TEST(OutputSurfaceTest,
gfx::FrameTime::Now() - base::TimeDelta::FromSeconds(1), big_interval);
output_surface.SetMaxFramesPending(2);
- output_surface.EnableRetroactiveBeginImplFrameDeadline(
- true, true, big_interval);
+ output_surface.EnableRetroactiveBeginFrameDeadline(true, true, big_interval);
- // We should start off with 0 BeginImplFrames
- EXPECT_EQ(client.begin_impl_frame_count(), 0);
+ // We should start off with 0 BeginFrames
+ EXPECT_EQ(client.begin_frame_count(), 0);
EXPECT_EQ(output_surface.pending_swap_buffers(), 0);
- // The first SetNeedsBeginImplFrame(true) should start a retroactive
- // BeginImplFrame.
+ // The first SetNeedsBeginFrame(true) should start a retroactive
+ // BeginFrame.
EXPECT_FALSE(task_runner->HasPendingTask());
- output_surface.SetNeedsBeginImplFrame(true);
+ output_surface.SetNeedsBeginFrame(true);
EXPECT_TRUE(task_runner->HasPendingTask());
EXPECT_GT(task_runner->NextPendingTaskDelay(), big_interval / 2);
- EXPECT_EQ(client.begin_impl_frame_count(), 1);
+ EXPECT_EQ(client.begin_frame_count(), 1);
- output_surface.SetNeedsBeginImplFrame(false);
+ output_surface.SetNeedsBeginFrame(false);
EXPECT_TRUE(task_runner->HasPendingTask());
- EXPECT_EQ(client.begin_impl_frame_count(), 1);
+ EXPECT_EQ(client.begin_frame_count(), 1);
- // The second SetNeedBeginImplFrame(true) should not retroactively start a
- // BeginImplFrame if the timestamp would be the same as the previous
- // BeginImplFrame.
- output_surface.SetNeedsBeginImplFrame(true);
+ // The second SetNeedBeginFrame(true) should not retroactively start a
+ // BeginFrame if the timestamp would be the same as the previous
+ // BeginFrame.
+ output_surface.SetNeedsBeginFrame(true);
EXPECT_TRUE(task_runner->HasPendingTask());
- EXPECT_EQ(client.begin_impl_frame_count(), 1);
+ EXPECT_EQ(client.begin_frame_count(), 1);
}
TEST(OutputSurfaceTest, MemoryAllocation) {
diff --git a/cc/scheduler/scheduler.cc b/cc/scheduler/scheduler.cc
index 20f1ede..5d70010 100644
--- a/cc/scheduler/scheduler.cc
+++ b/cc/scheduler/scheduler.cc
@@ -23,17 +23,20 @@ Scheduler::Scheduler(
client_(client),
layer_tree_host_id_(layer_tree_host_id),
impl_task_runner_(impl_task_runner),
- last_set_needs_begin_impl_frame_(false),
+ last_set_needs_begin_frame_(false),
+ begin_retro_frame_posted_(false),
state_machine_(scheduler_settings),
inside_process_scheduled_actions_(false),
inside_action_(SchedulerStateMachine::ACTION_NONE),
weak_factory_(this) {
DCHECK(client_);
- DCHECK(!state_machine_.BeginImplFrameNeeded());
+ DCHECK(!state_machine_.BeginFrameNeeded());
if (settings_.main_frame_before_activation_enabled) {
DCHECK(settings_.main_frame_before_draw_enabled);
}
+ begin_retro_frame_closure_ =
+ base::Bind(&Scheduler::BeginRetroFrame, weak_factory_.GetWeakPtr());
begin_impl_frame_deadline_closure_ = base::Bind(
&Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr());
poll_for_draw_triggers_closure_ = base::Bind(
@@ -118,13 +121,14 @@ void Scheduler::DidManageTiles() {
void Scheduler::DidLoseOutputSurface() {
TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface");
state_machine_.DidLoseOutputSurface();
- last_set_needs_begin_impl_frame_ = false;
+ last_set_needs_begin_frame_ = false;
+ begin_retro_frame_args_.clear();
ProcessScheduledActions();
}
void Scheduler::DidCreateAndInitializeOutputSurface() {
TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface");
- DCHECK(!last_set_needs_begin_impl_frame_);
+ DCHECK(!last_set_needs_begin_frame_);
DCHECK(begin_impl_frame_deadline_task_.IsCancelled());
state_machine_.DidCreateAndInitializeOutputSurface();
ProcessScheduledActions();
@@ -136,53 +140,54 @@ void Scheduler::NotifyBeginMainFrameStarted() {
}
base::TimeTicks Scheduler::AnticipatedDrawTime() const {
- if (!last_set_needs_begin_impl_frame_ ||
- last_begin_impl_frame_args_.interval <= base::TimeDelta())
+ if (!last_set_needs_begin_frame_ ||
+ begin_impl_frame_args_.interval <= base::TimeDelta())
return base::TimeTicks();
base::TimeTicks now = gfx::FrameTime::Now();
- base::TimeTicks timebase = std::max(last_begin_impl_frame_args_.frame_time,
- last_begin_impl_frame_args_.deadline);
- int64 intervals =
- 1 + ((now - timebase) / last_begin_impl_frame_args_.interval);
- return timebase + (last_begin_impl_frame_args_.interval * intervals);
+ base::TimeTicks timebase = std::max(begin_impl_frame_args_.frame_time,
+ begin_impl_frame_args_.deadline);
+ int64 intervals = 1 + ((now - timebase) / begin_impl_frame_args_.interval);
+ return timebase + (begin_impl_frame_args_.interval * intervals);
}
base::TimeTicks Scheduler::LastBeginImplFrameTime() {
- return last_begin_impl_frame_args_.frame_time;
+ return begin_impl_frame_args_.frame_time;
}
-void Scheduler::SetupNextBeginImplFrameIfNeeded() {
- bool needs_begin_impl_frame =
- state_machine_.BeginImplFrameNeeded();
+void Scheduler::SetupNextBeginFrameIfNeeded() {
+ bool needs_begin_frame = state_machine_.BeginFrameNeeded();
bool at_end_of_deadline =
state_machine_.begin_impl_frame_state() ==
SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE;
- bool should_call_set_needs_begin_impl_frame =
- // Always request the BeginImplFrame immediately if it wasn't needed
- // before.
- (needs_begin_impl_frame && !last_set_needs_begin_impl_frame_) ||
- // We always need to explicitly request our next BeginImplFrame.
+ bool should_call_set_needs_begin_frame =
+ // Always request the BeginFrame immediately if it wasn't needed before.
+ (needs_begin_frame && !last_set_needs_begin_frame_) ||
+ // We always need to explicitly request our next BeginFrame.
at_end_of_deadline;
- if (should_call_set_needs_begin_impl_frame) {
- client_->SetNeedsBeginImplFrame(needs_begin_impl_frame);
- last_set_needs_begin_impl_frame_ = needs_begin_impl_frame;
+ if (should_call_set_needs_begin_frame) {
+ client_->SetNeedsBeginFrame(needs_begin_frame);
+ last_set_needs_begin_frame_ = needs_begin_frame;
}
+ // Handle retroactive BeginFrames.
+ if (last_set_needs_begin_frame_)
+ PostBeginRetroFrameIfNeeded();
+
bool needs_advance_commit_state_timer = false;
// Setup PollForAnticipatedDrawTriggers if we need to monitor state but
- // aren't expecting any more BeginImplFrames. This should only be needed by
- // the synchronous compositor when BeginImplFrameNeeded is false.
+ // aren't expecting any more BeginFrames. This should only be needed by
+ // the synchronous compositor when BeginFrameNeeded is false.
if (state_machine_.ShouldPollForAnticipatedDrawTriggers()) {
- DCHECK(!state_machine_.SupportsProactiveBeginImplFrame());
- DCHECK(!needs_begin_impl_frame);
+ DCHECK(!state_machine_.SupportsProactiveBeginFrame());
+ DCHECK(!needs_begin_frame);
if (poll_for_draw_triggers_task_.IsCancelled()) {
poll_for_draw_triggers_task_.Reset(poll_for_draw_triggers_closure_);
- base::TimeDelta delay = last_begin_impl_frame_args_.IsValid()
- ? last_begin_impl_frame_args_.interval
+ base::TimeDelta delay = begin_impl_frame_args_.IsValid()
+ ? begin_impl_frame_args_.interval
: BeginFrameArgs::DefaultInterval();
impl_task_runner_->PostDelayedTask(
FROM_HERE, poll_for_draw_triggers_task_.callback(), delay);
@@ -192,10 +197,10 @@ void Scheduler::SetupNextBeginImplFrameIfNeeded() {
// At this point we'd prefer to advance through the commit flow by
// drawing a frame, however it's possible that the frame rate controller
- // will not give us a BeginImplFrame until the commit completes. See
+ // will not give us a BeginFrame until the commit completes. See
// crbug.com/317430 for an example of a swap ack being held on commit. Thus
// we set a repeating timer to poll on ProcessScheduledActions until we
- // successfully reach BeginImplFrame. Synchronous compositor does not use
+ // successfully reach BeginFrame. Synchronous compositor does not use
// frame rate controller or have the circular wait in the bug.
if (IsBeginMainFrameSentOrStarted() &&
!settings_.using_synchronous_renderer_compositor) {
@@ -205,20 +210,102 @@ void Scheduler::SetupNextBeginImplFrameIfNeeded() {
if (needs_advance_commit_state_timer) {
if (advance_commit_state_task_.IsCancelled() &&
- last_begin_impl_frame_args_.IsValid()) {
+ begin_impl_frame_args_.IsValid()) {
// Since we'd rather get a BeginImplFrame by the normal mechanism, we
// set the interval to twice the interval from the previous frame.
advance_commit_state_task_.Reset(advance_commit_state_closure_);
- impl_task_runner_->PostDelayedTask(
- FROM_HERE,
- advance_commit_state_task_.callback(),
- last_begin_impl_frame_args_.interval * 2);
+ impl_task_runner_->PostDelayedTask(FROM_HERE,
+ advance_commit_state_task_.callback(),
+ begin_impl_frame_args_.interval * 2);
}
} else {
advance_commit_state_task_.Cancel();
}
}
+// BeginFrame is the mechanism that tells us that now is a good time to start
+// making a frame. Usually this means that user input for the frame is complete.
+// If the scheduler is busy, we queue the BeginFrame to be handled later as
+// a BeginRetroFrame.
+void Scheduler::BeginFrame(const BeginFrameArgs& args) {
+ bool should_defer_begin_frame;
+ if (settings_.using_synchronous_renderer_compositor) {
+ should_defer_begin_frame = false;
+ } else {
+ should_defer_begin_frame =
+ !begin_retro_frame_args_.empty() || begin_retro_frame_posted_ ||
+ !last_set_needs_begin_frame_ ||
+ (state_machine_.begin_impl_frame_state() !=
+ SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
+ }
+
+ if (should_defer_begin_frame) {
+ begin_retro_frame_args_.push_back(args);
+ TRACE_EVENT_INSTANT0(
+ "cc", "Scheduler::BeginFrame deferred", TRACE_EVENT_SCOPE_THREAD);
+ return;
+ }
+
+ BeginImplFrame(args);
+}
+
+// BeginRetroFrame is called for BeginFrames that we've deferred because
+// the scheduler was in the middle of processing a previous BeginFrame.
+void Scheduler::BeginRetroFrame() {
+ TRACE_EVENT0("cc", "Scheduler::BeginRetroFrame");
+ DCHECK(begin_retro_frame_posted_);
+ DCHECK(!begin_retro_frame_args_.empty());
+ DCHECK(!settings_.using_synchronous_renderer_compositor);
+
+ // Discard expired BeginRetroFrames
+ // Today, we should always end up with at most one un-expired BeginRetroFrame
+ // because deadlines will not be greater than the next frame time. We don't
+ // DCHECK though because some systems don't always have monotonic timestamps.
+ // TODO(brianderson): In the future, long deadlines could result in us not
+ // draining the queue if we don't catch up. If we consistently can't catch
+ // up, our fallback should be to lower our frame rate.
+ base::TimeTicks now = gfx::FrameTime::Now();
+ base::TimeDelta draw_duration_estimate = client_->DrawDurationEstimate();
+ while (!begin_retro_frame_args_.empty() &&
+ now > AdjustedBeginImplFrameDeadline(begin_retro_frame_args_.front(),
+ draw_duration_estimate)) {
+ begin_retro_frame_args_.pop_front();
+ }
+
+ if (begin_retro_frame_args_.empty()) {
+ TRACE_EVENT_INSTANT0(
+ "cc", "Scheduler::BeginRetroFrames expired", TRACE_EVENT_SCOPE_THREAD);
+ } else {
+ BeginImplFrame(begin_retro_frame_args_.front());
+ begin_retro_frame_args_.pop_front();
+ }
+
+ begin_retro_frame_posted_ = false;
+}
+
+// There could be a race between the posted BeginRetroFrame and a new
+// BeginFrame arriving via the normal mechanism. Scheduler::BeginFrame
+// will check if there is a pending BeginRetroFrame to ensure we handle
+// BeginFrames in FIFO order.
+void Scheduler::PostBeginRetroFrameIfNeeded() {
+ if (begin_retro_frame_args_.empty() || begin_retro_frame_posted_)
+ return;
+
+ // begin_retro_frame_args_ should always be empty for the
+ // synchronous compositor.
+ DCHECK(!settings_.using_synchronous_renderer_compositor);
+
+ if (state_machine_.begin_impl_frame_state() !=
+ SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE)
+ return;
+
+ begin_retro_frame_posted_ = true;
+ impl_task_runner_->PostTask(FROM_HERE, begin_retro_frame_closure_);
+}
+
+// BeginImplFrame starts a compositor frame that will wait up until a deadline
+// for a BeginMainFrame+activation to complete before it times out and draws
+// any asynchronous animation and scroll/pinch updates.
void Scheduler::BeginImplFrame(const BeginFrameArgs& args) {
TRACE_EVENT0("cc", "Scheduler::BeginImplFrame");
DCHECK(state_machine_.begin_impl_frame_state() ==
@@ -227,8 +314,9 @@ void Scheduler::BeginImplFrame(const BeginFrameArgs& args) {
advance_commit_state_task_.Cancel();
- last_begin_impl_frame_args_ = args;
- last_begin_impl_frame_args_.deadline -= client_->DrawDurationEstimate();
+ base::TimeDelta draw_duration_estimate = client_->DrawDurationEstimate();
+ begin_impl_frame_args_ = args;
+ begin_impl_frame_args_.deadline -= draw_duration_estimate;
if (!state_machine_.smoothness_takes_priority() &&
state_machine_.MainThreadIsInHighLatencyMode() &&
@@ -236,7 +324,8 @@ void Scheduler::BeginImplFrame(const BeginFrameArgs& args) {
state_machine_.SetSkipNextBeginMainFrameToReduceLatency();
}
- state_machine_.OnBeginImplFrame(last_begin_impl_frame_args_);
+ client_->WillBeginImplFrame(begin_impl_frame_args_);
+ state_machine_.OnBeginImplFrame(begin_impl_frame_args_);
devtools_instrumentation::DidBeginFrame(layer_tree_host_id_);
ProcessScheduledActions();
@@ -245,11 +334,13 @@ void Scheduler::BeginImplFrame(const BeginFrameArgs& args) {
return;
state_machine_.OnBeginImplFrameDeadlinePending();
- base::TimeTicks adjusted_deadline = AdjustedBeginImplFrameDeadline();
- ScheduleBeginImplFrameDeadline(adjusted_deadline);
+ ScheduleBeginImplFrameDeadline(
+ AdjustedBeginImplFrameDeadline(args, draw_duration_estimate));
}
-base::TimeTicks Scheduler::AdjustedBeginImplFrameDeadline() const {
+base::TimeTicks Scheduler::AdjustedBeginImplFrameDeadline(
+ const BeginFrameArgs& args,
+ base::TimeDelta draw_duration_estimate) const {
if (settings_.using_synchronous_renderer_compositor) {
// The synchronous compositor needs to draw right away.
return base::TimeTicks();
@@ -259,7 +350,7 @@ base::TimeTicks Scheduler::AdjustedBeginImplFrameDeadline() const {
} else if (state_machine_.needs_redraw()) {
// We have an animation or fast input path on the impl thread that wants
// to draw, so don't wait too long for a new active tree.
- return last_begin_impl_frame_args_.deadline;
+ return args.deadline - draw_duration_estimate;
} else {
// The impl thread doesn't have anything it wants to draw and we are just
// waiting for a new active tree, so post the deadline for the next
@@ -268,8 +359,7 @@ base::TimeTicks Scheduler::AdjustedBeginImplFrameDeadline() const {
// BeginImplFrame.
// TODO(brianderson): Handle long deadlines (that are past the next frame's
// frame time) properly instead of using this hack.
- return last_begin_impl_frame_args_.frame_time +
- last_begin_impl_frame_args_.interval;
+ return args.frame_time + args.interval;
}
}
@@ -402,7 +492,7 @@ void Scheduler::ProcessScheduledActions() {
}
} while (action != SchedulerStateMachine::ACTION_NONE);
- SetupNextBeginImplFrameIfNeeded();
+ SetupNextBeginFrameIfNeeded();
client_->DidAnticipatedDrawTimeChange(AnticipatedDrawTime());
if (state_machine_.ShouldTriggerBeginImplFrameDeadlineEarly()) {
@@ -423,8 +513,8 @@ scoped_ptr<base::Value> Scheduler::StateAsValue() const {
scheduler_state->SetDouble(
"time_until_anticipated_draw_time_ms",
(AnticipatedDrawTime() - base::TimeTicks::Now()).InMillisecondsF());
- scheduler_state->SetBoolean("last_set_needs_begin_impl_frame_",
- last_set_needs_begin_impl_frame_);
+ scheduler_state->SetBoolean("last_set_needs_begin_frame_",
+ last_set_needs_begin_frame_);
scheduler_state->SetBoolean("begin_impl_frame_deadline_task_",
!begin_impl_frame_deadline_task_.IsCancelled());
scheduler_state->SetBoolean("poll_for_draw_triggers_task_",
@@ -450,19 +540,19 @@ bool Scheduler::CanCommitAndActivateBeforeDeadline() const {
// Check if the main thread computation and commit can be finished before the
// impl thread's deadline.
base::TimeTicks estimated_draw_time =
- last_begin_impl_frame_args_.frame_time +
+ begin_impl_frame_args_.frame_time +
client_->BeginMainFrameToCommitDurationEstimate() +
client_->CommitToActivateDurationEstimate();
- TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
- "CanCommitAndActivateBeforeDeadline",
- "time_left_after_drawing_ms",
- (last_begin_impl_frame_args_.deadline - estimated_draw_time)
- .InMillisecondsF(),
- "state",
- TracedValue::FromValue(StateAsValue().release()));
+ TRACE_EVENT2(
+ TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
+ "CanCommitAndActivateBeforeDeadline",
+ "time_left_after_drawing_ms",
+ (begin_impl_frame_args_.deadline - estimated_draw_time).InMillisecondsF(),
+ "state",
+ TracedValue::FromValue(StateAsValue().release()));
- return estimated_draw_time < last_begin_impl_frame_args_.deadline;
+ return estimated_draw_time < begin_impl_frame_args_.deadline;
}
bool Scheduler::IsBeginMainFrameSentOrStarted() const {
diff --git a/cc/scheduler/scheduler.h b/cc/scheduler/scheduler.h
index 4aa40ac..18ecb50 100644
--- a/cc/scheduler/scheduler.h
+++ b/cc/scheduler/scheduler.h
@@ -5,6 +5,7 @@
#ifndef CC_SCHEDULER_SCHEDULER_H_
#define CC_SCHEDULER_SCHEDULER_H_
+#include <deque>
#include <string>
#include "base/basictypes.h"
@@ -24,7 +25,8 @@ class Thread;
class SchedulerClient {
public:
- virtual void SetNeedsBeginImplFrame(bool enable) = 0;
+ virtual void SetNeedsBeginFrame(bool enable) = 0;
+ virtual void WillBeginImplFrame(const BeginFrameArgs& args) = 0;
virtual void ScheduledActionSendBeginMainFrame() = 0;
virtual DrawSwapReadbackResult ScheduledActionDrawAndSwapIfPossible() = 0;
virtual DrawSwapReadbackResult ScheduledActionDrawAndSwapForced() = 0;
@@ -107,6 +109,8 @@ class CC_EXPORT Scheduler {
base::TimeTicks LastBeginImplFrameTime();
+ void BeginFrame(const BeginFrameArgs& args);
+ void BeginRetroFrame();
void BeginImplFrame(const BeginFrameArgs& args);
void OnBeginImplFrameDeadline();
void PollForAnticipatedDrawTriggers();
@@ -129,9 +133,12 @@ class CC_EXPORT Scheduler {
int layer_tree_host_id,
const scoped_refptr<base::SequencedTaskRunner>& impl_task_runner);
- base::TimeTicks AdjustedBeginImplFrameDeadline() const;
+ base::TimeTicks AdjustedBeginImplFrameDeadline(
+ const BeginFrameArgs& args,
+ base::TimeDelta draw_duration_estimate) const;
void ScheduleBeginImplFrameDeadline(base::TimeTicks deadline);
- void SetupNextBeginImplFrameIfNeeded();
+ void SetupNextBeginFrameIfNeeded();
+ void PostBeginRetroFrameIfNeeded();
void ActivatePendingTree();
void DrawAndSwapIfPossible();
void DrawAndSwapForced();
@@ -148,9 +155,13 @@ class CC_EXPORT Scheduler {
int layer_tree_host_id_;
scoped_refptr<base::SequencedTaskRunner> impl_task_runner_;
- bool last_set_needs_begin_impl_frame_;
- BeginFrameArgs last_begin_impl_frame_args_;
+ bool last_set_needs_begin_frame_;
+ bool begin_retro_frame_posted_;
+ std::deque<BeginFrameArgs> begin_retro_frame_args_;
+ BeginFrameArgs begin_impl_frame_args_;
+
+ base::Closure begin_retro_frame_closure_;
base::Closure begin_impl_frame_deadline_closure_;
base::Closure poll_for_draw_triggers_closure_;
base::Closure advance_commit_state_closure_;
diff --git a/cc/scheduler/scheduler_state_machine.cc b/cc/scheduler/scheduler_state_machine.cc
index 886868d..9a08819 100644
--- a/cc/scheduler/scheduler_state_machine.cc
+++ b/cc/scheduler/scheduler_state_machine.cc
@@ -186,31 +186,27 @@ scoped_ptr<base::Value> SchedulerStateMachine::AsValue() const {
scoped_ptr<base::DictionaryValue> timestamps_state(new base::DictionaryValue);
base::TimeTicks now = gfx::FrameTime::Now();
timestamps_state->SetDouble(
- "0_interval",
- last_begin_impl_frame_args_.interval.InMicroseconds() / 1000.0L);
+ "0_interval", begin_impl_frame_args_.interval.InMicroseconds() / 1000.0L);
timestamps_state->SetDouble(
"1_now_to_deadline",
- (last_begin_impl_frame_args_.deadline - now).InMicroseconds() / 1000.0L);
+ (begin_impl_frame_args_.deadline - now).InMicroseconds() / 1000.0L);
timestamps_state->SetDouble(
"2_frame_time_to_now",
- (now - last_begin_impl_frame_args_.frame_time).InMicroseconds() /
- 1000.0L);
+ (now - begin_impl_frame_args_.frame_time).InMicroseconds() / 1000.0L);
timestamps_state->SetDouble(
"3_frame_time_to_deadline",
- (last_begin_impl_frame_args_.deadline -
- last_begin_impl_frame_args_.frame_time).InMicroseconds() /
+ (begin_impl_frame_args_.deadline - begin_impl_frame_args_.frame_time)
+ .InMicroseconds() /
1000.0L);
timestamps_state->SetDouble(
"4_now", (now - base::TimeTicks()).InMicroseconds() / 1000.0L);
timestamps_state->SetDouble(
"5_frame_time",
- (last_begin_impl_frame_args_.frame_time - base::TimeTicks())
- .InMicroseconds() /
+ (begin_impl_frame_args_.frame_time - base::TimeTicks()).InMicroseconds() /
1000.0L);
timestamps_state->SetDouble(
"6_deadline",
- (last_begin_impl_frame_args_.deadline - base::TimeTicks())
- .InMicroseconds() /
+ (begin_impl_frame_args_.deadline - base::TimeTicks()).InMicroseconds() /
1000.0L);
state->Set("major_timestamps_in_ms", timestamps_state.release());
@@ -460,7 +456,7 @@ bool SchedulerStateMachine::ShouldSendBeginMainFrame() const {
// TODO(brianderson): Allow sending BeginMainFrame while idle when the main
// thread isn't consuming user input.
if (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_IDLE &&
- BeginImplFrameNeeded())
+ BeginFrameNeeded())
return false;
// We need a new commit for the forced redraw. This honors the
@@ -767,34 +763,32 @@ void SchedulerStateMachine::SetSkipNextBeginMainFrameToReduceLatency() {
skip_next_begin_main_frame_to_reduce_latency_ = true;
}
-bool SchedulerStateMachine::BeginImplFrameNeeded() const {
- // Proactive BeginImplFrames are bad for the synchronous compositor because we
- // have to draw when we get the BeginImplFrame and could end up drawing many
+bool SchedulerStateMachine::BeginFrameNeeded() const {
+ // Proactive BeginFrames are bad for the synchronous compositor because we
+ // have to draw when we get the BeginFrame and could end up drawing many
// duplicate frames if our new frame isn't ready in time.
// To poll for state with the synchronous compositor without having to draw,
// we rely on ShouldPollForAnticipatedDrawTriggers instead.
- if (!SupportsProactiveBeginImplFrame())
- return BeginImplFrameNeededToDraw();
+ if (!SupportsProactiveBeginFrame())
+ return BeginFrameNeededToDraw();
- return BeginImplFrameNeededToDraw() ||
- ProactiveBeginImplFrameWanted();
+ return BeginFrameNeededToDraw() || ProactiveBeginFrameWanted();
}
bool SchedulerStateMachine::ShouldPollForAnticipatedDrawTriggers() const {
// ShouldPollForAnticipatedDrawTriggers is what we use in place of
- // ProactiveBeginImplFrameWanted when we are using the synchronous
+ // ProactiveBeginFrameWanted when we are using the synchronous
// compositor.
- if (!SupportsProactiveBeginImplFrame()) {
- return !BeginImplFrameNeededToDraw() &&
- ProactiveBeginImplFrameWanted();
+ if (!SupportsProactiveBeginFrame()) {
+ return !BeginFrameNeededToDraw() && ProactiveBeginFrameWanted();
}
// Non synchronous compositors should rely on
- // ProactiveBeginImplFrameWanted to poll for state instead.
+ // ProactiveBeginFrameWanted to poll for state instead.
return false;
}
-bool SchedulerStateMachine::SupportsProactiveBeginImplFrame() const {
+bool SchedulerStateMachine::SupportsProactiveBeginFrame() const {
// Both the synchronous compositor and disabled vsync settings
// make it undesirable to proactively request BeginImplFrames.
// If this is true, the scheduler should poll.
@@ -804,7 +798,7 @@ bool SchedulerStateMachine::SupportsProactiveBeginImplFrame() const {
// These are the cases where we definitely (or almost definitely) have a
// new frame to draw and can draw.
-bool SchedulerStateMachine::BeginImplFrameNeededToDraw() const {
+bool SchedulerStateMachine::BeginFrameNeededToDraw() const {
// The output surface is the provider of BeginImplFrames, so we are not going
// to get them even if we ask for them.
if (!HasInitializedOutputSurface())
@@ -835,8 +829,8 @@ bool SchedulerStateMachine::BeginImplFrameNeededToDraw() const {
// These are cases where we are very likely to draw soon, but might not
// actually have a new frame to draw when we receive the next BeginImplFrame.
// Proactively requesting the BeginImplFrame helps hide the round trip latency
-// of the SetNeedsBeginImplFrame request that has to go to the Browser.
-bool SchedulerStateMachine::ProactiveBeginImplFrameWanted() const {
+// of the SetNeedsBeginFrame request that has to go to the Browser.
+bool SchedulerStateMachine::ProactiveBeginFrameWanted() const {
// The output surface is the provider of BeginImplFrames,
// so we are not going to get them even if we ask for them.
if (!HasInitializedOutputSurface())
@@ -863,7 +857,7 @@ bool SchedulerStateMachine::ProactiveBeginImplFrameWanted() const {
// If we just swapped, it's likely that we are going to produce another
// frame soon. This helps avoid negative glitches in our
- // SetNeedsBeginImplFrame requests, which may propagate to the BeginImplFrame
+ // SetNeedsBeginFrame requests, which may propagate to the BeginImplFrame
// provider and get sampled at an inopportune time, delaying the next
// BeginImplFrame.
if (last_frame_number_swap_performed_ == current_frame_number_)
@@ -874,7 +868,7 @@ bool SchedulerStateMachine::ProactiveBeginImplFrameWanted() const {
void SchedulerStateMachine::OnBeginImplFrame(const BeginFrameArgs& args) {
AdvanceCurrentFrameNumber();
- last_begin_impl_frame_args_ = args;
+ begin_impl_frame_args_ = args;
DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_IDLE) << *AsValue();
begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING;
}
diff --git a/cc/scheduler/scheduler_state_machine.h b/cc/scheduler/scheduler_state_machine.h
index 7426d96..c8d68fc 100644
--- a/cc/scheduler/scheduler_state_machine.h
+++ b/cc/scheduler/scheduler_state_machine.h
@@ -123,7 +123,7 @@ class CC_EXPORT SchedulerStateMachine {
// Indicates whether the impl thread needs a BeginImplFrame callback in order
// to make progress.
- bool BeginImplFrameNeeded() const;
+ bool BeginFrameNeeded() const;
// Indicates that we need to independently poll for new state and actions
// because we can't expect a BeginImplFrame. This is mostly used to avoid
@@ -230,15 +230,15 @@ class CC_EXPORT SchedulerStateMachine {
// True if we need to abort draws to make forward progress.
bool PendingDrawsShouldBeAborted() const;
- bool SupportsProactiveBeginImplFrame() const;
+ bool SupportsProactiveBeginFrame() const;
void SetContinuousPainting(bool continuous_painting) {
continuous_painting_ = continuous_painting;
}
protected:
- bool BeginImplFrameNeededToDraw() const;
- bool ProactiveBeginImplFrameWanted() const;
+ bool BeginFrameNeededToDraw() const;
+ bool ProactiveBeginFrameWanted() const;
// True if we need to force activations to make forward progress.
bool PendingActivationsShouldBeForced() const;
@@ -271,7 +271,7 @@ class CC_EXPORT SchedulerStateMachine {
ForcedRedrawOnTimeoutState forced_redraw_state_;
SynchronousReadbackState readback_state_;
- BeginFrameArgs last_begin_impl_frame_args_;
+ BeginFrameArgs begin_impl_frame_args_;
int commit_count_;
int current_frame_number_;
diff --git a/cc/scheduler/scheduler_state_machine_unittest.cc b/cc/scheduler/scheduler_state_machine_unittest.cc
index 4d7ef3f..060269d 100644
--- a/cc/scheduler/scheduler_state_machine_unittest.cc
+++ b/cc/scheduler/scheduler_state_machine_unittest.cc
@@ -127,10 +127,10 @@ TEST(SchedulerStateMachineTest, TestNextActionBeginsMainFrameIfNeeded) {
state.SetNeedsRedraw(false);
state.SetVisible(true);
- EXPECT_FALSE(state.BeginImplFrameNeeded());
+ EXPECT_FALSE(state.BeginFrameNeeded());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
- EXPECT_FALSE(state.BeginImplFrameNeeded());
+ EXPECT_FALSE(state.BeginFrameNeeded());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
@@ -145,10 +145,10 @@ TEST(SchedulerStateMachineTest, TestNextActionBeginsMainFrameIfNeeded) {
state.SetVisible(true);
state.SetNeedsCommit();
- EXPECT_FALSE(state.BeginImplFrameNeeded());
+ EXPECT_FALSE(state.BeginFrameNeeded());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
- EXPECT_FALSE(state.BeginImplFrameNeeded());
+ EXPECT_FALSE(state.BeginFrameNeeded());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
@@ -165,7 +165,7 @@ TEST(SchedulerStateMachineTest, TestNextActionBeginsMainFrameIfNeeded) {
state.SetVisible(true);
state.SetNeedsCommit();
- EXPECT_TRUE(state.BeginImplFrameNeeded());
+ EXPECT_TRUE(state.BeginFrameNeeded());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(
@@ -201,7 +201,7 @@ TEST(SchedulerStateMachineTest, MainFrameBeforeDrawDisabled) {
state.SetCanDraw(true);
state.SetNeedsCommit();
- EXPECT_TRUE(state.BeginImplFrameNeeded());
+ EXPECT_TRUE(state.BeginFrameNeeded());
// Commit to the pending tree.
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
@@ -269,7 +269,7 @@ TEST(SchedulerStateMachineTest, MainFrameBeforeActivationEnabled) {
state.SetCanDraw(true);
state.SetNeedsCommit();
- EXPECT_TRUE(state.BeginImplFrameNeeded());
+ EXPECT_TRUE(state.BeginFrameNeeded());
// Commit to the pending tree.
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
@@ -326,7 +326,7 @@ TEST(SchedulerStateMachineTest,
state.SetCanDraw(true);
state.SetNeedsRedraw(true);
EXPECT_TRUE(state.RedrawPending());
- EXPECT_TRUE(state.BeginImplFrameNeeded());
+ EXPECT_TRUE(state.BeginFrameNeeded());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
@@ -359,7 +359,7 @@ TEST(SchedulerStateMachineTest, TestFailedDrawForMissingHighResNeedsCommit) {
state.SetCanDraw(true);
state.SetNeedsRedraw(true);
EXPECT_TRUE(state.RedrawPending());
- EXPECT_TRUE(state.BeginImplFrameNeeded());
+ EXPECT_TRUE(state.BeginFrameNeeded());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
@@ -392,7 +392,7 @@ TEST(SchedulerStateMachineTest,
state.SetCanDraw(true);
state.SetNeedsRedraw(true);
EXPECT_TRUE(state.RedrawPending());
- EXPECT_TRUE(state.BeginImplFrameNeeded());
+ EXPECT_TRUE(state.BeginFrameNeeded());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
@@ -450,7 +450,7 @@ void TestFailedDrawsEventuallyForceDrawAfterNextCommit(
state.DidDrawIfPossibleCompleted(
DrawSwapReadbackResult::DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
- EXPECT_TRUE(state.BeginImplFrameNeeded());
+ EXPECT_TRUE(state.BeginFrameNeeded());
EXPECT_TRUE(state.RedrawPending());
// But the commit is ongoing.
EXPECT_TRUE(state.CommitPending());
@@ -524,7 +524,7 @@ TEST(SchedulerStateMachineTest, TestFailedDrawsDoNotRestartForcedDraw) {
DrawSwapReadbackResult::DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
}
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
- EXPECT_TRUE(state.BeginImplFrameNeeded());
+ EXPECT_TRUE(state.BeginFrameNeeded());
EXPECT_TRUE(state.RedrawPending());
// But the commit is ongoing.
EXPECT_TRUE(state.CommitPending());
@@ -564,7 +564,7 @@ TEST(SchedulerStateMachineTest, TestFailedDrawIsRetriedInNextBeginImplFrame) {
// Start a draw.
state.SetNeedsRedraw(true);
- EXPECT_TRUE(state.BeginImplFrameNeeded());
+ EXPECT_TRUE(state.BeginFrameNeeded());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
@@ -581,7 +581,7 @@ TEST(SchedulerStateMachineTest, TestFailedDrawIsRetriedInNextBeginImplFrame) {
EXPECT_TRUE(state.RedrawPending());
// We should not be trying to draw again now, but we have a commit pending.
- EXPECT_TRUE(state.BeginImplFrameNeeded());
+ EXPECT_TRUE(state.BeginFrameNeeded());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
@@ -604,7 +604,7 @@ TEST(SchedulerStateMachineTest, TestDoestDrawTwiceInSameFrame) {
state.SetNeedsRedraw(true);
// Draw the first frame.
- EXPECT_TRUE(state.BeginImplFrameNeeded());
+ EXPECT_TRUE(state.BeginFrameNeeded());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
@@ -620,7 +620,7 @@ TEST(SchedulerStateMachineTest, TestDoestDrawTwiceInSameFrame) {
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
// Move to another frame. This should now draw.
- EXPECT_TRUE(state.BeginImplFrameNeeded());
+ EXPECT_TRUE(state.BeginFrameNeeded());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
@@ -632,7 +632,7 @@ TEST(SchedulerStateMachineTest, TestDoestDrawTwiceInSameFrame) {
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
// We just swapped, so we should proactively request another BeginImplFrame.
- EXPECT_TRUE(state.BeginImplFrameNeeded());
+ EXPECT_TRUE(state.BeginFrameNeeded());
}
TEST(SchedulerStateMachineTest, TestNextActionDrawsOnBeginImplFrame) {
@@ -705,14 +705,12 @@ TEST(SchedulerStateMachineTest, TestNextActionDrawsOnBeginImplFrame) {
}
// Case 1: needs_commit=false.
- EXPECT_NE(state.BeginImplFrameNeeded(), request_readback)
- << *state.AsValue();
+ EXPECT_NE(state.BeginFrameNeeded(), request_readback) << *state.AsValue();
EXPECT_EQ(state.NextAction(), expected_action) << *state.AsValue();
// Case 2: needs_commit=true.
state.SetNeedsCommit();
- EXPECT_NE(state.BeginImplFrameNeeded(), request_readback)
- << *state.AsValue();
+ EXPECT_NE(state.BeginFrameNeeded(), request_readback) << *state.AsValue();
EXPECT_EQ(state.NextAction(), expected_action) << *state.AsValue();
}
}
@@ -814,7 +812,7 @@ void TestSetNeedsCommitIsNotLost(bool main_frame_before_draw_enabled) {
state.SetVisible(true);
state.SetCanDraw(true);
- EXPECT_TRUE(state.BeginImplFrameNeeded());
+ EXPECT_TRUE(state.BeginFrameNeeded());
// Begin the frame.
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
diff --git a/cc/scheduler/scheduler_unittest.cc b/cc/scheduler/scheduler_unittest.cc
index c401850..68dc0d1 100644
--- a/cc/scheduler/scheduler_unittest.cc
+++ b/cc/scheduler/scheduler_unittest.cc
@@ -94,11 +94,15 @@ class FakeSchedulerClient : public SchedulerClient {
}
// SchedulerClient implementation.
- virtual void SetNeedsBeginImplFrame(bool enable) OVERRIDE {
- actions_.push_back("SetNeedsBeginImplFrame");
+ virtual void SetNeedsBeginFrame(bool enable) OVERRIDE {
+ actions_.push_back("SetNeedsBeginFrame");
states_.push_back(scheduler_->StateAsValue().release());
needs_begin_impl_frame_ = enable;
}
+ virtual void WillBeginImplFrame(const BeginFrameArgs& args) OVERRIDE {
+ actions_.push_back("WillBeginImplFrame");
+ states_.push_back(scheduler_->StateAsValue().release());
+ }
virtual void ScheduledActionSendBeginMainFrame() OVERRIDE {
actions_.push_back("ScheduledActionSendBeginMainFrame");
states_.push_back(scheduler_->StateAsValue().release());
@@ -190,7 +194,7 @@ void InitializeOutputSurfaceAndFirstCommit(Scheduler* scheduler,
scheduler->NotifyBeginMainFrameStarted();
scheduler->NotifyReadyToCommit();
// Go through the motions to draw the commit.
- scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting());
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
// Run the posted deadline task.
EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
@@ -198,8 +202,8 @@ void InitializeOutputSurfaceAndFirstCommit(Scheduler* scheduler,
EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
// We need another BeginImplFrame so Scheduler calls
- // SetNeedsBeginImplFrame(false).
- scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting());
+ // SetNeedsBeginFrame(false).
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
// Run the posted deadline task.
EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
@@ -236,19 +240,20 @@ TEST(SchedulerTest, RequestCommit) {
client.Reset();
scheduler->SetNeedsCommit();
EXPECT_TRUE(client.needs_begin_impl_frame());
- EXPECT_SINGLE_ACTION("SetNeedsBeginImplFrame", client);
+ EXPECT_SINGLE_ACTION("SetNeedsBeginFrame", client);
client.Reset();
- scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting());
- EXPECT_SINGLE_ACTION("ScheduledActionSendBeginMainFrame", client);
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
+ EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
+ EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client, 1, 2);
EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
EXPECT_TRUE(client.needs_begin_impl_frame());
client.Reset();
// If we don't swap on the deadline, we need to request another
// BeginImplFrame.
- scheduler->OnBeginImplFrameDeadline();
- EXPECT_SINGLE_ACTION("SetNeedsBeginImplFrame", client);
+ client.task_runner().RunPendingTasks(); // Run posted deadline.
+ EXPECT_SINGLE_ACTION("SetNeedsBeginFrame", client);
EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
EXPECT_TRUE(client.needs_begin_impl_frame());
client.Reset();
@@ -261,29 +266,29 @@ TEST(SchedulerTest, RequestCommit) {
client.Reset();
// BeginImplFrame should prepare the draw.
- scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting());
- EXPECT_EQ(client.num_actions_(), 0);
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
+ EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
EXPECT_TRUE(client.needs_begin_impl_frame());
client.Reset();
// BeginImplFrame deadline should draw.
- scheduler->OnBeginImplFrameDeadline();
+ client.task_runner().RunPendingTasks(); // Run posted deadline.
EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 2);
- EXPECT_ACTION("SetNeedsBeginImplFrame", client, 1, 2);
+ EXPECT_ACTION("SetNeedsBeginFrame", client, 1, 2);
EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
EXPECT_TRUE(client.needs_begin_impl_frame());
client.Reset();
- // The following BeginImplFrame deadline should SetNeedsBeginImplFrame(false)
+ // The following BeginImplFrame deadline should SetNeedsBeginFrame(false)
// to avoid excessive toggles.
- scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting());
- EXPECT_EQ(client.num_actions_(), 0);
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
+ EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
client.Reset();
- scheduler->OnBeginImplFrameDeadline();
- EXPECT_SINGLE_ACTION("SetNeedsBeginImplFrame", client);
+ client.task_runner().RunPendingTasks(); // Run posted deadline.
+ EXPECT_SINGLE_ACTION("SetNeedsBeginFrame", client);
EXPECT_FALSE(client.needs_begin_impl_frame());
client.Reset();
}
@@ -302,11 +307,12 @@ TEST(SchedulerTest, RequestCommitAfterBeginMainFrameSent) {
// SetNeedsCommit should begin the frame.
scheduler->SetNeedsCommit();
- EXPECT_SINGLE_ACTION("SetNeedsBeginImplFrame", client);
+ EXPECT_SINGLE_ACTION("SetNeedsBeginFrame", client);
client.Reset();
- scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting());
- EXPECT_SINGLE_ACTION("ScheduledActionSendBeginMainFrame", client);
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
+ EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
+ EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client, 1, 2);
EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
EXPECT_TRUE(client.needs_begin_impl_frame());
@@ -323,20 +329,20 @@ TEST(SchedulerTest, RequestCommitAfterBeginMainFrameSent) {
EXPECT_SINGLE_ACTION("ScheduledActionCommit", client);
EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
client.Reset();
- scheduler->OnBeginImplFrameDeadline();
+ client.task_runner().RunPendingTasks(); // Run posted deadline.
EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 2);
- EXPECT_ACTION("SetNeedsBeginImplFrame", client, 1, 2);
+ EXPECT_ACTION("SetNeedsBeginFrame", client, 1, 2);
EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
// Because we just swapped, the Scheduler should also request the next
// BeginImplFrame from the OutputSurface.
EXPECT_TRUE(client.needs_begin_impl_frame());
client.Reset();
-
// Since another commit is needed, the next BeginImplFrame should initiate
// the second commit.
- scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting());
- EXPECT_SINGLE_ACTION("ScheduledActionSendBeginMainFrame", client);
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
+ EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
+ EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client, 1, 2);
EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
client.Reset();
@@ -347,17 +353,17 @@ TEST(SchedulerTest, RequestCommitAfterBeginMainFrameSent) {
EXPECT_SINGLE_ACTION("ScheduledActionCommit", client);
EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
client.Reset();
- scheduler->OnBeginImplFrameDeadline();
+ client.task_runner().RunPendingTasks(); // Run posted deadline.
EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 2);
- EXPECT_ACTION("SetNeedsBeginImplFrame", client, 1, 2);
+ EXPECT_ACTION("SetNeedsBeginFrame", client, 1, 2);
EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
EXPECT_TRUE(client.needs_begin_impl_frame());
client.Reset();
// On the next BeginImplFrame, verify we go back to a quiescent state and
// no longer request BeginImplFrames.
- scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting());
- scheduler->OnBeginImplFrameDeadline();
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
+ client.task_runner().RunPendingTasks(); // Run posted deadline.
EXPECT_FALSE(client.needs_begin_impl_frame());
client.Reset();
}
@@ -405,22 +411,22 @@ TEST(SchedulerTest, RequestRedrawInsideDraw) {
EXPECT_TRUE(client.needs_begin_impl_frame());
EXPECT_EQ(0, client.num_draws());
- scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting());
- scheduler->OnBeginImplFrameDeadline();
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
+ client.task_runner().RunPendingTasks(); // Run posted deadline.
EXPECT_EQ(1, client.num_draws());
EXPECT_TRUE(scheduler->RedrawPending());
EXPECT_TRUE(client.needs_begin_impl_frame());
- scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting());
- scheduler->OnBeginImplFrameDeadline();
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
+ client.task_runner().RunPendingTasks(); // Run posted deadline.
EXPECT_EQ(2, client.num_draws());
EXPECT_FALSE(scheduler->RedrawPending());
EXPECT_TRUE(client.needs_begin_impl_frame());
// We stop requesting BeginImplFrames after a BeginImplFrame where we don't
// swap.
- scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting());
- scheduler->OnBeginImplFrameDeadline();
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
+ client.task_runner().RunPendingTasks(); // Run posted deadline.
EXPECT_EQ(2, client.num_draws());
EXPECT_FALSE(scheduler->RedrawPending());
EXPECT_FALSE(client.needs_begin_impl_frame());
@@ -445,8 +451,8 @@ TEST(SchedulerTest, RequestRedrawInsideFailedDraw) {
EXPECT_EQ(0, client.num_draws());
// Fail the draw.
- scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting());
- scheduler->OnBeginImplFrameDeadline();
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
+ client.task_runner().RunPendingTasks(); // Run posted deadline.
EXPECT_EQ(1, client.num_draws());
// We have a commit pending and the draw failed, and we didn't lose the redraw
@@ -456,8 +462,8 @@ TEST(SchedulerTest, RequestRedrawInsideFailedDraw) {
EXPECT_TRUE(client.needs_begin_impl_frame());
// Fail the draw again.
- scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting());
- scheduler->OnBeginImplFrameDeadline();
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
+ client.task_runner().RunPendingTasks(); // Run posted deadline.
EXPECT_EQ(2, client.num_draws());
EXPECT_TRUE(scheduler->CommitPending());
EXPECT_TRUE(scheduler->RedrawPending());
@@ -465,8 +471,8 @@ TEST(SchedulerTest, RequestRedrawInsideFailedDraw) {
// Draw successfully.
client.SetDrawWillHappen(true);
- scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting());
- scheduler->OnBeginImplFrameDeadline();
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
+ client.task_runner().RunPendingTasks(); // Run posted deadline.
EXPECT_EQ(3, client.num_draws());
EXPECT_TRUE(scheduler->CommitPending());
EXPECT_FALSE(scheduler->RedrawPending());
@@ -526,17 +532,17 @@ TEST(SchedulerTest, RequestCommitInsideDraw) {
EXPECT_TRUE(client.needs_begin_impl_frame());
client.SetNeedsCommitOnNextDraw();
- scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting());
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
client.SetNeedsCommitOnNextDraw();
- scheduler->OnBeginImplFrameDeadline();
+ client.task_runner().RunPendingTasks(); // Run posted deadline.
EXPECT_EQ(1, client.num_draws());
EXPECT_TRUE(scheduler->CommitPending());
EXPECT_TRUE(client.needs_begin_impl_frame());
scheduler->NotifyBeginMainFrameStarted();
scheduler->NotifyReadyToCommit();
- scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting());
- scheduler->OnBeginImplFrameDeadline();
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
+ client.task_runner().RunPendingTasks(); // Run posted deadline.
EXPECT_EQ(2, client.num_draws());
EXPECT_FALSE(scheduler->RedrawPending());
@@ -545,8 +551,8 @@ TEST(SchedulerTest, RequestCommitInsideDraw) {
// We stop requesting BeginImplFrames after a BeginImplFrame where we don't
// swap.
- scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting());
- scheduler->OnBeginImplFrameDeadline();
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
+ client.task_runner().RunPendingTasks(); // Run posted deadline.
EXPECT_EQ(2, client.num_draws());
EXPECT_FALSE(scheduler->RedrawPending());
EXPECT_FALSE(scheduler->CommitPending());
@@ -572,8 +578,8 @@ TEST(SchedulerTest, RequestCommitInsideFailedDraw) {
EXPECT_EQ(0, client.num_draws());
// Fail the draw.
- scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting());
- scheduler->OnBeginImplFrameDeadline();
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
+ client.task_runner().RunPendingTasks(); // Run posted deadline.
EXPECT_EQ(1, client.num_draws());
// We have a commit pending and the draw failed, and we didn't lose the commit
@@ -583,8 +589,9 @@ TEST(SchedulerTest, RequestCommitInsideFailedDraw) {
EXPECT_TRUE(client.needs_begin_impl_frame());
// Fail the draw again.
- scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting());
- scheduler->OnBeginImplFrameDeadline();
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
+
+ client.task_runner().RunPendingTasks(); // Run posted deadline.
EXPECT_EQ(2, client.num_draws());
EXPECT_TRUE(scheduler->CommitPending());
EXPECT_TRUE(scheduler->RedrawPending());
@@ -592,8 +599,8 @@ TEST(SchedulerTest, RequestCommitInsideFailedDraw) {
// Draw successfully.
client.SetDrawWillHappen(true);
- scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting());
- scheduler->OnBeginImplFrameDeadline();
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
+ client.task_runner().RunPendingTasks(); // Run posted deadline.
EXPECT_EQ(3, client.num_draws());
EXPECT_TRUE(scheduler->CommitPending());
EXPECT_FALSE(scheduler->RedrawPending());
@@ -617,8 +624,8 @@ TEST(SchedulerTest, NoSwapWhenDrawFails) {
// Draw successfully, this starts a new frame.
client.SetNeedsCommitOnNextDraw();
- scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting());
- scheduler->OnBeginImplFrameDeadline();
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
+ client.task_runner().RunPendingTasks(); // Run posted deadline.
EXPECT_EQ(1, client.num_draws());
scheduler->SetNeedsRedraw();
@@ -628,8 +635,8 @@ TEST(SchedulerTest, NoSwapWhenDrawFails) {
// Fail to draw, this should not start a frame.
client.SetDrawWillHappen(false);
client.SetNeedsCommitOnNextDraw();
- scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting());
- scheduler->OnBeginImplFrameDeadline();
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
+ client.task_runner().RunPendingTasks(); // Run posted deadline.
EXPECT_EQ(2, client.num_draws());
}
@@ -714,13 +721,13 @@ TEST(SchedulerTest, ManageTiles) {
// We have no immediate actions to perform, so the BeginImplFrame should post
// the deadline task.
client.Reset();
- scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting());
- EXPECT_EQ(client.num_actions_(), 0);
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
+ EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
// On the deadline, he actions should have occured in the right order.
client.Reset();
- scheduler->OnBeginImplFrameDeadline();
+ client.task_runner().RunPendingTasks(); // Run posted deadline.
EXPECT_EQ(1, client.num_draws());
EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndSwapIfPossible"));
EXPECT_TRUE(client.HasAction("ScheduledActionManageTiles"));
@@ -741,15 +748,15 @@ TEST(SchedulerTest, ManageTiles) {
// We have no immediate actions to perform, so the BeginImplFrame should post
// the deadline task.
client.Reset();
- scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting());
- EXPECT_EQ(client.num_actions_(), 0);
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
+ EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
// Draw. The draw will trigger SetNeedsManageTiles, and
// then the ManageTiles action will be triggered after the Draw.
// Afterwards, neither a draw nor ManageTiles are pending.
client.Reset();
- scheduler->OnBeginImplFrameDeadline();
+ client.task_runner().RunPendingTasks(); // Run posted deadline.
EXPECT_EQ(1, client.num_draws());
EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndSwapIfPossible"));
EXPECT_TRUE(client.HasAction("ScheduledActionManageTiles"));
@@ -761,12 +768,12 @@ TEST(SchedulerTest, ManageTiles) {
// We need a BeginImplFrame where we don't swap to go idle.
client.Reset();
- scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting());
- EXPECT_EQ(client.num_actions_(), 0);
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
+ EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
client.Reset();
- scheduler->OnBeginImplFrameDeadline();
- EXPECT_SINGLE_ACTION("SetNeedsBeginImplFrame", client);
+ client.task_runner().RunPendingTasks(); // Run posted deadline.
+ EXPECT_SINGLE_ACTION("SetNeedsBeginFrame", client);
EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
EXPECT_EQ(0, client.num_draws());
@@ -781,11 +788,11 @@ TEST(SchedulerTest, ManageTiles) {
// BeginImplFrame. There will be no draw, only ManageTiles.
client.Reset();
- scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting());
- EXPECT_EQ(client.num_actions_(), 0);
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
+ EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
client.Reset();
- scheduler->OnBeginImplFrameDeadline();
+ client.task_runner().RunPendingTasks(); // Run posted deadline.
EXPECT_EQ(0, client.num_draws());
EXPECT_FALSE(client.HasAction("ScheduledActionDrawAndSwapIfPossible"));
EXPECT_TRUE(client.HasAction("ScheduledActionManageTiles"));
@@ -807,8 +814,8 @@ TEST(SchedulerTest, ManageTilesOncePerFrame) {
scheduler->SetNeedsManageTiles();
scheduler->SetNeedsRedraw();
client.Reset();
- scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting());
- EXPECT_EQ(client.num_actions_(), 0);
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
+ EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
EXPECT_TRUE(scheduler->ManageTilesPending());
@@ -816,7 +823,7 @@ TEST(SchedulerTest, ManageTilesOncePerFrame) {
EXPECT_FALSE(scheduler->ManageTilesPending());
client.Reset();
- scheduler->OnBeginImplFrameDeadline();
+ client.task_runner().RunPendingTasks(); // Run posted deadline.
EXPECT_EQ(1, client.num_draws());
EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndSwapIfPossible"));
EXPECT_FALSE(client.HasAction("ScheduledActionManageTiles"));
@@ -828,12 +835,12 @@ TEST(SchedulerTest, ManageTilesOncePerFrame) {
scheduler->SetNeedsManageTiles();
scheduler->SetNeedsRedraw();
client.Reset();
- scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting());
- EXPECT_EQ(client.num_actions_(), 0);
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
+ EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
client.Reset();
- scheduler->OnBeginImplFrameDeadline();
+ client.task_runner().RunPendingTasks(); // Run posted deadline.
EXPECT_EQ(1, client.num_draws());
EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndSwapIfPossible"));
EXPECT_TRUE(client.HasAction("ScheduledActionManageTiles"));
@@ -850,14 +857,14 @@ TEST(SchedulerTest, ManageTilesOncePerFrame) {
scheduler->SetNeedsManageTiles();
scheduler->SetNeedsRedraw();
client.Reset();
- scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting());
- EXPECT_EQ(client.num_actions_(), 0);
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
+ EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
EXPECT_TRUE(scheduler->ManageTilesPending());
client.Reset();
- scheduler->OnBeginImplFrameDeadline();
+ client.task_runner().RunPendingTasks(); // Run posted deadline.
EXPECT_EQ(1, client.num_draws());
EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndSwapIfPossible"));
EXPECT_FALSE(client.HasAction("ScheduledActionManageTiles"));
@@ -872,14 +879,14 @@ TEST(SchedulerTest, ManageTilesOncePerFrame) {
scheduler->SetNeedsManageTiles();
scheduler->SetNeedsRedraw();
client.Reset();
- scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting());
- EXPECT_EQ(client.num_actions_(), 0);
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
+ EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
EXPECT_TRUE(scheduler->ManageTilesPending());
client.Reset();
- scheduler->OnBeginImplFrameDeadline();
+ client.task_runner().RunPendingTasks(); // Run posted deadline.
EXPECT_EQ(1, client.num_draws());
EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndSwapIfPossible"));
EXPECT_FALSE(client.HasAction("ScheduledActionManageTiles"));
@@ -890,12 +897,12 @@ TEST(SchedulerTest, ManageTilesOncePerFrame) {
scheduler->SetNeedsManageTiles();
scheduler->SetNeedsRedraw();
client.Reset();
- scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting());
- EXPECT_EQ(client.num_actions_(), 0);
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
+ EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
client.Reset();
- scheduler->OnBeginImplFrameDeadline();
+ client.task_runner().RunPendingTasks(); // Run posted deadline.
EXPECT_EQ(1, client.num_draws());
EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndSwapIfPossible"));
EXPECT_TRUE(client.HasAction("ScheduledActionManageTiles"));
@@ -917,9 +924,8 @@ TEST(SchedulerTest, TriggerBeginFrameDeadlineEarly) {
InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
client.Reset();
- BeginFrameArgs impl_frame_args = BeginFrameArgs::CreateForTesting();
scheduler->SetNeedsRedraw();
- scheduler->BeginImplFrame(impl_frame_args);
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
// The deadline should be zero since there is no work other than drawing
// pending.
@@ -975,9 +981,9 @@ void MainFrameInHighLatencyMode(int64 begin_main_frame_to_commit_estimate_in_ms,
client.Reset();
scheduler->SetNeedsCommit();
EXPECT_FALSE(scheduler->MainThreadIsInHighLatencyMode());
- scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting());
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
EXPECT_FALSE(scheduler->MainThreadIsInHighLatencyMode());
- scheduler->OnBeginImplFrameDeadline();
+ client.task_runner().RunPendingTasks(); // Run posted deadline.
EXPECT_TRUE(scheduler->MainThreadIsInHighLatencyMode());
scheduler->NotifyBeginMainFrameStarted();
scheduler->NotifyReadyToCommit();
@@ -987,9 +993,9 @@ void MainFrameInHighLatencyMode(int64 begin_main_frame_to_commit_estimate_in_ms,
client.Reset();
scheduler->SetNeedsCommit();
EXPECT_TRUE(scheduler->MainThreadIsInHighLatencyMode());
- scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting());
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
EXPECT_TRUE(scheduler->MainThreadIsInHighLatencyMode());
- scheduler->OnBeginImplFrameDeadline();
+ client.task_runner().RunPendingTasks(); // Run posted deadline.
EXPECT_EQ(scheduler->MainThreadIsInHighLatencyMode(),
should_send_begin_main_frame);
EXPECT_EQ(client.HasAction("ScheduledActionSendBeginMainFrame"),
@@ -1044,9 +1050,9 @@ TEST(SchedulerTest, PollForCommitCompletion) {
scheduler->NotifyReadyToCommit();
scheduler->SetNeedsRedraw();
- BeginFrameArgs impl_frame_args = BeginFrameArgs::CreateForTesting();
- impl_frame_args.interval = base::TimeDelta::FromMilliseconds(1000);
- scheduler->BeginImplFrame(impl_frame_args);
+ BeginFrameArgs frame_args = BeginFrameArgs::CreateForTesting();
+ frame_args.interval = base::TimeDelta::FromMilliseconds(1000);
+ scheduler->BeginFrame(frame_args);
EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
client.task_runner().RunPendingTasks(); // Run posted deadline.
@@ -1056,7 +1062,7 @@ TEST(SchedulerTest, PollForCommitCompletion) {
// the NotifyReadyToCommit for now.
EXPECT_FALSE(scheduler->CommitPending());
scheduler->SetNeedsCommit();
- scheduler->BeginImplFrame(impl_frame_args);
+ scheduler->BeginFrame(frame_args);
EXPECT_TRUE(scheduler->CommitPending());
// Spin the event loop a few times and make sure we get more
@@ -1065,7 +1071,7 @@ TEST(SchedulerTest, PollForCommitCompletion) {
// Does three iterations to make sure that the timer is properly repeating.
for (int i = 0; i < 3; ++i) {
- EXPECT_EQ((impl_frame_args.interval * 2).InMicroseconds(),
+ EXPECT_EQ((frame_args.interval * 2).InMicroseconds(),
client.task_runner().NextPendingTaskDelay().InMicroseconds())
<< *scheduler->StateAsValue();
client.task_runner().RunPendingTasks();
@@ -1078,7 +1084,7 @@ TEST(SchedulerTest, PollForCommitCompletion) {
// Do the same thing after BeginMainFrame starts but still before activation.
scheduler->NotifyBeginMainFrameStarted();
for (int i = 0; i < 3; ++i) {
- EXPECT_EQ((impl_frame_args.interval * 2).InMicroseconds(),
+ EXPECT_EQ((frame_args.interval * 2).InMicroseconds(),
client.task_runner().NextPendingTaskDelay().InMicroseconds())
<< *scheduler->StateAsValue();
client.task_runner().RunPendingTasks();
@@ -1089,5 +1095,82 @@ TEST(SchedulerTest, PollForCommitCompletion) {
}
}
+TEST(SchedulerTest, BeginRetroFrame) {
+ FakeSchedulerClient client;
+ SchedulerSettings scheduler_settings;
+ Scheduler* scheduler = client.CreateScheduler(scheduler_settings);
+ scheduler->SetCanStart();
+ scheduler->SetVisible(true);
+ scheduler->SetCanDraw(true);
+ InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
+
+ // SetNeedsCommit should begin the frame on the next BeginImplFrame.
+ client.Reset();
+ scheduler->SetNeedsCommit();
+ EXPECT_TRUE(client.needs_begin_impl_frame());
+ EXPECT_SINGLE_ACTION("SetNeedsBeginFrame", client);
+ client.Reset();
+
+ // Create a BeginFrame with a long deadline to avoid race conditions.
+ // This is the first BeginFrame, which will be handled immediately.
+ BeginFrameArgs args = BeginFrameArgs::CreateForTesting();
+ args.deadline += base::TimeDelta::FromHours(1);
+ scheduler->BeginFrame(args);
+
+ EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
+ EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client, 1, 2);
+ EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
+ EXPECT_TRUE(client.needs_begin_impl_frame());
+ client.Reset();
+
+ // Queue BeginFrames while we are still handling the previous BeginFrame.
+ args.frame_time += base::TimeDelta::FromSeconds(1);
+ scheduler->BeginFrame(args);
+ args.frame_time += base::TimeDelta::FromSeconds(1);
+ scheduler->BeginFrame(args);
+
+ // If we don't swap on the deadline, we need to request another
+ // BeginImplFrame.
+ client.task_runner().RunPendingTasks(); // Run posted deadline.
+ EXPECT_SINGLE_ACTION("SetNeedsBeginFrame", client);
+ EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
+ EXPECT_TRUE(client.needs_begin_impl_frame());
+ client.Reset();
+
+ // NotifyReadyToCommit should trigger the commit.
+ scheduler->NotifyBeginMainFrameStarted();
+ scheduler->NotifyReadyToCommit();
+ EXPECT_SINGLE_ACTION("ScheduledActionCommit", client);
+ EXPECT_TRUE(client.needs_begin_impl_frame());
+ client.Reset();
+
+ // BeginImplFrame should prepare the draw.
+ client.task_runner().RunPendingTasks(); // Run posted BeginRetroFrame.
+ EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
+ EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
+ EXPECT_TRUE(client.needs_begin_impl_frame());
+ client.Reset();
+
+ // BeginImplFrame deadline should draw.
+ client.task_runner().RunPendingTasks(); // Run posted deadline.
+ EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 2);
+ EXPECT_ACTION("SetNeedsBeginFrame", client, 1, 2);
+ EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
+ EXPECT_TRUE(client.needs_begin_impl_frame());
+ client.Reset();
+
+ // The following BeginImplFrame deadline should SetNeedsBeginFrame(false)
+ // to avoid excessive toggles.
+ client.task_runner().RunPendingTasks(); // Run posted BeginRetroFrame.
+ EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
+ EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
+ client.Reset();
+
+ client.task_runner().RunPendingTasks(); // Run posted deadline.
+ EXPECT_SINGLE_ACTION("SetNeedsBeginFrame", client);
+ EXPECT_FALSE(client.needs_begin_impl_frame());
+ client.Reset();
+}
+
} // namespace
} // namespace cc
diff --git a/cc/test/fake_layer_tree_host_impl_client.h b/cc/test/fake_layer_tree_host_impl_client.h
index 123a661..975992d 100644
--- a/cc/test/fake_layer_tree_host_impl_client.h
+++ b/cc/test/fake_layer_tree_host_impl_client.h
@@ -17,8 +17,7 @@ class FakeLayerTreeHostImplClient : public LayerTreeHostImplClient {
virtual void DidLoseOutputSurfaceOnImplThread() OVERRIDE {}
virtual void DidSwapBuffersOnImplThread() OVERRIDE {}
virtual void OnSwapBuffersCompleteOnImplThread() OVERRIDE {}
- virtual void BeginImplFrame(const BeginFrameArgs& args)
- OVERRIDE {}
+ virtual void BeginFrame(const BeginFrameArgs& args) OVERRIDE {}
virtual void OnCanDrawStateChanged(bool can_draw) OVERRIDE {}
virtual void NotifyReadyToActivate() OVERRIDE {}
virtual void SetNeedsRedrawOnImplThread() OVERRIDE {}
diff --git a/cc/test/fake_output_surface.cc b/cc/test/fake_output_surface.cc
index e72253c..920b689 100644
--- a/cc/test/fake_output_surface.cc
+++ b/cc/test/fake_output_surface.cc
@@ -19,7 +19,7 @@ FakeOutputSurface::FakeOutputSurface(
: OutputSurface(context_provider),
client_(NULL),
num_sent_frames_(0),
- needs_begin_impl_frame_(false),
+ needs_begin_frame_(false),
forced_draw_to_software_device_(false),
has_external_stencil_test_(false),
fake_weak_ptr_factory_(this) {
@@ -84,22 +84,23 @@ void FakeOutputSurface::SwapBuffers(CompositorFrame* frame) {
}
}
-void FakeOutputSurface::SetNeedsBeginImplFrame(bool enable) {
- needs_begin_impl_frame_ = enable;
- OutputSurface::SetNeedsBeginImplFrame(enable);
+void FakeOutputSurface::SetNeedsBeginFrame(bool enable) {
+ needs_begin_frame_ = enable;
+ OutputSurface::SetNeedsBeginFrame(enable);
- // If there is not BeginImplFrame emulation from the FrameRateController,
- // then we just post a BeginImplFrame to emulate it as part of the test.
+ // If there is not BeginFrame emulation from the FrameRateController,
+ // then we just post a BeginFrame to emulate it as part of the test.
if (enable && !frame_rate_controller_) {
base::MessageLoop::current()->PostDelayedTask(
- FROM_HERE, base::Bind(&FakeOutputSurface::OnBeginImplFrame,
- fake_weak_ptr_factory_.GetWeakPtr()),
+ FROM_HERE,
+ base::Bind(&FakeOutputSurface::OnBeginFrame,
+ fake_weak_ptr_factory_.GetWeakPtr()),
base::TimeDelta::FromMilliseconds(16));
}
}
-void FakeOutputSurface::OnBeginImplFrame() {
- OutputSurface::BeginImplFrame(BeginFrameArgs::CreateForTesting());
+void FakeOutputSurface::OnBeginFrame() {
+ OutputSurface::BeginFrame(BeginFrameArgs::CreateForTesting());
}
diff --git a/cc/test/fake_output_surface.h b/cc/test/fake_output_surface.h
index 965f543..e44153c 100644
--- a/cc/test/fake_output_surface.h
+++ b/cc/test/fake_output_surface.h
@@ -94,10 +94,8 @@ class FakeOutputSurface : public OutputSurface {
virtual void SwapBuffers(CompositorFrame* frame) OVERRIDE;
- virtual void SetNeedsBeginImplFrame(bool enable) OVERRIDE;
- bool needs_begin_impl_frame() const {
- return needs_begin_impl_frame_;
- }
+ virtual void SetNeedsBeginFrame(bool enable) OVERRIDE;
+ bool needs_begin_frame() const { return needs_begin_frame_; }
void set_forced_draw_to_software_device(bool forced) {
forced_draw_to_software_device_ = forced;
@@ -140,12 +138,12 @@ class FakeOutputSurface : public OutputSurface {
scoped_ptr<SoftwareOutputDevice> software_device,
bool delegated_rendering);
- void OnBeginImplFrame();
+ void OnBeginFrame();
OutputSurfaceClient* client_;
CompositorFrame last_sent_frame_;
size_t num_sent_frames_;
- bool needs_begin_impl_frame_;
+ bool needs_begin_frame_;
bool forced_draw_to_software_device_;
bool has_external_stencil_test_;
TransferableResourceArray resources_held_by_parent_;
diff --git a/cc/test/fake_output_surface_client.cc b/cc/test/fake_output_surface_client.cc
index ce4feef..20de00e 100644
--- a/cc/test/fake_output_surface_client.cc
+++ b/cc/test/fake_output_surface_client.cc
@@ -12,8 +12,8 @@ bool FakeOutputSurfaceClient::DeferredInitialize(
return deferred_initialize_result_;
}
-void FakeOutputSurfaceClient::BeginImplFrame(const BeginFrameArgs& args) {
- begin_impl_frame_count_++;
+void FakeOutputSurfaceClient::BeginFrame(const BeginFrameArgs& args) {
+ begin_frame_count_++;
}
void FakeOutputSurfaceClient::DidLoseOutputSurface() {
diff --git a/cc/test/fake_output_surface_client.h b/cc/test/fake_output_surface_client.h
index b944d09..d64e063 100644
--- a/cc/test/fake_output_surface_client.h
+++ b/cc/test/fake_output_surface_client.h
@@ -13,7 +13,7 @@ namespace cc {
class FakeOutputSurfaceClient : public OutputSurfaceClient {
public:
FakeOutputSurfaceClient()
- : begin_impl_frame_count_(0),
+ : begin_frame_count_(0),
deferred_initialize_result_(true),
deferred_initialize_called_(false),
did_lose_output_surface_called_(false),
@@ -23,7 +23,7 @@ class FakeOutputSurfaceClient : public OutputSurfaceClient {
scoped_refptr<ContextProvider> offscreen_context_provider) OVERRIDE;
virtual void ReleaseGL() OVERRIDE {}
virtual void SetNeedsRedrawRect(const gfx::Rect& damage_rect) OVERRIDE {}
- virtual void BeginImplFrame(const BeginFrameArgs& args) OVERRIDE;
+ virtual void BeginFrame(const BeginFrameArgs& args) OVERRIDE;
virtual void DidSwapBuffers() OVERRIDE {}
virtual void OnSwapBuffersComplete() OVERRIDE {}
virtual void ReclaimResources(const CompositorFrameAck* ack) OVERRIDE {}
@@ -36,9 +36,7 @@ class FakeOutputSurfaceClient : public OutputSurfaceClient {
virtual void SetMemoryPolicy(const ManagedMemoryPolicy& policy) OVERRIDE;
virtual void SetTreeActivationCallback(const base::Closure&) OVERRIDE {}
- int begin_impl_frame_count() {
- return begin_impl_frame_count_;
- }
+ int begin_frame_count() { return begin_frame_count_; }
void set_deferred_initialize_result(bool result) {
deferred_initialize_result_ = result;
@@ -55,7 +53,7 @@ class FakeOutputSurfaceClient : public OutputSurfaceClient {
const ManagedMemoryPolicy& memory_policy() const { return memory_policy_; }
private:
- int begin_impl_frame_count_;
+ int begin_frame_count_;
bool deferred_initialize_result_;
bool deferred_initialize_called_;
bool did_lose_output_surface_called_;
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc
index 69f42e0..ed8de34 100644
--- a/cc/test/layer_tree_test.cc
+++ b/cc/test/layer_tree_test.cc
@@ -83,10 +83,9 @@ class LayerTreeHostImplForTesting : public LayerTreeHostImpl {
block_notify_ready_to_activate_for_testing_(false),
notify_ready_to_activate_was_blocked_(false) {}
- virtual void BeginImplFrame(const BeginFrameArgs& args) OVERRIDE {
+ virtual void WillBeginImplFrame(const BeginFrameArgs& args) OVERRIDE {
+ LayerTreeHostImpl::WillBeginImplFrame(args);
test_hooks_->WillBeginImplFrameOnThread(this, args);
- LayerTreeHostImpl::BeginImplFrame(args);
- test_hooks_->DidBeginImplFrameOnThread(this, args);
}
virtual void BeginMainFrameAborted(bool did_handle) OVERRIDE {
@@ -628,7 +627,7 @@ void LayerTreeTest::RunTest(bool threaded,
delegating_renderer_ = delegating_renderer;
- // Spend less time waiting for BeginImplFrame because the output is
+ // Spend less time waiting for BeginFrame because the output is
// mocked out.
settings_.refresh_rate = 200.0;
if (impl_side_painting) {
diff --git a/cc/test/layer_tree_test.h b/cc/test/layer_tree_test.h
index 86208f2..19a379b 100644
--- a/cc/test/layer_tree_test.h
+++ b/cc/test/layer_tree_test.h
@@ -36,8 +36,6 @@ class TestHooks : public AnimationDelegate {
virtual void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
const BeginFrameArgs& args) {}
- virtual void DidBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
- const BeginFrameArgs& args) {}
virtual void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
bool did_handle) {}
virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) {}
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index abf777a..cbfbd45 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -1282,8 +1282,8 @@ void LayerTreeHostImpl::SetNeedsRedrawRect(const gfx::Rect& damage_rect) {
client_->SetNeedsRedrawRectOnImplThread(damage_rect);
}
-void LayerTreeHostImpl::BeginImplFrame(const BeginFrameArgs& args) {
- client_->BeginImplFrame(args);
+void LayerTreeHostImpl::BeginFrame(const BeginFrameArgs& args) {
+ client_->BeginFrame(args);
}
void LayerTreeHostImpl::DidSwapBuffers() {
@@ -1499,9 +1499,15 @@ bool LayerTreeHostImpl::SwapBuffers(const LayerTreeHostImpl::FrameData& frame) {
return true;
}
-void LayerTreeHostImpl::SetNeedsBeginImplFrame(bool enable) {
+void LayerTreeHostImpl::SetNeedsBeginFrame(bool enable) {
if (output_surface_)
- output_surface_->SetNeedsBeginImplFrame(enable);
+ output_surface_->SetNeedsBeginFrame(enable);
+}
+
+void LayerTreeHostImpl::WillBeginImplFrame(const BeginFrameArgs& args) {
+ // Sample the frame time now. This time will be used for updating animations
+ // when we draw.
+ UpdateCurrentFrameTime();
}
gfx::SizeF LayerTreeHostImpl::ComputeInnerViewportContainerSize() const {
@@ -1877,14 +1883,14 @@ bool LayerTreeHostImpl::InitializeRenderer(
GetRendererCapabilities().allow_rasterize_on_demand);
}
- // Setup BeginImplFrameEmulation if it's not supported natively
+ // Setup BeginFrameEmulation if it's not supported natively
if (!settings_.begin_impl_frame_scheduling_enabled) {
const base::TimeDelta display_refresh_interval =
base::TimeDelta::FromMicroseconds(
base::Time::kMicrosecondsPerSecond /
settings_.refresh_rate);
- output_surface->InitializeBeginImplFrameEmulation(
+ output_surface->InitializeBeginFrameEmulation(
proxy_->ImplThreadTaskRunner(),
settings_.throttle_frame_production,
display_refresh_interval);
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h
index 048c3c7..b002362 100644
--- a/cc/trees/layer_tree_host_impl.h
+++ b/cc/trees/layer_tree_host_impl.h
@@ -64,7 +64,7 @@ class LayerTreeHostImplClient {
virtual void DidLoseOutputSurfaceOnImplThread() = 0;
virtual void DidSwapBuffersOnImplThread() = 0;
virtual void OnSwapBuffersCompleteOnImplThread() = 0;
- virtual void BeginImplFrame(const BeginFrameArgs& args) = 0;
+ virtual void BeginFrame(const BeginFrameArgs& args) = 0;
virtual void OnCanDrawStateChanged(bool can_draw) = 0;
virtual void NotifyReadyToActivate() = 0;
// Please call these 2 functions through
@@ -224,7 +224,7 @@ class CC_EXPORT LayerTreeHostImpl
scoped_refptr<ContextProvider> offscreen_context_provider) OVERRIDE;
virtual void ReleaseGL() OVERRIDE;
virtual void SetNeedsRedrawRect(const gfx::Rect& rect) OVERRIDE;
- virtual void BeginImplFrame(const BeginFrameArgs& args) OVERRIDE;
+ virtual void BeginFrame(const BeginFrameArgs& args) OVERRIDE;
virtual void SetExternalDrawConstraints(
const gfx::Transform& transform,
const gfx::Rect& viewport,
@@ -263,7 +263,8 @@ class CC_EXPORT LayerTreeHostImpl
const RendererCapabilitiesImpl& GetRendererCapabilities() const;
virtual bool SwapBuffers(const FrameData& frame);
- void SetNeedsBeginImplFrame(bool enable);
+ void SetNeedsBeginFrame(bool enable);
+ virtual void WillBeginImplFrame(const BeginFrameArgs& args);
void DidModifyTilePriorities();
void Readback(void* pixels, const 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 f8dbcec..0fff5ff 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -110,7 +110,7 @@ class LayerTreeHostImplTest : public testing::Test,
virtual void DidLoseOutputSurfaceOnImplThread() OVERRIDE {}
virtual void DidSwapBuffersOnImplThread() OVERRIDE {}
virtual void OnSwapBuffersCompleteOnImplThread() OVERRIDE {}
- virtual void BeginImplFrame(const BeginFrameArgs& args) OVERRIDE {}
+ virtual void BeginFrame(const BeginFrameArgs& args) 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 f2012a4..b1e33dd 100644
--- a/cc/trees/layer_tree_host_unittest.cc
+++ b/cc/trees/layer_tree_host_unittest.cc
@@ -1046,15 +1046,11 @@ class LayerTreeHostTestFrameTimeUpdatesAfterActivationFails
if (impl->pending_tree())
frame_count_with_pending_tree_++;
- if (frame_count_with_pending_tree_ == 2)
- impl->BlockNotifyReadyToActivateForTesting(false);
- }
-
- virtual void DidBeginImplFrameOnThread(LayerTreeHostImpl* impl,
- const BeginFrameArgs& args) OVERRIDE {
if (frame_count_with_pending_tree_ == 1) {
EXPECT_EQ(first_frame_time_.ToInternalValue(), 0);
first_frame_time_ = impl->CurrentFrameTimeTicks();
+ } else if (frame_count_with_pending_tree_ == 2) {
+ impl->BlockNotifyReadyToActivateForTesting(false);
}
}
@@ -2604,16 +2600,16 @@ class LayerTreeHostTestLCDNotification : public LayerTreeHostTest {
SINGLE_THREAD_TEST_F(LayerTreeHostTestLCDNotification);
-// Verify that the BeginImplFrame notification is used to initiate rendering.
-class LayerTreeHostTestBeginImplFrameNotification : public LayerTreeHostTest {
+// Verify that the BeginFrame notification is used to initiate rendering.
+class LayerTreeHostTestBeginFrameNotification : public LayerTreeHostTest {
public:
virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
settings->begin_impl_frame_scheduling_enabled = true;
}
virtual void BeginTest() OVERRIDE {
- // This will trigger a SetNeedsBeginImplFrame which will trigger a
- // BeginImplFrame.
+ // This will trigger a SetNeedsBeginFrame which will trigger a
+ // BeginFrame.
PostSetNeedsCommitToMainThread();
}
@@ -2631,9 +2627,9 @@ class LayerTreeHostTestBeginImplFrameNotification : public LayerTreeHostTest {
base::TimeTicks frame_time_;
};
-MULTI_THREAD_TEST_F(LayerTreeHostTestBeginImplFrameNotification);
+MULTI_THREAD_TEST_F(LayerTreeHostTestBeginFrameNotification);
-class LayerTreeHostTestBeginImplFrameNotificationShutdownWhileEnabled
+class LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled
: public LayerTreeHostTest {
public:
virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
@@ -2644,11 +2640,11 @@ class LayerTreeHostTestBeginImplFrameNotificationShutdownWhileEnabled
virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
- // The BeginImplFrame notification is turned off now but will get enabled
+ // The BeginFrame notification is turned off now but will get enabled
// once we return. End test while it's enabled.
ImplThreadTaskRunner()->PostTask(
FROM_HERE,
- base::Bind(&LayerTreeHostTestBeginImplFrameNotification::EndTest,
+ base::Bind(&LayerTreeHostTestBeginFrameNotification::EndTest,
base::Unretained(this)));
}
@@ -2656,7 +2652,7 @@ class LayerTreeHostTestBeginImplFrameNotificationShutdownWhileEnabled
};
MULTI_THREAD_TEST_F(
- LayerTreeHostTestBeginImplFrameNotificationShutdownWhileEnabled);
+ LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled);
class LayerTreeHostTestAbortedCommitDoesntStall : public LayerTreeHostTest {
protected:
diff --git a/cc/trees/single_thread_proxy.h b/cc/trees/single_thread_proxy.h
index dc1bb13..a52a6f5 100644
--- a/cc/trees/single_thread_proxy.h
+++ b/cc/trees/single_thread_proxy.h
@@ -57,8 +57,7 @@ class SingleThreadProxy : public Proxy, LayerTreeHostImplClient {
virtual void DidLoseOutputSurfaceOnImplThread() OVERRIDE;
virtual void DidSwapBuffersOnImplThread() OVERRIDE;
virtual void OnSwapBuffersCompleteOnImplThread() OVERRIDE;
- virtual void BeginImplFrame(const BeginFrameArgs& args)
- OVERRIDE {}
+ virtual void BeginFrame(const BeginFrameArgs& args) OVERRIDE {}
virtual void OnCanDrawStateChanged(bool can_draw) OVERRIDE;
virtual void NotifyReadyToActivate() OVERRIDE;
virtual void SetNeedsRedrawOnImplThread() OVERRIDE;
diff --git a/cc/trees/thread_proxy.cc b/cc/trees/thread_proxy.cc
index e30edd7..b0cd328 100644
--- a/cc/trees/thread_proxy.cc
+++ b/cc/trees/thread_proxy.cc
@@ -441,22 +441,18 @@ void ThreadProxy::OnSwapBuffersCompleteOnImplThread() {
base::Bind(&ThreadProxy::DidCompleteSwapBuffers, main_thread_weak_ptr_));
}
-void ThreadProxy::SetNeedsBeginImplFrame(bool enable) {
- TRACE_EVENT1("cc", "ThreadProxy::SetNeedsBeginImplFrame", "enable", enable);
- DCHECK(IsImplThread());
- impl().layer_tree_host_impl->SetNeedsBeginImplFrame(enable);
+void ThreadProxy::SetNeedsBeginFrame(bool enable) {
+ TRACE_EVENT1("cc", "ThreadProxy::SetNeedsBeginFrame", "enable", enable);
+ impl().layer_tree_host_impl->SetNeedsBeginFrame(enable);
UpdateBackgroundAnimateTicking();
}
-void ThreadProxy::BeginImplFrame(const BeginFrameArgs& args) {
- TRACE_EVENT0("cc", "ThreadProxy::BeginImplFrame");
- DCHECK(IsImplThread());
-
- // Sample the frame time now. This time will be used for updating animations
- // when we draw.
- impl().layer_tree_host_impl->UpdateCurrentFrameTime();
+void ThreadProxy::BeginFrame(const BeginFrameArgs& args) {
+ impl().scheduler->BeginFrame(args);
+}
- impl().scheduler->BeginImplFrame(args);
+void ThreadProxy::WillBeginImplFrame(const BeginFrameArgs& args) {
+ impl().layer_tree_host_impl->WillBeginImplFrame(args);
}
void ThreadProxy::OnCanDrawStateChanged(bool can_draw) {
@@ -1496,7 +1492,7 @@ void ThreadProxy::LayerTreeHostClosedOnImplThread(CompletionEvent* completion) {
layer_tree_host()->DeleteContentsTexturesOnImplThread(
impl().layer_tree_host_impl->resource_provider());
impl().current_resource_update_controller.reset();
- impl().layer_tree_host_impl->SetNeedsBeginImplFrame(false);
+ impl().layer_tree_host_impl->SetNeedsBeginFrame(false);
impl().scheduler.reset();
impl().layer_tree_host_impl.reset();
impl().weak_factory.InvalidateWeakPtrs();
diff --git a/cc/trees/thread_proxy.h b/cc/trees/thread_proxy.h
index 540e83a..b105c93 100644
--- a/cc/trees/thread_proxy.h
+++ b/cc/trees/thread_proxy.h
@@ -75,7 +75,7 @@ class ThreadProxy : public Proxy,
virtual void DidLoseOutputSurfaceOnImplThread() OVERRIDE;
virtual void DidSwapBuffersOnImplThread() OVERRIDE {}
virtual void OnSwapBuffersCompleteOnImplThread() OVERRIDE;
- virtual void BeginImplFrame(const BeginFrameArgs& args) OVERRIDE;
+ virtual void BeginFrame(const BeginFrameArgs& args) OVERRIDE;
virtual void OnCanDrawStateChanged(bool can_draw) OVERRIDE;
virtual void NotifyReadyToActivate() OVERRIDE;
// Please call these 2 functions through
@@ -100,7 +100,8 @@ class ThreadProxy : public Proxy,
virtual void DidManageTiles() OVERRIDE;
// SchedulerClient implementation
- virtual void SetNeedsBeginImplFrame(bool enable) OVERRIDE;
+ virtual void SetNeedsBeginFrame(bool enable) OVERRIDE;
+ virtual void WillBeginImplFrame(const BeginFrameArgs& args) OVERRIDE;
virtual void ScheduledActionSendBeginMainFrame() OVERRIDE;
virtual DrawSwapReadbackResult ScheduledActionDrawAndSwapIfPossible()
OVERRIDE;
diff --git a/content/browser/android/in_process/synchronous_compositor_output_surface.cc b/content/browser/android/in_process/synchronous_compositor_output_surface.cc
index e65291b..af79e1b 100644
--- a/content/browser/android/in_process/synchronous_compositor_output_surface.cc
+++ b/content/browser/android/in_process/synchronous_compositor_output_surface.cc
@@ -123,14 +123,13 @@ void SynchronousCompositorOutputSurface::Reshape(
// Intentional no-op: surface size is controlled by the embedder.
}
-void SynchronousCompositorOutputSurface::SetNeedsBeginImplFrame(
- bool enable) {
+void SynchronousCompositorOutputSurface::SetNeedsBeginFrame(bool enable) {
DCHECK(CalledOnValidThread());
- needs_begin_impl_frame_ = enable;
- client_ready_for_begin_impl_frame_ = true;
+ needs_begin_frame_ = enable;
+ client_ready_for_begin_frame_ = true;
SynchronousCompositorOutputSurfaceDelegate* delegate = GetDelegate();
if (delegate && !invoking_composite_)
- delegate->SetContinuousInvalidate(needs_begin_impl_frame_);
+ delegate->SetContinuousInvalidate(needs_begin_frame_);
}
void SynchronousCompositorOutputSurface::SwapBuffers(
@@ -239,7 +238,7 @@ void SynchronousCompositorOutputSurface::InvokeComposite(
SetExternalDrawConstraints(
adjusted_transform, viewport, clip, valid_for_tile_management);
SetNeedsRedrawRect(gfx::Rect(viewport.size()));
- BeginImplFrame(cc::BeginFrameArgs::CreateForSynchronousCompositor());
+ BeginFrame(cc::BeginFrameArgs::CreateForSynchronousCompositor());
// After software draws (which might move the viewport arbitrarily), restore
// the previous hardware viewport to allow CC's tile manager to prioritize
@@ -258,12 +257,11 @@ void SynchronousCompositorOutputSurface::InvokeComposite(
SynchronousCompositorOutputSurfaceDelegate* delegate = GetDelegate();
if (delegate)
- delegate->SetContinuousInvalidate(needs_begin_impl_frame_);
+ delegate->SetContinuousInvalidate(needs_begin_frame_);
}
-void
-SynchronousCompositorOutputSurface::PostCheckForRetroactiveBeginImplFrame() {
- // Synchronous compositor cannot perform retroactive BeginImplFrames, so
+void SynchronousCompositorOutputSurface::PostCheckForRetroactiveBeginFrame() {
+ // Synchronous compositor cannot perform retroactive BeginFrames, so
// intentionally no-op here.
}
diff --git a/content/browser/android/in_process/synchronous_compositor_output_surface.h b/content/browser/android/in_process/synchronous_compositor_output_surface.h
index c695334..dc8cf7d 100644
--- a/content/browser/android/in_process/synchronous_compositor_output_surface.h
+++ b/content/browser/android/in_process/synchronous_compositor_output_surface.h
@@ -59,7 +59,7 @@ class SynchronousCompositorOutputSurface
virtual bool ForcedDrawToSoftwareDevice() const OVERRIDE;
virtual bool BindToClient(cc::OutputSurfaceClient* surface_client) OVERRIDE;
virtual void Reshape(const gfx::Size& size, float scale_factor) OVERRIDE;
- virtual void SetNeedsBeginImplFrame(bool enable) OVERRIDE;
+ virtual void SetNeedsBeginFrame(bool enable) OVERRIDE;
virtual void SwapBuffers(cc::CompositorFrame* frame) OVERRIDE;
// Partial SynchronousCompositor API implementation.
@@ -80,7 +80,7 @@ class SynchronousCompositorOutputSurface
friend class SoftwareDevice;
// Private OutputSurface overrides.
- virtual void PostCheckForRetroactiveBeginImplFrame() OVERRIDE;
+ virtual void PostCheckForRetroactiveBeginFrame() OVERRIDE;
void InvokeComposite(const gfx::Transform& transform,
gfx::Rect viewport,
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc
index d52a1f2..37d2cd4 100644
--- a/content/public/common/content_switches.cc
+++ b/content/public/common/content_switches.cc
@@ -366,7 +366,7 @@ const char kEnableContainerCulling[] = "enable-container-culling";
// Turns on extremely verbose logging of accessibility events.
const char kEnableAccessibilityLogging[] = "enable-accessibility-logging";
-// Use a BeginImplFrame signal from browser to renderer to schedule rendering.
+// Use a BeginFrame signal from browser to renderer to schedule rendering.
const char kEnableBeginFrameScheduling[] = "enable-begin-frame-scheduling";
// Enables browser plugin for all types of pages.
diff --git a/content/renderer/gpu/compositor_output_surface.cc b/content/renderer/gpu/compositor_output_surface.cc
index 19e5939..dd9d632 100644
--- a/content/renderer/gpu/compositor_output_surface.cc
+++ b/content/renderer/gpu/compositor_output_surface.cc
@@ -80,7 +80,7 @@ CompositorOutputSurface::CompositorOutputSurface(
CompositorOutputSurface::~CompositorOutputSurface() {
DCHECK(CalledOnValidThread());
- SetNeedsBeginImplFrame(false);
+ SetNeedsBeginFrame(false);
if (!HasClient())
return;
UpdateSmoothnessTakesPriority(false);
@@ -192,7 +192,7 @@ void CompositorOutputSurface::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(ViewMsg_SwapCompositorFrameAck, OnSwapAck);
IPC_MESSAGE_HANDLER(ViewMsg_ReclaimCompositorResources, OnReclaimResources);
#if defined(OS_ANDROID)
- IPC_MESSAGE_HANDLER(ViewMsg_BeginFrame, OnBeginImplFrame);
+ IPC_MESSAGE_HANDLER(ViewMsg_BeginFrame, OnBeginFrame);
#endif
IPC_END_MESSAGE_MAP()
}
@@ -205,16 +205,16 @@ void CompositorOutputSurface::OnUpdateVSyncParametersFromBrowser(
}
#if defined(OS_ANDROID)
-void CompositorOutputSurface::SetNeedsBeginImplFrame(bool enable) {
+void CompositorOutputSurface::SetNeedsBeginFrame(bool enable) {
DCHECK(CalledOnValidThread());
- if (needs_begin_impl_frame_ != enable)
+ if (needs_begin_frame_ != enable)
Send(new ViewHostMsg_SetNeedsBeginFrame(routing_id_, enable));
- OutputSurface::SetNeedsBeginImplFrame(enable);
+ OutputSurface::SetNeedsBeginFrame(enable);
}
-void CompositorOutputSurface::OnBeginImplFrame(const cc::BeginFrameArgs& args) {
+void CompositorOutputSurface::OnBeginFrame(const cc::BeginFrameArgs& args) {
DCHECK(CalledOnValidThread());
- BeginImplFrame(args);
+ BeginFrame(args);
}
#endif // defined(OS_ANDROID)
diff --git a/content/renderer/gpu/compositor_output_surface.h b/content/renderer/gpu/compositor_output_surface.h
index a1127c3..df91047 100644
--- a/content/renderer/gpu/compositor_output_surface.h
+++ b/content/renderer/gpu/compositor_output_surface.h
@@ -57,7 +57,7 @@ class CompositorOutputSurface
virtual bool BindToClient(cc::OutputSurfaceClient* client) OVERRIDE;
virtual void SwapBuffers(cc::CompositorFrame* frame) OVERRIDE;
#if defined(OS_ANDROID)
- virtual void SetNeedsBeginImplFrame(bool enable) OVERRIDE;
+ virtual void SetNeedsBeginFrame(bool enable) OVERRIDE;
#endif
// TODO(epenner): This seems out of place here and would be a better fit
@@ -99,7 +99,7 @@ class CompositorOutputSurface
void OnUpdateVSyncParametersFromBrowser(base::TimeTicks timebase,
base::TimeDelta interval);
#if defined(OS_ANDROID)
- void OnBeginImplFrame(const cc::BeginFrameArgs& args);
+ void OnBeginFrame(const cc::BeginFrameArgs& args);
#endif
bool Send(IPC::Message* message);