| OLD | NEW |
| 1 // Copyright 2011 The Chromium Authors. All rights reserved. | 1 // Copyright 2011 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 "cc/scheduler/scheduler.h" | 5 #include "cc/scheduler/scheduler.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 scheduler_(nullptr) { | 53 scheduler_(nullptr) { |
| 54 Reset(); | 54 Reset(); |
| 55 } | 55 } |
| 56 | 56 |
| 57 void Reset() { | 57 void Reset() { |
| 58 actions_.clear(); | 58 actions_.clear(); |
| 59 states_.clear(); | 59 states_.clear(); |
| 60 draw_will_happen_ = true; | 60 draw_will_happen_ = true; |
| 61 swap_will_happen_if_draw_happens_ = true; | 61 swap_will_happen_if_draw_happens_ = true; |
| 62 num_draws_ = 0; | 62 num_draws_ = 0; |
| 63 log_anticipated_draw_time_change_ = false; | |
| 64 begin_frame_args_sent_to_children_ = BeginFrameArgs(); | 63 begin_frame_args_sent_to_children_ = BeginFrameArgs(); |
| 65 } | 64 } |
| 66 | 65 |
| 67 void set_scheduler(TestScheduler* scheduler) { scheduler_ = scheduler; } | 66 void set_scheduler(TestScheduler* scheduler) { scheduler_ = scheduler; } |
| 68 | 67 |
| 69 // Most tests don't care about DidAnticipatedDrawTimeChange, so only record it | |
| 70 // for tests that do. | |
| 71 void set_log_anticipated_draw_time_change(bool log) { | |
| 72 log_anticipated_draw_time_change_ = log; | |
| 73 } | |
| 74 bool needs_begin_frames() { | 68 bool needs_begin_frames() { |
| 75 return scheduler_->frame_source().NeedsBeginFrames(); | 69 return scheduler_->frame_source().NeedsBeginFrames(); |
| 76 } | 70 } |
| 77 int num_draws() const { return num_draws_; } | 71 int num_draws() const { return num_draws_; } |
| 78 int num_actions_() const { return static_cast<int>(actions_.size()); } | 72 int num_actions_() const { return static_cast<int>(actions_.size()); } |
| 79 const char* Action(int i) const { return actions_[i]; } | 73 const char* Action(int i) const { return actions_[i]; } |
| 80 std::string StateForAction(int i) const { return states_[i]->ToString(); } | 74 std::string StateForAction(int i) const { return states_[i]->ToString(); } |
| 81 base::TimeTicks posted_begin_impl_frame_deadline() const { | 75 base::TimeTicks posted_begin_impl_frame_deadline() const { |
| 82 return posted_begin_impl_frame_deadline_; | 76 return posted_begin_impl_frame_deadline_; |
| 83 } | 77 } |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 void ScheduledActionBeginOutputSurfaceCreation() override { | 134 void ScheduledActionBeginOutputSurfaceCreation() override { |
| 141 PushAction("ScheduledActionBeginOutputSurfaceCreation"); | 135 PushAction("ScheduledActionBeginOutputSurfaceCreation"); |
| 142 } | 136 } |
| 143 void ScheduledActionPrepareTiles() override { | 137 void ScheduledActionPrepareTiles() override { |
| 144 PushAction("ScheduledActionPrepareTiles"); | 138 PushAction("ScheduledActionPrepareTiles"); |
| 145 } | 139 } |
| 146 void ScheduledActionInvalidateOutputSurface() override { | 140 void ScheduledActionInvalidateOutputSurface() override { |
| 147 actions_.push_back("ScheduledActionInvalidateOutputSurface"); | 141 actions_.push_back("ScheduledActionInvalidateOutputSurface"); |
| 148 states_.push_back(scheduler_->AsValue()); | 142 states_.push_back(scheduler_->AsValue()); |
| 149 } | 143 } |
| 150 void DidAnticipatedDrawTimeChange(base::TimeTicks) override { | |
| 151 if (log_anticipated_draw_time_change_) | |
| 152 PushAction("DidAnticipatedDrawTimeChange"); | |
| 153 } | |
| 154 base::TimeDelta DrawDurationEstimate() override { return base::TimeDelta(); } | 144 base::TimeDelta DrawDurationEstimate() override { return base::TimeDelta(); } |
| 155 base::TimeDelta BeginMainFrameToCommitDurationEstimate() override { | 145 base::TimeDelta BeginMainFrameToCommitDurationEstimate() override { |
| 156 return base::TimeDelta(); | 146 return base::TimeDelta(); |
| 157 } | 147 } |
| 158 base::TimeDelta CommitToActivateDurationEstimate() override { | 148 base::TimeDelta CommitToActivateDurationEstimate() override { |
| 159 return base::TimeDelta(); | 149 return base::TimeDelta(); |
| 160 } | 150 } |
| 161 | 151 |
| 162 void SendBeginFramesToChildren(const BeginFrameArgs& args) override { | 152 void SendBeginFramesToChildren(const BeginFrameArgs& args) override { |
| 163 begin_frame_args_sent_to_children_ = args; | 153 begin_frame_args_sent_to_children_ = args; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 188 | 178 |
| 189 protected: | 179 protected: |
| 190 bool ImplFrameDeadlinePendingCallback(bool state) { | 180 bool ImplFrameDeadlinePendingCallback(bool state) { |
| 191 return scheduler_->BeginImplFrameDeadlinePending() == state; | 181 return scheduler_->BeginImplFrameDeadlinePending() == state; |
| 192 } | 182 } |
| 193 | 183 |
| 194 bool draw_will_happen_; | 184 bool draw_will_happen_; |
| 195 bool swap_will_happen_if_draw_happens_; | 185 bool swap_will_happen_if_draw_happens_; |
| 196 bool automatic_swap_ack_; | 186 bool automatic_swap_ack_; |
| 197 int num_draws_; | 187 int num_draws_; |
| 198 bool log_anticipated_draw_time_change_; | |
| 199 BeginFrameArgs begin_frame_args_sent_to_children_; | 188 BeginFrameArgs begin_frame_args_sent_to_children_; |
| 200 base::TimeTicks posted_begin_impl_frame_deadline_; | 189 base::TimeTicks posted_begin_impl_frame_deadline_; |
| 201 std::vector<const char*> actions_; | 190 std::vector<const char*> actions_; |
| 202 std::vector<scoped_refptr<base::trace_event::ConvertableToTraceFormat>> | 191 std::vector<scoped_refptr<base::trace_event::ConvertableToTraceFormat>> |
| 203 states_; | 192 states_; |
| 204 TestScheduler* scheduler_; | 193 TestScheduler* scheduler_; |
| 205 }; | 194 }; |
| 206 | 195 |
| 207 class SchedulerClientWithFixedEstimates : public FakeSchedulerClient { | 196 class SchedulerClientWithFixedEstimates : public FakeSchedulerClient { |
| 208 public: | 197 public: |
| (...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 758 } | 747 } |
| 759 return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible(); | 748 return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible(); |
| 760 } | 749 } |
| 761 | 750 |
| 762 DrawResult ScheduledActionDrawAndSwapForced() override { | 751 DrawResult ScheduledActionDrawAndSwapForced() override { |
| 763 NOTREACHED(); | 752 NOTREACHED(); |
| 764 return DRAW_SUCCESS; | 753 return DRAW_SUCCESS; |
| 765 } | 754 } |
| 766 | 755 |
| 767 void ScheduledActionCommit() override {} | 756 void ScheduledActionCommit() override {} |
| 768 void DidAnticipatedDrawTimeChange(base::TimeTicks) override {} | |
| 769 | 757 |
| 770 private: | 758 private: |
| 771 bool request_redraws_; | 759 bool request_redraws_; |
| 772 }; | 760 }; |
| 773 | 761 |
| 774 // Tests for two different situations: | 762 // Tests for two different situations: |
| 775 // 1. the scheduler dropping SetNeedsRedraw requests that happen inside | 763 // 1. the scheduler dropping SetNeedsRedraw requests that happen inside |
| 776 // a ScheduledActionDrawAndSwap | 764 // a ScheduledActionDrawAndSwap |
| 777 // 2. the scheduler drawing twice inside a single tick | 765 // 2. the scheduler drawing twice inside a single tick |
| 778 TEST_F(SchedulerTest, RequestRedrawInsideDraw) { | 766 TEST_F(SchedulerTest, RequestRedrawInsideDraw) { |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 870 } | 858 } |
| 871 return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible(); | 859 return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible(); |
| 872 } | 860 } |
| 873 | 861 |
| 874 DrawResult ScheduledActionDrawAndSwapForced() override { | 862 DrawResult ScheduledActionDrawAndSwapForced() override { |
| 875 NOTREACHED(); | 863 NOTREACHED(); |
| 876 return DRAW_SUCCESS; | 864 return DRAW_SUCCESS; |
| 877 } | 865 } |
| 878 | 866 |
| 879 void ScheduledActionCommit() override {} | 867 void ScheduledActionCommit() override {} |
| 880 void DidAnticipatedDrawTimeChange(base::TimeTicks) override {} | |
| 881 | 868 |
| 882 void SetNeedsCommitOnNextDraw() { set_needs_commit_on_next_draw_ = true; } | 869 void SetNeedsCommitOnNextDraw() { set_needs_commit_on_next_draw_ = true; } |
| 883 | 870 |
| 884 private: | 871 private: |
| 885 bool set_needs_commit_on_next_draw_; | 872 bool set_needs_commit_on_next_draw_; |
| 886 }; | 873 }; |
| 887 | 874 |
| 888 // Tests for the scheduler infinite-looping on SetNeedsCommit requests that | 875 // Tests for the scheduler infinite-looping on SetNeedsCommit requests that |
| 889 // happen inside a ScheduledActionDrawAndSwap | 876 // happen inside a ScheduledActionDrawAndSwap |
| 890 TEST_F(SchedulerTest, RequestCommitInsideDraw) { | 877 TEST_F(SchedulerTest, RequestCommitInsideDraw) { |
| (...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1390 EXPECT_SCOPED(MainFrameInHighLatencyMode(1, 10, false, true)); | 1377 EXPECT_SCOPED(MainFrameInHighLatencyMode(1, 10, false, true)); |
| 1391 } | 1378 } |
| 1392 | 1379 |
| 1393 TEST_F(SchedulerTest, NotSkipMainFrameInPreferImplLatencyMode) { | 1380 TEST_F(SchedulerTest, NotSkipMainFrameInPreferImplLatencyMode) { |
| 1394 // Set up client so that estimates indicate that we can commit and activate | 1381 // Set up client so that estimates indicate that we can commit and activate |
| 1395 // before the deadline (~8ms by default), but also enable impl latency takes | 1382 // before the deadline (~8ms by default), but also enable impl latency takes |
| 1396 // priority mode. | 1383 // priority mode. |
| 1397 EXPECT_SCOPED(MainFrameInHighLatencyMode(1, 1, true, true)); | 1384 EXPECT_SCOPED(MainFrameInHighLatencyMode(1, 1, true, true)); |
| 1398 } | 1385 } |
| 1399 | 1386 |
| 1400 TEST_F(SchedulerTest, | |
| 1401 Deadlock_NotifyReadyToCommitMakesProgressWhileSwapTrottled) { | |
| 1402 // NPAPI plugins on Windows block the Browser UI thread on the Renderer main | |
| 1403 // thread. This prevents the scheduler from receiving any pending swap acks. | |
| 1404 // This test makes sure that we keep updating the TextureUploader with | |
| 1405 // DidAnticipatedDrawTimeChange's so that it can make forward progress and | |
| 1406 // upload all the textures needed for the commit to complete. | |
| 1407 | |
| 1408 // Since we are simulating a long commit, set up a client with draw duration | |
| 1409 // estimates that prevent skipping main frames to get to low latency mode. | |
| 1410 SchedulerClientWithFixedEstimates* client = | |
| 1411 new SchedulerClientWithFixedEstimates( | |
| 1412 base::TimeDelta::FromMilliseconds(1), | |
| 1413 base::TimeDelta::FromMilliseconds(32), | |
| 1414 base::TimeDelta::FromMilliseconds(32)); | |
| 1415 scheduler_settings_.use_external_begin_frame_source = true; | |
| 1416 SetUpScheduler(make_scoped_ptr(client).Pass(), true); | |
| 1417 | |
| 1418 client->set_log_anticipated_draw_time_change(true); | |
| 1419 | |
| 1420 BeginFrameArgs frame_args = | |
| 1421 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src()); | |
| 1422 frame_args.interval = base::TimeDelta::FromMilliseconds(1000); | |
| 1423 | |
| 1424 // At this point, we've drawn a frame. Start another commit, but hold off on | |
| 1425 // the NotifyReadyToCommit for now. | |
| 1426 EXPECT_FALSE(scheduler_->CommitPending()); | |
| 1427 scheduler_->SetNeedsCommit(); | |
| 1428 fake_external_begin_frame_source()->TestOnBeginFrame(frame_args); | |
| 1429 EXPECT_TRUE(scheduler_->CommitPending()); | |
| 1430 | |
| 1431 // Draw and swap the frame, but don't ack the swap to simulate the Browser | |
| 1432 // blocking on the renderer. | |
| 1433 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); | |
| 1434 task_runner().RunPendingTasks(); // Run posted deadline. | |
| 1435 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending()); | |
| 1436 scheduler_->DidSwapBuffers(); | |
| 1437 | |
| 1438 // Spin the event loop a few times and make sure we get more | |
| 1439 // DidAnticipateDrawTimeChange calls every time. | |
| 1440 int actions_so_far = client->num_actions_(); | |
| 1441 | |
| 1442 // Does three iterations to make sure that the timer is properly repeating. | |
| 1443 for (int i = 0; i < 3; ++i) { | |
| 1444 EXPECT_EQ((frame_args.interval * 2).InMicroseconds(), | |
| 1445 task_runner().DelayToNextTaskTime().InMicroseconds()) | |
| 1446 << scheduler_->AsValue()->ToString(); | |
| 1447 task_runner().RunPendingTasks(); | |
| 1448 EXPECT_GT(client->num_actions_(), actions_so_far); | |
| 1449 EXPECT_STREQ(client->Action(client->num_actions_() - 1), | |
| 1450 "DidAnticipatedDrawTimeChange"); | |
| 1451 actions_so_far = client->num_actions_(); | |
| 1452 } | |
| 1453 | |
| 1454 // Do the same thing after BeginMainFrame starts but still before activation. | |
| 1455 scheduler_->NotifyBeginMainFrameStarted(); | |
| 1456 for (int i = 0; i < 3; ++i) { | |
| 1457 EXPECT_EQ((frame_args.interval * 2).InMicroseconds(), | |
| 1458 task_runner().DelayToNextTaskTime().InMicroseconds()) | |
| 1459 << scheduler_->AsValue()->ToString(); | |
| 1460 task_runner().RunPendingTasks(); | |
| 1461 EXPECT_GT(client->num_actions_(), actions_so_far); | |
| 1462 EXPECT_STREQ(client->Action(client->num_actions_() - 1), | |
| 1463 "DidAnticipatedDrawTimeChange"); | |
| 1464 actions_so_far = client->num_actions_(); | |
| 1465 } | |
| 1466 } | |
| 1467 | |
| 1468 TEST_F( | 1387 TEST_F( |
| 1469 SchedulerTest, | 1388 SchedulerTest, |
| 1470 Deadlock_CommitMakesProgressWhileSwapTrottledAndActiveTreeNeedsFirstDraw) { | 1389 Deadlock_CommitMakesProgressWhileSwapTrottledAndActiveTreeNeedsFirstDraw) { |
| 1471 // NPAPI plugins on Windows block the Browser UI thread on the Renderer main | 1390 // NPAPI plugins on Windows block the Browser UI thread on the Renderer main |
| 1472 // thread. This prevents the scheduler from receiving any pending swap acks. | 1391 // thread. This prevents the scheduler from receiving any pending swap acks. |
| 1473 | 1392 |
| 1474 // Since we are simulating a long commit, set up a client with draw duration | 1393 // Since we are simulating a long commit, set up a client with draw duration |
| 1475 // estimates that prevent skipping main frames to get to low latency mode. | 1394 // estimates that prevent skipping main frames to get to low latency mode. |
| 1476 SchedulerClientWithFixedEstimates* client = | 1395 SchedulerClientWithFixedEstimates* client = |
| 1477 new SchedulerClientWithFixedEstimates( | 1396 new SchedulerClientWithFixedEstimates( |
| (...skipping 1583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3061 scheduler_->SetImplLatencyTakesPriority(true); | 2980 scheduler_->SetImplLatencyTakesPriority(true); |
| 3062 scheduler_->SetChildrenNeedBeginFrames(true); | 2981 scheduler_->SetChildrenNeedBeginFrames(true); |
| 3063 | 2982 |
| 3064 EXPECT_SCOPED(AdvanceFrame()); | 2983 EXPECT_SCOPED(AdvanceFrame()); |
| 3065 EXPECT_TRUE(client_->begin_frame_is_sent_to_children()); | 2984 EXPECT_TRUE(client_->begin_frame_is_sent_to_children()); |
| 3066 EXPECT_FALSE(client_->begin_frame_args_sent_to_children().on_critical_path); | 2985 EXPECT_FALSE(client_->begin_frame_args_sent_to_children().on_critical_path); |
| 3067 } | 2986 } |
| 3068 | 2987 |
| 3069 } // namespace | 2988 } // namespace |
| 3070 } // namespace cc | 2989 } // namespace cc |
| OLD | NEW |