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 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 PushAction("ScheduledActionPrepareTiles"); | 143 PushAction("ScheduledActionPrepareTiles"); |
144 } | 144 } |
145 void ScheduledActionInvalidateOutputSurface() override { | 145 void ScheduledActionInvalidateOutputSurface() override { |
146 actions_.push_back("ScheduledActionInvalidateOutputSurface"); | 146 actions_.push_back("ScheduledActionInvalidateOutputSurface"); |
147 states_.push_back(scheduler_->AsValue()); | 147 states_.push_back(scheduler_->AsValue()); |
148 } | 148 } |
149 void DidAnticipatedDrawTimeChange(base::TimeTicks) override { | 149 void DidAnticipatedDrawTimeChange(base::TimeTicks) override { |
150 if (log_anticipated_draw_time_change_) | 150 if (log_anticipated_draw_time_change_) |
151 PushAction("DidAnticipatedDrawTimeChange"); | 151 PushAction("DidAnticipatedDrawTimeChange"); |
152 } | 152 } |
153 base::TimeDelta DrawDurationEstimate() override { return base::TimeDelta(); } | 153 |
| 154 // Use really long estimations by default so we don't inadvertently |
| 155 // test latency recovery logic unless a test explicitly wants to. |
| 156 base::TimeDelta DrawDurationEstimate() override { |
| 157 return base::TimeDelta::FromHours(1); |
| 158 } |
154 base::TimeDelta BeginMainFrameToCommitDurationEstimate() override { | 159 base::TimeDelta BeginMainFrameToCommitDurationEstimate() override { |
155 return base::TimeDelta(); | 160 return base::TimeDelta::FromHours(1); |
156 } | 161 } |
157 base::TimeDelta CommitToActivateDurationEstimate() override { | 162 base::TimeDelta CommitToActivateDurationEstimate() override { |
158 return base::TimeDelta(); | 163 return base::TimeDelta::FromHours(1); |
159 } | 164 } |
160 | 165 |
161 void SendBeginFramesToChildren(const BeginFrameArgs& args) override { | 166 void SendBeginFramesToChildren(const BeginFrameArgs& args) override { |
162 begin_frame_args_sent_to_children_ = args; | 167 begin_frame_args_sent_to_children_ = args; |
163 } | 168 } |
164 | 169 |
165 void SendBeginMainFrameNotExpectedSoon() override { | 170 void SendBeginMainFrameNotExpectedSoon() override { |
166 PushAction("SendBeginMainFrameNotExpectedSoon"); | 171 PushAction("SendBeginMainFrameNotExpectedSoon"); |
167 } | 172 } |
168 | 173 |
(...skipping 27 matching lines...) Expand all Loading... |
196 int num_draws_; | 201 int num_draws_; |
197 bool log_anticipated_draw_time_change_; | 202 bool log_anticipated_draw_time_change_; |
198 BeginFrameArgs begin_frame_args_sent_to_children_; | 203 BeginFrameArgs begin_frame_args_sent_to_children_; |
199 base::TimeTicks posted_begin_impl_frame_deadline_; | 204 base::TimeTicks posted_begin_impl_frame_deadline_; |
200 std::vector<const char*> actions_; | 205 std::vector<const char*> actions_; |
201 std::vector<scoped_refptr<base::trace_event::ConvertableToTraceFormat>> | 206 std::vector<scoped_refptr<base::trace_event::ConvertableToTraceFormat>> |
202 states_; | 207 states_; |
203 TestScheduler* scheduler_; | 208 TestScheduler* scheduler_; |
204 }; | 209 }; |
205 | 210 |
206 class SchedulerClientWithFixedEstimates : public FakeSchedulerClient { | 211 class SchedulerClientWithCustomEstimates : public FakeSchedulerClient { |
207 public: | 212 public: |
208 SchedulerClientWithFixedEstimates( | 213 SchedulerClientWithCustomEstimates( |
209 base::TimeDelta draw_duration, | 214 base::TimeDelta draw_duration, |
210 base::TimeDelta begin_main_frame_to_commit_duration, | 215 base::TimeDelta begin_main_frame_to_commit_duration, |
211 base::TimeDelta commit_to_activate_duration) | 216 base::TimeDelta commit_to_activate_duration) |
212 : draw_duration_(draw_duration), | 217 : draw_duration_(draw_duration), |
213 begin_main_frame_to_commit_duration_( | 218 begin_main_frame_to_commit_duration_( |
214 begin_main_frame_to_commit_duration), | 219 begin_main_frame_to_commit_duration), |
215 commit_to_activate_duration_(commit_to_activate_duration) {} | 220 commit_to_activate_duration_(commit_to_activate_duration) {} |
216 | 221 |
217 base::TimeDelta DrawDurationEstimate() override { return draw_duration_; } | 222 base::TimeDelta DrawDurationEstimate() override { return draw_duration_; } |
218 base::TimeDelta BeginMainFrameToCommitDurationEstimate() override { | 223 base::TimeDelta BeginMainFrameToCommitDurationEstimate() override { |
219 return begin_main_frame_to_commit_duration_; | 224 return begin_main_frame_to_commit_duration_; |
220 } | 225 } |
221 base::TimeDelta CommitToActivateDurationEstimate() override { | 226 base::TimeDelta CommitToActivateDurationEstimate() override { |
222 return commit_to_activate_duration_; | 227 return commit_to_activate_duration_; |
223 } | 228 } |
224 | 229 |
225 private: | 230 public: |
226 base::TimeDelta draw_duration_; | 231 base::TimeDelta draw_duration_; |
227 base::TimeDelta begin_main_frame_to_commit_duration_; | 232 base::TimeDelta begin_main_frame_to_commit_duration_; |
228 base::TimeDelta commit_to_activate_duration_; | 233 base::TimeDelta commit_to_activate_duration_; |
229 }; | 234 }; |
230 | 235 |
231 class FakeExternalBeginFrameSource : public BeginFrameSourceMixIn { | 236 class FakeExternalBeginFrameSource : public BeginFrameSourceMixIn { |
232 public: | 237 public: |
233 explicit FakeExternalBeginFrameSource(FakeSchedulerClient* client) | 238 explicit FakeExternalBeginFrameSource(FakeSchedulerClient* client) |
234 : client_(client) {} | 239 : client_(client) {} |
235 ~FakeExternalBeginFrameSource() override {} | 240 ~FakeExternalBeginFrameSource() override {} |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
411 | 416 |
412 FakeExternalBeginFrameSource* fake_external_begin_frame_source() const { | 417 FakeExternalBeginFrameSource* fake_external_begin_frame_source() const { |
413 return fake_external_begin_frame_source_; | 418 return fake_external_begin_frame_source_; |
414 } | 419 } |
415 | 420 |
416 void MainFrameInHighLatencyMode( | 421 void MainFrameInHighLatencyMode( |
417 int64 begin_main_frame_to_commit_estimate_in_ms, | 422 int64 begin_main_frame_to_commit_estimate_in_ms, |
418 int64 commit_to_activate_estimate_in_ms, | 423 int64 commit_to_activate_estimate_in_ms, |
419 bool impl_latency_takes_priority, | 424 bool impl_latency_takes_priority, |
420 bool should_send_begin_main_frame); | 425 bool should_send_begin_main_frame); |
| 426 void SwapIsHighLatency(int64 draw_estimate_in_ms, |
| 427 int64 begin_main_frame_to_commit_estimate_in_ms, |
| 428 int64 commit_to_activate_estimate_in_ms, |
| 429 bool has_impl_side_updates, |
| 430 bool swap_ack_before_deadline, |
| 431 bool should_draw_and_swap_in_high_latency); |
421 void BeginFramesNotFromClient(bool use_external_begin_frame_source, | 432 void BeginFramesNotFromClient(bool use_external_begin_frame_source, |
422 bool throttle_frame_production); | 433 bool throttle_frame_production); |
423 void BeginFramesNotFromClient_SwapThrottled( | 434 void BeginFramesNotFromClient_SwapThrottled( |
424 bool use_external_begin_frame_source, | 435 bool use_external_begin_frame_source, |
425 bool throttle_frame_production); | 436 bool throttle_frame_production); |
426 void DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatency( | 437 void DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatency( |
427 bool impl_side_painting); | 438 bool impl_side_painting); |
428 void DidLoseOutputSurfaceAfterReadyToCommit(bool impl_side_painting); | 439 void DidLoseOutputSurfaceAfterReadyToCommit(bool impl_side_painting); |
429 | 440 |
430 scoped_refptr<TestNowSource> now_src_; | 441 scoped_refptr<TestNowSource> now_src_; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
477 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_); | 488 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_); |
478 EXPECT_TRUE(client_->needs_begin_frames()); | 489 EXPECT_TRUE(client_->needs_begin_frames()); |
479 | 490 |
480 client_->Reset(); | 491 client_->Reset(); |
481 EXPECT_SCOPED(AdvanceFrame()); | 492 EXPECT_SCOPED(AdvanceFrame()); |
482 EXPECT_TRUE(client_->begin_frame_is_sent_to_children()); | 493 EXPECT_TRUE(client_->begin_frame_is_sent_to_children()); |
483 } | 494 } |
484 | 495 |
485 TEST_F(SchedulerTest, SendBeginFramesToChildrenDeadlineNotAdjusted) { | 496 TEST_F(SchedulerTest, SendBeginFramesToChildrenDeadlineNotAdjusted) { |
486 // Set up client with specified estimates. | 497 // Set up client with specified estimates. |
487 SchedulerClientWithFixedEstimates* client = | 498 SchedulerClientWithCustomEstimates* client = |
488 new SchedulerClientWithFixedEstimates( | 499 new SchedulerClientWithCustomEstimates( |
489 base::TimeDelta::FromMilliseconds(1), | 500 base::TimeDelta::FromMilliseconds(1), |
490 base::TimeDelta::FromMilliseconds(2), | 501 base::TimeDelta::FromMilliseconds(2), |
491 base::TimeDelta::FromMilliseconds(4)); | 502 base::TimeDelta::FromMilliseconds(4)); |
492 scheduler_settings_.use_external_begin_frame_source = true; | 503 scheduler_settings_.use_external_begin_frame_source = true; |
493 SetUpScheduler(make_scoped_ptr(client).Pass(), true); | 504 SetUpScheduler(make_scoped_ptr(client).Pass(), true); |
494 | 505 |
495 EXPECT_FALSE(client_->needs_begin_frames()); | 506 EXPECT_FALSE(client_->needs_begin_frames()); |
496 scheduler_->SetChildrenNeedBeginFrames(true); | 507 scheduler_->SetChildrenNeedBeginFrames(true); |
497 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_); | 508 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_); |
498 EXPECT_TRUE(client_->needs_begin_frames()); | 509 EXPECT_TRUE(client_->needs_begin_frames()); |
(...skipping 810 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1309 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 1, 3); | 1320 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 1, 3); |
1310 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3); | 1321 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3); |
1311 } | 1322 } |
1312 | 1323 |
1313 void SchedulerTest::MainFrameInHighLatencyMode( | 1324 void SchedulerTest::MainFrameInHighLatencyMode( |
1314 int64 begin_main_frame_to_commit_estimate_in_ms, | 1325 int64 begin_main_frame_to_commit_estimate_in_ms, |
1315 int64 commit_to_activate_estimate_in_ms, | 1326 int64 commit_to_activate_estimate_in_ms, |
1316 bool impl_latency_takes_priority, | 1327 bool impl_latency_takes_priority, |
1317 bool should_send_begin_main_frame) { | 1328 bool should_send_begin_main_frame) { |
1318 // Set up client with specified estimates (draw duration is set to 1). | 1329 // Set up client with specified estimates (draw duration is set to 1). |
1319 SchedulerClientWithFixedEstimates* client = | 1330 SchedulerClientWithCustomEstimates* client = |
1320 new SchedulerClientWithFixedEstimates( | 1331 new SchedulerClientWithCustomEstimates( |
1321 base::TimeDelta::FromMilliseconds(1), | 1332 base::TimeDelta::FromMilliseconds(1), |
1322 base::TimeDelta::FromMilliseconds( | 1333 base::TimeDelta::FromMilliseconds( |
1323 begin_main_frame_to_commit_estimate_in_ms), | 1334 begin_main_frame_to_commit_estimate_in_ms), |
1324 base::TimeDelta::FromMilliseconds(commit_to_activate_estimate_in_ms)); | 1335 base::TimeDelta::FromMilliseconds(commit_to_activate_estimate_in_ms)); |
1325 | 1336 |
1326 scheduler_settings_.use_external_begin_frame_source = true; | 1337 scheduler_settings_.use_external_begin_frame_source = true; |
1327 SetUpScheduler(make_scoped_ptr(client).Pass(), true); | 1338 SetUpScheduler(make_scoped_ptr(client).Pass(), true); |
1328 | 1339 |
1329 scheduler_->SetImplLatencyTakesPriority(impl_latency_takes_priority); | 1340 scheduler_->SetImplLatencyTakesPriority(impl_latency_takes_priority); |
1330 | 1341 |
(...skipping 17 matching lines...) Expand all Loading... |
1348 task_runner().RunPendingTasks(); // Run posted deadline. | 1359 task_runner().RunPendingTasks(); // Run posted deadline. |
1349 EXPECT_EQ(scheduler_->MainThreadIsInHighLatencyMode(), | 1360 EXPECT_EQ(scheduler_->MainThreadIsInHighLatencyMode(), |
1350 should_send_begin_main_frame); | 1361 should_send_begin_main_frame); |
1351 EXPECT_EQ(client->HasAction("ScheduledActionSendBeginMainFrame"), | 1362 EXPECT_EQ(client->HasAction("ScheduledActionSendBeginMainFrame"), |
1352 should_send_begin_main_frame); | 1363 should_send_begin_main_frame); |
1353 } | 1364 } |
1354 | 1365 |
1355 TEST_F(SchedulerTest, | 1366 TEST_F(SchedulerTest, |
1356 SkipMainFrameIfHighLatencyAndCanCommitAndActivateBeforeDeadline) { | 1367 SkipMainFrameIfHighLatencyAndCanCommitAndActivateBeforeDeadline) { |
1357 // Set up client so that estimates indicate that we can commit and activate | 1368 // Set up client so that estimates indicate that we can commit and activate |
1358 // before the deadline (~8ms by default). | 1369 // before the deadline (~11ms by default). |
1359 EXPECT_SCOPED(MainFrameInHighLatencyMode(1, 1, false, false)); | 1370 EXPECT_SCOPED(MainFrameInHighLatencyMode(1, 1, false, false)); |
1360 } | 1371 } |
1361 | 1372 |
1362 TEST_F(SchedulerTest, NotSkipMainFrameIfHighLatencyAndCanCommitTooLong) { | 1373 TEST_F(SchedulerTest, NotSkipMainFrameIfHighLatencyAndCanCommitTooLong) { |
1363 // Set up client so that estimates indicate that the commit cannot finish | 1374 // Set up client so that estimates indicate that the commit cannot finish |
1364 // before the deadline (~8ms by default). | 1375 // before the deadline (~11ms by default). |
1365 EXPECT_SCOPED(MainFrameInHighLatencyMode(10, 1, false, true)); | 1376 EXPECT_SCOPED(MainFrameInHighLatencyMode(10, 1, false, true)); |
1366 } | 1377 } |
1367 | 1378 |
1368 TEST_F(SchedulerTest, NotSkipMainFrameIfHighLatencyAndCanActivateTooLong) { | 1379 TEST_F(SchedulerTest, NotSkipMainFrameIfHighLatencyAndCanActivateTooLong) { |
1369 // Set up client so that estimates indicate that the activate cannot finish | 1380 // Set up client so that estimates indicate that the activate cannot finish |
1370 // before the deadline (~8ms by default). | 1381 // before the deadline (~11ms by default). |
1371 EXPECT_SCOPED(MainFrameInHighLatencyMode(1, 10, false, true)); | 1382 EXPECT_SCOPED(MainFrameInHighLatencyMode(1, 10, false, true)); |
1372 } | 1383 } |
1373 | 1384 |
1374 TEST_F(SchedulerTest, NotSkipMainFrameInPreferImplLatencyMode) { | 1385 TEST_F(SchedulerTest, NotSkipMainFrameInPreferImplLatencyMode) { |
1375 // Set up client so that estimates indicate that we can commit and activate | 1386 // Set up client so that estimates indicate that we can commit and activate |
1376 // before the deadline (~8ms by default), but also enable impl latency takes | 1387 // before the deadline (~11ms by default), but also enable impl latency takes |
1377 // priority mode. | 1388 // priority mode. |
1378 EXPECT_SCOPED(MainFrameInHighLatencyMode(1, 1, true, true)); | 1389 EXPECT_SCOPED(MainFrameInHighLatencyMode(1, 1, true, true)); |
1379 } | 1390 } |
1380 | 1391 |
| 1392 void SchedulerTest::SwapIsHighLatency( |
| 1393 int64 draw_estimate_in_ms, |
| 1394 int64 begin_main_frame_to_commit_estimate_in_ms, |
| 1395 int64 commit_to_activate_estimate_in_ms, |
| 1396 bool has_impl_side_updates, |
| 1397 bool swap_ack_before_deadline, |
| 1398 bool should_draw_and_swap_in_high_latency) { |
| 1399 // Set up client with specified estimates. |
| 1400 SchedulerClientWithCustomEstimates* client = |
| 1401 new SchedulerClientWithCustomEstimates( |
| 1402 base::TimeDelta::FromMilliseconds(draw_estimate_in_ms), |
| 1403 base::TimeDelta::FromMilliseconds( |
| 1404 begin_main_frame_to_commit_estimate_in_ms), |
| 1405 base::TimeDelta::FromMilliseconds(commit_to_activate_estimate_in_ms)); |
| 1406 |
| 1407 scheduler_settings_.use_external_begin_frame_source = true; |
| 1408 SetUpScheduler(make_scoped_ptr(client).Pass(), true); |
| 1409 EXPECT_FALSE(scheduler_->SwapsAreLikelyHighLatency()); |
| 1410 |
| 1411 // To get into a high latency state, this test disables automatic swap acks. |
| 1412 scheduler_->SetMaxSwapsPending(1); |
| 1413 client_->SetAutomaticSwapAck(false); |
| 1414 |
| 1415 // Draw and swap for first BeginFrame |
| 1416 client->Reset(); |
| 1417 scheduler_->SetNeedsCommit(); |
| 1418 if (has_impl_side_updates) |
| 1419 scheduler_->SetNeedsRedraw(); |
| 1420 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1421 EXPECT_FALSE(scheduler_->SwapsAreLikelyHighLatency()); |
| 1422 EXPECT_SCOPED(AdvanceFrame()); |
| 1423 scheduler_->NotifyBeginMainFrameStarted(); |
| 1424 scheduler_->NotifyReadyToCommit(); |
| 1425 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1426 EXPECT_FALSE(scheduler_->SwapsAreLikelyHighLatency()); |
| 1427 task_runner().RunPendingTasks(); // Run posted deadline. |
| 1428 EXPECT_TRUE(client->HasAction("ScheduledActionDrawAndSwapIfPossible")); |
| 1429 |
| 1430 // Not calling scheduler_->DidSwapBuffersComplete() until after next frame |
| 1431 // puts impl thread in high latency mode. |
| 1432 client->Reset(); |
| 1433 scheduler_->SetNeedsCommit(); |
| 1434 if (has_impl_side_updates) |
| 1435 scheduler_->SetNeedsRedraw(); |
| 1436 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1437 EXPECT_FALSE(scheduler_->SwapsAreLikelyHighLatency()); |
| 1438 EXPECT_SCOPED(AdvanceFrame()); |
| 1439 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1440 EXPECT_TRUE(scheduler_->SwapsAreLikelyHighLatency()); |
| 1441 |
| 1442 if (should_draw_and_swap_in_high_latency) { |
| 1443 DCHECK(swap_ack_before_deadline); |
| 1444 scheduler_->DidSwapBuffersComplete(); |
| 1445 scheduler_->NotifyBeginMainFrameStarted(); |
| 1446 scheduler_->NotifyReadyToCommit(); |
| 1447 task_runner().RunPendingTasks(); // Run posted deadline. |
| 1448 } else if (swap_ack_before_deadline) { |
| 1449 scheduler_->DidSwapBuffersComplete(); |
| 1450 task_runner().RunPendingTasks(); // Run posted deadline. |
| 1451 } else { |
| 1452 task_runner().RunPendingTasks(); // Run posted deadline. |
| 1453 scheduler_->DidSwapBuffersComplete(); |
| 1454 } |
| 1455 |
| 1456 // Verify that we recovered immediately if we were supposed to. |
| 1457 EXPECT_EQ(should_draw_and_swap_in_high_latency, |
| 1458 client->HasAction("ScheduledActionDrawAndSwapIfPossible")); |
| 1459 if (should_draw_and_swap_in_high_latency) |
| 1460 scheduler_->DidSwapBuffersComplete(); |
| 1461 |
| 1462 // Verify that we: |
| 1463 // 1) Don't skip two frames in a row. |
| 1464 // 2) Continue normal operation if we didn't skip a frame. |
| 1465 // 3) Make forward progress even when we aren't expecting another swap ack. |
| 1466 client->Reset(); |
| 1467 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1468 EXPECT_EQ(scheduler_->SwapsAreLikelyHighLatency(), |
| 1469 should_draw_and_swap_in_high_latency); |
| 1470 scheduler_->SetNeedsCommit(); |
| 1471 if (has_impl_side_updates) |
| 1472 scheduler_->SetNeedsRedraw(); |
| 1473 EXPECT_SCOPED(AdvanceFrame()); |
| 1474 scheduler_->NotifyBeginMainFrameStarted(); |
| 1475 scheduler_->NotifyReadyToCommit(); |
| 1476 task_runner().RunPendingTasks(); // Run posted deadline. |
| 1477 EXPECT_TRUE(client->HasAction("ScheduledActionDrawAndSwapIfPossible")); |
| 1478 } |
| 1479 |
| 1480 TEST_F(SchedulerTest, |
| 1481 SkipSwapIfHighLatencyAndCanDrawBeforeDeadline_SwapAckThenDeadline) { |
| 1482 // Set up client so that estimates indicate that we can commit and activate |
| 1483 // before the deadline (~11ms by default). |
| 1484 EXPECT_SCOPED(SwapIsHighLatency(1, 1, 1, true, true, false)); |
| 1485 } |
| 1486 |
| 1487 TEST_F(SchedulerTest, |
| 1488 SkipSwapIfHighLatencyAndCanDrawBeforeDeadline_DeadlineThenSwapAck) { |
| 1489 // Set up client so that estimates indicate that we can commit and activate |
| 1490 // before the deadline (~11ms by default). |
| 1491 EXPECT_SCOPED(SwapIsHighLatency(1, 1, 1, true, false, false)); |
| 1492 } |
| 1493 |
| 1494 TEST_F(SchedulerTest, NotSkipSwapIfHighLatencyAndCanDrawTooLong) { |
| 1495 // Set up client so that estimates indicate that the commit cannot finish |
| 1496 // before the deadline (~11ms by default). |
| 1497 EXPECT_SCOPED(SwapIsHighLatency(20, 1, 1, true, true, true)); |
| 1498 } |
| 1499 |
| 1500 TEST_F(SchedulerTest, NotSkipSwapIfHighLatencyAndCanActivateTooLong) { |
| 1501 // Set up client so that estimates indicate that the activate cannot finish |
| 1502 // before the deadline (~11ms by default). |
| 1503 EXPECT_SCOPED(SwapIsHighLatency(1, 8, 8, false, true, true)); |
| 1504 } |
| 1505 |
| 1506 TEST_F(SchedulerTest, MainAndSwapInHighLatencyMode) { |
| 1507 // Set up client with custom estimates. |
| 1508 // This test starts off with expensive estimates to prevent latency recovery |
| 1509 // initially, the lowers the estimates to enable it once both the main |
| 1510 // and impl threads are in a high latency mode. |
| 1511 auto fast_duration = base::TimeDelta::FromMilliseconds(1); |
| 1512 auto slow_duration = base::TimeDelta::FromMilliseconds(10); |
| 1513 SchedulerClientWithCustomEstimates* client = |
| 1514 new SchedulerClientWithCustomEstimates(slow_duration, slow_duration, |
| 1515 slow_duration); |
| 1516 |
| 1517 scheduler_settings_.use_external_begin_frame_source = true; |
| 1518 SetUpScheduler(make_scoped_ptr(client).Pass(), true); |
| 1519 EXPECT_FALSE(scheduler_->SwapsAreLikelyHighLatency()); |
| 1520 |
| 1521 // To get into a high latency state, this test disables automatic swap acks. |
| 1522 scheduler_->SetMaxSwapsPending(1); |
| 1523 client_->SetAutomaticSwapAck(false); |
| 1524 |
| 1525 // Impl thread hits deadline before commit finishes to make |
| 1526 // MainThreadIsInHighLatencyMode true |
| 1527 client->Reset(); |
| 1528 scheduler_->SetNeedsCommit(); |
| 1529 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1530 EXPECT_FALSE(scheduler_->SwapsAreLikelyHighLatency()); |
| 1531 EXPECT_SCOPED(AdvanceFrame()); |
| 1532 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1533 EXPECT_FALSE(scheduler_->SwapsAreLikelyHighLatency()); |
| 1534 task_runner().RunPendingTasks(); // Run posted deadline. |
| 1535 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1536 EXPECT_FALSE(scheduler_->SwapsAreLikelyHighLatency()); |
| 1537 scheduler_->NotifyBeginMainFrameStarted(); |
| 1538 scheduler_->NotifyReadyToCommit(); |
| 1539 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1540 EXPECT_FALSE(scheduler_->SwapsAreLikelyHighLatency()); |
| 1541 EXPECT_TRUE(client->HasAction("WillBeginImplFrame")); |
| 1542 EXPECT_TRUE(client->HasAction("ScheduledActionSendBeginMainFrame")); |
| 1543 |
| 1544 // Draw and swap for first commit, start second commit. |
| 1545 client->Reset(); |
| 1546 scheduler_->SetNeedsCommit(); |
| 1547 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1548 EXPECT_FALSE(scheduler_->SwapsAreLikelyHighLatency()); |
| 1549 EXPECT_SCOPED(AdvanceFrame()); |
| 1550 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1551 EXPECT_FALSE(scheduler_->SwapsAreLikelyHighLatency()); |
| 1552 task_runner().RunPendingTasks(); // Run posted deadline. |
| 1553 scheduler_->NotifyBeginMainFrameStarted(); |
| 1554 scheduler_->NotifyReadyToCommit(); |
| 1555 EXPECT_TRUE(client->HasAction("WillBeginImplFrame")); |
| 1556 EXPECT_TRUE(client->HasAction("ScheduledActionSendBeginMainFrame")); |
| 1557 EXPECT_TRUE(client->HasAction("ScheduledActionDrawAndSwapIfPossible")); |
| 1558 |
| 1559 // Don't call scheduler_->DidSwapBuffersComplete() until after next frame |
| 1560 // to make SwapsAreLikelyHighLatency true. |
| 1561 client->Reset(); |
| 1562 scheduler_->SetNeedsCommit(); |
| 1563 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1564 EXPECT_FALSE(scheduler_->SwapsAreLikelyHighLatency()); |
| 1565 EXPECT_SCOPED(AdvanceFrame()); |
| 1566 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1567 EXPECT_TRUE(scheduler_->SwapsAreLikelyHighLatency()); |
| 1568 task_runner().RunPendingTasks(); // Run posted deadline. |
| 1569 scheduler_->DidSwapBuffersComplete(); |
| 1570 EXPECT_TRUE(scheduler_->SwapsAreLikelyHighLatency()); |
| 1571 EXPECT_TRUE(client->HasAction("WillBeginImplFrame")); |
| 1572 // Note: BeginMainFrame and BeginImplFrame are skipped here because |
| 1573 // of backpressure, not because of latency recovery. |
| 1574 EXPECT_FALSE(client->HasAction("ScheduledActionSendBeginMainFrame")); |
| 1575 EXPECT_FALSE(client->HasAction("ScheduledActionDrawAndSwapIfPossible")); |
| 1576 |
| 1577 // Lower estimates so that the scheduler will attempt latency recovery. |
| 1578 client->begin_main_frame_to_commit_duration_ = fast_duration; |
| 1579 client->commit_to_activate_duration_ = fast_duration; |
| 1580 client->draw_duration_ = fast_duration; |
| 1581 |
| 1582 // Now that both threads are in a high latency mode, make sure we |
| 1583 // skip the BeginMainFrame, then the BeginImplFrame, but not both |
| 1584 // at the same time. |
| 1585 |
| 1586 // Verify we skip BeginMainFrame first. |
| 1587 client->Reset(); |
| 1588 EXPECT_TRUE(scheduler_->NeedsCommit()); // Previous commit still outstanding. |
| 1589 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1590 EXPECT_TRUE(scheduler_->SwapsAreLikelyHighLatency()); |
| 1591 SendNextBeginFrame(); |
| 1592 task_runner().RunPendingTasks(); // Run posted deadline. |
| 1593 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1594 EXPECT_TRUE(scheduler_->SwapsAreLikelyHighLatency()); |
| 1595 EXPECT_TRUE(client->HasAction("WillBeginImplFrame")); |
| 1596 EXPECT_FALSE(client->HasAction("ScheduledActionSendBeginMainFrame")); |
| 1597 EXPECT_TRUE(client->HasAction("ScheduledActionDrawAndSwapIfPossible")); |
| 1598 |
| 1599 // Verify we skip the DrawAndSwap second. |
| 1600 client->Reset(); |
| 1601 EXPECT_TRUE(scheduler_->NeedsCommit()); // Previous commit still outstanding. |
| 1602 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1603 EXPECT_TRUE(scheduler_->SwapsAreLikelyHighLatency()); |
| 1604 SendNextBeginFrame(); |
| 1605 task_runner().RunPendingTasks(); // Run posted deadline. |
| 1606 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1607 EXPECT_TRUE(scheduler_->SwapsAreLikelyHighLatency()); |
| 1608 scheduler_->DidSwapBuffersComplete(); |
| 1609 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1610 EXPECT_FALSE(scheduler_->SwapsAreLikelyHighLatency()); |
| 1611 EXPECT_TRUE(client->HasAction("WillBeginImplFrame")); |
| 1612 EXPECT_FALSE(client->HasAction("ScheduledActionSendBeginMainFrame")); |
| 1613 EXPECT_FALSE(client->HasAction("ScheduledActionDrawAndSwapIfPossible")); |
| 1614 |
| 1615 // Then verify we operate in a low latency mode. |
| 1616 client->Reset(); |
| 1617 EXPECT_TRUE(scheduler_->NeedsCommit()); // Previous commit still outstanding. |
| 1618 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1619 EXPECT_FALSE(scheduler_->SwapsAreLikelyHighLatency()); |
| 1620 SendNextBeginFrame(); |
| 1621 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1622 EXPECT_FALSE(scheduler_->SwapsAreLikelyHighLatency()); |
| 1623 scheduler_->NotifyBeginMainFrameStarted(); |
| 1624 scheduler_->NotifyReadyToCommit(); |
| 1625 task_runner().RunPendingTasks(); // Run posted deadline. |
| 1626 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1627 EXPECT_FALSE(scheduler_->SwapsAreLikelyHighLatency()); |
| 1628 scheduler_->DidSwapBuffersComplete(); |
| 1629 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1630 EXPECT_FALSE(scheduler_->SwapsAreLikelyHighLatency()); |
| 1631 EXPECT_TRUE(client->HasAction("WillBeginImplFrame")); |
| 1632 EXPECT_TRUE(client->HasAction("ScheduledActionSendBeginMainFrame")); |
| 1633 EXPECT_TRUE(client->HasAction("ScheduledActionDrawAndSwapIfPossible")); |
| 1634 } |
| 1635 |
1381 TEST_F(SchedulerTest, PollForCommitCompletion) { | 1636 TEST_F(SchedulerTest, PollForCommitCompletion) { |
1382 // Since we are simulating a long commit, set up a client with draw duration | 1637 // Since we are simulating a long commit, set up a client with draw duration |
1383 // estimates that prevent skipping main frames to get to low latency mode. | 1638 // estimates that prevent skipping main frames to get to low latency mode. |
1384 SchedulerClientWithFixedEstimates* client = | 1639 SchedulerClientWithCustomEstimates* client = |
1385 new SchedulerClientWithFixedEstimates( | 1640 new SchedulerClientWithCustomEstimates( |
1386 base::TimeDelta::FromMilliseconds(1), | 1641 base::TimeDelta::FromMilliseconds(1), |
1387 base::TimeDelta::FromMilliseconds(32), | 1642 base::TimeDelta::FromMilliseconds(32), |
1388 base::TimeDelta::FromMilliseconds(32)); | 1643 base::TimeDelta::FromMilliseconds(32)); |
1389 scheduler_settings_.use_external_begin_frame_source = true; | 1644 scheduler_settings_.use_external_begin_frame_source = true; |
1390 SetUpScheduler(make_scoped_ptr(client).Pass(), true); | 1645 SetUpScheduler(make_scoped_ptr(client).Pass(), true); |
1391 | 1646 |
1392 client->set_log_anticipated_draw_time_change(true); | 1647 client->set_log_anticipated_draw_time_change(true); |
1393 | 1648 |
1394 BeginFrameArgs frame_args = | 1649 BeginFrameArgs frame_args = |
1395 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src()); | 1650 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src()); |
(...skipping 1243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2639 | 2894 |
2640 // At the next BeginFrame, authoritative interval is used instead of previous | 2895 // At the next BeginFrame, authoritative interval is used instead of previous |
2641 // interval. | 2896 // interval. |
2642 EXPECT_NE(initial_interval, scheduler_->begin_impl_frame_args().interval); | 2897 EXPECT_NE(initial_interval, scheduler_->begin_impl_frame_args().interval); |
2643 EXPECT_EQ(authoritative_interval, | 2898 EXPECT_EQ(authoritative_interval, |
2644 scheduler_->begin_impl_frame_args().interval); | 2899 scheduler_->begin_impl_frame_args().interval); |
2645 } | 2900 } |
2646 | 2901 |
2647 } // namespace | 2902 } // namespace |
2648 } // namespace cc | 2903 } // namespace cc |
OLD | NEW |