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

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

Issue 2691453002: [cc] Track observer status in ExternalBeginFrameSource. (Closed)
Patch Set: Use flat_set and SmallMap. Created 3 years, 10 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
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/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
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 public:
588 void SetDiscardNextBeginFrame() { discard_next_begin_frame_ = true; }
589
590 private:
591 bool OnBeginFrameDerivedImpl(const BeginFrameArgs& args) override {
592 // Consume the args and indicate whether we used them.
593 bool discard_this_begin_frame = discard_next_begin_frame_;
594 discard_next_begin_frame_ = false;
595 return !discard_this_begin_frame;
596 }
597 void OnBeginFrameSourcePausedChanged(bool paused) override {}
598
599 bool discard_next_begin_frame_ = false;
600 };
601
602 // Use EXPECT_TRUE instead of EXPECT_EQ for |finished| and |damage| as gcc 4.7
603 // issues the following warning on EXPECT_EQ(false, x), which is turned into an
604 // error with -Werror=conversion-null:
605 //
606 // converting 'false' to pointer type for argument 1 of
607 // 'char testing::internal::IsNullLiteralHelper(testing::internal::Secret*)'
608 #define EXPECT_ACK_TRACKER_STATE(finished, damage, latest_confirmed) \
609 EXPECT_TRUE(finished == tracker_->AllObserversFinishedFrame()) \
610 << "expected: " << finished; \
611 EXPECT_TRUE(damage == tracker_->AnyObserversHadDamage()) << "expected: " \
612 << damage; \
613 EXPECT_EQ(latest_confirmed, tracker_->LatestConfirmedSequenceNumber())
614
615 class BeginFrameObserverAckTrackerTest : public ::testing::Test {
616 public:
617 BeginFrameArgs current_args_;
618 std::unique_ptr<BeginFrameObserverAckTracker> tracker_;
619 std::unique_ptr<TestBeginFrameConsumer> obs1_;
620 std::unique_ptr<TestBeginFrameConsumer> obs2_;
brianderson 2017/02/17 21:26:09 Do these need to be unique_ptrs?
Eric Seckler 2017/02/21 12:10:57 Since I now no longer need to recreate the TestBeg
621
622 void SetUp() override {
623 current_args_ = CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 1);
624 tracker_.reset(new BeginFrameObserverAckTracker());
625 obs1_.reset(new TestBeginFrameConsumer);
626 obs2_.reset(new TestBeginFrameConsumer);
627 }
628 };
629
630 TEST_F(BeginFrameObserverAckTrackerTest, CorrectnessWithoutObservers) {
631 // Check initial state.
632 EXPECT_ACK_TRACKER_STATE(true, false, 1u);
633
634 // A new BeginFrame is immediately finished and confirmed.
635 current_args_ = CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 2);
636 tracker_->OnBeginFrame(current_args_);
637 EXPECT_ACK_TRACKER_STATE(true, false, 2u);
638 }
639
640 TEST_F(BeginFrameObserverAckTrackerTest, CorrectnessWith1Observer) {
641 // Check initial state.
642 EXPECT_ACK_TRACKER_STATE(true, false, 1u);
643
644 // After adding an observer, the BeginFrame is not finished or confirmed.
645 tracker_->OnObserverAdded(obs1_.get());
646 EXPECT_ACK_TRACKER_STATE(false, false, 0u); // up to date to previous frame.
647
648 // On removing it, the BeginFrame is back to original state.
649 tracker_->OnObserverRemoved(obs1_.get());
650 EXPECT_ACK_TRACKER_STATE(true, false, 1u);
651
652 // After adding it back, the BeginFrame is again not finished or confirmed.
653 tracker_->OnObserverAdded(obs1_.get());
654 EXPECT_ACK_TRACKER_STATE(false, false, 0u); // up to date to previous frame.
655
656 // When the observer finishes and confirms, the BeginFrame is finished
657 // and confirmed.
658 obs1_->OnBeginFrame(current_args_);
659 tracker_->OnObserverBeginFrame(obs1_.get(), current_args_);
660 tracker_->OnObserverFinishedFrame(obs1_.get(),
661 BeginFrameAck(0, 1, 1, 0, false));
662 EXPECT_ACK_TRACKER_STATE(true, false, 1u);
663
664 // A new BeginFrame is initially not finished or confirmed.
665 current_args_ = CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 2);
666 tracker_->OnBeginFrame(current_args_);
667 EXPECT_ACK_TRACKER_STATE(false, false, 1u);
668
669 // Stray ACK for an old BeginFrame is ignored.
670 tracker_->OnObserverFinishedFrame(obs1_.get(),
671 BeginFrameAck(0, 1, 1, 0, false));
672 EXPECT_ACK_TRACKER_STATE(false, false, 1u);
673
674 // When the observer finishes but doesn't confirm, the BeginFrame is finished
675 // but not confirmed.
676 obs1_->OnBeginFrame(current_args_);
677 tracker_->OnObserverBeginFrame(obs1_.get(), current_args_);
678 tracker_->OnObserverFinishedFrame(obs1_.get(),
679 BeginFrameAck(0, 2, 1, 0, false));
680 EXPECT_ACK_TRACKER_STATE(true, false, 1u);
681
682 // Damage from ACK propagates.
683 current_args_ = CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 3);
684 tracker_->OnBeginFrame(current_args_);
685 EXPECT_ACK_TRACKER_STATE(false, false, 1u);
686 obs1_->OnBeginFrame(current_args_);
687 tracker_->OnObserverBeginFrame(obs1_.get(), current_args_);
688 tracker_->OnObserverFinishedFrame(obs1_.get(),
689 BeginFrameAck(0, 3, 3, 0, true));
690 EXPECT_ACK_TRACKER_STATE(true, true, 3u);
691
692 // Observer discarding frame during OnBeginFrame also finishes BeginFrame, but
693 // doesn't confirm it.
694 current_args_ = CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 4);
695 tracker_->OnBeginFrame(current_args_);
696 EXPECT_ACK_TRACKER_STATE(false, false, 3u);
697 obs1_->SetDiscardNextBeginFrame();
698 obs1_->OnBeginFrame(current_args_);
699 tracker_->OnObserverBeginFrame(obs1_.get(), current_args_);
700 EXPECT_ACK_TRACKER_STATE(true, false, 3u);
701
702 // Removing the observer confirms the latest BeginFrame.
703 tracker_->OnObserverRemoved(obs1_.get());
704 EXPECT_ACK_TRACKER_STATE(true, false, 4u);
705 }
706
707 TEST_F(BeginFrameObserverAckTrackerTest, CorrectnessWith2Observers) {
708 // Check initial state.
709 EXPECT_ACK_TRACKER_STATE(true, false, 1u);
710
711 // After adding observers, the BeginFrame is not finished or confirmed.
712 tracker_->OnObserverAdded(obs1_.get());
713 EXPECT_ACK_TRACKER_STATE(false, false, 0u); // up to date to previous frame.
714 tracker_->OnObserverAdded(obs2_.get());
715 EXPECT_ACK_TRACKER_STATE(false, false, 0u); // up to date to previous frame.
716
717 // Removing one of them changes nothing. Same for adding back.
718 tracker_->OnObserverRemoved(obs1_.get());
719 EXPECT_ACK_TRACKER_STATE(false, false, 0u);
720 tracker_->OnObserverAdded(obs1_.get());
721 EXPECT_ACK_TRACKER_STATE(false, false, 0u);
722
723 // When one observer finishes and confirms, nothing changes.
724 obs1_->OnBeginFrame(current_args_);
725 tracker_->OnObserverBeginFrame(obs1_.get(), current_args_);
726 tracker_->OnObserverFinishedFrame(obs1_.get(),
727 BeginFrameAck(0, 1, 1, 0, false));
728 EXPECT_ACK_TRACKER_STATE(false, false, 0u);
729 // When both finish and confirm, the BeginFrame is finished and confirmed.
730 obs2_->OnBeginFrame(current_args_);
731 tracker_->OnObserverBeginFrame(obs2_.get(), current_args_);
732 tracker_->OnObserverFinishedFrame(obs2_.get(),
733 BeginFrameAck(0, 1, 1, 0, false));
734 EXPECT_ACK_TRACKER_STATE(true, false, 1u);
735
736 // A new BeginFrame is not finished or confirmed.
737 current_args_ = CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 2);
738 tracker_->OnBeginFrame(current_args_);
739 EXPECT_ACK_TRACKER_STATE(false, false, 1u);
740
741 // When both observers finish but only one confirms, the BeginFrame is
742 // finished but not confirmed.
743 obs1_->OnBeginFrame(current_args_);
744 tracker_->OnObserverBeginFrame(obs1_.get(), current_args_);
745 tracker_->OnObserverFinishedFrame(obs1_.get(),
746 BeginFrameAck(0, 2, 2, 0, false));
747 EXPECT_ACK_TRACKER_STATE(false, false, 1u);
748 obs2_->OnBeginFrame(current_args_);
749 tracker_->OnObserverBeginFrame(obs2_.get(), current_args_);
750 tracker_->OnObserverFinishedFrame(obs2_.get(),
751 BeginFrameAck(0, 2, 1, 0, false));
752 EXPECT_ACK_TRACKER_STATE(true, false, 1u);
753
754 // With reversed confirmations in the next ACKs, the latest confirmed frame
755 // increases but the latest BeginFrame remains unconfirmed.
756 current_args_ = CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 3);
757 tracker_->OnBeginFrame(current_args_);
758 EXPECT_ACK_TRACKER_STATE(false, false, 1u);
759 obs1_->OnBeginFrame(current_args_);
760 tracker_->OnObserverBeginFrame(obs1_.get(), current_args_);
761 tracker_->OnObserverFinishedFrame(obs1_.get(),
762 BeginFrameAck(0, 3, 2, 0, false));
763 EXPECT_ACK_TRACKER_STATE(false, false, 1u);
764 obs2_->OnBeginFrame(current_args_);
765 tracker_->OnObserverBeginFrame(obs2_.get(), current_args_);
766 tracker_->OnObserverFinishedFrame(obs2_.get(),
767 BeginFrameAck(0, 3, 3, 0, false));
768 EXPECT_ACK_TRACKER_STATE(true, false, 2u);
769
770 // Only a single ACK with damage suffices.
771 current_args_ = CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 4);
772 tracker_->OnBeginFrame(current_args_);
773 EXPECT_ACK_TRACKER_STATE(false, false, 2u);
774 obs1_->OnBeginFrame(current_args_);
775 tracker_->OnObserverBeginFrame(obs1_.get(), current_args_);
776 tracker_->OnObserverFinishedFrame(obs1_.get(),
777 BeginFrameAck(0, 4, 4, 0, true));
778 EXPECT_ACK_TRACKER_STATE(false, true, 3u);
779 obs2_->OnBeginFrame(current_args_);
780 tracker_->OnObserverBeginFrame(obs2_.get(), current_args_);
781 tracker_->OnObserverFinishedFrame(obs2_.get(),
782 BeginFrameAck(0, 4, 4, 0, false));
783 EXPECT_ACK_TRACKER_STATE(true, true, 4u);
784
785 // Removing the damaging observer makes no difference in this case.
786 tracker_->OnObserverRemoved(obs1_.get());
787 EXPECT_ACK_TRACKER_STATE(true, true, 4u);
788
789 // Adding the observer back considers it up to date up to the current
790 // BeginFrame, because it is the last used one. Thus, the current BeginFrame
791 // is still finished, too.
792 tracker_->OnObserverAdded(obs1_.get());
793 EXPECT_ACK_TRACKER_STATE(true, true, 4u);
794
795 // Adding the observer back after the next BeginFrame considers it up to date
796 // up to last BeginFrame only.
797 tracker_->OnObserverRemoved(obs1_.get());
798 current_args_ = CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 5);
799 tracker_->OnBeginFrame(current_args_);
800 tracker_->OnObserverAdded(obs1_.get());
801 EXPECT_ACK_TRACKER_STATE(false, false, 4u);
802 // Both observers need to finish for the BeginFrame to be finished.
803 obs1_->OnBeginFrame(current_args_);
804 tracker_->OnObserverBeginFrame(obs1_.get(), current_args_);
805 tracker_->OnObserverFinishedFrame(obs1_.get(),
806 BeginFrameAck(0, 5, 5, 0, false));
807 EXPECT_ACK_TRACKER_STATE(false, false, 4u);
808 obs2_->OnBeginFrame(current_args_);
809 tracker_->OnObserverBeginFrame(obs2_.get(), current_args_);
810 tracker_->OnObserverFinishedFrame(obs2_.get(),
811 BeginFrameAck(0, 5, 5, 0, false));
812 EXPECT_ACK_TRACKER_STATE(true, false, 5u);
813 }
814
815 TEST_F(BeginFrameObserverAckTrackerTest, ChangingSourceIdOnBeginFrame) {
816 // Check initial state.
817 EXPECT_ACK_TRACKER_STATE(true, false, 1u);
818
819 // Changing source id without observer updates confirmed BeginFrame.
820 current_args_ = CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 1, 10);
821 tracker_->OnBeginFrame(current_args_);
822 EXPECT_ACK_TRACKER_STATE(true, false, 10u);
823
824 // Setup an observer for current BeginFrame.
825 tracker_->OnObserverAdded(obs1_.get());
826 EXPECT_ACK_TRACKER_STATE(false, false, 9u); // up to date to previous frame.
827 obs1_->OnBeginFrame(current_args_);
828 tracker_->OnObserverBeginFrame(obs1_.get(), current_args_);
829 tracker_->OnObserverFinishedFrame(obs1_.get(),
830 BeginFrameAck(1, 10, 10, 0, true));
831 EXPECT_ACK_TRACKER_STATE(true, true, 10u);
832
833 // Changing source id with an observer sets confirmed BeginFrame to invalid.
834 current_args_ = CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 2, 20);
835 tracker_->OnBeginFrame(current_args_);
836 EXPECT_ACK_TRACKER_STATE(false, false, BeginFrameArgs::kInvalidFrameNumber);
837 }
838
839 TEST_F(BeginFrameObserverAckTrackerTest, ChangingSourceIdOnObserverBeginFrame) {
840 // Check initial state.
841 EXPECT_ACK_TRACKER_STATE(true, false, 1u);
842
843 // Advance to a sequence number that isn't kInvalidFrameNumber+1.
844 current_args_ = CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 5);
845 tracker_->OnBeginFrame(current_args_);
846 EXPECT_ACK_TRACKER_STATE(true, false, 5u);
847
848 // Assume that source has changed. When an observer is added before the next
849 // OnBeginFrame() from the new source, the tracker may see a call to
850 // OnObserverBeginFrame() with a new source_id. In this case, the confirmed
851 // BeginFrame should be set to invalid.
852 tracker_->OnObserverAdded(obs1_.get());
853 EXPECT_ACK_TRACKER_STATE(false, false, 4u); // up to date to previous frame.
854 current_args_ = CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 1, 10);
855 obs1_->OnBeginFrame(current_args_);
856 tracker_->OnObserverBeginFrame(obs1_.get(), current_args_);
857 EXPECT_ACK_TRACKER_STATE(false, false, BeginFrameArgs::kInvalidFrameNumber);
858 }
859
860 // ExternalBeginFrameSource testing --------------------------------------------
861 class MockExternalBeginFrameSourceClient
862 : public ExternalBeginFrameSourceClient {
863 public:
864 MOCK_METHOD1(OnNeedsBeginFrames, void(bool));
865 MOCK_METHOD1(OnDidFinishFrame, void(const BeginFrameAck&));
866 };
867
868 class ExternalBeginFrameSourceTest : public ::testing::Test {
869 public:
870 std::unique_ptr<MockExternalBeginFrameSourceClient> client_;
871 std::unique_ptr<ExternalBeginFrameSource> source_;
872 std::unique_ptr<MockBeginFrameObserver> obs_;
brianderson 2017/02/17 21:26:09 Do these need to be unique_ptrs?
Eric Seckler 2017/02/21 12:10:57 At the very least, obs_ and client_ should stay on
873
874 void SetUp() override {
875 client_.reset(new MockExternalBeginFrameSourceClient);
876 source_.reset(new ExternalBeginFrameSource(client_.get()));
877 obs_.reset(new MockBeginFrameObserver);
878 }
879 };
880
881 TEST_F(ExternalBeginFrameSourceTest, CallsOnDidFinishFrameWithoutObservers) {
882 EXPECT_CALL((*client_), OnDidFinishFrame(BeginFrameAck(0, 2, 2, 0, false)))
883 .Times(1);
884 source_->OnBeginFrame(CreateBeginFrameArgsForTesting(
885 BEGINFRAME_FROM_HERE, 0, 2, base::TimeTicks::FromInternalValue(10000)));
886 }
887
888 TEST_F(ExternalBeginFrameSourceTest,
889 CallsOnDidFinishFrameWhenObserverFinishes) {
890 EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
891 EXPECT_CALL((*client_), OnNeedsBeginFrames(true)).Times(1);
892 source_->AddObserver(obs_.get());
893
894 BeginFrameArgs args = CreateBeginFrameArgsForTesting(
895 BEGINFRAME_FROM_HERE, 0, 2, base::TimeTicks::FromInternalValue(10000));
896 EXPECT_BEGIN_FRAME_ARGS_USED(*obs_, args);
897 source_->OnBeginFrame(args);
898
899 EXPECT_CALL((*client_), OnDidFinishFrame(BeginFrameAck(0, 2, 2, 0, true)))
900 .Times(1);
901 source_->DidFinishFrame(obs_.get(), BeginFrameAck(0, 2, 2, 0, true));
902
903 args = CreateBeginFrameArgsForTesting(
904 BEGINFRAME_FROM_HERE, 0, 3, base::TimeTicks::FromInternalValue(20000));
905 EXPECT_BEGIN_FRAME_ARGS_USED(*obs_, args);
906 source_->OnBeginFrame(args);
907
908 EXPECT_CALL((*client_), OnDidFinishFrame(BeginFrameAck(0, 3, 2, 0, false)))
909 .Times(1);
910 source_->DidFinishFrame(obs_.get(), BeginFrameAck(0, 3, 2, 0, false));
911 }
912
913 TEST_F(ExternalBeginFrameSourceTest,
914 CallsOnDidFinishFrameWhenObserverDropsBeginFrame) {
915 EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
916 EXPECT_CALL((*client_), OnNeedsBeginFrames(true)).Times(1);
917 source_->AddObserver(obs_.get());
918
919 BeginFrameArgs args = CreateBeginFrameArgsForTesting(
920 BEGINFRAME_FROM_HERE, 0, 2, base::TimeTicks::FromInternalValue(10000));
921 EXPECT_BEGIN_FRAME_ARGS_DROP(*obs_, args);
922 EXPECT_CALL((*client_), OnDidFinishFrame(BeginFrameAck(0, 2, 0, 0, false)))
923 .Times(1);
924 source_->OnBeginFrame(args);
925 }
926
927 TEST_F(ExternalBeginFrameSourceTest, CallsOnDidFinishFrameWhenObserverRemoved) {
928 EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
929 EXPECT_CALL((*client_), OnNeedsBeginFrames(true)).Times(1);
930 source_->AddObserver(obs_.get());
931
932 BeginFrameArgs args = CreateBeginFrameArgsForTesting(
933 BEGINFRAME_FROM_HERE, 0, 2, base::TimeTicks::FromInternalValue(10000));
934 EXPECT_BEGIN_FRAME_ARGS_USED(*obs_, args);
935 source_->OnBeginFrame(args);
936
937 EXPECT_CALL((*client_), OnDidFinishFrame(BeginFrameAck(0, 2, 2, 0, false)))
938 .Times(1);
939 EXPECT_CALL((*client_), OnNeedsBeginFrames(false)).Times(1);
940 source_->RemoveObserver(obs_.get());
941 }
942
585 } // namespace 943 } // namespace
586 } // namespace cc 944 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698