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 1360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1371 EXPECT_SCOPED(MainFrameInHighLatencyMode(1, 10, false, true)); | 1371 EXPECT_SCOPED(MainFrameInHighLatencyMode(1, 10, false, true)); |
1372 } | 1372 } |
1373 | 1373 |
1374 TEST_F(SchedulerTest, NotSkipMainFrameInPreferImplLatencyMode) { | 1374 TEST_F(SchedulerTest, NotSkipMainFrameInPreferImplLatencyMode) { |
1375 // Set up client so that estimates indicate that we can commit and activate | 1375 // 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 | 1376 // before the deadline (~8ms by default), but also enable impl latency takes |
1377 // priority mode. | 1377 // priority mode. |
1378 EXPECT_SCOPED(MainFrameInHighLatencyMode(1, 1, true, true)); | 1378 EXPECT_SCOPED(MainFrameInHighLatencyMode(1, 1, true, true)); |
1379 } | 1379 } |
1380 | 1380 |
1381 TEST_F(SchedulerTest, PollForCommitCompletion) { | 1381 TEST_F(SchedulerTest, |
1382 Deadlock_NotifyReadyToCommitMakesProgressWhileSwapTrottled) { | |
1383 // NPAPI plugins on Windows block the Browser UI thread on the Renderer main | |
1384 // thread. This prevents the scheduler from receiving any pending swap acks. | |
1385 // This test makes sure that we keep updating the TextureUploader with | |
1386 // DidAnticipatedDrawTimeChange's so that it can make forward progress and | |
1387 // upload all the textures needed for the commit to complete. | |
1388 | |
1382 // Since we are simulating a long commit, set up a client with draw duration | 1389 // 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. | 1390 // estimates that prevent skipping main frames to get to low latency mode. |
1384 SchedulerClientWithFixedEstimates* client = | 1391 SchedulerClientWithFixedEstimates* client = |
1385 new SchedulerClientWithFixedEstimates( | 1392 new SchedulerClientWithFixedEstimates( |
1386 base::TimeDelta::FromMilliseconds(1), | 1393 base::TimeDelta::FromMilliseconds(1), |
1387 base::TimeDelta::FromMilliseconds(32), | 1394 base::TimeDelta::FromMilliseconds(32), |
1388 base::TimeDelta::FromMilliseconds(32)); | 1395 base::TimeDelta::FromMilliseconds(32)); |
1389 scheduler_settings_.use_external_begin_frame_source = true; | 1396 scheduler_settings_.use_external_begin_frame_source = true; |
1390 SetUpScheduler(make_scoped_ptr(client).Pass(), true); | 1397 SetUpScheduler(make_scoped_ptr(client).Pass(), true); |
1391 | 1398 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1432 task_runner().DelayToNextTaskTime().InMicroseconds()) | 1439 task_runner().DelayToNextTaskTime().InMicroseconds()) |
1433 << scheduler_->AsValue()->ToString(); | 1440 << scheduler_->AsValue()->ToString(); |
1434 task_runner().RunPendingTasks(); | 1441 task_runner().RunPendingTasks(); |
1435 EXPECT_GT(client->num_actions_(), actions_so_far); | 1442 EXPECT_GT(client->num_actions_(), actions_so_far); |
1436 EXPECT_STREQ(client->Action(client->num_actions_() - 1), | 1443 EXPECT_STREQ(client->Action(client->num_actions_() - 1), |
1437 "DidAnticipatedDrawTimeChange"); | 1444 "DidAnticipatedDrawTimeChange"); |
1438 actions_so_far = client->num_actions_(); | 1445 actions_so_far = client->num_actions_(); |
1439 } | 1446 } |
1440 } | 1447 } |
1441 | 1448 |
1449 TEST_F( | |
1450 SchedulerTest, | |
1451 Deadlock_CommitMakesProgressWhileSwapTrottledAndActiveTreeNeedsFirstDraw) { | |
1452 // NPAPI plugins on Windows block the Browser UI thread on the Renderer main | |
1453 // thread. This prevents the scheduler from receiving any pending swap acks. | |
1454 | |
1455 // Since we are simulating a long commit, set up a client with draw duration | |
1456 // estimates that prevent skipping main frames to get to low latency mode. | |
1457 SchedulerClientWithFixedEstimates* client = | |
1458 new SchedulerClientWithFixedEstimates( | |
1459 base::TimeDelta::FromMilliseconds(1), | |
1460 base::TimeDelta::FromMilliseconds(32), | |
1461 base::TimeDelta::FromMilliseconds(32)); | |
1462 scheduler_settings_.use_external_begin_frame_source = true; | |
1463 scheduler_settings_.main_frame_while_swap_throttled_enabled = true; | |
1464 scheduler_settings_.impl_side_painting = true; | |
1465 SetUpScheduler(make_scoped_ptr(client).Pass(), true); | |
1466 | |
1467 // Disables automatic swap acks so this test can force swap ack throttling | |
1468 // to simulate a blocked Browser ui thread. | |
1469 scheduler_->SetMaxSwapsPending(1); | |
1470 client_->SetAutomaticSwapAck(false); | |
1471 | |
1472 // Get a new active tree in main-thread high latency mode and put us | |
1473 // in a swap throttled state. | |
1474 client_->Reset(); | |
1475 EXPECT_FALSE(scheduler_->CommitPending()); | |
1476 scheduler_->SetNeedsCommit(); | |
1477 scheduler_->SetNeedsRedraw(); | |
1478 EXPECT_SCOPED(AdvanceFrame()); | |
1479 EXPECT_TRUE(scheduler_->CommitPending()); | |
1480 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); | |
1481 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true)); | |
1482 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending()); | |
1483 scheduler_->NotifyBeginMainFrameStarted(); | |
1484 scheduler_->NotifyReadyToCommit(); | |
1485 scheduler_->NotifyReadyToActivate(); | |
1486 EXPECT_FALSE(scheduler_->CommitPending()); | |
1487 EXPECT_ACTION("SetNeedsBeginFrames(true)", client_, 0, 7); | |
1488 EXPECT_ACTION("WillBeginImplFrame", client_, 1, 7); | |
1489 EXPECT_ACTION("ScheduledActionAnimate", client_, 2, 7); | |
1490 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 3, 7); | |
1491 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 4, 7); | |
1492 EXPECT_ACTION("ScheduledActionCommit", client_, 5, 7); | |
1493 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 6, 7); | |
1494 | |
1495 // Make sure that we can finish the next commit even while swap throttled. | |
1496 client_->Reset(); | |
1497 EXPECT_FALSE(scheduler_->CommitPending()); | |
1498 scheduler_->SetNeedsCommit(); | |
1499 EXPECT_SCOPED(AdvanceFrame()); | |
1500 scheduler_->NotifyBeginMainFrameStarted(); | |
1501 scheduler_->NotifyReadyToCommit(); | |
1502 scheduler_->NotifyReadyToActivate(); | |
1503 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); | |
1504 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true)); | |
1505 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending()); | |
1506 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 5); | |
1507 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 5); | |
1508 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 5); | |
1509 EXPECT_ACTION("ScheduledActionCommit", client_, 3, 5); | |
1510 EXPECT_ACTION("ScheduledActionAnimate", client_, 4, 5); | |
1511 | |
1512 // Make sure we do not send a BeginMainFrame while swap throttled and | |
1513 // we have both a pending tree and an active tree. | |
1514 client_->Reset(); | |
1515 EXPECT_FALSE(scheduler_->CommitPending()); | |
1516 scheduler_->SetNeedsCommit(); | |
1517 EXPECT_SCOPED(AdvanceFrame()); | |
1518 EXPECT_FALSE(scheduler_->CommitPending()); | |
1519 task_runner().RunPendingTasks(); // Run posted deadline. | |
1520 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); | |
1521 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2); | |
1522 } | |
1523 | |
1524 TEST_F(SchedulerTest, | |
1525 Deadlock_NoBeginMainFrameWhileSwapTrottledAndPipelineFull) { | |
1526 // NPAPI plugins on Windows block the Browser UI thread on the Renderer main | |
1527 // thread. This prevents the scheduler from receiving any pending swap acks. | |
1528 | |
1529 // This particular test makes sure we do not send a BeginMainFrame while | |
1530 // swap trottled and we have a pending tree and active tree that | |
1531 // still needs to be drawn for the first time. | |
1532 | |
1533 // Since we are simulating a long commit, set up a client with draw duration | |
1534 // estimates that prevent skipping main frames to get to low latency mode. | |
1535 SchedulerClientWithFixedEstimates* client = | |
1536 new SchedulerClientWithFixedEstimates( | |
1537 base::TimeDelta::FromMilliseconds(1), | |
1538 base::TimeDelta::FromMilliseconds(32), | |
1539 base::TimeDelta::FromMilliseconds(32)); | |
1540 scheduler_settings_.use_external_begin_frame_source = true; | |
1541 scheduler_settings_.main_frame_while_swap_throttled_enabled = true; | |
1542 scheduler_settings_.main_frame_before_activation_enabled = true; | |
1543 scheduler_settings_.impl_side_painting = true; | |
1544 SetUpScheduler(make_scoped_ptr(client).Pass(), true); | |
1545 | |
1546 // Disables automatic swap acks so this test can force swap ack throttling | |
1547 // to simulate a blocked Browser ui thread. | |
1548 scheduler_->SetMaxSwapsPending(1); | |
1549 client_->SetAutomaticSwapAck(false); | |
1550 | |
1551 // Start a new commit in main-thread high latency mode and hold off on | |
1552 // activation. | |
1553 client_->Reset(); | |
1554 EXPECT_FALSE(scheduler_->CommitPending()); | |
1555 scheduler_->SetNeedsCommit(); | |
1556 scheduler_->SetNeedsRedraw(); | |
1557 EXPECT_SCOPED(AdvanceFrame()); | |
1558 EXPECT_TRUE(scheduler_->CommitPending()); | |
1559 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); | |
1560 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true)); | |
1561 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending()); | |
1562 scheduler_->DidSwapBuffersComplete(); | |
1563 scheduler_->NotifyBeginMainFrameStarted(); | |
1564 scheduler_->NotifyReadyToCommit(); | |
1565 EXPECT_FALSE(scheduler_->CommitPending()); | |
1566 EXPECT_ACTION("SetNeedsBeginFrames(true)", client_, 0, 6); | |
1567 EXPECT_ACTION("WillBeginImplFrame", client_, 1, 6); | |
1568 EXPECT_ACTION("ScheduledActionAnimate", client_, 2, 6); | |
1569 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 3, 6); | |
1570 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 4, 6); | |
1571 EXPECT_ACTION("ScheduledActionCommit", client_, 5, 6); | |
1572 | |
1573 // Start another commit while we still have an active tree. | |
sunnyps
2015/05/20 19:26:51
nit: while we have a pending tree.
brianderson
2015/05/20 19:49:47
Done.
| |
1574 // Enter a swap throttled state. | |
1575 client_->Reset(); | |
1576 EXPECT_FALSE(scheduler_->CommitPending()); | |
1577 scheduler_->SetNeedsCommit(); | |
1578 scheduler_->SetNeedsRedraw(); | |
1579 EXPECT_SCOPED(AdvanceFrame()); | |
1580 EXPECT_TRUE(scheduler_->CommitPending()); | |
1581 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); | |
1582 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true)); | |
1583 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending()); | |
1584 scheduler_->NotifyBeginMainFrameStarted(); | |
1585 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 4); | |
1586 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 4); | |
1587 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 4); | |
1588 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 3, 4); | |
1589 | |
1590 // Can't commit yet because there's still a pending tree. | |
1591 client_->Reset(); | |
1592 scheduler_->NotifyReadyToCommit(); | |
1593 EXPECT_NO_ACTION(client_); | |
1594 | |
1595 // Activate the pending tree, which also unblocks the commit immediately. | |
1596 client_->Reset(); | |
1597 scheduler_->NotifyReadyToActivate(); | |
1598 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 0, 2); | |
1599 EXPECT_ACTION("ScheduledActionCommit", client_, 1, 2); | |
1600 | |
1601 // Make sure we do not send a BeginMainFrame while swap throttled and | |
1602 // we have both a pending tree and an active tree that still needs | |
1603 // it's first draw. | |
1604 client_->Reset(); | |
1605 EXPECT_FALSE(scheduler_->CommitPending()); | |
1606 scheduler_->SetNeedsCommit(); | |
1607 EXPECT_SCOPED(AdvanceFrame()); | |
1608 EXPECT_FALSE(scheduler_->CommitPending()); | |
1609 task_runner().RunPendingTasks(); // Run posted deadline. | |
1610 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); | |
1611 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2); | |
1612 } | |
1613 | |
1614 TEST_F( | |
1615 SchedulerTest, | |
1616 CommitMakesProgressWhenIdleAndHasPendingTreeAndActiveTreeNeedsFirstDraw) { | |
1617 // This verifies we don't block commits longer than we need to | |
1618 // for performance reasons - not deadlock reasons. | |
1619 | |
1620 // Since we are simulating a long commit, set up a client with draw duration | |
1621 // estimates that prevent skipping main frames to get to low latency mode. | |
1622 SchedulerClientWithFixedEstimates* client = | |
1623 new SchedulerClientWithFixedEstimates( | |
1624 base::TimeDelta::FromMilliseconds(1), | |
1625 base::TimeDelta::FromMilliseconds(32), | |
1626 base::TimeDelta::FromMilliseconds(32)); | |
1627 scheduler_settings_.use_external_begin_frame_source = true; | |
1628 scheduler_settings_.main_frame_while_swap_throttled_enabled = true; | |
1629 scheduler_settings_.main_frame_before_activation_enabled = true; | |
1630 scheduler_settings_.impl_side_painting = true; | |
1631 SetUpScheduler(make_scoped_ptr(client).Pass(), true); | |
1632 | |
1633 // Disables automatic swap acks so this test can force swap ack throttling | |
1634 // to simulate a blocked Browser ui thread. | |
1635 scheduler_->SetMaxSwapsPending(1); | |
1636 client_->SetAutomaticSwapAck(false); | |
1637 | |
1638 // Start a new commit in main-thread high latency mode and hold off on | |
1639 // activation. | |
1640 client_->Reset(); | |
1641 EXPECT_FALSE(scheduler_->CommitPending()); | |
1642 scheduler_->SetNeedsCommit(); | |
1643 scheduler_->SetNeedsRedraw(); | |
1644 EXPECT_SCOPED(AdvanceFrame()); | |
1645 EXPECT_TRUE(scheduler_->CommitPending()); | |
1646 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); | |
1647 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true)); | |
1648 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending()); | |
1649 scheduler_->DidSwapBuffersComplete(); | |
1650 scheduler_->NotifyBeginMainFrameStarted(); | |
1651 scheduler_->NotifyReadyToCommit(); | |
1652 EXPECT_FALSE(scheduler_->CommitPending()); | |
1653 EXPECT_ACTION("SetNeedsBeginFrames(true)", client_, 0, 6); | |
1654 EXPECT_ACTION("WillBeginImplFrame", client_, 1, 6); | |
1655 EXPECT_ACTION("ScheduledActionAnimate", client_, 2, 6); | |
1656 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 3, 6); | |
1657 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 4, 6); | |
1658 EXPECT_ACTION("ScheduledActionCommit", client_, 5, 6); | |
1659 | |
1660 // Start another commit while we still have an active tree. | |
1661 client_->Reset(); | |
1662 EXPECT_FALSE(scheduler_->CommitPending()); | |
1663 scheduler_->SetNeedsCommit(); | |
1664 scheduler_->SetNeedsRedraw(); | |
1665 EXPECT_SCOPED(AdvanceFrame()); | |
1666 EXPECT_TRUE(scheduler_->CommitPending()); | |
1667 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); | |
1668 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true)); | |
1669 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending()); | |
1670 scheduler_->NotifyBeginMainFrameStarted(); | |
1671 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 4); | |
1672 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 4); | |
1673 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 4); | |
1674 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 3, 4); | |
1675 scheduler_->DidSwapBuffersComplete(); | |
sunnyps
2015/05/20 19:26:51
nit: Move the DidSwapBuffersComplete call above th
brianderson
2015/05/20 19:49:47
Done.
| |
1676 | |
1677 // Can't commit yet because there's still a pending tree. | |
1678 client_->Reset(); | |
1679 scheduler_->NotifyReadyToCommit(); | |
1680 EXPECT_NO_ACTION(client_); | |
1681 | |
1682 // Activate the pending tree, which also unblocks the commit immediately | |
1683 // while we are in an idle state. | |
1684 client_->Reset(); | |
1685 scheduler_->NotifyReadyToActivate(); | |
1686 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 0, 2); | |
1687 EXPECT_ACTION("ScheduledActionCommit", client_, 1, 2); | |
1688 } | |
1689 | |
1442 TEST_F(SchedulerTest, BeginRetroFrame) { | 1690 TEST_F(SchedulerTest, BeginRetroFrame) { |
1443 scheduler_settings_.use_external_begin_frame_source = true; | 1691 scheduler_settings_.use_external_begin_frame_source = true; |
1444 SetUpScheduler(true); | 1692 SetUpScheduler(true); |
1445 | 1693 |
1446 // SetNeedsCommit should begin the frame on the next BeginImplFrame. | 1694 // SetNeedsCommit should begin the frame on the next BeginImplFrame. |
1447 scheduler_->SetNeedsCommit(); | 1695 scheduler_->SetNeedsCommit(); |
1448 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_); | 1696 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_); |
1449 client_->Reset(); | 1697 client_->Reset(); |
1450 | 1698 |
1451 // Create a BeginFrame with a long deadline to avoid race conditions. | 1699 // Create a BeginFrame with a long deadline to avoid race conditions. |
(...skipping 1187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2639 | 2887 |
2640 // At the next BeginFrame, authoritative interval is used instead of previous | 2888 // At the next BeginFrame, authoritative interval is used instead of previous |
2641 // interval. | 2889 // interval. |
2642 EXPECT_NE(initial_interval, scheduler_->begin_impl_frame_args().interval); | 2890 EXPECT_NE(initial_interval, scheduler_->begin_impl_frame_args().interval); |
2643 EXPECT_EQ(authoritative_interval, | 2891 EXPECT_EQ(authoritative_interval, |
2644 scheduler_->begin_impl_frame_args().interval); | 2892 scheduler_->begin_impl_frame_args().interval); |
2645 } | 2893 } |
2646 | 2894 |
2647 } // namespace | 2895 } // namespace |
2648 } // namespace cc | 2896 } // namespace cc |
OLD | NEW |