Index: cc/scheduler/scheduler_unittest.cc |
diff --git a/cc/scheduler/scheduler_unittest.cc b/cc/scheduler/scheduler_unittest.cc |
index f4027bf4a112fdea5eee4b2138fc928d1ea5b38f..67a064b59d6e93cfefa37f02dc34dfb25edcc217 100644 |
--- a/cc/scheduler/scheduler_unittest.cc |
+++ b/cc/scheduler/scheduler_unittest.cc |
@@ -10,6 +10,7 @@ |
#include "base/memory/scoped_vector.h" |
#include "base/message_loop/message_loop.h" |
#include "base/run_loop.h" |
+#include "base/test/test_simple_task_runner.h" |
#include "base/time/time.h" |
#include "cc/test/scheduler_test_common.h" |
#include "testing/gmock/include/gmock/gmock.h" |
@@ -31,19 +32,10 @@ |
namespace cc { |
namespace { |
-void InitializeOutputSurfaceAndFirstCommit(Scheduler* scheduler) { |
- scheduler->DidCreateAndInitializeOutputSurface(); |
- scheduler->SetNeedsCommit(); |
- scheduler->NotifyBeginMainFrameStarted(); |
- scheduler->NotifyReadyToCommit(); |
- // Go through the motions to draw the commit. |
- scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting()); |
- scheduler->OnBeginImplFrameDeadline(); |
- // We need another BeginImplFrame so Scheduler calls |
- // SetNeedsBeginImplFrame(false). |
- scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting()); |
- scheduler->OnBeginImplFrameDeadline(); |
-} |
+class FakeSchedulerClient; |
+ |
+void InitializeOutputSurfaceAndFirstCommit(Scheduler* scheduler, |
+ FakeSchedulerClient* client); |
class FakeSchedulerClient : public SchedulerClient { |
public: |
@@ -62,8 +54,8 @@ class FakeSchedulerClient : public SchedulerClient { |
} |
Scheduler* CreateScheduler(const SchedulerSettings& settings) { |
- scheduler_ = |
- Scheduler::Create(this, settings, 0, base::MessageLoopProxy::current()); |
+ task_runner_ = new base::TestSimpleTaskRunner; |
+ scheduler_ = Scheduler::Create(this, settings, 0, task_runner_); |
return scheduler_.get(); |
} |
@@ -81,6 +73,8 @@ class FakeSchedulerClient : public SchedulerClient { |
return posted_begin_impl_frame_deadline_; |
} |
+ base::TestSimpleTaskRunner& task_runner() { return *task_runner_; } |
+ |
int ActionIndex(const char* action) const { |
for (size_t i = 0; i < actions_.size(); i++) |
if (!strcmp(actions_[i], action)) |
@@ -190,8 +184,33 @@ class FakeSchedulerClient : public SchedulerClient { |
std::vector<const char*> actions_; |
ScopedVector<base::Value> states_; |
scoped_ptr<Scheduler> scheduler_; |
+ scoped_refptr<base::TestSimpleTaskRunner> task_runner_; |
}; |
+void InitializeOutputSurfaceAndFirstCommit(Scheduler* scheduler, |
+ FakeSchedulerClient* client) { |
+ scheduler->DidCreateAndInitializeOutputSurface(); |
+ scheduler->SetNeedsCommit(); |
+ scheduler->NotifyBeginMainFrameStarted(); |
+ scheduler->NotifyReadyToCommit(); |
+ // Go through the motions to draw the commit. |
+ scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting()); |
+ |
+ // Run the posted deadline task. |
+ EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending()); |
+ client->task_runner().RunPendingTasks(); |
+ EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending()); |
+ |
+ // We need another BeginImplFrame so Scheduler calls |
+ // SetNeedsBeginImplFrame(false). |
+ scheduler->BeginImplFrame(BeginFrameArgs::CreateForTesting()); |
+ |
+ // Run the posted deadline task. |
+ EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending()); |
+ client->task_runner().RunPendingTasks(); |
+ EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending()); |
+} |
+ |
TEST(SchedulerTest, InitializeOutputSurfaceDoesNotBeginImplFrame) { |
FakeSchedulerClient client; |
SchedulerSettings default_scheduler_settings; |
@@ -215,7 +234,7 @@ TEST(SchedulerTest, RequestCommit) { |
scheduler->SetCanDraw(true); |
EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client); |
- InitializeOutputSurfaceAndFirstCommit(scheduler); |
+ InitializeOutputSurfaceAndFirstCommit(scheduler, &client); |
// SetNeedsCommit should begin the frame on the next BeginImplFrame. |
client.Reset(); |
@@ -282,7 +301,7 @@ TEST(SchedulerTest, RequestCommitAfterBeginMainFrameSent) { |
scheduler->SetCanDraw(true); |
EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client); |
- InitializeOutputSurfaceAndFirstCommit(scheduler); |
+ InitializeOutputSurfaceAndFirstCommit(scheduler, &client); |
client.Reset(); |
// SetNeedsCommit should begin the frame. |
@@ -356,7 +375,7 @@ TEST(SchedulerTest, TextureAcquisitionCausesCommitInsteadOfDraw) { |
scheduler->SetCanDraw(true); |
EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client); |
- InitializeOutputSurfaceAndFirstCommit(scheduler); |
+ InitializeOutputSurfaceAndFirstCommit(scheduler, &client); |
client.Reset(); |
scheduler->SetNeedsRedraw(); |
EXPECT_TRUE(scheduler->RedrawPending()); |
@@ -456,7 +475,7 @@ TEST(SchedulerTest, TextureAcquisitionCollision) { |
scheduler->SetCanDraw(true); |
EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client); |
- InitializeOutputSurfaceAndFirstCommit(scheduler); |
+ InitializeOutputSurfaceAndFirstCommit(scheduler, &client); |
client.Reset(); |
scheduler->SetNeedsCommit(); |
@@ -624,7 +643,7 @@ TEST(SchedulerTest, RequestRedrawInsideDraw) { |
scheduler->SetCanStart(); |
scheduler->SetVisible(true); |
scheduler->SetCanDraw(true); |
- InitializeOutputSurfaceAndFirstCommit(scheduler); |
+ InitializeOutputSurfaceAndFirstCommit(scheduler, &client); |
client.Reset(); |
scheduler->SetNeedsRedraw(); |
@@ -661,7 +680,7 @@ TEST(SchedulerTest, RequestRedrawInsideFailedDraw) { |
scheduler->SetCanStart(); |
scheduler->SetVisible(true); |
scheduler->SetCanDraw(true); |
- InitializeOutputSurfaceAndFirstCommit(scheduler); |
+ InitializeOutputSurfaceAndFirstCommit(scheduler, &client); |
client.Reset(); |
client.SetDrawWillHappen(false); |
@@ -743,7 +762,7 @@ TEST(SchedulerTest, RequestCommitInsideDraw) { |
scheduler->SetCanStart(); |
scheduler->SetVisible(true); |
scheduler->SetCanDraw(true); |
- InitializeOutputSurfaceAndFirstCommit(scheduler); |
+ InitializeOutputSurfaceAndFirstCommit(scheduler, &client); |
client.Reset(); |
EXPECT_FALSE(client.needs_begin_impl_frame()); |
@@ -788,7 +807,7 @@ TEST(SchedulerTest, RequestCommitInsideFailedDraw) { |
scheduler->SetCanStart(); |
scheduler->SetVisible(true); |
scheduler->SetCanDraw(true); |
- InitializeOutputSurfaceAndFirstCommit(scheduler); |
+ InitializeOutputSurfaceAndFirstCommit(scheduler, &client); |
client.Reset(); |
client.SetDrawWillHappen(false); |
@@ -834,7 +853,7 @@ TEST(SchedulerTest, NoSwapWhenDrawFails) { |
scheduler->SetCanStart(); |
scheduler->SetVisible(true); |
scheduler->SetCanDraw(true); |
- InitializeOutputSurfaceAndFirstCommit(scheduler); |
+ InitializeOutputSurfaceAndFirstCommit(scheduler, &client); |
client.Reset(); |
scheduler->SetNeedsRedraw(); |
@@ -924,7 +943,7 @@ TEST(SchedulerTest, ManageTiles) { |
scheduler->SetCanStart(); |
scheduler->SetVisible(true); |
scheduler->SetCanDraw(true); |
- InitializeOutputSurfaceAndFirstCommit(scheduler); |
+ InitializeOutputSurfaceAndFirstCommit(scheduler, &client); |
// Request both draw and manage tiles. ManageTiles shouldn't |
// be trigged until BeginImplFrame. |
@@ -1028,7 +1047,7 @@ TEST(SchedulerTest, ManageTilesOncePerFrame) { |
scheduler->SetCanStart(); |
scheduler->SetVisible(true); |
scheduler->SetCanDraw(true); |
- InitializeOutputSurfaceAndFirstCommit(scheduler); |
+ InitializeOutputSurfaceAndFirstCommit(scheduler, &client); |
// If DidManageTiles during a frame, then ManageTiles should not occur again. |
scheduler->SetNeedsManageTiles(); |
@@ -1141,7 +1160,7 @@ TEST(SchedulerTest, TriggerBeginFrameDeadlineEarly) { |
scheduler->SetCanStart(); |
scheduler->SetVisible(true); |
scheduler->SetCanDraw(true); |
- InitializeOutputSurfaceAndFirstCommit(scheduler); |
+ InitializeOutputSurfaceAndFirstCommit(scheduler, &client); |
client.Reset(); |
BeginFrameArgs impl_frame_args = BeginFrameArgs::CreateForTesting(); |
@@ -1196,7 +1215,7 @@ void MainFrameInHighLatencyMode(int64 begin_main_frame_to_commit_estimate_in_ms, |
scheduler->SetVisible(true); |
scheduler->SetCanDraw(true); |
scheduler->SetSmoothnessTakesPriority(smoothness_takes_priority); |
- InitializeOutputSurfaceAndFirstCommit(scheduler); |
+ InitializeOutputSurfaceAndFirstCommit(scheduler, &client); |
// Impl thread hits deadline before commit finishes. |
client.Reset(); |
@@ -1249,15 +1268,6 @@ TEST(SchedulerTest, NotSkipMainFrameInPreferSmoothnessMode) { |
MainFrameInHighLatencyMode(1, 1, true, true); |
} |
-void SpinForMillis(int millis) { |
- base::RunLoop run_loop; |
- base::MessageLoop::current()->PostDelayedTask( |
- FROM_HERE, |
- run_loop.QuitClosure(), |
- base::TimeDelta::FromMilliseconds(millis)); |
- run_loop.Run(); |
-} |
- |
TEST(SchedulerTest, PollForCommitCompletion) { |
// Since we are simulating a long commit, set up a client with draw duration |
// estimates that prevent skipping main frames to get to low latency mode. |
@@ -1266,9 +1276,8 @@ TEST(SchedulerTest, PollForCommitCompletion) { |
base::TimeDelta::FromMilliseconds(32), |
base::TimeDelta::FromMilliseconds(32)); |
client.set_log_anticipated_draw_time_change(true); |
- SchedulerSettings settings = SchedulerSettings(); |
- settings.throttle_frame_production = false; |
- Scheduler* scheduler = client.CreateScheduler(settings); |
+ SchedulerSettings default_scheduler_settings; |
+ Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); |
scheduler->SetCanDraw(true); |
scheduler->SetCanStart(); |
@@ -1280,16 +1289,20 @@ TEST(SchedulerTest, PollForCommitCompletion) { |
scheduler->NotifyBeginMainFrameStarted(); |
scheduler->NotifyReadyToCommit(); |
scheduler->SetNeedsRedraw(); |
+ |
BeginFrameArgs impl_frame_args = BeginFrameArgs::CreateForTesting(); |
- const int interval = 1; |
- impl_frame_args.interval = base::TimeDelta::FromMilliseconds(interval); |
+ impl_frame_args.interval = base::TimeDelta::FromMilliseconds(1000); |
scheduler->BeginImplFrame(impl_frame_args); |
- scheduler->OnBeginImplFrameDeadline(); |
- // At this point, we've drawn a frame. Start another commit, but hold off on |
+ EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending()); |
+ client.task_runner().RunPendingTasks(); // Run posted deadline. |
+ EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending()); |
+ |
+ // At this point, we've drawn a frame. Start another commit, but hold off on |
// the NotifyReadyToCommit for now. |
EXPECT_FALSE(scheduler->CommitPending()); |
scheduler->SetNeedsCommit(); |
+ scheduler->BeginImplFrame(impl_frame_args); |
EXPECT_TRUE(scheduler->CommitPending()); |
// Spin the event loop a few times and make sure we get more |
@@ -1298,9 +1311,23 @@ TEST(SchedulerTest, PollForCommitCompletion) { |
// Does three iterations to make sure that the timer is properly repeating. |
for (int i = 0; i < 3; ++i) { |
- // Wait for 2x the frame interval to match |
- // Scheduler::advance_commit_state_timer_'s rate. |
- SpinForMillis(interval * 2); |
+ EXPECT_EQ((impl_frame_args.interval * 2).InMicroseconds(), |
+ client.task_runner().NextPendingTaskDelay().InMicroseconds()) |
+ << *scheduler->StateAsValue(); |
+ client.task_runner().RunPendingTasks(); |
+ EXPECT_GT(client.num_actions_(), actions_so_far); |
+ EXPECT_STREQ(client.Action(client.num_actions_() - 1), |
+ "DidAnticipatedDrawTimeChange"); |
+ actions_so_far = client.num_actions_(); |
+ } |
+ |
+ // 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(), |
+ client.task_runner().NextPendingTaskDelay().InMicroseconds()) |
+ << *scheduler->StateAsValue(); |
+ client.task_runner().RunPendingTasks(); |
EXPECT_GT(client.num_actions_(), actions_so_far); |
EXPECT_STREQ(client.Action(client.num_actions_() - 1), |
"DidAnticipatedDrawTimeChange"); |