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 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
365 } | 365 } |
366 | 366 |
367 if (!scheduler_->settings().using_synchronous_renderer_compositor) { | 367 if (!scheduler_->settings().using_synchronous_renderer_compositor) { |
368 // Then run tasks until new deadline is scheduled. | 368 // Then run tasks until new deadline is scheduled. |
369 EXPECT_TRUE(task_runner_->RunTasksWhile( | 369 EXPECT_TRUE(task_runner_->RunTasksWhile( |
370 client_->ImplFrameDeadlinePending(false))); | 370 client_->ImplFrameDeadlinePending(false))); |
371 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); | 371 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); |
372 } | 372 } |
373 } | 373 } |
374 | 374 |
375 BeginFrameArgs SendNextBeginFrame() { | 375 void SendNextBeginFrame() { |
376 DCHECK(scheduler_->settings().use_external_begin_frame_source); | 376 DCHECK(scheduler_->settings().use_external_begin_frame_source); |
377 // Creep the time forward so that any BeginFrameArgs is not equal to the | 377 // Creep the time forward so that any BeginFrameArgs is not equal to the |
378 // last one otherwise we violate the BeginFrameSource contract. | 378 // last one otherwise we violate the BeginFrameSource contract. |
379 now_src_->AdvanceNow(BeginFrameArgs::DefaultInterval()); | 379 now_src_->AdvanceNow(BeginFrameArgs::DefaultInterval()); |
380 BeginFrameArgs args = | 380 fake_external_begin_frame_source_->TestOnBeginFrame( |
381 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src()); | 381 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src())); |
382 fake_external_begin_frame_source_->TestOnBeginFrame(args); | |
383 return args; | |
384 } | 382 } |
385 | 383 |
386 FakeExternalBeginFrameSource* fake_external_begin_frame_source() const { | 384 FakeExternalBeginFrameSource* fake_external_begin_frame_source() const { |
387 return fake_external_begin_frame_source_; | 385 return fake_external_begin_frame_source_; |
388 } | 386 } |
389 | 387 |
390 void MainFrameInHighLatencyMode( | 388 void MainFrameInHighLatencyMode( |
391 int64 begin_main_frame_to_commit_estimate_in_ms, | 389 int64 begin_main_frame_to_commit_estimate_in_ms, |
392 int64 commit_to_activate_estimate_in_ms, | 390 int64 commit_to_activate_estimate_in_ms, |
393 bool impl_latency_takes_priority, | 391 bool impl_latency_takes_priority, |
(...skipping 1147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1541 client_->Reset(); | 1539 client_->Reset(); |
1542 EXPECT_SCOPED(AdvanceFrame()); | 1540 EXPECT_SCOPED(AdvanceFrame()); |
1543 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); | 1541 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); |
1544 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); | 1542 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); |
1545 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); | 1543 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); |
1546 | 1544 |
1547 client_->Reset(); | 1545 client_->Reset(); |
1548 scheduler_->NotifyBeginMainFrameStarted(); | 1546 scheduler_->NotifyBeginMainFrameStarted(); |
1549 | 1547 |
1550 client_->Reset(); | 1548 client_->Reset(); |
1551 BeginFrameArgs retro_frame_args = SendNextBeginFrame(); | 1549 SendNextBeginFrame(); |
1552 // This BeginFrame is queued up as a retro frame. | 1550 // This BeginFrame is queued up as a retro frame. |
1553 EXPECT_NO_ACTION(client_); | 1551 EXPECT_NO_ACTION(client_); |
1554 // The previous deadline is still pending. | 1552 // The previous deadline is still pending. |
1555 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); | 1553 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); |
1556 | 1554 |
1557 client_->Reset(); | 1555 client_->Reset(); |
1558 // This commit should schedule the (previous) deadline to trigger immediately. | 1556 // This commit should schedule the (previous) deadline to trigger immediately. |
1559 scheduler_->NotifyReadyToCommit(); | 1557 scheduler_->NotifyReadyToCommit(); |
1560 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_); | 1558 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_); |
1561 | 1559 |
1562 client_->Reset(); | 1560 client_->Reset(); |
1563 // The deadline task should trigger causing a draw. | 1561 // The deadline task should trigger causing a draw. |
1564 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); | 1562 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); |
1565 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true)); | 1563 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true)); |
1566 EXPECT_ACTION("ScheduledActionAnimate", client_, 0, 2); | 1564 EXPECT_ACTION("ScheduledActionAnimate", client_, 0, 2); |
1567 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 1, 2); | 1565 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 1, 2); |
1568 | 1566 |
1569 // Keep animating. | 1567 // Keep animating. |
1570 client_->Reset(); | 1568 client_->Reset(); |
1571 scheduler_->SetNeedsAnimate(); | 1569 scheduler_->SetNeedsAnimate(); |
1572 scheduler_->SetNeedsRedraw(); | 1570 scheduler_->SetNeedsRedraw(); |
1573 EXPECT_NO_ACTION(client_); | 1571 EXPECT_NO_ACTION(client_); |
1574 | 1572 |
1575 // Let's advance to the retro frame's deadline. | 1573 // Let's advance sufficiently past the next frame's deadline. |
1576 now_src()->AdvanceNow(retro_frame_args.deadline - now_src()->Now()); | 1574 now_src()->AdvanceNow(BeginFrameArgs::DefaultInterval() - |
| 1575 BeginFrameArgs::DefaultEstimatedParentDrawTime() + |
| 1576 base::TimeDelta::FromMicroseconds(1)); |
1577 | 1577 |
1578 // The retro frame hasn't expired yet. | 1578 // The retro frame hasn't expired yet. |
1579 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(false)); | 1579 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(false)); |
1580 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); | 1580 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); |
1581 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2); | 1581 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2); |
1582 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); | 1582 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); |
1583 | 1583 |
1584 // This is an immediate deadline case. | 1584 // This is an immediate deadline case. |
1585 client_->Reset(); | 1585 client_->Reset(); |
1586 task_runner().RunPendingTasks(); | 1586 task_runner().RunPendingTasks(); |
1587 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending()); | 1587 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending()); |
1588 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_); | 1588 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_); |
1589 } | 1589 } |
1590 | 1590 |
1591 TEST_F(SchedulerTest, RetroFrameExpiresOnTime) { | 1591 TEST_F(SchedulerTest, RetroFrameDoesNotExpireTooLate) { |
1592 scheduler_settings_.use_external_begin_frame_source = true; | 1592 scheduler_settings_.use_external_begin_frame_source = true; |
1593 SetUpScheduler(true); | 1593 SetUpScheduler(true); |
1594 | 1594 |
1595 scheduler_->SetNeedsCommit(); | 1595 scheduler_->SetNeedsCommit(); |
1596 EXPECT_TRUE(client_->needs_begin_frames()); | 1596 EXPECT_TRUE(client_->needs_begin_frames()); |
1597 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_); | 1597 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_); |
1598 | 1598 |
1599 client_->Reset(); | 1599 client_->Reset(); |
1600 EXPECT_SCOPED(AdvanceFrame()); | 1600 EXPECT_SCOPED(AdvanceFrame()); |
1601 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); | 1601 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); |
1602 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); | 1602 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); |
1603 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); | 1603 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); |
1604 | 1604 |
1605 client_->Reset(); | 1605 client_->Reset(); |
1606 scheduler_->NotifyBeginMainFrameStarted(); | 1606 scheduler_->NotifyBeginMainFrameStarted(); |
1607 | 1607 |
1608 client_->Reset(); | 1608 client_->Reset(); |
1609 BeginFrameArgs retro_frame_args = SendNextBeginFrame(); | 1609 SendNextBeginFrame(); |
1610 // This BeginFrame is queued up as a retro frame. | 1610 // This BeginFrame is queued up as a retro frame. |
1611 EXPECT_NO_ACTION(client_); | 1611 EXPECT_NO_ACTION(client_); |
1612 // The previous deadline is still pending. | 1612 // The previous deadline is still pending. |
1613 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); | 1613 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); |
1614 | 1614 |
1615 client_->Reset(); | 1615 client_->Reset(); |
1616 // This commit should schedule the (previous) deadline to trigger immediately. | 1616 // This commit should schedule the (previous) deadline to trigger immediately. |
1617 scheduler_->NotifyReadyToCommit(); | 1617 scheduler_->NotifyReadyToCommit(); |
1618 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_); | 1618 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_); |
1619 | 1619 |
1620 client_->Reset(); | 1620 client_->Reset(); |
1621 // The deadline task should trigger causing a draw. | 1621 // The deadline task should trigger causing a draw. |
1622 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); | 1622 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); |
1623 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true)); | 1623 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true)); |
1624 EXPECT_ACTION("ScheduledActionAnimate", client_, 0, 2); | 1624 EXPECT_ACTION("ScheduledActionAnimate", client_, 0, 2); |
1625 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 1, 2); | 1625 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 1, 2); |
1626 | 1626 |
1627 // Keep animating. | 1627 // Keep animating. |
1628 client_->Reset(); | 1628 client_->Reset(); |
1629 scheduler_->SetNeedsAnimate(); | 1629 scheduler_->SetNeedsAnimate(); |
1630 scheduler_->SetNeedsRedraw(); | 1630 scheduler_->SetNeedsRedraw(); |
1631 EXPECT_NO_ACTION(client_); | 1631 EXPECT_NO_ACTION(client_); |
1632 | 1632 |
1633 // Let's advance sufficiently past the retro frame's deadline. | 1633 // Let's advance sufficiently past the next frame's deadline. |
1634 now_src()->AdvanceNow(retro_frame_args.deadline - now_src()->Now() + | 1634 now_src()->AdvanceNow(BeginFrameArgs::DefaultInterval() + |
1635 base::TimeDelta::FromMicroseconds(1)); | 1635 base::TimeDelta::FromMicroseconds(1)); |
1636 | 1636 |
1637 // The retro frame should've expired. | 1637 // The retro frame should've expired. |
1638 EXPECT_NO_ACTION(client_); | 1638 EXPECT_NO_ACTION(client_); |
1639 } | 1639 } |
1640 | 1640 |
1641 TEST_F(SchedulerTest, MissedFrameDoesNotExpireTooEarly) { | |
1642 scheduler_settings_.use_external_begin_frame_source = true; | |
1643 SetUpScheduler(true); | |
1644 | |
1645 scheduler_->SetNeedsCommit(); | |
1646 EXPECT_TRUE(client_->needs_begin_frames()); | |
1647 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_); | |
1648 | |
1649 BeginFrameArgs missed_frame_args = | |
1650 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src()); | |
1651 missed_frame_args.type = BeginFrameArgs::MISSED; | |
1652 | |
1653 // Advance to the deadline. | |
1654 now_src()->AdvanceNow(missed_frame_args.deadline - now_src()->Now()); | |
1655 | |
1656 // Missed frame is handled because it's on time. | |
1657 client_->Reset(); | |
1658 fake_external_begin_frame_source_->TestOnBeginFrame(missed_frame_args); | |
1659 EXPECT_TRUE( | |
1660 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(false))); | |
1661 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); | |
1662 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); | |
1663 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); | |
1664 } | |
1665 | |
1666 TEST_F(SchedulerTest, MissedFrameExpiresOnTime) { | |
1667 scheduler_settings_.use_external_begin_frame_source = true; | |
1668 SetUpScheduler(true); | |
1669 | |
1670 scheduler_->SetNeedsCommit(); | |
1671 EXPECT_TRUE(client_->needs_begin_frames()); | |
1672 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_); | |
1673 | |
1674 BeginFrameArgs missed_frame_args = | |
1675 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src()); | |
1676 missed_frame_args.type = BeginFrameArgs::MISSED; | |
1677 | |
1678 // Advance sufficiently past the deadline. | |
1679 now_src()->AdvanceNow(missed_frame_args.deadline - now_src()->Now() + | |
1680 base::TimeDelta::FromMicroseconds(1)); | |
1681 | |
1682 // Missed frame is dropped because it's too late. | |
1683 client_->Reset(); | |
1684 fake_external_begin_frame_source_->TestOnBeginFrame(missed_frame_args); | |
1685 EXPECT_FALSE( | |
1686 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(false))); | |
1687 EXPECT_NO_ACTION(client_); | |
1688 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending()); | |
1689 } | |
1690 | |
1691 void SchedulerTest::BeginFramesNotFromClient( | 1641 void SchedulerTest::BeginFramesNotFromClient( |
1692 bool use_external_begin_frame_source, | 1642 bool use_external_begin_frame_source, |
1693 bool throttle_frame_production) { | 1643 bool throttle_frame_production) { |
1694 scheduler_settings_.use_external_begin_frame_source = | 1644 scheduler_settings_.use_external_begin_frame_source = |
1695 use_external_begin_frame_source; | 1645 use_external_begin_frame_source; |
1696 scheduler_settings_.throttle_frame_production = throttle_frame_production; | 1646 scheduler_settings_.throttle_frame_production = throttle_frame_production; |
1697 SetUpScheduler(true); | 1647 SetUpScheduler(true); |
1698 | 1648 |
1699 // SetNeedsCommit should begin the frame on the next BeginImplFrame | 1649 // SetNeedsCommit should begin the frame on the next BeginImplFrame |
1700 // without calling SetNeedsBeginFrame. | 1650 // without calling SetNeedsBeginFrame. |
(...skipping 872 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2573 | 2523 |
2574 // At the next BeginFrame, authoritative interval is used instead of previous | 2524 // At the next BeginFrame, authoritative interval is used instead of previous |
2575 // interval. | 2525 // interval. |
2576 EXPECT_NE(initial_interval, scheduler_->begin_impl_frame_args().interval); | 2526 EXPECT_NE(initial_interval, scheduler_->begin_impl_frame_args().interval); |
2577 EXPECT_EQ(authoritative_interval, | 2527 EXPECT_EQ(authoritative_interval, |
2578 scheduler_->begin_impl_frame_args().interval); | 2528 scheduler_->begin_impl_frame_args().interval); |
2579 } | 2529 } |
2580 | 2530 |
2581 } // namespace | 2531 } // namespace |
2582 } // namespace cc | 2532 } // namespace cc |
OLD | NEW |