| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/renderer/scheduler/renderer_scheduler_impl.h" | 5 #include "content/renderer/scheduler/renderer_scheduler_impl.h" |
| 6 | 6 |
| 7 #include "base/callback.h" | 7 #include "base/callback.h" |
| 8 #include "cc/output/begin_frame_args.h" | 8 #include "cc/output/begin_frame_args.h" |
| 9 #include "cc/test/ordered_simple_task_runner.h" | 9 #include "cc/test/ordered_simple_task_runner.h" |
| 10 #include "testing/gmock/include/gmock/gmock.h" | 10 #include "testing/gmock/include/gmock/gmock.h" |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 public: | 44 public: |
| 45 using Policy = RendererSchedulerImpl::Policy; | 45 using Policy = RendererSchedulerImpl::Policy; |
| 46 | 46 |
| 47 RendererSchedulerImplTest() | 47 RendererSchedulerImplTest() |
| 48 : clock_(cc::TestNowSource::Create(5000)), | 48 : clock_(cc::TestNowSource::Create(5000)), |
| 49 mock_task_runner_(new cc::OrderedSimpleTaskRunner(clock_, false)), | 49 mock_task_runner_(new cc::OrderedSimpleTaskRunner(clock_, false)), |
| 50 scheduler_(new RendererSchedulerImpl(mock_task_runner_)), | 50 scheduler_(new RendererSchedulerImpl(mock_task_runner_)), |
| 51 default_task_runner_(scheduler_->DefaultTaskRunner()), | 51 default_task_runner_(scheduler_->DefaultTaskRunner()), |
| 52 compositor_task_runner_(scheduler_->CompositorTaskRunner()), | 52 compositor_task_runner_(scheduler_->CompositorTaskRunner()), |
| 53 loading_task_runner_(scheduler_->LoadingTaskRunner()), | 53 loading_task_runner_(scheduler_->LoadingTaskRunner()), |
| 54 idle_task_runner_(scheduler_->IdleTaskRunner()) { | 54 idle_task_runner_(scheduler_->IdleTaskRunner()), |
| 55 timer_task_runner_(scheduler_->TimerTaskRunner()) { |
| 55 scheduler_->SetTimeSourceForTesting(clock_); | 56 scheduler_->SetTimeSourceForTesting(clock_); |
| 56 } | 57 } |
| 57 ~RendererSchedulerImplTest() override {} | 58 ~RendererSchedulerImplTest() override {} |
| 58 | 59 |
| 59 void RunUntilIdle() { mock_task_runner_->RunUntilIdle(); } | 60 void RunUntilIdle() { mock_task_runner_->RunUntilIdle(); } |
| 60 | 61 |
| 61 void DoMainFrame() { | 62 void DoMainFrame() { |
| 62 scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create( | 63 scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create( |
| 63 BEGINFRAME_FROM_HERE, clock_->Now(), base::TimeTicks(), | 64 BEGINFRAME_FROM_HERE, clock_->Now(), base::TimeTicks(), |
| 64 base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL)); | 65 base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL)); |
| 65 scheduler_->DidCommitFrameToCompositor(); | 66 scheduler_->DidCommitFrameToCompositor(); |
| 66 } | 67 } |
| 67 | 68 |
| 68 void EnableIdleTasks() { DoMainFrame(); } | 69 void EnableIdleTasks() { DoMainFrame(); } |
| 69 | 70 |
| 70 Policy CurrentPolicy() { return scheduler_->current_policy_; } | 71 Policy CurrentPolicy() { return scheduler_->current_policy_; } |
| 71 | 72 |
| 72 // Helper for posting several tasks of specific types. |task_descriptor| is a | 73 // Helper for posting several tasks of specific types. |task_descriptor| is a |
| 73 // string with space delimited task identifiers. The first letter of each | 74 // string with space delimited task identifiers. The first letter of each |
| 74 // task identifier specifies the task type: | 75 // task identifier specifies the task type: |
| 75 // - 'D': Default task | 76 // - 'D': Default task |
| 76 // - 'C': Compositor task | 77 // - 'C': Compositor task |
| 77 // - 'L': Loading task | 78 // - 'L': Loading task |
| 78 // - 'I': Idle task | 79 // - 'I': Idle task |
| 80 // - 'T': Timer task |
| 79 void PostTestTasks(std::vector<std::string>* run_order, | 81 void PostTestTasks(std::vector<std::string>* run_order, |
| 80 const std::string& task_descriptor) { | 82 const std::string& task_descriptor) { |
| 81 std::istringstream stream(task_descriptor); | 83 std::istringstream stream(task_descriptor); |
| 82 while (!stream.eof()) { | 84 while (!stream.eof()) { |
| 83 std::string task; | 85 std::string task; |
| 84 stream >> task; | 86 stream >> task; |
| 85 switch (task[0]) { | 87 switch (task[0]) { |
| 86 case 'D': | 88 case 'D': |
| 87 default_task_runner_->PostTask( | 89 default_task_runner_->PostTask( |
| 88 FROM_HERE, base::Bind(&AppendToVectorTestTask, run_order, task)); | 90 FROM_HERE, base::Bind(&AppendToVectorTestTask, run_order, task)); |
| 89 break; | 91 break; |
| 90 case 'C': | 92 case 'C': |
| 91 compositor_task_runner_->PostTask( | 93 compositor_task_runner_->PostTask( |
| 92 FROM_HERE, base::Bind(&AppendToVectorTestTask, run_order, task)); | 94 FROM_HERE, base::Bind(&AppendToVectorTestTask, run_order, task)); |
| 93 break; | 95 break; |
| 94 case 'L': | 96 case 'L': |
| 95 loading_task_runner_->PostTask( | 97 loading_task_runner_->PostTask( |
| 96 FROM_HERE, base::Bind(&AppendToVectorTestTask, run_order, task)); | 98 FROM_HERE, base::Bind(&AppendToVectorTestTask, run_order, task)); |
| 97 break; | 99 break; |
| 98 case 'I': | 100 case 'I': |
| 99 idle_task_runner_->PostIdleTask( | 101 idle_task_runner_->PostIdleTask( |
| 100 FROM_HERE, | 102 FROM_HERE, |
| 101 base::Bind(&AppendToVectorIdleTestTask, run_order, task)); | 103 base::Bind(&AppendToVectorIdleTestTask, run_order, task)); |
| 102 break; | 104 break; |
| 105 case 'T': |
| 106 timer_task_runner_->PostTask( |
| 107 FROM_HERE, base::Bind(&AppendToVectorTestTask, run_order, task)); |
| 108 break; |
| 103 default: | 109 default: |
| 104 NOTREACHED(); | 110 NOTREACHED(); |
| 105 } | 111 } |
| 106 } | 112 } |
| 107 } | 113 } |
| 108 | 114 |
| 109 protected: | 115 protected: |
| 110 static base::TimeDelta priority_escalation_after_input_duration() { | 116 static base::TimeDelta priority_escalation_after_input_duration() { |
| 111 return base::TimeDelta::FromMilliseconds( | 117 return base::TimeDelta::FromMilliseconds( |
| 112 RendererSchedulerImpl::kPriorityEscalationAfterInputMillis); | 118 RendererSchedulerImpl::kPriorityEscalationAfterInputMillis); |
| 113 } | 119 } |
| 114 | 120 |
| 115 scoped_refptr<cc::TestNowSource> clock_; | 121 scoped_refptr<cc::TestNowSource> clock_; |
| 116 scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_; | 122 scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_; |
| 117 | 123 |
| 118 scoped_ptr<RendererSchedulerImpl> scheduler_; | 124 scoped_ptr<RendererSchedulerImpl> scheduler_; |
| 119 scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_; | 125 scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_; |
| 120 scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_; | 126 scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_; |
| 121 scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner_; | 127 scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner_; |
| 122 scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_; | 128 scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_; |
| 129 scoped_refptr<base::SingleThreadTaskRunner> timer_task_runner_; |
| 123 | 130 |
| 124 DISALLOW_COPY_AND_ASSIGN(RendererSchedulerImplTest); | 131 DISALLOW_COPY_AND_ASSIGN(RendererSchedulerImplTest); |
| 125 }; | 132 }; |
| 126 | 133 |
| 127 void NullTask() { | 134 void NullTask() { |
| 128 } | 135 } |
| 129 | 136 |
| 130 void AppendToVectorReentrantTask( | 137 void AppendToVectorReentrantTask( |
| 131 scoped_refptr<base::SingleThreadTaskRunner> task_runner, | 138 scoped_refptr<base::SingleThreadTaskRunner> task_runner, |
| 132 std::vector<int>* vector, | 139 std::vector<int>* vector, |
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 438 EnableIdleTasks(); | 445 EnableIdleTasks(); |
| 439 RunUntilIdle(); | 446 RunUntilIdle(); |
| 440 EXPECT_THAT(run_order, | 447 EXPECT_THAT(run_order, |
| 441 testing::ElementsAre(std::string("C1"), std::string("C2"), | 448 testing::ElementsAre(std::string("C1"), std::string("C2"), |
| 442 std::string("D1"), std::string("D2"), | 449 std::string("D1"), std::string("D2"), |
| 443 std::string("I1"))); | 450 std::string("I1"))); |
| 444 } | 451 } |
| 445 | 452 |
| 446 TEST_F(RendererSchedulerImplTest, TestTouchstartPolicy) { | 453 TEST_F(RendererSchedulerImplTest, TestTouchstartPolicy) { |
| 447 std::vector<std::string> run_order; | 454 std::vector<std::string> run_order; |
| 448 PostTestTasks(&run_order, "L1 D1 C1 D2 C2"); | 455 PostTestTasks(&run_order, "L1 D1 C1 D2 C2 T1 T2"); |
| 449 | 456 |
| 450 // Observation of touchstart should defer execution of idle and loading tasks. | 457 // Observation of touchstart should defer execution of timer, idle and loading |
| 458 // tasks. |
| 451 scheduler_->DidReceiveInputEventOnCompositorThread( | 459 scheduler_->DidReceiveInputEventOnCompositorThread( |
| 452 FakeInputEvent(blink::WebInputEvent::TouchStart)); | 460 FakeInputEvent(blink::WebInputEvent::TouchStart)); |
| 453 RunUntilIdle(); | 461 RunUntilIdle(); |
| 454 EXPECT_THAT(run_order, | 462 EXPECT_THAT(run_order, |
| 455 testing::ElementsAre(std::string("C1"), std::string("C2"), | 463 testing::ElementsAre(std::string("C1"), std::string("C2"), |
| 456 std::string("D1"), std::string("D2"))); | 464 std::string("D1"), std::string("D2"))); |
| 457 | 465 |
| 458 // Meta events like TapDown/FlingCancel shouldn't affect the priority. | 466 // Meta events like TapDown/FlingCancel shouldn't affect the priority. |
| 459 run_order.clear(); | 467 run_order.clear(); |
| 460 scheduler_->DidReceiveInputEventOnCompositorThread( | 468 scheduler_->DidReceiveInputEventOnCompositorThread( |
| 461 FakeInputEvent(blink::WebInputEvent::GestureFlingCancel)); | 469 FakeInputEvent(blink::WebInputEvent::GestureFlingCancel)); |
| 462 scheduler_->DidReceiveInputEventOnCompositorThread( | 470 scheduler_->DidReceiveInputEventOnCompositorThread( |
| 463 FakeInputEvent(blink::WebInputEvent::GestureTapDown)); | 471 FakeInputEvent(blink::WebInputEvent::GestureTapDown)); |
| 464 RunUntilIdle(); | 472 RunUntilIdle(); |
| 465 EXPECT_TRUE(run_order.empty()); | 473 EXPECT_TRUE(run_order.empty()); |
| 466 | 474 |
| 467 // Action events like ScrollBegin will kick us back into compositor priority, | 475 // Action events like ScrollBegin will kick us back into compositor priority, |
| 468 // allowing servie of the loading and idle queues. | 476 // allowing servie of the timer, loading and idle queues. |
| 469 run_order.clear(); | 477 run_order.clear(); |
| 470 scheduler_->DidReceiveInputEventOnCompositorThread( | 478 scheduler_->DidReceiveInputEventOnCompositorThread( |
| 471 FakeInputEvent(blink::WebInputEvent::GestureScrollBegin)); | 479 FakeInputEvent(blink::WebInputEvent::GestureScrollBegin)); |
| 472 RunUntilIdle(); | 480 RunUntilIdle(); |
| 473 EXPECT_THAT(run_order, testing::ElementsAre(std::string("L1"))); | 481 // Note that the Timer tasks run before the loading task because we are in |
| 482 // COMPOSITOR_PRIORITY policy. |
| 483 EXPECT_THAT(run_order, |
| 484 testing::ElementsAre(std::string("T1"), std::string("T2"), |
| 485 std::string("L1"))); |
| 474 } | 486 } |
| 475 | 487 |
| 476 TEST_F(RendererSchedulerImplTest, | 488 TEST_F(RendererSchedulerImplTest, |
| 477 DidReceiveInputEventOnCompositorThread_IgnoresMouseMove_WhenMouseUp) { | 489 DidReceiveInputEventOnCompositorThread_IgnoresMouseMove_WhenMouseUp) { |
| 478 std::vector<std::string> run_order; | 490 std::vector<std::string> run_order; |
| 479 PostTestTasks(&run_order, "I1 D1 C1 D2 C2"); | 491 PostTestTasks(&run_order, "I1 D1 C1 D2 C2"); |
| 480 | 492 |
| 481 scheduler_->DidReceiveInputEventOnCompositorThread( | 493 scheduler_->DidReceiveInputEventOnCompositorThread( |
| 482 FakeInputEvent(blink::WebInputEvent::MouseMove)); | 494 FakeInputEvent(blink::WebInputEvent::MouseMove)); |
| 483 EnableIdleTasks(); | 495 EnableIdleTasks(); |
| (...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 840 RunUntilIdle(); | 852 RunUntilIdle(); |
| 841 EXPECT_EQ(Policy::COMPOSITOR_PRIORITY, CurrentPolicy()); | 853 EXPECT_EQ(Policy::COMPOSITOR_PRIORITY, CurrentPolicy()); |
| 842 | 854 |
| 843 // Process the input event with a new BeginMainFrame. | 855 // Process the input event with a new BeginMainFrame. |
| 844 DoMainFrame(); | 856 DoMainFrame(); |
| 845 clock_->AdvanceNow(2 * priority_escalation_after_input_duration()); | 857 clock_->AdvanceNow(2 * priority_escalation_after_input_duration()); |
| 846 RunUntilIdle(); | 858 RunUntilIdle(); |
| 847 EXPECT_EQ(Policy::NORMAL, CurrentPolicy()); | 859 EXPECT_EQ(Policy::NORMAL, CurrentPolicy()); |
| 848 } | 860 } |
| 849 | 861 |
| 862 TEST_F(RendererSchedulerImplTest, TimerQueueEnabledByDefault) { |
| 863 std::vector<std::string> run_order; |
| 864 PostTestTasks(&run_order, "T1 T2"); |
| 865 RunUntilIdle(); |
| 866 EXPECT_THAT(run_order, |
| 867 testing::ElementsAre(std::string("T1"), std::string("T2"))); |
| 868 } |
| 869 |
| 870 TEST_F(RendererSchedulerImplTest, SuspendAndResumeTimerQueue) { |
| 871 std::vector<std::string> run_order; |
| 872 PostTestTasks(&run_order, "T1 T2"); |
| 873 |
| 874 scheduler_->SuspendTimerQueue(); |
| 875 RunUntilIdle(); |
| 876 EXPECT_TRUE(run_order.empty()); |
| 877 |
| 878 scheduler_->ResumeTimerQueue(); |
| 879 RunUntilIdle(); |
| 880 EXPECT_THAT(run_order, |
| 881 testing::ElementsAre(std::string("T1"), std::string("T2"))); |
| 882 } |
| 883 |
| 884 TEST_F(RendererSchedulerImplTest, MultipleSuspendsNeedMultipleResumes) { |
| 885 std::vector<std::string> run_order; |
| 886 PostTestTasks(&run_order, "T1 T2"); |
| 887 |
| 888 scheduler_->SuspendTimerQueue(); |
| 889 scheduler_->SuspendTimerQueue(); |
| 890 scheduler_->SuspendTimerQueue(); |
| 891 RunUntilIdle(); |
| 892 EXPECT_TRUE(run_order.empty()); |
| 893 |
| 894 scheduler_->ResumeTimerQueue(); |
| 895 RunUntilIdle(); |
| 896 EXPECT_TRUE(run_order.empty()); |
| 897 |
| 898 scheduler_->ResumeTimerQueue(); |
| 899 RunUntilIdle(); |
| 900 EXPECT_TRUE(run_order.empty()); |
| 901 |
| 902 scheduler_->ResumeTimerQueue(); |
| 903 RunUntilIdle(); |
| 904 EXPECT_THAT(run_order, |
| 905 testing::ElementsAre(std::string("T1"), std::string("T2"))); |
| 906 } |
| 907 |
| 850 } // namespace content | 908 } // namespace content |
| OLD | NEW |