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 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
393 } | 393 } |
394 | 394 |
395 if (!scheduler_->settings().using_synchronous_renderer_compositor) { | 395 if (!scheduler_->settings().using_synchronous_renderer_compositor) { |
396 // Then run tasks until new deadline is scheduled. | 396 // Then run tasks until new deadline is scheduled. |
397 EXPECT_TRUE(task_runner_->RunTasksWhile( | 397 EXPECT_TRUE(task_runner_->RunTasksWhile( |
398 client_->ImplFrameDeadlinePending(false))); | 398 client_->ImplFrameDeadlinePending(false))); |
399 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); | 399 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); |
400 } | 400 } |
401 } | 401 } |
402 | 402 |
403 void SendNextBeginFrame() { | 403 BeginFrameArgs SendNextBeginFrame() { |
404 DCHECK(scheduler_->settings().use_external_begin_frame_source); | 404 DCHECK(scheduler_->settings().use_external_begin_frame_source); |
405 // Creep the time forward so that any BeginFrameArgs is not equal to the | 405 // Creep the time forward so that any BeginFrameArgs is not equal to the |
406 // last one otherwise we violate the BeginFrameSource contract. | 406 // last one otherwise we violate the BeginFrameSource contract. |
407 now_src_->AdvanceNow(BeginFrameArgs::DefaultInterval()); | 407 now_src_->AdvanceNow(BeginFrameArgs::DefaultInterval()); |
408 fake_external_begin_frame_source_->TestOnBeginFrame( | 408 BeginFrameArgs args = |
409 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src())); | 409 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src()); |
| 410 fake_external_begin_frame_source_->TestOnBeginFrame(args); |
| 411 return args; |
410 } | 412 } |
411 | 413 |
412 FakeExternalBeginFrameSource* fake_external_begin_frame_source() const { | 414 FakeExternalBeginFrameSource* fake_external_begin_frame_source() const { |
413 return fake_external_begin_frame_source_; | 415 return fake_external_begin_frame_source_; |
414 } | 416 } |
415 | 417 |
416 void MainFrameInHighLatencyMode( | 418 void MainFrameInHighLatencyMode( |
417 int64 begin_main_frame_to_commit_estimate_in_ms, | 419 int64 begin_main_frame_to_commit_estimate_in_ms, |
418 int64 commit_to_activate_estimate_in_ms, | 420 int64 commit_to_activate_estimate_in_ms, |
419 bool impl_latency_takes_priority, | 421 bool impl_latency_takes_priority, |
(...skipping 1179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1599 client_->Reset(); | 1601 client_->Reset(); |
1600 EXPECT_SCOPED(AdvanceFrame()); | 1602 EXPECT_SCOPED(AdvanceFrame()); |
1601 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); | 1603 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); |
1602 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); | 1604 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); |
1603 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); | 1605 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); |
1604 | 1606 |
1605 client_->Reset(); | 1607 client_->Reset(); |
1606 scheduler_->NotifyBeginMainFrameStarted(); | 1608 scheduler_->NotifyBeginMainFrameStarted(); |
1607 | 1609 |
1608 client_->Reset(); | 1610 client_->Reset(); |
1609 SendNextBeginFrame(); | 1611 BeginFrameArgs retro_frame_args = SendNextBeginFrame(); |
1610 // This BeginFrame is queued up as a retro frame. | 1612 // This BeginFrame is queued up as a retro frame. |
1611 EXPECT_NO_ACTION(client_); | 1613 EXPECT_NO_ACTION(client_); |
1612 // The previous deadline is still pending. | 1614 // The previous deadline is still pending. |
1613 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); | 1615 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); |
1614 | 1616 |
1615 client_->Reset(); | 1617 client_->Reset(); |
1616 // This commit should schedule the (previous) deadline to trigger immediately. | 1618 // This commit should schedule the (previous) deadline to trigger immediately. |
1617 scheduler_->NotifyReadyToCommit(); | 1619 scheduler_->NotifyReadyToCommit(); |
1618 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_); | 1620 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_); |
1619 | 1621 |
1620 client_->Reset(); | 1622 client_->Reset(); |
1621 // The deadline task should trigger causing a draw. | 1623 // The deadline task should trigger causing a draw. |
1622 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); | 1624 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); |
1623 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true)); | 1625 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true)); |
1624 EXPECT_ACTION("ScheduledActionAnimate", client_, 0, 2); | 1626 EXPECT_ACTION("ScheduledActionAnimate", client_, 0, 2); |
1625 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 1, 2); | 1627 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 1, 2); |
1626 | 1628 |
1627 // Keep animating. | 1629 // Keep animating. |
1628 client_->Reset(); | 1630 client_->Reset(); |
1629 scheduler_->SetNeedsAnimate(); | 1631 scheduler_->SetNeedsAnimate(); |
1630 scheduler_->SetNeedsRedraw(); | 1632 scheduler_->SetNeedsRedraw(); |
1631 EXPECT_NO_ACTION(client_); | 1633 EXPECT_NO_ACTION(client_); |
1632 | 1634 |
1633 // Let's advance sufficiently past the next frame's deadline. | 1635 // Let's advance to the retro frame's deadline. |
1634 now_src()->AdvanceNow(BeginFrameArgs::DefaultInterval() - | 1636 now_src()->AdvanceNow(retro_frame_args.deadline - now_src()->Now()); |
1635 BeginFrameArgs::DefaultEstimatedParentDrawTime() + | |
1636 base::TimeDelta::FromMicroseconds(1)); | |
1637 | 1637 |
1638 // The retro frame hasn't expired yet. | 1638 // The retro frame hasn't expired yet. |
1639 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(false)); | 1639 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(false)); |
1640 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); | 1640 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); |
1641 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2); | 1641 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2); |
1642 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); | 1642 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); |
1643 | 1643 |
1644 // This is an immediate deadline case. | 1644 // This is an immediate deadline case. |
1645 client_->Reset(); | 1645 client_->Reset(); |
1646 task_runner().RunPendingTasks(); | 1646 task_runner().RunPendingTasks(); |
1647 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending()); | 1647 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending()); |
1648 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_); | 1648 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_); |
1649 } | 1649 } |
1650 | 1650 |
1651 TEST_F(SchedulerTest, RetroFrameDoesNotExpireTooLate) { | 1651 TEST_F(SchedulerTest, RetroFrameExpiresOnTime) { |
1652 scheduler_settings_.use_external_begin_frame_source = true; | 1652 scheduler_settings_.use_external_begin_frame_source = true; |
1653 SetUpScheduler(true); | 1653 SetUpScheduler(true); |
1654 | 1654 |
1655 scheduler_->SetNeedsCommit(); | 1655 scheduler_->SetNeedsCommit(); |
1656 EXPECT_TRUE(client_->needs_begin_frames()); | 1656 EXPECT_TRUE(client_->needs_begin_frames()); |
1657 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_); | 1657 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_); |
1658 | 1658 |
1659 client_->Reset(); | 1659 client_->Reset(); |
1660 EXPECT_SCOPED(AdvanceFrame()); | 1660 EXPECT_SCOPED(AdvanceFrame()); |
1661 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); | 1661 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); |
1662 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); | 1662 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); |
1663 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); | 1663 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); |
1664 | 1664 |
1665 client_->Reset(); | 1665 client_->Reset(); |
1666 scheduler_->NotifyBeginMainFrameStarted(); | 1666 scheduler_->NotifyBeginMainFrameStarted(); |
1667 | 1667 |
1668 client_->Reset(); | 1668 client_->Reset(); |
1669 SendNextBeginFrame(); | 1669 BeginFrameArgs retro_frame_args = SendNextBeginFrame(); |
1670 // This BeginFrame is queued up as a retro frame. | 1670 // This BeginFrame is queued up as a retro frame. |
1671 EXPECT_NO_ACTION(client_); | 1671 EXPECT_NO_ACTION(client_); |
1672 // The previous deadline is still pending. | 1672 // The previous deadline is still pending. |
1673 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); | 1673 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); |
1674 | 1674 |
1675 client_->Reset(); | 1675 client_->Reset(); |
1676 // This commit should schedule the (previous) deadline to trigger immediately. | 1676 // This commit should schedule the (previous) deadline to trigger immediately. |
1677 scheduler_->NotifyReadyToCommit(); | 1677 scheduler_->NotifyReadyToCommit(); |
1678 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_); | 1678 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_); |
1679 | 1679 |
1680 client_->Reset(); | 1680 client_->Reset(); |
1681 // The deadline task should trigger causing a draw. | 1681 // The deadline task should trigger causing a draw. |
1682 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); | 1682 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); |
1683 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true)); | 1683 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true)); |
1684 EXPECT_ACTION("ScheduledActionAnimate", client_, 0, 2); | 1684 EXPECT_ACTION("ScheduledActionAnimate", client_, 0, 2); |
1685 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 1, 2); | 1685 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 1, 2); |
1686 | 1686 |
1687 // Keep animating. | 1687 // Keep animating. |
1688 client_->Reset(); | 1688 client_->Reset(); |
1689 scheduler_->SetNeedsAnimate(); | 1689 scheduler_->SetNeedsAnimate(); |
1690 scheduler_->SetNeedsRedraw(); | 1690 scheduler_->SetNeedsRedraw(); |
1691 EXPECT_NO_ACTION(client_); | 1691 EXPECT_NO_ACTION(client_); |
1692 | 1692 |
1693 // Let's advance sufficiently past the next frame's deadline. | 1693 // Let's advance sufficiently past the retro frame's deadline. |
1694 now_src()->AdvanceNow(BeginFrameArgs::DefaultInterval() + | 1694 now_src()->AdvanceNow(retro_frame_args.deadline - now_src()->Now() + |
1695 base::TimeDelta::FromMicroseconds(1)); | 1695 base::TimeDelta::FromMicroseconds(1)); |
1696 | 1696 |
1697 // The retro frame should've expired. | 1697 // The retro frame should've expired. |
1698 EXPECT_NO_ACTION(client_); | 1698 EXPECT_NO_ACTION(client_); |
1699 } | 1699 } |
1700 | 1700 |
| 1701 TEST_F(SchedulerTest, MissedFrameDoesNotExpireTooEarly) { |
| 1702 scheduler_settings_.use_external_begin_frame_source = true; |
| 1703 SetUpScheduler(true); |
| 1704 |
| 1705 scheduler_->SetNeedsCommit(); |
| 1706 EXPECT_TRUE(client_->needs_begin_frames()); |
| 1707 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_); |
| 1708 |
| 1709 BeginFrameArgs missed_frame_args = |
| 1710 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src()); |
| 1711 missed_frame_args.type = BeginFrameArgs::MISSED; |
| 1712 |
| 1713 // Advance to the deadline. |
| 1714 now_src()->AdvanceNow(missed_frame_args.deadline - now_src()->Now()); |
| 1715 |
| 1716 // Missed frame is handled because it's on time. |
| 1717 client_->Reset(); |
| 1718 fake_external_begin_frame_source_->TestOnBeginFrame(missed_frame_args); |
| 1719 EXPECT_TRUE( |
| 1720 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(false))); |
| 1721 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); |
| 1722 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); |
| 1723 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); |
| 1724 } |
| 1725 |
| 1726 TEST_F(SchedulerTest, MissedFrameExpiresOnTime) { |
| 1727 scheduler_settings_.use_external_begin_frame_source = true; |
| 1728 SetUpScheduler(true); |
| 1729 |
| 1730 scheduler_->SetNeedsCommit(); |
| 1731 EXPECT_TRUE(client_->needs_begin_frames()); |
| 1732 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_); |
| 1733 |
| 1734 BeginFrameArgs missed_frame_args = |
| 1735 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src()); |
| 1736 missed_frame_args.type = BeginFrameArgs::MISSED; |
| 1737 |
| 1738 // Advance sufficiently past the deadline. |
| 1739 now_src()->AdvanceNow(missed_frame_args.deadline - now_src()->Now() + |
| 1740 base::TimeDelta::FromMicroseconds(1)); |
| 1741 |
| 1742 // Missed frame is dropped because it's too late. |
| 1743 client_->Reset(); |
| 1744 fake_external_begin_frame_source_->TestOnBeginFrame(missed_frame_args); |
| 1745 EXPECT_FALSE( |
| 1746 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(false))); |
| 1747 EXPECT_NO_ACTION(client_); |
| 1748 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending()); |
| 1749 } |
| 1750 |
1701 void SchedulerTest::BeginFramesNotFromClient( | 1751 void SchedulerTest::BeginFramesNotFromClient( |
1702 bool use_external_begin_frame_source, | 1752 bool use_external_begin_frame_source, |
1703 bool throttle_frame_production) { | 1753 bool throttle_frame_production) { |
1704 scheduler_settings_.use_external_begin_frame_source = | 1754 scheduler_settings_.use_external_begin_frame_source = |
1705 use_external_begin_frame_source; | 1755 use_external_begin_frame_source; |
1706 scheduler_settings_.throttle_frame_production = throttle_frame_production; | 1756 scheduler_settings_.throttle_frame_production = throttle_frame_production; |
1707 SetUpScheduler(true); | 1757 SetUpScheduler(true); |
1708 | 1758 |
1709 // SetNeedsCommit should begin the frame on the next BeginImplFrame | 1759 // SetNeedsCommit should begin the frame on the next BeginImplFrame |
1710 // without calling SetNeedsBeginFrame. | 1760 // without calling SetNeedsBeginFrame. |
(...skipping 928 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2639 | 2689 |
2640 // At the next BeginFrame, authoritative interval is used instead of previous | 2690 // At the next BeginFrame, authoritative interval is used instead of previous |
2641 // interval. | 2691 // interval. |
2642 EXPECT_NE(initial_interval, scheduler_->begin_impl_frame_args().interval); | 2692 EXPECT_NE(initial_interval, scheduler_->begin_impl_frame_args().interval); |
2643 EXPECT_EQ(authoritative_interval, | 2693 EXPECT_EQ(authoritative_interval, |
2644 scheduler_->begin_impl_frame_args().interval); | 2694 scheduler_->begin_impl_frame_args().interval); |
2645 } | 2695 } |
2646 | 2696 |
2647 } // namespace | 2697 } // namespace |
2648 } // namespace cc | 2698 } // namespace cc |
OLD | NEW |