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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
56 void EnableIdleTasks() { DoMainFrame(); } | 56 void EnableIdleTasks() { DoMainFrame(); } |
57 | 57 |
58 Policy CurrentPolicy() { return scheduler_->current_policy_; } | 58 Policy CurrentPolicy() { return scheduler_->current_policy_; } |
59 | 59 |
60 protected: | 60 protected: |
61 static base::TimeDelta priority_escalation_after_input_duration() { | 61 static base::TimeDelta priority_escalation_after_input_duration() { |
62 return base::TimeDelta::FromMilliseconds( | 62 return base::TimeDelta::FromMilliseconds( |
63 RendererSchedulerImpl::kPriorityEscalationAfterInputMillis); | 63 RendererSchedulerImpl::kPriorityEscalationAfterInputMillis); |
64 } | 64 } |
65 | 65 |
| 66 static base::TimeDelta maximum_idle_period_duration() { |
| 67 return base::TimeDelta::FromMilliseconds( |
| 68 RendererSchedulerImpl::kMaximumIdlePeriodMillis); |
| 69 } |
| 70 |
| 71 base::TimeTicks CurrentIdleTaskDeadline() { |
| 72 base::TimeTicks deadline; |
| 73 scheduler_->CurrentIdleTaskDeadlineCallback(&deadline); |
| 74 return deadline; |
| 75 } |
| 76 |
66 scoped_refptr<cc::TestNowSource> clock_; | 77 scoped_refptr<cc::TestNowSource> clock_; |
67 scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_; | 78 scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_; |
68 | 79 |
69 scoped_ptr<RendererSchedulerImpl> scheduler_; | 80 scoped_ptr<RendererSchedulerImpl> scheduler_; |
70 scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_; | 81 scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_; |
71 scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_; | 82 scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_; |
72 scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner_; | 83 scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner_; |
73 scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_; | 84 scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_; |
74 | 85 |
75 DISALLOW_COPY_AND_ASSIGN(RendererSchedulerImplTest); | 86 DISALLOW_COPY_AND_ASSIGN(RendererSchedulerImplTest); |
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
479 compositor_task_runner_->PostTask( | 490 compositor_task_runner_->PostTask( |
480 FROM_HERE, | 491 FROM_HERE, |
481 base::Bind(&AppendToVectorTestTask, &order, std::string("C1"))); | 492 base::Bind(&AppendToVectorTestTask, &order, std::string("C1"))); |
482 default_task_runner_->PostTask( | 493 default_task_runner_->PostTask( |
483 FROM_HERE, | 494 FROM_HERE, |
484 base::Bind(&AppendToVectorTestTask, &order, std::string("D2"))); | 495 base::Bind(&AppendToVectorTestTask, &order, std::string("D2"))); |
485 compositor_task_runner_->PostTask( | 496 compositor_task_runner_->PostTask( |
486 FROM_HERE, | 497 FROM_HERE, |
487 base::Bind(&AppendToVectorTestTask, &order, std::string("C2"))); | 498 base::Bind(&AppendToVectorTestTask, &order, std::string("C2"))); |
488 | 499 |
489 // Observation of touchstart should defer execution of idle and loading tasks. | 500 // Observation of touchstart should defer execution of loading tasks. |
490 scheduler_->DidReceiveInputEventOnCompositorThread( | 501 scheduler_->DidReceiveInputEventOnCompositorThread( |
491 FakeInputEvent(blink::WebInputEvent::TouchStart)); | 502 FakeInputEvent(blink::WebInputEvent::TouchStart)); |
492 RunUntilIdle(); | 503 RunUntilIdle(); |
493 EXPECT_THAT(order, | 504 EXPECT_THAT(order, |
494 testing::ElementsAre(std::string("C1"), std::string("C2"), | 505 testing::ElementsAre(std::string("C1"), std::string("C2"), |
495 std::string("D1"), std::string("D2"))); | 506 std::string("D1"), std::string("D2"))); |
496 | 507 |
497 // Meta events like TapDown/FlingCancel shouldn't affect the priority. | 508 // Meta events like TapDown/FlingCancel shouldn't affect the priority. |
498 order.clear(); | 509 order.clear(); |
499 scheduler_->DidReceiveInputEventOnCompositorThread( | 510 scheduler_->DidReceiveInputEventOnCompositorThread( |
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
999 RunUntilIdle(); | 1010 RunUntilIdle(); |
1000 EXPECT_EQ(Policy::COMPOSITOR_PRIORITY, CurrentPolicy()); | 1011 EXPECT_EQ(Policy::COMPOSITOR_PRIORITY, CurrentPolicy()); |
1001 | 1012 |
1002 // Process the input event with a new BeginMainFrame. | 1013 // Process the input event with a new BeginMainFrame. |
1003 DoMainFrame(); | 1014 DoMainFrame(); |
1004 clock_->AdvanceNow(2 * priority_escalation_after_input_duration()); | 1015 clock_->AdvanceNow(2 * priority_escalation_after_input_duration()); |
1005 RunUntilIdle(); | 1016 RunUntilIdle(); |
1006 EXPECT_EQ(Policy::NORMAL, CurrentPolicy()); | 1017 EXPECT_EQ(Policy::NORMAL, CurrentPolicy()); |
1007 } | 1018 } |
1008 | 1019 |
| 1020 TEST_F(RendererSchedulerImplTest, TestLongIdlePeriod) { |
| 1021 base::TimeTicks expected_deadline = |
| 1022 clock_->Now() + maximum_idle_period_duration(); |
| 1023 base::TimeTicks deadline_in_task; |
| 1024 int run_count = 0; |
| 1025 |
| 1026 idle_task_runner_->PostIdleTask( |
| 1027 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); |
| 1028 |
| 1029 RunUntilIdle(); |
| 1030 EXPECT_EQ(0, run_count); // Shouldn't run yet as no idle period. |
| 1031 |
| 1032 scheduler_->BeginFrameNotExpectedSoon(); |
| 1033 RunUntilIdle(); |
| 1034 EXPECT_EQ(1, run_count); // Should have run in a long idle time. |
| 1035 EXPECT_EQ(expected_deadline, deadline_in_task); |
| 1036 } |
| 1037 |
| 1038 TEST_F(RendererSchedulerImplTest, TestLongIdlePeriodWithPendingDelayedTask) { |
| 1039 base::TimeDelta pending_task_delay = base::TimeDelta::FromMilliseconds(30); |
| 1040 base::TimeTicks expected_deadline = clock_->Now() + pending_task_delay; |
| 1041 base::TimeTicks deadline_in_task; |
| 1042 int run_count = 0; |
| 1043 |
| 1044 idle_task_runner_->PostIdleTask( |
| 1045 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); |
| 1046 default_task_runner_->PostDelayedTask( |
| 1047 FROM_HERE, base::Bind(&NullTask), pending_task_delay); |
| 1048 |
| 1049 scheduler_->BeginFrameNotExpectedSoon(); |
| 1050 RunUntilIdle(); |
| 1051 EXPECT_EQ(1, run_count); // Should have run in a long idle time. |
| 1052 EXPECT_EQ(expected_deadline, deadline_in_task); |
| 1053 } |
| 1054 |
| 1055 TEST_F(RendererSchedulerImplTest, |
| 1056 TestLongIdlePeriodWithLatePendingDelayedTask) { |
| 1057 base::TimeDelta pending_task_delay = base::TimeDelta::FromMilliseconds(10); |
| 1058 base::TimeTicks deadline_in_task; |
| 1059 int run_count = 0; |
| 1060 |
| 1061 default_task_runner_->PostDelayedTask( |
| 1062 FROM_HERE, base::Bind(&NullTask), pending_task_delay); |
| 1063 |
| 1064 // Advance clock until after delayed task was meant to be run. |
| 1065 clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(20)); |
| 1066 |
| 1067 // Post an idle task and BeginFrameNotExpectedSoon to initiate a long idle |
| 1068 // period. Since there is a late pending delayed task this shouldn't actually |
| 1069 // start an idle period. |
| 1070 idle_task_runner_->PostIdleTask( |
| 1071 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); |
| 1072 scheduler_->BeginFrameNotExpectedSoon(); |
| 1073 RunUntilIdle(); |
| 1074 EXPECT_EQ(0, run_count); |
| 1075 |
| 1076 // After the delayed task has been run we should trigger an idle period. |
| 1077 clock_->AdvanceNow(maximum_idle_period_duration()); |
| 1078 RunUntilIdle(); |
| 1079 EXPECT_EQ(1, run_count); |
| 1080 } |
| 1081 |
| 1082 TEST_F(RendererSchedulerImplTest, TestLongIdlePeriodRepeating) { |
| 1083 int run_count = 0; |
| 1084 |
| 1085 idle_task_runner_->PostIdleTask( |
| 1086 FROM_HERE, |
| 1087 base::Bind(&RepostingIdleTestTask, idle_task_runner_, &run_count)); |
| 1088 |
| 1089 scheduler_->BeginFrameNotExpectedSoon(); |
| 1090 RunUntilIdle(); |
| 1091 EXPECT_EQ(1, run_count); // Should only run once per idle period. |
| 1092 |
| 1093 // Advance time to start of next long idle period and check task reposted task |
| 1094 // gets run. |
| 1095 clock_->AdvanceNow(maximum_idle_period_duration()); |
| 1096 RunUntilIdle(); |
| 1097 EXPECT_EQ(2, run_count); |
| 1098 |
| 1099 // Advance time to start of next long idle period then end idle period with a |
| 1100 // new BeginMainFrame and check idle task doesn't run. |
| 1101 clock_->AdvanceNow(maximum_idle_period_duration()); |
| 1102 scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create( |
| 1103 BEGINFRAME_FROM_HERE, clock_->Now(), base::TimeTicks(), |
| 1104 base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL)); |
| 1105 RunUntilIdle(); |
| 1106 EXPECT_EQ(2, run_count); |
| 1107 } |
| 1108 |
| 1109 TEST_F(RendererSchedulerImplTest, TestLongIdlePeriodDoesNotWakeScheduler) { |
| 1110 base::TimeTicks deadline_in_task; |
| 1111 int run_count = 0; |
| 1112 |
| 1113 // Start a long idle period and get the time it should end. |
| 1114 scheduler_->BeginFrameNotExpectedSoon(); |
| 1115 // The scheduler should not run the initiate_next_long_idle_period task if |
| 1116 // there are no idle tasks and no other task woke up the scheduler, thus |
| 1117 // the idle period deadline shouldn't update at the end of the current long |
| 1118 // idle period. |
| 1119 base::TimeTicks idle_period_deadline = CurrentIdleTaskDeadline(); |
| 1120 clock_->AdvanceNow(maximum_idle_period_duration()); |
| 1121 RunUntilIdle(); |
| 1122 |
| 1123 base::TimeTicks new_idle_period_deadline = CurrentIdleTaskDeadline(); |
| 1124 EXPECT_EQ(idle_period_deadline, new_idle_period_deadline); |
| 1125 |
| 1126 // Posting a after-wakeup idle task also shouldn't wake the scheduler or |
| 1127 // initiate the next long idle period. |
| 1128 idle_task_runner_->PostIdleTaskAfterWakeup( |
| 1129 FROM_HERE, |
| 1130 base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); |
| 1131 RunUntilIdle(); |
| 1132 new_idle_period_deadline = CurrentIdleTaskDeadline(); |
| 1133 EXPECT_EQ(idle_period_deadline, new_idle_period_deadline); |
| 1134 EXPECT_EQ(0, run_count); |
| 1135 |
| 1136 // Running a normal task should initiate a new long idle period though. |
| 1137 default_task_runner_->PostTask(FROM_HERE, base::Bind(&NullTask)); |
| 1138 RunUntilIdle(); |
| 1139 new_idle_period_deadline = CurrentIdleTaskDeadline(); |
| 1140 EXPECT_EQ(idle_period_deadline + maximum_idle_period_duration(), |
| 1141 new_idle_period_deadline); |
| 1142 |
| 1143 EXPECT_EQ(1, run_count); |
| 1144 } |
| 1145 |
| 1146 TEST_F(RendererSchedulerImplTest, TestLongIdlePeriodInTouchStartPolicy) { |
| 1147 base::TimeTicks deadline_in_task; |
| 1148 int run_count = 0; |
| 1149 |
| 1150 idle_task_runner_->PostIdleTask( |
| 1151 FROM_HERE, |
| 1152 base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); |
| 1153 |
| 1154 // Observation of touchstart should defer the start of the long idle period. |
| 1155 scheduler_->DidReceiveInputEventOnCompositorThread( |
| 1156 FakeInputEvent(blink::WebInputEvent::TouchStart)); |
| 1157 scheduler_->BeginFrameNotExpectedSoon(); |
| 1158 RunUntilIdle(); |
| 1159 EXPECT_EQ(0, run_count); |
| 1160 |
| 1161 // The long idle period should start after the touchstart policy has finished. |
| 1162 clock_->AdvanceNow(priority_escalation_after_input_duration()); |
| 1163 RunUntilIdle(); |
| 1164 EXPECT_EQ(1, run_count); |
| 1165 } |
| 1166 |
1009 } // namespace content | 1167 } // namespace content |
OLD | NEW |