Chromium Code Reviews| Index: components/scheduler/renderer/renderer_scheduler_impl_unittest.cc |
| diff --git a/components/scheduler/renderer/renderer_scheduler_impl_unittest.cc b/components/scheduler/renderer/renderer_scheduler_impl_unittest.cc |
| index 4956bf135d1ed31f9c69b325f4d3b5cb354d0295..3324d9559c37e4174d147e93b4875d913b188c8b 100644 |
| --- a/components/scheduler/renderer/renderer_scheduler_impl_unittest.cc |
| +++ b/components/scheduler/renderer/renderer_scheduler_impl_unittest.cc |
| @@ -266,6 +266,8 @@ class RendererSchedulerImplTest : public testing::Test { |
| make_scoped_ptr(new TestTimeSource(clock_.get()))); |
| scheduler_->GetTimerTaskCostEstimatorForTesting()->SetTimeSourceForTesting( |
| make_scoped_ptr(new TestTimeSource(clock_.get()))); |
| + scheduler_->GetIdleTimeEstimatorForTesting()->SetTimeSourceForTesting( |
| + make_scoped_ptr(new TestTimeSource(clock_.get()))); |
| } |
| void TearDown() override { |
| @@ -337,6 +339,27 @@ class RendererSchedulerImplTest : public testing::Test { |
| mock_task_runner_->SetAutoAdvanceNowToPendingTasks(false); |
| } |
| + void WillBeginMainThreadGestureFrame() { |
| + scheduler_->DidAnimateForInputOnCompositorThread(); |
| + cc::BeginFrameArgs begin_frame_args1 = cc::BeginFrameArgs::Create( |
|
Sami
2015/10/09 02:32:19
Why begin_frame_args1?
alex clarke (OOO till 29th)
2015/10/15 13:24:01
Done.
|
| + BEGINFRAME_FROM_HERE, clock_->NowTicks(), base::TimeTicks(), |
| + base::TimeDelta::FromMilliseconds(16), cc::BeginFrameArgs::NORMAL); |
| + begin_frame_args1.on_critical_path = true; |
| + scheduler_->WillBeginFrame(begin_frame_args1); |
| + } |
| + |
| + void SimulateMainFrameGestureCompositorTask( |
|
Sami
2015/10/09 02:32:19
s/Frame/Thread/?
alex clarke (OOO till 29th)
2015/10/15 13:24:01
Done.
|
| + base::TimeDelta begin_main_frame_duration) { |
| + WillBeginMainThreadGestureFrame(); |
| + clock_->Advance(begin_main_frame_duration); |
| + scheduler_->DidCommitFrameToCompositor(); |
| + } |
| + |
| + void SimulateTimerTask(base::TimeDelta duration) { |
| + clock_->Advance(duration); |
| + simulate_timer_task_ran_ = true; |
| + } |
| + |
| void EnableIdleTasks() { DoMainFrame(); } |
| UseCase CurrentUseCase() { |
| @@ -364,6 +387,10 @@ class RendererSchedulerImplTest : public testing::Test { |
| return scheduler_->MainThreadOnly().timer_tasks_seem_expensive; |
| } |
| + base::TimeTicks EstimatedNextFrameBegin() { |
| + return scheduler_->MainThreadOnly().estimated_next_frame_begin; |
| + } |
| + |
| // Helper for posting several tasks of specific types. |task_descriptor| is a |
| // string with space delimited task identifiers. The first letter of each |
| // task identifier specifies the task type: |
| @@ -466,6 +493,7 @@ class RendererSchedulerImplTest : public testing::Test { |
| scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner_; |
| scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_; |
| scoped_refptr<base::SingleThreadTaskRunner> timer_task_runner_; |
| + bool simulate_timer_task_ran_; |
| DISALLOW_COPY_AND_ASSIGN(RendererSchedulerImplTest); |
| }; |
| @@ -736,10 +764,9 @@ TEST_F(RendererSchedulerImplTest, TestCompositorPolicy_DidAnimateForInput) { |
| EXPECT_EQ(RendererScheduler::UseCase::COMPOSITOR_GESTURE, CurrentUseCase()); |
| } |
| -// TODO(skyostil): Re-enable once timer blocking is re-enabled. |
| TEST_F( |
| RendererSchedulerImplTest, |
| - DISABLED_TestCompositorPolicy_ExpensiveTimersDontRunWhenMainThreadOnCriticalPath) { |
| + TestCompositorPolicy_ExpensiveTimersDontRunWhenMainThreadOnCriticalPath) { |
| std::vector<std::string> run_order; |
| SimulateExpensiveTasks(timer_task_runner_); |
| @@ -748,12 +775,7 @@ TEST_F( |
| PostTestTasks(&run_order, "C1 T1"); |
| // Trigger main_thread_gesture UseCase |
| - scheduler_->DidAnimateForInputOnCompositorThread(); |
| - cc::BeginFrameArgs begin_frame_args1 = cc::BeginFrameArgs::Create( |
| - BEGINFRAME_FROM_HERE, clock_->NowTicks(), base::TimeTicks(), |
| - base::TimeDelta::FromMilliseconds(16), cc::BeginFrameArgs::NORMAL); |
| - begin_frame_args1.on_critical_path = true; |
| - scheduler_->WillBeginFrame(begin_frame_args1); |
| + WillBeginMainThreadGestureFrame(); |
| RunUntilIdle(); |
| EXPECT_EQ(RendererScheduler::UseCase::MAIN_THREAD_GESTURE, CurrentUseCase()); |
| @@ -773,12 +795,7 @@ TEST_F(RendererSchedulerImplTest, Navigation_ResetsTaskCostEstimations) { |
| scheduler_->OnNavigationStarted(); |
| PostTestTasks(&run_order, "C1 T1"); |
| - scheduler_->DidAnimateForInputOnCompositorThread(); |
| - cc::BeginFrameArgs begin_frame_args1 = cc::BeginFrameArgs::Create( |
| - BEGINFRAME_FROM_HERE, clock_->NowTicks(), base::TimeTicks(), |
| - base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL); |
| - begin_frame_args1.on_critical_path = true; |
| - scheduler_->WillBeginFrame(begin_frame_args1); |
| + WillBeginMainThreadGestureFrame(); |
| scheduler_->DidCommitFrameToCompositor(); // Starts Idle Period |
| RunUntilIdle(); |
| @@ -2101,5 +2118,62 @@ TEST_F( |
| EXPECT_THAT(run_order, testing::ElementsAre(std::string("D1"))); |
| } |
| +TEST_F(RendererSchedulerImplTest, ModeratelyExpensiveTimer_NotBlocked) { |
| + for (int i = 0; i < 20; i++) { |
| + simulate_timer_task_ran_ = false; |
| + compositor_task_runner_->PostTask( |
| + FROM_HERE, |
| + base::Bind( |
| + &RendererSchedulerImplTest::SimulateMainFrameGestureCompositorTask, |
| + base::Unretained(this), base::TimeDelta::FromMilliseconds(4))); |
| + timer_task_runner_->PostTask( |
| + FROM_HERE, base::Bind(&RendererSchedulerImplTest::SimulateTimerTask, |
| + base::Unretained(this), |
| + base::TimeDelta::FromMilliseconds(10))); |
| + RunUntilIdle(); |
| + EXPECT_TRUE(simulate_timer_task_ran_); |
| + EXPECT_EQ(RendererScheduler::UseCase::MAIN_THREAD_GESTURE, |
| + CurrentUseCase()); |
| + EXPECT_FALSE(LoadingTasksSeemExpensive()); |
| + EXPECT_FALSE(TimerTasksSeemExpensive()); |
| + |
| + base::TimeDelta time_till_next_frame = |
| + EstimatedNextFrameBegin() - clock_->NowTicks(); |
| + if (time_till_next_frame > base::TimeDelta()) |
| + clock_->Advance(time_till_next_frame); |
| + } |
| +} |
| + |
| +TEST_F(RendererSchedulerImplTest, ExpensiveTimer_Blocked) { |
| + for (int i = 0; i < 20; i++) { |
| + simulate_timer_task_ran_ = false; |
| + compositor_task_runner_->PostTask( |
| + FROM_HERE, |
| + base::Bind( |
| + &RendererSchedulerImplTest::SimulateMainFrameGestureCompositorTask, |
| + base::Unretained(this), base::TimeDelta::FromMilliseconds(8))); |
| + timer_task_runner_->PostTask( |
| + FROM_HERE, base::Bind(&RendererSchedulerImplTest::SimulateTimerTask, |
| + base::Unretained(this), |
| + base::TimeDelta::FromMilliseconds(10))); |
| + |
| + RunUntilIdle(); |
| + EXPECT_EQ(RendererScheduler::UseCase::MAIN_THREAD_GESTURE, |
| + CurrentUseCase()); |
| + EXPECT_FALSE(LoadingTasksSeemExpensive()); |
| + if (i == 0) { |
| + EXPECT_FALSE(TimerTasksSeemExpensive()); |
| + EXPECT_TRUE(simulate_timer_task_ran_); |
| + } else { |
| + EXPECT_TRUE(TimerTasksSeemExpensive()); |
| + EXPECT_FALSE(simulate_timer_task_ran_); |
| + } |
| + |
| + base::TimeDelta time_till_next_frame = |
| + EstimatedNextFrameBegin() - clock_->NowTicks(); |
| + if (time_till_next_frame > base::TimeDelta()) |
| + clock_->Advance(time_till_next_frame); |
| + } |
| +} |
| } // namespace scheduler |