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 "components/scheduler/renderer/renderer_scheduler_impl.h" | 5 #include "components/scheduler/renderer/renderer_scheduler_impl.h" |
6 | 6 |
7 #include "base/callback.h" | 7 #include "base/callback.h" |
8 #include "base/test/simple_test_tick_clock.h" | 8 #include "base/test/simple_test_tick_clock.h" |
9 #include "cc/output/begin_frame_args.h" | 9 #include "cc/output/begin_frame_args.h" |
10 #include "cc/test/ordered_simple_task_runner.h" | 10 #include "cc/test/ordered_simple_task_runner.h" |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 } | 301 } |
302 | 302 |
303 void ForceMainThreadScrollingUseCase() { | 303 void ForceMainThreadScrollingUseCase() { |
304 cc::BeginFrameArgs begin_frame_args = cc::BeginFrameArgs::Create( | 304 cc::BeginFrameArgs begin_frame_args = cc::BeginFrameArgs::Create( |
305 BEGINFRAME_FROM_HERE, clock_->NowTicks(), base::TimeTicks(), | 305 BEGINFRAME_FROM_HERE, clock_->NowTicks(), base::TimeTicks(), |
306 base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL); | 306 base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL); |
307 begin_frame_args.on_critical_path = true; | 307 begin_frame_args.on_critical_path = true; |
308 scheduler_->WillBeginFrame(begin_frame_args); | 308 scheduler_->WillBeginFrame(begin_frame_args); |
309 } | 309 } |
310 | 310 |
| 311 void ForceTouchStartToBeExpectedSoon() { |
| 312 scheduler_->DidHandleInputEventOnCompositorThread( |
| 313 FakeInputEvent(blink::WebInputEvent::GestureScrollEnd), |
| 314 RendererScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR); |
| 315 clock_->Advance(priority_escalation_after_input_duration() * 2); |
| 316 scheduler_->ForceUpdatePolicy(); |
| 317 } |
| 318 |
| 319 void SimulateExpensiveTasks( |
| 320 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) { |
| 321 // RunUntilIdle won't actually run all of the SimpleTestTickClock::Advance |
| 322 // tasks unless we set AutoAdvanceNow to true :/ |
| 323 mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true); |
| 324 |
| 325 // Simulate a bunch of expensive tasks |
| 326 for (int i = 0; i < 10; i++) { |
| 327 task_runner->PostTask(FROM_HERE, |
| 328 base::Bind(&base::SimpleTestTickClock::Advance, |
| 329 base::Unretained(clock_.get()), |
| 330 base::TimeDelta::FromMilliseconds(500))); |
| 331 } |
| 332 |
| 333 RunUntilIdle(); |
| 334 |
| 335 // Switch back to not auto-advancing because we want to be in control of |
| 336 // when time advances. |
| 337 mock_task_runner_->SetAutoAdvanceNowToPendingTasks(false); |
| 338 } |
| 339 |
311 void EnableIdleTasks() { DoMainFrame(); } | 340 void EnableIdleTasks() { DoMainFrame(); } |
312 | 341 |
313 UseCase CurrentUseCase() { | 342 UseCase CurrentUseCase() { |
314 return scheduler_->MainThreadOnly().current_use_case; | 343 return scheduler_->MainThreadOnly().current_use_case; |
315 } | 344 } |
316 | 345 |
317 UseCase ForceUpdatePolicyAndGetCurrentUseCase() { | 346 UseCase ForceUpdatePolicyAndGetCurrentUseCase() { |
318 scheduler_->ForceUpdatePolicy(); | 347 scheduler_->ForceUpdatePolicy(); |
319 return scheduler_->MainThreadOnly().current_use_case; | 348 return scheduler_->MainThreadOnly().current_use_case; |
320 } | 349 } |
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
705 std::string("D2"), std::string("C2"), | 734 std::string("D2"), std::string("C2"), |
706 std::string("I1"))); | 735 std::string("I1"))); |
707 EXPECT_EQ(RendererScheduler::UseCase::COMPOSITOR_GESTURE, CurrentUseCase()); | 736 EXPECT_EQ(RendererScheduler::UseCase::COMPOSITOR_GESTURE, CurrentUseCase()); |
708 } | 737 } |
709 | 738 |
710 TEST_F( | 739 TEST_F( |
711 RendererSchedulerImplTest, | 740 RendererSchedulerImplTest, |
712 TestCompositorPolicy_ExpensiveTimersDontRunWhenMainThreadOnCriticalPath) { | 741 TestCompositorPolicy_ExpensiveTimersDontRunWhenMainThreadOnCriticalPath) { |
713 std::vector<std::string> run_order; | 742 std::vector<std::string> run_order; |
714 | 743 |
715 // RunUntilIdle won't actually run all of the SimpleTestTickClock::Advance | 744 SimulateExpensiveTasks(timer_task_runner_); |
716 // tasks unless we set AutoAdvanceNow to true :/ | |
717 mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true); | |
718 | |
719 // Simulate a bunch of expensive timer tasks | |
720 for (int i = 0; i < 10; i++) { | |
721 timer_task_runner_->PostTask( | |
722 FROM_HERE, base::Bind(&base::SimpleTestTickClock::Advance, | |
723 base::Unretained(clock_.get()), | |
724 base::TimeDelta::FromMilliseconds(500))); | |
725 } | |
726 | |
727 RunUntilIdle(); | |
728 | |
729 // Switch back to not auto-advancing because we want to be in control of when | |
730 // time advances. | |
731 mock_task_runner_->SetAutoAdvanceNowToPendingTasks(false); | |
732 | 745 |
733 // Timers should now be disabled during main thread user user interactions. | 746 // Timers should now be disabled during main thread user user interactions. |
734 PostTestTasks(&run_order, "C1 T1"); | 747 PostTestTasks(&run_order, "C1 T1"); |
735 | 748 |
736 // Trigger main_thread_gesture UseCase | 749 // Trigger main_thread_gesture UseCase |
737 scheduler_->DidAnimateForInputOnCompositorThread(); | 750 scheduler_->DidAnimateForInputOnCompositorThread(); |
738 cc::BeginFrameArgs begin_frame_args1 = cc::BeginFrameArgs::Create( | 751 cc::BeginFrameArgs begin_frame_args1 = cc::BeginFrameArgs::Create( |
739 BEGINFRAME_FROM_HERE, clock_->NowTicks(), base::TimeTicks(), | 752 BEGINFRAME_FROM_HERE, clock_->NowTicks(), base::TimeTicks(), |
740 base::TimeDelta::FromMilliseconds(16), cc::BeginFrameArgs::NORMAL); | 753 base::TimeDelta::FromMilliseconds(16), cc::BeginFrameArgs::NORMAL); |
741 begin_frame_args1.on_critical_path = true; | 754 begin_frame_args1.on_critical_path = true; |
742 scheduler_->WillBeginFrame(begin_frame_args1); | 755 scheduler_->WillBeginFrame(begin_frame_args1); |
743 RunUntilIdle(); | 756 RunUntilIdle(); |
744 EXPECT_EQ(RendererScheduler::UseCase::MAIN_THREAD_GESTURE, CurrentUseCase()); | 757 EXPECT_EQ(RendererScheduler::UseCase::MAIN_THREAD_GESTURE, CurrentUseCase()); |
745 | 758 |
746 EXPECT_THAT(run_order, testing::ElementsAre(std::string("C1"))); | 759 EXPECT_THAT(run_order, testing::ElementsAre(std::string("C1"))); |
747 clock_->Advance(subsequent_input_expected_after_input_duration() * 2); | 760 clock_->Advance(subsequent_input_expected_after_input_duration() * 2); |
748 | 761 |
749 run_order.clear(); | 762 run_order.clear(); |
750 RunUntilIdle(); | 763 RunUntilIdle(); |
751 EXPECT_EQ(RendererScheduler::UseCase::NONE, CurrentUseCase()); | 764 EXPECT_EQ(RendererScheduler::UseCase::NONE, CurrentUseCase()); |
752 EXPECT_THAT(run_order, testing::ElementsAre(std::string("T1"))); | 765 EXPECT_THAT(run_order, testing::ElementsAre(std::string("T1"))); |
753 } | 766 } |
754 | 767 |
755 TEST_F(RendererSchedulerImplTest, Navigation_ResetsTaskCostEstimations) { | 768 TEST_F(RendererSchedulerImplTest, Navigation_ResetsTaskCostEstimations) { |
756 std::vector<std::string> run_order; | 769 std::vector<std::string> run_order; |
757 | 770 |
758 // RunUntilIdle won't actually run all of the SimpleTestTickClock::Advance | 771 SimulateExpensiveTasks(timer_task_runner_); |
759 // tasks unless we set AutoAdvanceNow to true :/ | 772 scheduler_->OnNavigationStarted(); |
760 mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true); | |
761 | |
762 // Simulate a bunch of expensive timer tasks | |
763 for (int i = 0; i < 10; i++) { | |
764 timer_task_runner_->PostTask( | |
765 FROM_HERE, base::Bind(&base::SimpleTestTickClock::Advance, | |
766 base::Unretained(clock_.get()), | |
767 base::TimeDelta::FromMilliseconds(500))); | |
768 } | |
769 | |
770 RunUntilIdle(); | |
771 | |
772 // Switch back to not auto-advancing because we want to be in control of when | |
773 // time advances. | |
774 mock_task_runner_->SetAutoAdvanceNowToPendingTasks(false); | |
775 | |
776 scheduler_->OnPageLoadStarted(); | |
777 PostTestTasks(&run_order, "C1 T1"); | 773 PostTestTasks(&run_order, "C1 T1"); |
778 | 774 |
779 scheduler_->DidAnimateForInputOnCompositorThread(); | 775 scheduler_->DidAnimateForInputOnCompositorThread(); |
780 cc::BeginFrameArgs begin_frame_args1 = cc::BeginFrameArgs::Create( | 776 cc::BeginFrameArgs begin_frame_args1 = cc::BeginFrameArgs::Create( |
781 BEGINFRAME_FROM_HERE, clock_->NowTicks(), base::TimeTicks(), | 777 BEGINFRAME_FROM_HERE, clock_->NowTicks(), base::TimeTicks(), |
782 base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL); | 778 base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL); |
783 begin_frame_args1.on_critical_path = true; | 779 begin_frame_args1.on_critical_path = true; |
784 scheduler_->WillBeginFrame(begin_frame_args1); | 780 scheduler_->WillBeginFrame(begin_frame_args1); |
785 scheduler_->DidCommitFrameToCompositor(); // Starts Idle Period | 781 scheduler_->DidCommitFrameToCompositor(); // Starts Idle Period |
786 RunUntilIdle(); | 782 RunUntilIdle(); |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
909 EXPECT_THAT(run_order, | 905 EXPECT_THAT(run_order, |
910 testing::ElementsAre(std::string("L1"), std::string("T1"), | 906 testing::ElementsAre(std::string("L1"), std::string("T1"), |
911 std::string("T2"))); | 907 std::string("T2"))); |
912 } | 908 } |
913 | 909 |
914 // TODO(alexclarke): Reenable once we've reinstaed the Loading UseCase. | 910 // TODO(alexclarke): Reenable once we've reinstaed the Loading UseCase. |
915 TEST_F(RendererSchedulerImplTest, DISABLED_LoadingUseCase) { | 911 TEST_F(RendererSchedulerImplTest, DISABLED_LoadingUseCase) { |
916 std::vector<std::string> run_order; | 912 std::vector<std::string> run_order; |
917 PostTestTasks(&run_order, "I1 D1 C1 T1 L1 D2 C2 T2 L2"); | 913 PostTestTasks(&run_order, "I1 D1 C1 T1 L1 D2 C2 T2 L2"); |
918 | 914 |
919 scheduler_->OnPageLoadStarted(); | 915 scheduler_->OnNavigationStarted(); |
920 EnableIdleTasks(); | 916 EnableIdleTasks(); |
921 RunUntilIdle(); | 917 RunUntilIdle(); |
922 | 918 |
923 // In loading policy, loading tasks are prioritized other others. | 919 // In loading policy, loading tasks are prioritized other others. |
924 std::string loading_policy_expected[] = { | 920 std::string loading_policy_expected[] = { |
925 std::string("D1"), std::string("L1"), std::string("D2"), | 921 std::string("D1"), std::string("L1"), std::string("D2"), |
926 std::string("L2"), std::string("C1"), std::string("T1"), | 922 std::string("L2"), std::string("C1"), std::string("T1"), |
927 std::string("C2"), std::string("T2"), std::string("I1")}; | 923 std::string("C2"), std::string("T2"), std::string("I1")}; |
928 EXPECT_THAT(run_order, testing::ElementsAreArray(loading_policy_expected)); | 924 EXPECT_THAT(run_order, testing::ElementsAreArray(loading_policy_expected)); |
929 EXPECT_EQ(RendererScheduler::UseCase::LOADING, CurrentUseCase()); | 925 EXPECT_EQ(RendererScheduler::UseCase::LOADING, CurrentUseCase()); |
(...skipping 1049 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1979 run_order.clear(); | 1975 run_order.clear(); |
1980 PostTestTasks(&run_order, "T6"); | 1976 PostTestTasks(&run_order, "T6"); |
1981 RunUntilIdle(); | 1977 RunUntilIdle(); |
1982 EXPECT_THAT(run_order, testing::ElementsAre(std::string("T6"))); | 1978 EXPECT_THAT(run_order, testing::ElementsAre(std::string("T6"))); |
1983 } | 1979 } |
1984 | 1980 |
1985 TEST_F(RendererSchedulerImplTest, | 1981 TEST_F(RendererSchedulerImplTest, |
1986 ExpensiveLoadingTasksNotBlockedTillFirstBeginMainFrame) { | 1982 ExpensiveLoadingTasksNotBlockedTillFirstBeginMainFrame) { |
1987 std::vector<std::string> run_order; | 1983 std::vector<std::string> run_order; |
1988 | 1984 |
1989 // RunUntilIdle won't actually run all of the SimpleTestTickClock::Advance | 1985 SimulateExpensiveTasks(loading_task_runner_); |
1990 // tasks unless we set AutoAdvanceNow to true :/ | 1986 ForceTouchStartToBeExpectedSoon(); |
1991 mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true); | |
1992 | |
1993 // Simulate a bunch of expensive loading tasks | |
1994 for (int i = 0; i < 10; i++) { | |
1995 loading_task_runner_->PostTask( | |
1996 FROM_HERE, base::Bind(&base::SimpleTestTickClock::Advance, | |
1997 base::Unretained(clock_.get()), | |
1998 base::TimeDelta::FromMilliseconds(500))); | |
1999 } | |
2000 | |
2001 RunUntilIdle(); | |
2002 | |
2003 PostTestTasks(&run_order, "L1 D1"); | 1987 PostTestTasks(&run_order, "L1 D1"); |
2004 RunUntilIdle(); | 1988 RunUntilIdle(); |
2005 | 1989 |
2006 EXPECT_EQ(UseCase::NONE, ForceUpdatePolicyAndGetCurrentUseCase()); | 1990 EXPECT_EQ(UseCase::NONE, ForceUpdatePolicyAndGetCurrentUseCase()); |
2007 EXPECT_FALSE(HaveSeenABeginMainframe()); | 1991 EXPECT_FALSE(HaveSeenABeginMainframe()); |
2008 EXPECT_TRUE(LoadingTasksSeemExpensive()); | 1992 EXPECT_TRUE(LoadingTasksSeemExpensive()); |
2009 EXPECT_FALSE(TimerTasksSeemExpensive()); | 1993 EXPECT_FALSE(TimerTasksSeemExpensive()); |
| 1994 EXPECT_TRUE(TouchStartExpectedSoon()); |
2010 EXPECT_THAT(run_order, | 1995 EXPECT_THAT(run_order, |
2011 testing::ElementsAre(std::string("L1"), std::string("D1"))); | 1996 testing::ElementsAre(std::string("L1"), std::string("D1"))); |
2012 | 1997 |
2013 // Emit a BeginMainFrame, and the loading task should get blocked. | 1998 // Emit a BeginMainFrame, and the loading task should get blocked. |
2014 DoMainFrame(); | 1999 DoMainFrame(); |
2015 run_order.clear(); | 2000 run_order.clear(); |
2016 | 2001 |
2017 PostTestTasks(&run_order, "L1 D1"); | 2002 PostTestTasks(&run_order, "L1 D1"); |
| 2003 RunUntilIdle(); |
| 2004 |
| 2005 EXPECT_EQ(RendererScheduler::UseCase::NONE, CurrentUseCase()); |
| 2006 EXPECT_TRUE(HaveSeenABeginMainframe()); |
| 2007 EXPECT_TRUE(LoadingTasksSeemExpensive()); |
| 2008 EXPECT_FALSE(TimerTasksSeemExpensive()); |
| 2009 EXPECT_TRUE(TouchStartExpectedSoon()); |
| 2010 EXPECT_THAT(run_order, testing::ElementsAre(std::string("D1"))); |
| 2011 } |
| 2012 |
| 2013 TEST_F(RendererSchedulerImplTest, |
| 2014 ExpensiveLoadingTasksNotBlockedIfNavigationExpected) { |
| 2015 std::vector<std::string> run_order; |
| 2016 |
| 2017 DoMainFrame(); |
| 2018 SimulateExpensiveTasks(loading_task_runner_); |
| 2019 ForceTouchStartToBeExpectedSoon(); |
| 2020 scheduler_->AddPendingNavigation(); |
| 2021 |
| 2022 PostTestTasks(&run_order, "L1 D1"); |
| 2023 RunUntilIdle(); |
| 2024 |
| 2025 EXPECT_EQ(UseCase::NONE, ForceUpdatePolicyAndGetCurrentUseCase()); |
| 2026 EXPECT_TRUE(HaveSeenABeginMainframe()); |
| 2027 EXPECT_TRUE(LoadingTasksSeemExpensive()); |
| 2028 EXPECT_FALSE(TimerTasksSeemExpensive()); |
| 2029 EXPECT_TRUE(TouchStartExpectedSoon()); |
| 2030 EXPECT_THAT(run_order, |
| 2031 testing::ElementsAre(std::string("L1"), std::string("D1"))); |
| 2032 |
| 2033 // After the nagigation has been cancelled, the expensive loading tasks should |
| 2034 // get blocked. |
| 2035 scheduler_->RemovePendingNavigation(); |
| 2036 run_order.clear(); |
| 2037 |
| 2038 PostTestTasks(&run_order, "L1 D1"); |
2018 RunUntilIdle(); | 2039 RunUntilIdle(); |
2019 | 2040 |
2020 EXPECT_EQ(RendererScheduler::UseCase::NONE, CurrentUseCase()); | 2041 EXPECT_EQ(RendererScheduler::UseCase::NONE, CurrentUseCase()); |
2021 EXPECT_TRUE(HaveSeenABeginMainframe()); | 2042 EXPECT_TRUE(HaveSeenABeginMainframe()); |
2022 EXPECT_TRUE(LoadingTasksSeemExpensive()); | 2043 EXPECT_TRUE(LoadingTasksSeemExpensive()); |
2023 EXPECT_FALSE(TimerTasksSeemExpensive()); | 2044 EXPECT_FALSE(TimerTasksSeemExpensive()); |
| 2045 EXPECT_TRUE(TouchStartExpectedSoon()); |
| 2046 EXPECT_THAT(run_order, testing::ElementsAre(std::string("D1"))); |
| 2047 } |
| 2048 |
| 2049 TEST_F( |
| 2050 RendererSchedulerImplTest, |
| 2051 ExpensiveLoadingTasksNotBlockedIfNavigationExpected_MultipleNavigations) { |
| 2052 std::vector<std::string> run_order; |
| 2053 |
| 2054 DoMainFrame(); |
| 2055 SimulateExpensiveTasks(loading_task_runner_); |
| 2056 ForceTouchStartToBeExpectedSoon(); |
| 2057 scheduler_->AddPendingNavigation(); |
| 2058 scheduler_->AddPendingNavigation(); |
| 2059 |
| 2060 PostTestTasks(&run_order, "L1 D1"); |
| 2061 RunUntilIdle(); |
| 2062 |
| 2063 EXPECT_EQ(UseCase::NONE, ForceUpdatePolicyAndGetCurrentUseCase()); |
| 2064 EXPECT_TRUE(HaveSeenABeginMainframe()); |
| 2065 EXPECT_TRUE(LoadingTasksSeemExpensive()); |
| 2066 EXPECT_FALSE(TimerTasksSeemExpensive()); |
| 2067 EXPECT_TRUE(TouchStartExpectedSoon()); |
2024 EXPECT_THAT(run_order, | 2068 EXPECT_THAT(run_order, |
2025 testing::ElementsAre(std::string("L1"), std::string("D1"))); | 2069 testing::ElementsAre(std::string("L1"), std::string("D1"))); |
| 2070 |
| 2071 |
| 2072 run_order.clear(); |
| 2073 scheduler_->RemovePendingNavigation(); |
| 2074 // Navigation task expected ref count non-zero so expensive tasks still not |
| 2075 // blocked. |
| 2076 PostTestTasks(&run_order, "L1 D1"); |
| 2077 RunUntilIdle(); |
| 2078 |
| 2079 EXPECT_EQ(UseCase::NONE, ForceUpdatePolicyAndGetCurrentUseCase()); |
| 2080 EXPECT_TRUE(HaveSeenABeginMainframe()); |
| 2081 EXPECT_TRUE(LoadingTasksSeemExpensive()); |
| 2082 EXPECT_FALSE(TimerTasksSeemExpensive()); |
| 2083 EXPECT_TRUE(TouchStartExpectedSoon()); |
| 2084 EXPECT_THAT(run_order, |
| 2085 testing::ElementsAre(std::string("L1"), std::string("D1"))); |
| 2086 |
| 2087 |
| 2088 run_order.clear(); |
| 2089 scheduler_->RemovePendingNavigation(); |
| 2090 // Navigation task expected ref count is now zero, the expensive loading tasks |
| 2091 // should get blocked. |
| 2092 PostTestTasks(&run_order, "L1 D1"); |
| 2093 RunUntilIdle(); |
| 2094 |
| 2095 EXPECT_EQ(RendererScheduler::UseCase::NONE, CurrentUseCase()); |
| 2096 EXPECT_TRUE(HaveSeenABeginMainframe()); |
| 2097 EXPECT_TRUE(LoadingTasksSeemExpensive()); |
| 2098 EXPECT_FALSE(TimerTasksSeemExpensive()); |
| 2099 EXPECT_TRUE(TouchStartExpectedSoon()); |
| 2100 EXPECT_THAT(run_order, testing::ElementsAre(std::string("D1"))); |
2026 } | 2101 } |
2027 | 2102 |
| 2103 |
2028 } // namespace scheduler | 2104 } // namespace scheduler |
OLD | NEW |