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/begin_frame_source.h" | 5 #include "cc/scheduler/begin_frame_source.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include "base/memory/ptr_util.h" | 9 #include "base/memory/ptr_util.h" |
10 #include "base/test/test_simple_task_runner.h" | 10 #include "base/test/test_simple_task_runner.h" |
(...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
575 now_src_->Advance(base::TimeDelta::FromInternalValue(5000)); | 575 now_src_->Advance(base::TimeDelta::FromInternalValue(5000)); |
576 EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs, false); | 576 EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs, false); |
577 // Sequence number is incremented again, because the missed frame has | 577 // Sequence number is incremented again, because the missed frame has |
578 // different time/interval. | 578 // different time/interval. |
579 EXPECT_BEGIN_FRAME_USED_MISSED(obs, source_->source_id(), 3, 10000, 20000, | 579 EXPECT_BEGIN_FRAME_USED_MISSED(obs, source_->source_id(), 3, 10000, 20000, |
580 10000); | 580 10000); |
581 source_->AddObserver(&obs); | 581 source_->AddObserver(&obs); |
582 source_->RemoveObserver(&obs); | 582 source_->RemoveObserver(&obs); |
583 } | 583 } |
584 | 584 |
| 585 // BeginFrameObserverAckTracker testing ---------------------------------------- |
| 586 class TestBeginFrameConsumer : public BeginFrameObserverBase { |
| 587 private: |
| 588 bool OnBeginFrameDerivedImpl(const BeginFrameArgs& args) override { |
| 589 // Consume the args. |
| 590 return true; |
| 591 } |
| 592 void OnBeginFrameSourcePausedChanged(bool paused) override {} |
| 593 }; |
| 594 |
| 595 // Use EXPECT_TRUE instead of EXPECT_EQ for |finished| and |damage| as gcc 4.7 |
| 596 // issues the following warning on EXPECT_EQ(false, x), which is turned into an |
| 597 // error with -Werror=conversion-null: |
| 598 // |
| 599 // converting 'false' to pointer type for argument 1 of |
| 600 // 'char testing::internal::IsNullLiteralHelper(testing::internal::Secret*)' |
| 601 #define EXPECT_ACK_TRACKER_STATE(finished, damage, latest_confirmed) \ |
| 602 EXPECT_TRUE(finished == tracker_->AllObserversFinishedFrame()) \ |
| 603 << "expected: " << finished; \ |
| 604 EXPECT_TRUE(damage == tracker_->AnyObserversHadDamage()) << "expected: " \ |
| 605 << damage; \ |
| 606 EXPECT_EQ(latest_confirmed, tracker_->LatestConfirmedSequenceNumber()) |
| 607 |
| 608 class BeginFrameObserverAckTrackerTest : public ::testing::Test { |
| 609 public: |
| 610 BeginFrameArgs current_args_; |
| 611 std::unique_ptr<BeginFrameObserverAckTracker> tracker_; |
| 612 TestBeginFrameConsumer obs1_; |
| 613 TestBeginFrameConsumer obs2_; |
| 614 |
| 615 void SetUp() override { |
| 616 current_args_ = CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 1); |
| 617 tracker_.reset(new BeginFrameObserverAckTracker()); |
| 618 } |
| 619 }; |
| 620 |
| 621 TEST_F(BeginFrameObserverAckTrackerTest, CorrectnessWithoutObservers) { |
| 622 // Check initial state. |
| 623 EXPECT_ACK_TRACKER_STATE(true, false, 1u); |
| 624 |
| 625 // A new BeginFrame is immediately finished and confirmed. |
| 626 current_args_ = CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 2); |
| 627 tracker_->OnBeginFrame(current_args_); |
| 628 EXPECT_ACK_TRACKER_STATE(true, false, 2u); |
| 629 } |
| 630 |
| 631 TEST_F(BeginFrameObserverAckTrackerTest, CorrectnessWith1Observer) { |
| 632 // Check initial state. |
| 633 EXPECT_ACK_TRACKER_STATE(true, false, 1u); |
| 634 |
| 635 // After adding an observer, the BeginFrame is not finished or confirmed. |
| 636 tracker_->OnObserverAdded(&obs1_); |
| 637 EXPECT_ACK_TRACKER_STATE(false, false, 0u); // up to date to previous frame. |
| 638 |
| 639 // On removing it, the BeginFrame is back to original state. |
| 640 tracker_->OnObserverRemoved(&obs1_); |
| 641 EXPECT_ACK_TRACKER_STATE(true, false, 1u); |
| 642 |
| 643 // After adding it back, the BeginFrame is again not finished or confirmed. |
| 644 tracker_->OnObserverAdded(&obs1_); |
| 645 EXPECT_ACK_TRACKER_STATE(false, false, 0u); // up to date to previous frame. |
| 646 |
| 647 // When the observer finishes and confirms, the BeginFrame is finished |
| 648 // and confirmed. |
| 649 obs1_.OnBeginFrame(current_args_); |
| 650 tracker_->OnObserverFinishedFrame(&obs1_, BeginFrameAck(0, 1, 1, 0, false)); |
| 651 EXPECT_ACK_TRACKER_STATE(true, false, 1u); |
| 652 |
| 653 // A new BeginFrame is initially not finished or confirmed. |
| 654 current_args_ = CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 2); |
| 655 tracker_->OnBeginFrame(current_args_); |
| 656 EXPECT_ACK_TRACKER_STATE(false, false, 1u); |
| 657 |
| 658 // Stray ACK for an old BeginFrame is ignored. |
| 659 tracker_->OnObserverFinishedFrame(&obs1_, BeginFrameAck(0, 1, 1, 0, false)); |
| 660 EXPECT_ACK_TRACKER_STATE(false, false, 1u); |
| 661 |
| 662 // When the observer finishes but doesn't confirm, the BeginFrame is finished |
| 663 // but not confirmed. |
| 664 obs1_.OnBeginFrame(current_args_); |
| 665 tracker_->OnObserverFinishedFrame(&obs1_, BeginFrameAck(0, 2, 1, 0, false)); |
| 666 EXPECT_ACK_TRACKER_STATE(true, false, 1u); |
| 667 |
| 668 // Damage from ACK propagates. |
| 669 current_args_ = CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 3); |
| 670 tracker_->OnBeginFrame(current_args_); |
| 671 EXPECT_ACK_TRACKER_STATE(false, false, 1u); |
| 672 obs1_.OnBeginFrame(current_args_); |
| 673 tracker_->OnObserverFinishedFrame(&obs1_, BeginFrameAck(0, 3, 3, 0, true)); |
| 674 EXPECT_ACK_TRACKER_STATE(true, true, 3u); |
| 675 |
| 676 // Removing an out-of-date observer confirms the latest BeginFrame. |
| 677 current_args_ = CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 4); |
| 678 tracker_->OnBeginFrame(current_args_); |
| 679 EXPECT_ACK_TRACKER_STATE(false, false, 3u); |
| 680 obs1_.OnBeginFrame(current_args_); |
| 681 tracker_->OnObserverFinishedFrame(&obs1_, BeginFrameAck(0, 4, 3, 0, false)); |
| 682 EXPECT_ACK_TRACKER_STATE(true, false, 3u); |
| 683 tracker_->OnObserverRemoved(&obs1_); |
| 684 EXPECT_ACK_TRACKER_STATE(true, false, 4u); |
| 685 } |
| 686 |
| 687 TEST_F(BeginFrameObserverAckTrackerTest, CorrectnessWith2Observers) { |
| 688 // Check initial state. |
| 689 EXPECT_ACK_TRACKER_STATE(true, false, 1u); |
| 690 |
| 691 // After adding observers, the BeginFrame is not finished or confirmed. |
| 692 tracker_->OnObserverAdded(&obs1_); |
| 693 EXPECT_ACK_TRACKER_STATE(false, false, 0u); // up to date to previous frame. |
| 694 tracker_->OnObserverAdded(&obs2_); |
| 695 EXPECT_ACK_TRACKER_STATE(false, false, 0u); // up to date to previous frame. |
| 696 |
| 697 // Removing one of them changes nothing. Same for adding back. |
| 698 tracker_->OnObserverRemoved(&obs1_); |
| 699 EXPECT_ACK_TRACKER_STATE(false, false, 0u); |
| 700 tracker_->OnObserverAdded(&obs1_); |
| 701 EXPECT_ACK_TRACKER_STATE(false, false, 0u); |
| 702 |
| 703 // When one observer finishes and confirms, nothing changes. |
| 704 obs1_.OnBeginFrame(current_args_); |
| 705 tracker_->OnObserverFinishedFrame(&obs1_, BeginFrameAck(0, 1, 1, 0, false)); |
| 706 EXPECT_ACK_TRACKER_STATE(false, false, 0u); |
| 707 // When both finish and confirm, the BeginFrame is finished and confirmed. |
| 708 obs2_.OnBeginFrame(current_args_); |
| 709 tracker_->OnObserverFinishedFrame(&obs2_, BeginFrameAck(0, 1, 1, 0, false)); |
| 710 EXPECT_ACK_TRACKER_STATE(true, false, 1u); |
| 711 |
| 712 // A new BeginFrame is not finished or confirmed. |
| 713 current_args_ = CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 2); |
| 714 tracker_->OnBeginFrame(current_args_); |
| 715 EXPECT_ACK_TRACKER_STATE(false, false, 1u); |
| 716 |
| 717 // When both observers finish but only one confirms, the BeginFrame is |
| 718 // finished but not confirmed. |
| 719 obs1_.OnBeginFrame(current_args_); |
| 720 tracker_->OnObserverFinishedFrame(&obs1_, BeginFrameAck(0, 2, 2, 0, false)); |
| 721 EXPECT_ACK_TRACKER_STATE(false, false, 1u); |
| 722 obs2_.OnBeginFrame(current_args_); |
| 723 tracker_->OnObserverFinishedFrame(&obs2_, BeginFrameAck(0, 2, 1, 0, false)); |
| 724 EXPECT_ACK_TRACKER_STATE(true, false, 1u); |
| 725 |
| 726 // With reversed confirmations in the next ACKs, the latest confirmed frame |
| 727 // increases but the latest BeginFrame remains unconfirmed. |
| 728 current_args_ = CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 3); |
| 729 tracker_->OnBeginFrame(current_args_); |
| 730 EXPECT_ACK_TRACKER_STATE(false, false, 1u); |
| 731 obs1_.OnBeginFrame(current_args_); |
| 732 tracker_->OnObserverFinishedFrame(&obs1_, BeginFrameAck(0, 3, 2, 0, false)); |
| 733 EXPECT_ACK_TRACKER_STATE(false, false, 1u); |
| 734 obs2_.OnBeginFrame(current_args_); |
| 735 tracker_->OnObserverFinishedFrame(&obs2_, BeginFrameAck(0, 3, 3, 0, false)); |
| 736 EXPECT_ACK_TRACKER_STATE(true, false, 2u); |
| 737 |
| 738 // Only a single ACK with damage suffices. |
| 739 current_args_ = CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 4); |
| 740 tracker_->OnBeginFrame(current_args_); |
| 741 EXPECT_ACK_TRACKER_STATE(false, false, 2u); |
| 742 obs1_.OnBeginFrame(current_args_); |
| 743 tracker_->OnObserverFinishedFrame(&obs1_, BeginFrameAck(0, 4, 4, 0, true)); |
| 744 EXPECT_ACK_TRACKER_STATE(false, true, 3u); |
| 745 obs2_.OnBeginFrame(current_args_); |
| 746 tracker_->OnObserverFinishedFrame(&obs2_, BeginFrameAck(0, 4, 4, 0, false)); |
| 747 EXPECT_ACK_TRACKER_STATE(true, true, 4u); |
| 748 |
| 749 // Removing the damaging observer makes no difference in this case. |
| 750 tracker_->OnObserverRemoved(&obs1_); |
| 751 EXPECT_ACK_TRACKER_STATE(true, true, 4u); |
| 752 |
| 753 // Adding the observer back considers it up to date up to the current |
| 754 // BeginFrame, because it is the last used one. Thus, the current BeginFrame |
| 755 // is still finished, too. |
| 756 tracker_->OnObserverAdded(&obs1_); |
| 757 EXPECT_ACK_TRACKER_STATE(true, true, 4u); |
| 758 |
| 759 // Adding the observer back after the next BeginFrame considers it up to date |
| 760 // up to last BeginFrame only. |
| 761 tracker_->OnObserverRemoved(&obs1_); |
| 762 current_args_ = CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 5); |
| 763 tracker_->OnBeginFrame(current_args_); |
| 764 tracker_->OnObserverAdded(&obs1_); |
| 765 EXPECT_ACK_TRACKER_STATE(false, false, 4u); |
| 766 // Both observers need to finish for the BeginFrame to be finished. |
| 767 obs1_.OnBeginFrame(current_args_); |
| 768 tracker_->OnObserverFinishedFrame(&obs1_, BeginFrameAck(0, 5, 5, 0, false)); |
| 769 EXPECT_ACK_TRACKER_STATE(false, false, 4u); |
| 770 obs2_.OnBeginFrame(current_args_); |
| 771 tracker_->OnObserverFinishedFrame(&obs2_, BeginFrameAck(0, 5, 5, 0, false)); |
| 772 EXPECT_ACK_TRACKER_STATE(true, false, 5u); |
| 773 } |
| 774 |
| 775 TEST_F(BeginFrameObserverAckTrackerTest, ChangingSourceIdOnBeginFrame) { |
| 776 // Check initial state. |
| 777 EXPECT_ACK_TRACKER_STATE(true, false, 1u); |
| 778 |
| 779 // Changing source id without observer updates confirmed BeginFrame. |
| 780 current_args_ = CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 1, 10); |
| 781 tracker_->OnBeginFrame(current_args_); |
| 782 EXPECT_ACK_TRACKER_STATE(true, false, 10u); |
| 783 |
| 784 // Setup an observer for current BeginFrame. |
| 785 tracker_->OnObserverAdded(&obs1_); |
| 786 EXPECT_ACK_TRACKER_STATE(false, false, 9u); // up to date to previous frame. |
| 787 obs1_.OnBeginFrame(current_args_); |
| 788 tracker_->OnObserverFinishedFrame(&obs1_, BeginFrameAck(1, 10, 10, 0, true)); |
| 789 EXPECT_ACK_TRACKER_STATE(true, true, 10u); |
| 790 |
| 791 // Changing source id with an observer sets confirmed BeginFrame to invalid. |
| 792 current_args_ = CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 2, 20); |
| 793 tracker_->OnBeginFrame(current_args_); |
| 794 EXPECT_ACK_TRACKER_STATE(false, false, BeginFrameArgs::kInvalidFrameNumber); |
| 795 } |
| 796 |
| 797 // ExternalBeginFrameSource testing -------------------------------------------- |
| 798 class MockExternalBeginFrameSourceClient |
| 799 : public ExternalBeginFrameSourceClient { |
| 800 public: |
| 801 MOCK_METHOD1(OnNeedsBeginFrames, void(bool)); |
| 802 MOCK_METHOD1(OnDidFinishFrame, void(const BeginFrameAck&)); |
| 803 }; |
| 804 |
| 805 class ExternalBeginFrameSourceTest : public ::testing::Test { |
| 806 public: |
| 807 std::unique_ptr<MockExternalBeginFrameSourceClient> client_; |
| 808 std::unique_ptr<ExternalBeginFrameSource> source_; |
| 809 std::unique_ptr<MockBeginFrameObserver> obs_; |
| 810 |
| 811 void SetUp() override { |
| 812 client_.reset(new MockExternalBeginFrameSourceClient); |
| 813 source_.reset(new ExternalBeginFrameSource(client_.get())); |
| 814 obs_.reset(new MockBeginFrameObserver); |
| 815 } |
| 816 |
| 817 void TearDown() override { |
| 818 client_.reset(); |
| 819 obs_.reset(); |
| 820 } |
| 821 }; |
| 822 |
| 823 TEST_F(ExternalBeginFrameSourceTest, CallsOnDidFinishFrameWithoutObservers) { |
| 824 EXPECT_CALL((*client_), OnDidFinishFrame(BeginFrameAck(0, 2, 2, 0, false))) |
| 825 .Times(1); |
| 826 source_->OnBeginFrame(CreateBeginFrameArgsForTesting( |
| 827 BEGINFRAME_FROM_HERE, 0, 2, base::TimeTicks::FromInternalValue(10000))); |
| 828 } |
| 829 |
| 830 TEST_F(ExternalBeginFrameSourceTest, |
| 831 CallsOnDidFinishFrameWhenObserverFinishes) { |
| 832 EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false); |
| 833 EXPECT_CALL((*client_), OnNeedsBeginFrames(true)).Times(1); |
| 834 source_->AddObserver(obs_.get()); |
| 835 |
| 836 BeginFrameArgs args = CreateBeginFrameArgsForTesting( |
| 837 BEGINFRAME_FROM_HERE, 0, 2, base::TimeTicks::FromInternalValue(10000)); |
| 838 EXPECT_BEGIN_FRAME_ARGS_USED(*obs_, args); |
| 839 source_->OnBeginFrame(args); |
| 840 |
| 841 EXPECT_CALL((*client_), OnDidFinishFrame(BeginFrameAck(0, 2, 2, 0, true))) |
| 842 .Times(1); |
| 843 source_->DidFinishFrame(obs_.get(), BeginFrameAck(0, 2, 2, 0, true)); |
| 844 |
| 845 args = CreateBeginFrameArgsForTesting( |
| 846 BEGINFRAME_FROM_HERE, 0, 3, base::TimeTicks::FromInternalValue(20000)); |
| 847 EXPECT_BEGIN_FRAME_ARGS_USED(*obs_, args); |
| 848 source_->OnBeginFrame(args); |
| 849 |
| 850 EXPECT_CALL((*client_), OnDidFinishFrame(BeginFrameAck(0, 3, 2, 0, false))) |
| 851 .Times(1); |
| 852 source_->DidFinishFrame(obs_.get(), BeginFrameAck(0, 3, 2, 0, false)); |
| 853 } |
| 854 |
| 855 TEST_F(ExternalBeginFrameSourceTest, |
| 856 CallsOnDidFinishFrameWhenObserverDropsBeginFrame) { |
| 857 EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false); |
| 858 EXPECT_CALL((*client_), OnNeedsBeginFrames(true)).Times(1); |
| 859 source_->AddObserver(obs_.get()); |
| 860 |
| 861 BeginFrameArgs args = CreateBeginFrameArgsForTesting( |
| 862 BEGINFRAME_FROM_HERE, 0, 2, base::TimeTicks::FromInternalValue(10000)); |
| 863 EXPECT_BEGIN_FRAME_ARGS_DROP(*obs_, args); |
| 864 source_->OnBeginFrame(args); |
| 865 EXPECT_CALL((*client_), OnDidFinishFrame(BeginFrameAck(0, 2, 0, 0, false))) |
| 866 .Times(1); |
| 867 source_->DidFinishFrame(obs_.get(), BeginFrameAck(0, 2, 0, 0, false)); |
| 868 } |
| 869 |
| 870 TEST_F(ExternalBeginFrameSourceTest, CallsOnDidFinishFrameWhenObserverRemoved) { |
| 871 EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false); |
| 872 EXPECT_CALL((*client_), OnNeedsBeginFrames(true)).Times(1); |
| 873 source_->AddObserver(obs_.get()); |
| 874 |
| 875 BeginFrameArgs args = CreateBeginFrameArgsForTesting( |
| 876 BEGINFRAME_FROM_HERE, 0, 2, base::TimeTicks::FromInternalValue(10000)); |
| 877 EXPECT_BEGIN_FRAME_ARGS_USED(*obs_, args); |
| 878 source_->OnBeginFrame(args); |
| 879 |
| 880 EXPECT_CALL((*client_), OnDidFinishFrame(BeginFrameAck(0, 2, 2, 0, false))) |
| 881 .Times(1); |
| 882 EXPECT_CALL((*client_), OnNeedsBeginFrames(false)).Times(1); |
| 883 source_->RemoveObserver(obs_.get()); |
| 884 } |
| 885 |
585 } // namespace | 886 } // namespace |
586 } // namespace cc | 887 } // namespace cc |
OLD | NEW |