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 |