Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(52)

Side by Side Diff: cc/scheduler/scheduler_unittest.cc

Issue 1133673004: cc: Heuristic for Renderer latency recovery (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase, address Tim's comments Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « cc/scheduler/scheduler_state_machine.cc ('k') | cc/test/scheduler_test_common.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 scoped_ptr<FakeCompositorTimingHistory> fake_compositor_timing_history = 239 scoped_ptr<FakeCompositorTimingHistory> fake_compositor_timing_history =
240 FakeCompositorTimingHistory::Create(); 240 FakeCompositorTimingHistory::Create();
241 fake_compositor_timing_history_ = fake_compositor_timing_history.get(); 241 fake_compositor_timing_history_ = fake_compositor_timing_history.get();
242 242
243 scheduler_ = TestScheduler::Create( 243 scheduler_ = TestScheduler::Create(
244 now_src_.get(), client_.get(), scheduler_settings_, 0, 244 now_src_.get(), client_.get(), scheduler_settings_, 0,
245 task_runner_.get(), fake_external_begin_frame_source_.get(), 245 task_runner_.get(), fake_external_begin_frame_source_.get(),
246 fake_compositor_timing_history.Pass()); 246 fake_compositor_timing_history.Pass());
247 DCHECK(scheduler_); 247 DCHECK(scheduler_);
248 client_->set_scheduler(scheduler_.get()); 248 client_->set_scheduler(scheduler_.get());
249
250 // Use large estimates by default to avoid latency recovery
251 // in most tests.
252 base::TimeDelta one_second = base::TimeDelta::FromSeconds(1);
253 fake_compositor_timing_history_->SetDrawDurationEstimate(one_second);
254 fake_compositor_timing_history_->SetBeginMainFrameToCommitDurationEstimate(
255 one_second);
256 fake_compositor_timing_history_->SetCommitToReadyToActivateDurationEstimate(
257 one_second);
258
249 return scheduler_.get(); 259 return scheduler_.get();
250 } 260 }
251 261
252 void CreateSchedulerAndInitSurface() { 262 void CreateSchedulerAndInitSurface() {
253 CreateScheduler(); 263 CreateScheduler();
254 EXPECT_SCOPED(InitializeOutputSurfaceAndFirstCommit()); 264 EXPECT_SCOPED(InitializeOutputSurfaceAndFirstCommit());
255 } 265 }
256 266
257 void SetUpScheduler(bool initSurface) { 267 void SetUpScheduler(bool initSurface) {
258 SetUpScheduler(make_scoped_ptr(new FakeSchedulerClient), initSurface); 268 SetUpScheduler(make_scoped_ptr(new FakeSchedulerClient), initSurface);
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 392
383 FakeExternalBeginFrameSource* fake_external_begin_frame_source() const { 393 FakeExternalBeginFrameSource* fake_external_begin_frame_source() const {
384 return fake_external_begin_frame_source_.get(); 394 return fake_external_begin_frame_source_.get();
385 } 395 }
386 396
387 void MainFrameInHighLatencyMode( 397 void MainFrameInHighLatencyMode(
388 int64 begin_main_frame_to_commit_estimate_in_ms, 398 int64 begin_main_frame_to_commit_estimate_in_ms,
389 int64 commit_to_activate_estimate_in_ms, 399 int64 commit_to_activate_estimate_in_ms,
390 bool impl_latency_takes_priority, 400 bool impl_latency_takes_priority,
391 bool should_send_begin_main_frame); 401 bool should_send_begin_main_frame);
402 void ImplFrameInHighLatency(int64 draw_estimate_in_ms,
403 int64 begin_main_frame_to_commit_estimate_in_ms,
404 int64 commit_to_activate_estimate_in_ms,
405 bool has_impl_side_updates,
406 bool swap_ack_before_deadline,
407 bool expect_begin_impl_frame_in_high_latency);
392 void BeginFramesNotFromClient(bool use_external_begin_frame_source, 408 void BeginFramesNotFromClient(bool use_external_begin_frame_source,
393 bool throttle_frame_production); 409 bool throttle_frame_production);
394 void BeginFramesNotFromClient_SwapThrottled( 410 void BeginFramesNotFromClient_SwapThrottled(
395 bool use_external_begin_frame_source, 411 bool use_external_begin_frame_source,
396 bool throttle_frame_production); 412 bool throttle_frame_production);
397 413
398 scoped_ptr<base::SimpleTestTickClock> now_src_; 414 scoped_ptr<base::SimpleTestTickClock> now_src_;
399 scoped_refptr<OrderedSimpleTaskRunner> task_runner_; 415 scoped_refptr<OrderedSimpleTaskRunner> task_runner_;
400 scoped_ptr<FakeExternalBeginFrameSource> fake_external_begin_frame_source_; 416 scoped_ptr<FakeExternalBeginFrameSource> fake_external_begin_frame_source_;
401 SchedulerSettings scheduler_settings_; 417 SchedulerSettings scheduler_settings_;
(...skipping 926 matching lines...) Expand 10 before | Expand all | Expand 10 after
1328 task_runner().RunPendingTasks(); // Run posted deadline. 1344 task_runner().RunPendingTasks(); // Run posted deadline.
1329 EXPECT_EQ(scheduler_->MainThreadIsInHighLatencyMode(), 1345 EXPECT_EQ(scheduler_->MainThreadIsInHighLatencyMode(),
1330 should_send_begin_main_frame); 1346 should_send_begin_main_frame);
1331 EXPECT_EQ(client_->HasAction("ScheduledActionSendBeginMainFrame"), 1347 EXPECT_EQ(client_->HasAction("ScheduledActionSendBeginMainFrame"),
1332 should_send_begin_main_frame); 1348 should_send_begin_main_frame);
1333 } 1349 }
1334 1350
1335 TEST_F(SchedulerTest, 1351 TEST_F(SchedulerTest,
1336 SkipMainFrameIfHighLatencyAndCanCommitAndActivateBeforeDeadline) { 1352 SkipMainFrameIfHighLatencyAndCanCommitAndActivateBeforeDeadline) {
1337 // Set up client so that estimates indicate that we can commit and activate 1353 // Set up client so that estimates indicate that we can commit and activate
1338 // before the deadline (~8ms by default). 1354 // before the deadline (~11ms by default).
1339 EXPECT_SCOPED(MainFrameInHighLatencyMode(1, 1, false, false)); 1355 EXPECT_SCOPED(MainFrameInHighLatencyMode(1, 1, false, false));
1340 } 1356 }
1341 1357
1342 TEST_F(SchedulerTest, NotSkipMainFrameIfHighLatencyAndCanCommitTooLong) { 1358 TEST_F(SchedulerTest, NotSkipMainFrameIfHighLatencyAndCanCommitTooLong) {
1343 // Set up client so that estimates indicate that the commit cannot finish 1359 // Set up client so that estimates indicate that the commit cannot finish
1344 // before the deadline (~8ms by default). 1360 // before the deadline (~11ms by default).
1345 EXPECT_SCOPED(MainFrameInHighLatencyMode(10, 1, false, true)); 1361 EXPECT_SCOPED(MainFrameInHighLatencyMode(10, 1, false, true));
1346 } 1362 }
1347 1363
1348 TEST_F(SchedulerTest, NotSkipMainFrameIfHighLatencyAndCanActivateTooLong) { 1364 TEST_F(SchedulerTest, NotSkipMainFrameIfHighLatencyAndCanActivateTooLong) {
1349 // Set up client so that estimates indicate that the activate cannot finish 1365 // Set up client so that estimates indicate that the activate cannot finish
1350 // before the deadline (~8ms by default). 1366 // before the deadline (~11ms by default).
1351 EXPECT_SCOPED(MainFrameInHighLatencyMode(1, 10, false, true)); 1367 EXPECT_SCOPED(MainFrameInHighLatencyMode(1, 10, false, true));
1352 } 1368 }
1353 1369
1354 TEST_F(SchedulerTest, NotSkipMainFrameInPreferImplLatencyMode) { 1370 TEST_F(SchedulerTest, NotSkipMainFrameInPreferImplLatencyMode) {
1355 // Set up client so that estimates indicate that we can commit and activate 1371 // Set up client so that estimates indicate that we can commit and activate
1356 // before the deadline (~8ms by default), but also enable impl latency takes 1372 // before the deadline (~11ms by default), but also enable impl latency takes
1357 // priority mode. 1373 // priority mode.
1358 EXPECT_SCOPED(MainFrameInHighLatencyMode(1, 1, true, true)); 1374 EXPECT_SCOPED(MainFrameInHighLatencyMode(1, 1, true, true));
1359 } 1375 }
1360 1376
1377 void SchedulerTest::ImplFrameInHighLatency(
1378 int64 draw_estimate_in_ms,
1379 int64 begin_main_frame_to_commit_estimate_in_ms,
1380 int64 commit_to_activate_estimate_in_ms,
1381 bool has_impl_side_updates,
1382 bool swap_ack_before_deadline,
1383 bool expect_begin_impl_frame_in_high_latency) {
1384 // Set up client with specified estimates.
1385 scheduler_settings_.use_external_begin_frame_source = true;
1386 SetUpScheduler(true);
1387
1388 fake_compositor_timing_history_->SetDrawDurationEstimate(
1389 base::TimeDelta::FromMilliseconds(draw_estimate_in_ms));
1390 fake_compositor_timing_history_->SetBeginMainFrameToCommitDurationEstimate(
1391 base::TimeDelta::FromMilliseconds(
1392 begin_main_frame_to_commit_estimate_in_ms));
1393 fake_compositor_timing_history_->SetCommitToReadyToActivateDurationEstimate(
1394 base::TimeDelta::FromMilliseconds(commit_to_activate_estimate_in_ms));
1395
1396 // To get into a high latency state, this test disables automatic swap acks.
1397 scheduler_->SetMaxSwapsPending(1);
1398 client_->SetAutomaticSwapAck(false);
1399
1400 // Draw and swap for first BeginFrame
1401 client_->Reset();
1402 scheduler_->SetNeedsCommit();
1403 if (has_impl_side_updates) {
1404 scheduler_->SetNeedsRedraw();
1405 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
1406 SendNextBeginFrame();
1407 EXPECT_ACTION("SetNeedsBeginFrames(true)", client_, 0, 4);
1408 EXPECT_ACTION("WillBeginImplFrame", client_, 1, 4);
1409 EXPECT_ACTION("ScheduledActionAnimate", client_, 2, 4);
1410 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 3, 4);
1411 } else {
1412 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
1413 SendNextBeginFrame();
1414 EXPECT_ACTION("SetNeedsBeginFrames(true)", client_, 0, 3);
1415 EXPECT_ACTION("WillBeginImplFrame", client_, 1, 3);
1416 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 3);
1417 }
1418
1419 client_->Reset();
1420 scheduler_->NotifyBeginMainFrameStarted();
1421 scheduler_->NotifyReadyToCommit();
1422 scheduler_->NotifyReadyToActivate();
1423 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
1424 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
1425 EXPECT_ACTION("ScheduledActionCommit", client_, 0, 4);
1426 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 1, 4);
1427 EXPECT_ACTION("ScheduledActionAnimate", client_, 2, 4);
1428 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 3, 4);
1429
1430 // Not calling scheduler_->DidSwapBuffersComplete() until after next frame
1431 // puts the 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 SendNextBeginFrame();
1438 if (expect_begin_impl_frame_in_high_latency) {
1439 if (has_impl_side_updates) {
1440 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
1441 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
mithro-old 2015/07/07 07:35:38 Why does "has_impl_side_updates" imply a Scheduled
brianderson 2015/07/07 18:34:03 Opened up a a followup bug for this: https://code.
1442 } else {
1443 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_);
1444 }
1445 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
1446 } else {
1447 EXPECT_NO_ACTION(client_);
1448 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
1449 }
1450 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
1451
1452 client_->Reset();
1453 if (expect_begin_impl_frame_in_high_latency) {
1454 DCHECK(swap_ack_before_deadline);
1455 scheduler_->DidSwapBuffersComplete();
mithro-old 2015/07/07 07:35:38 Why does this path require all the extra Notify ca
brianderson 2015/07/07 18:34:03 Because the DidSwapBuffersComplete will trigger a
1456 scheduler_->NotifyBeginMainFrameStarted();
1457 scheduler_->NotifyReadyToCommit();
1458 scheduler_->NotifyReadyToActivate();
1459 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
1460 } else if (swap_ack_before_deadline) {
1461 scheduler_->DidSwapBuffersComplete();
1462 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
1463 } else {
1464 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
1465 scheduler_->DidSwapBuffersComplete();
1466 }
1467
1468 // Verify that we recovered immediately if we were supposed to and
1469 // that we didn't if weren't.
1470 if (expect_begin_impl_frame_in_high_latency) {
1471 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 0, 5);
1472 EXPECT_ACTION("ScheduledActionCommit", client_, 1, 5);
1473 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 2, 5);
1474 EXPECT_ACTION("ScheduledActionAnimate", client_, 3, 5);
1475 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 4, 5);
1476 scheduler_->DidSwapBuffersComplete();
mithro-old 2015/07/07 07:35:38 The expect_begin_impl_frame_in_high_latency seems
brianderson 2015/07/07 18:34:03 I will add a comment. The ScheduledActionSendBegin
1477 } else {
1478 EXPECT_NO_ACTION(client_);
1479 }
1480
1481 // Verify that we:
1482 // 1) Don't skip two frames in a row.
1483 // 2) Continue normal operation if we didn't skip a frame.
1484 // 3) Make forward progress even when we aren't expecting another swap ack.
1485 client_->Reset();
1486 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
1487 scheduler_->SetNeedsCommit();
1488 if (has_impl_side_updates) {
1489 scheduler_->SetNeedsRedraw();
1490 SendNextBeginFrame();
1491 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3);
1492 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 3);
1493 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 3);
1494 } else {
1495 SendNextBeginFrame();
1496 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
1497 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
1498 }
1499
1500 client_->Reset();
1501 scheduler_->NotifyBeginMainFrameStarted();
1502 scheduler_->NotifyReadyToCommit();
1503 scheduler_->NotifyReadyToActivate();
1504 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
1505 EXPECT_ACTION("ScheduledActionCommit", client_, 0, 4);
1506 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 1, 4);
1507 EXPECT_ACTION("ScheduledActionAnimate", client_, 2, 4);
1508 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 3, 4);
1509 }
1510
1511 TEST_F(SchedulerTest,
1512 SkipSwapIfHighLatencyAndCanDrawBeforeDeadline_SwapAckThenDeadline) {
1513 // Use estimates that indicate commit and activate can finish before the
1514 // deadline.
1515 int64 draw_estimate_in_ms = 1;
1516 int64 begin_main_frame_to_commit_estimate_in_ms = 1;
1517 int64 commit_to_activate_estimate_in_ms = 1;
1518 bool has_impl_side_updates = true;
1519 bool swap_ack_before_deadline = true;
1520 bool expect_begin_impl_frame_in_high_latency = false;
1521 EXPECT_SCOPED(ImplFrameInHighLatency(
1522 draw_estimate_in_ms, begin_main_frame_to_commit_estimate_in_ms,
1523 commit_to_activate_estimate_in_ms, has_impl_side_updates,
1524 swap_ack_before_deadline, expect_begin_impl_frame_in_high_latency));
1525 }
1526
1527 TEST_F(SchedulerTest,
1528 SkipSwapIfHighLatencyAndCanDrawBeforeDeadline_DeadlineThenSwapAck) {
1529 // Use estimates that indicate commit and activate can finish before the
1530 // deadline.
1531 int64 draw_estimate_in_ms = 1;
1532 int64 begin_main_frame_to_commit_estimate_in_ms = 1;
1533 int64 commit_to_activate_estimate_in_ms = 1;
1534 bool has_impl_side_updates = true;
1535 bool swap_ack_before_deadline = false;
1536 bool expect_begin_impl_frame_in_high_latency = false;
1537 EXPECT_SCOPED(ImplFrameInHighLatency(
1538 draw_estimate_in_ms, begin_main_frame_to_commit_estimate_in_ms,
1539 commit_to_activate_estimate_in_ms, has_impl_side_updates,
1540 swap_ack_before_deadline, expect_begin_impl_frame_in_high_latency));
1541 }
1542
1543 TEST_F(SchedulerTest, NotSkipSwapIfHighLatencyAndCanDrawTooLong) {
mithro-old 2015/07/07 07:35:38 nit: CanDrawTooLong? DontSkipSwapIfHighLatencyAndD
brianderson 2015/07/07 18:34:03 Yeah, the test names are pretty bad. DontSkipSwapI
1544 // Use estimates that indicate draw cannot finish before the deadline.
1545 int64 draw_estimate_in_ms = 20;
1546 int64 begin_main_frame_to_commit_estimate_in_ms = 1;
1547 int64 commit_to_activate_estimate_in_ms = 1;
1548 bool has_impl_side_updates = true;
1549 bool swap_ack_before_deadline = true;
1550 bool expect_begin_impl_frame_in_high_latency = true;
1551 EXPECT_SCOPED(ImplFrameInHighLatency(
1552 draw_estimate_in_ms, begin_main_frame_to_commit_estimate_in_ms,
1553 commit_to_activate_estimate_in_ms, has_impl_side_updates,
1554 swap_ack_before_deadline, expect_begin_impl_frame_in_high_latency));
1555 }
1556
1557 TEST_F(SchedulerTest, NotSkipSwapIfHighLatencyAndCanActivateTooLong) {
1558 // Use estimates that indicate commit and activate cannot finish before the
1559 // deadline.
1560 int64 draw_estimate_in_ms = 1;
1561 int64 begin_main_frame_to_commit_estimate_in_ms = 8;
1562 int64 commit_to_activate_estimate_in_ms = 8;
1563 bool has_impl_side_updates = false;
1564 bool swap_ack_before_deadline = true;
1565 bool expect_begin_impl_frame_in_high_latency = true;
1566 EXPECT_SCOPED(ImplFrameInHighLatency(
1567 draw_estimate_in_ms, begin_main_frame_to_commit_estimate_in_ms,
1568 commit_to_activate_estimate_in_ms, has_impl_side_updates,
1569 swap_ack_before_deadline, expect_begin_impl_frame_in_high_latency));
1570 }
1571
1572 TEST_F(SchedulerTest, MainAndSwapInHighLatencyMode) {
1573 // Set up client with custom estimates.
1574 // This test starts off with expensive estimates to prevent latency recovery
1575 // initially, the lowers the estimates to enable it once both the main
1576 // and impl threads are in a high latency mode.
1577 scheduler_settings_.use_external_begin_frame_source = true;
1578 SetUpScheduler(true);
1579
1580 auto slow_duration = base::TimeDelta::FromMilliseconds(10);
1581 fake_compositor_timing_history_->SetDrawDurationEstimate(slow_duration);
1582 fake_compositor_timing_history_->SetBeginMainFrameToCommitDurationEstimate(
1583 slow_duration);
1584 fake_compositor_timing_history_->SetCommitToReadyToActivateDurationEstimate(
1585 slow_duration);
1586
1587 // To get into a high latency state, this test disables automatic swap acks.
1588 scheduler_->SetMaxSwapsPending(1);
1589 client_->SetAutomaticSwapAck(false);
1590
1591 // Impl thread hits deadline before commit finishes to make
1592 // MainThreadIsInHighLatencyMode true
1593 client_->Reset();
1594 scheduler_->SetNeedsCommit();
1595 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
1596 EXPECT_SCOPED(AdvanceFrame());
1597 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
1598 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
1599 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
1600 scheduler_->NotifyBeginMainFrameStarted();
1601 scheduler_->NotifyReadyToCommit();
1602 scheduler_->NotifyReadyToActivate();
1603 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
1604
1605 EXPECT_ACTION("SetNeedsBeginFrames(true)", client_, 0, 5);
1606 EXPECT_ACTION("WillBeginImplFrame", client_, 1, 5);
1607 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 5);
1608 EXPECT_ACTION("ScheduledActionCommit", client_, 3, 5);
1609 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 4, 5);
1610
1611 // Draw and swap for first commit, start second commit.
1612 client_->Reset();
1613 scheduler_->SetNeedsCommit();
1614 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
1615 EXPECT_SCOPED(AdvanceFrame());
1616 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
1617 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
1618 scheduler_->NotifyBeginMainFrameStarted();
1619 scheduler_->NotifyReadyToCommit();
1620 scheduler_->NotifyReadyToActivate();
1621
1622 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 6);
1623 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 6);
1624 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 6);
1625 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 3, 6);
1626 EXPECT_ACTION("ScheduledActionCommit", client_, 4, 6);
1627 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 5, 6);
1628
1629 // Don't call scheduler_->DidSwapBuffersComplete() until after next frame
1630 // to put the impl thread in a high latency mode.
1631 client_->Reset();
1632 scheduler_->SetNeedsCommit();
1633 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
1634 EXPECT_SCOPED(AdvanceFrame());
1635 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
1636 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
1637 scheduler_->DidSwapBuffersComplete();
1638
1639 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
1640 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
1641 // Note: BeginMainFrame and swap are skipped here because of
1642 // swap ack backpressure, not because of latency recovery.
1643 EXPECT_FALSE(client_->HasAction("ScheduledActionSendBeginMainFrame"));
1644 EXPECT_FALSE(client_->HasAction("ScheduledActionDrawAndSwapIfPossible"));
1645
1646 // Lower estimates so that the scheduler will attempt latency recovery.
1647 auto fast_duration = base::TimeDelta::FromMilliseconds(1);
1648 fake_compositor_timing_history_->SetDrawDurationEstimate(fast_duration);
1649 fake_compositor_timing_history_->SetBeginMainFrameToCommitDurationEstimate(
1650 fast_duration);
1651 fake_compositor_timing_history_->SetCommitToReadyToActivateDurationEstimate(
1652 fast_duration);
1653
1654 // Now that both threads are in a high latency mode, make sure we
1655 // skip the BeginMainFrame, then the BeginImplFrame, but not both
1656 // at the same time.
1657
1658 // Verify we skip BeginMainFrame first.
1659 client_->Reset();
1660 // Previous commit request is still outstanding.
1661 EXPECT_TRUE(scheduler_->NeedsCommit());
1662 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
1663 SendNextBeginFrame();
1664 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
1665 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
1666
1667 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3);
1668 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 3);
1669 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 2, 3);
1670 EXPECT_FALSE(client_->HasAction("ScheduledActionSendBeginMainFrame"));
1671
1672 // Verify we skip the BeginImplFrame second.
1673 client_->Reset();
1674 // Previous commit request is still outstanding.
1675 EXPECT_TRUE(scheduler_->NeedsCommit());
1676 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
1677 SendNextBeginFrame();
1678 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
1679 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
1680 scheduler_->DidSwapBuffersComplete();
1681 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
1682
1683 EXPECT_NO_ACTION(client_);
1684
1685 // Then verify we operate in a low latency mode.
1686 client_->Reset();
1687 // Previous commit request is still outstanding.
1688 EXPECT_TRUE(scheduler_->NeedsCommit());
1689 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
1690 SendNextBeginFrame();
1691 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
1692 scheduler_->NotifyBeginMainFrameStarted();
1693 scheduler_->NotifyReadyToCommit();
1694 scheduler_->NotifyReadyToActivate();
1695 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
1696 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
1697 scheduler_->DidSwapBuffersComplete();
1698 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
1699
1700 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 6);
1701 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 6);
1702 EXPECT_ACTION("ScheduledActionCommit", client_, 2, 6);
1703 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 3, 6);
1704 EXPECT_ACTION("ScheduledActionAnimate", client_, 4, 6);
1705 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 5, 6);
1706 }
1707
1361 TEST_F( 1708 TEST_F(
1362 SchedulerTest, 1709 SchedulerTest,
1363 Deadlock_CommitMakesProgressWhileSwapTrottledAndActiveTreeNeedsFirstDraw) { 1710 Deadlock_CommitMakesProgressWhileSwapTrottledAndActiveTreeNeedsFirstDraw) {
1364 // NPAPI plugins on Windows block the Browser UI thread on the Renderer main 1711 // NPAPI plugins on Windows block the Browser UI thread on the Renderer main
1365 // thread. This prevents the scheduler from receiving any pending swap acks. 1712 // thread. This prevents the scheduler from receiving any pending swap acks.
1366 1713
1367 // Since we are simulating a long commit, set up a client with draw duration 1714 // Since we are simulating a long commit, set up a client with draw duration
1368 // estimates that prevent skipping main frames to get to low latency mode. 1715 // estimates that prevent skipping main frames to get to low latency mode.
1369 scheduler_settings_.use_external_begin_frame_source = true; 1716 scheduler_settings_.use_external_begin_frame_source = true;
1370 scheduler_settings_.main_frame_while_swap_throttled_enabled = true; 1717 scheduler_settings_.main_frame_while_swap_throttled_enabled = true;
(...skipping 1584 matching lines...) Expand 10 before | Expand all | Expand 10 after
2955 scheduler_->SetImplLatencyTakesPriority(true); 3302 scheduler_->SetImplLatencyTakesPriority(true);
2956 scheduler_->SetChildrenNeedBeginFrames(true); 3303 scheduler_->SetChildrenNeedBeginFrames(true);
2957 3304
2958 EXPECT_SCOPED(AdvanceFrame()); 3305 EXPECT_SCOPED(AdvanceFrame());
2959 EXPECT_TRUE(client_->begin_frame_is_sent_to_children()); 3306 EXPECT_TRUE(client_->begin_frame_is_sent_to_children());
2960 EXPECT_FALSE(client_->begin_frame_args_sent_to_children().on_critical_path); 3307 EXPECT_FALSE(client_->begin_frame_args_sent_to_children().on_critical_path);
2961 } 3308 }
2962 3309
2963 } // namespace 3310 } // namespace
2964 } // namespace cc 3311 } // namespace cc
OLDNEW
« no previous file with comments | « cc/scheduler/scheduler_state_machine.cc ('k') | cc/test/scheduler_test_common.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698