| Index: cc/scheduler/frame_source_unittest.cc
|
| diff --git a/cc/scheduler/frame_source_unittest.cc b/cc/scheduler/frame_source_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..be5484fa233feb49f4c3617b020685589d3bce6e
|
| --- /dev/null
|
| +++ b/cc/scheduler/frame_source_unittest.cc
|
| @@ -0,0 +1,618 @@
|
| +// Copyright 2011 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include <deque>
|
| +
|
| +#include "base/basictypes.h"
|
| +#include "base/gtest_prod_util.h"
|
| +#include "base/test/test_simple_task_runner.h"
|
| +#include "cc/scheduler/frame_source.h"
|
| +#include "cc/test/begin_frame_args_test.h"
|
| +#include "cc/test/scheduler_test_common.h"
|
| +#include "testing/gmock/include/gmock/gmock.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +#define EXPECT_BEGIN_FRAME(obs, ...) \
|
| + { \
|
| + ::testing::Expectation exp = \
|
| + EXPECT_CALL(obs, \
|
| + OnBeginFrame(CreateBeginFrameArgsForTesting(__VA_ARGS__))) \
|
| + .InSequence(obs.sequence); \
|
| + BeginFrameArgs args = CreateBeginFrameArgsForTesting(__VA_ARGS__); \
|
| + EXPECT_CALL(obs, LastBeginFrameArgs()) \
|
| + .Times(::testing::AnyNumber()) \
|
| + .After(exp) \
|
| + .WillRepeatedly(::testing::ReturnRefOfCopy(args)); \
|
| + }
|
| +
|
| +#define EXPECT_BEGIN_FRAME_P(obs_ptr, ...) \
|
| + EXPECT_BEGIN_FRAME((*obs_ptr), __VA_ARGS__);
|
| +
|
| +#define SEND_BEGIN_FRAME(source, ...) \
|
| + source.TestSendBeginFrame(CreateBeginFrameArgsForTesting(__VA_ARGS__));
|
| +
|
| +#define SEND_BEGIN_FRAME_P(source, ...) \
|
| + SEND_BEGIN_FRAME((*source), __VA_ARGS__);
|
| +
|
| +namespace cc {
|
| +namespace {
|
| +
|
| +class MockBeginFrameObserver : public BeginFrameObserver {
|
| + public:
|
| + MOCK_METHOD1(OnBeginFrame, void(const BeginFrameArgs&));
|
| + MOCK_CONST_METHOD0(LastBeginFrameArgs, const BeginFrameArgs&());
|
| + // MOCK_CONST_METHOD0(AsValueInto, void(base::debug::TracedValue*));
|
| +
|
| + virtual void AsValueInto(base::debug::TracedValue* dict) const {
|
| + dict->SetString("type", "MockBeginFrameObserver");
|
| + dict->BeginDictionary("last_begin_frame_args");
|
| + LastBeginFrameArgs().AsValueInto(dict);
|
| + dict->EndDictionary();
|
| + }
|
| +
|
| + static const BeginFrameArgs kDefaultBeginFrameArgs;
|
| + MockBeginFrameObserver() {
|
| + // Set a "default" value returned by LastBeginFrameArgs so that gMock
|
| + // doesn't fail an assert and instead returns useful information.
|
| + EXPECT_CALL(*this, LastBeginFrameArgs())
|
| + .Times(::testing::AnyNumber())
|
| + .InSequence(sequence)
|
| + .WillRepeatedly(::testing::ReturnRef(kDefaultBeginFrameArgs));
|
| + }
|
| + virtual ~MockBeginFrameObserver() {}
|
| +
|
| + ::testing::Sequence sequence;
|
| +};
|
| +
|
| +TEST(MockBeginFrameObserverTest, Basic) {
|
| + ::testing::NiceMock<MockBeginFrameObserver> obs;
|
| + EXPECT_BEGIN_FRAME(obs, 100, 200, 300);
|
| + EXPECT_BEGIN_FRAME(obs, 400, 600, 300);
|
| + EXPECT_BEGIN_FRAME(obs, 700, 900, 300);
|
| +
|
| + EXPECT_EQ(obs.LastBeginFrameArgs(),
|
| + MockBeginFrameObserver::kDefaultBeginFrameArgs);
|
| +
|
| + obs.OnBeginFrame(CreateBeginFrameArgsForTesting(
|
| + 100, 200, 300)); // One call to LastBeginFrameArgs
|
| + EXPECT_EQ(obs.LastBeginFrameArgs(),
|
| + CreateBeginFrameArgsForTesting(100, 200, 300));
|
| +
|
| + obs.OnBeginFrame(CreateBeginFrameArgsForTesting(
|
| + 400, 600, 300)); // Multiple calls to LastBeginFrameArgs
|
| + EXPECT_EQ(obs.LastBeginFrameArgs(),
|
| + CreateBeginFrameArgsForTesting(400, 600, 300));
|
| + EXPECT_EQ(obs.LastBeginFrameArgs(),
|
| + CreateBeginFrameArgsForTesting(400, 600, 300));
|
| +
|
| + obs.OnBeginFrame(CreateBeginFrameArgsForTesting(
|
| + 700, 900, 300)); // No calls to LastBeginFrameArgs
|
| +
|
| + ::testing::Mock::VerifyAndClearExpectations(&obs);
|
| +}
|
| +
|
| +const BeginFrameArgs MockBeginFrameObserver::kDefaultBeginFrameArgs =
|
| + CreateBeginFrameArgsForTesting(-1, -1, -1);
|
| +
|
| +// BeginFrameSource testing ----------------------------------------------
|
| +TEST(BeginFrameSourceTest, Observer) {
|
| + MockBeginFrameObserver obs;
|
| + MockBeginFrameObserver otherObs;
|
| + FakeBeginFrameSource source;
|
| +
|
| + source.AddObserver(&obs);
|
| + EXPECT_EQ(&obs, source.GetObserver());
|
| +
|
| +#ifndef NDEBUG
|
| + // Adding an observer when an observer already exists should DCHECK fail.
|
| + EXPECT_DEATH({ source.AddObserver(&otherObs); }, "");
|
| +
|
| + // Removing wrong observer should DCHECK fail.
|
| + EXPECT_DEATH({ source.RemoveObserver(&otherObs); }, "");
|
| +
|
| + // Removing an observer when there is no observer should DCHECK fail.
|
| + EXPECT_DEATH({
|
| + source.RemoveObserver(&obs);
|
| + source.RemoveObserver(&obs);
|
| + },
|
| + "");
|
| +#endif
|
| + source.RemoveObserver(&obs);
|
| +
|
| + source.AddObserver(&otherObs);
|
| + EXPECT_EQ(&otherObs, source.GetObserver());
|
| + source.RemoveObserver(&otherObs);
|
| +}
|
| +
|
| +class LoopingBeginFrameObserver : public BeginFrameObserver {
|
| + public:
|
| + BeginFrameArgs args_;
|
| + BeginFrameSource* source_;
|
| +
|
| + virtual const BeginFrameArgs& LastBeginFrameArgs() const OVERRIDE {
|
| + return args_;
|
| + };
|
| + virtual void OnBeginFrame(const BeginFrameArgs& args) OVERRIDE{};
|
| +
|
| + virtual void AsValueInto(base::debug::TracedValue* dict) const OVERRIDE {
|
| + dict->SetString("type", "LoopingBeginFrameObserver");
|
| + dict->BeginDictionary("source");
|
| + source_->AsValueInto(dict);
|
| + dict->EndDictionary();
|
| + }
|
| +};
|
| +
|
| +TEST(BeginFrameSourceTest, DetectAsValueIntoLoop) {
|
| + LoopingBeginFrameObserver obs;
|
| + FakeBeginFrameSource source;
|
| +
|
| + obs.source_ = &source;
|
| + source.AddObserver(&obs);
|
| +
|
| + scoped_refptr<base::debug::TracedValue> state =
|
| + new base::debug::TracedValue();
|
| + source.AsValueInto(state.get());
|
| +}
|
| +
|
| +// BackToBackBeginFrameSource testing -----------------------------------------
|
| +class TestBackToBackBeginFrameSource : public BackToBackBeginFrameSource {
|
| + public:
|
| + static scoped_ptr<TestBackToBackBeginFrameSource> Create(
|
| + scoped_refptr<TestNowSource> now_src,
|
| + base::SingleThreadTaskRunner* task_runner) {
|
| + return make_scoped_ptr(
|
| + new TestBackToBackBeginFrameSource(now_src, task_runner));
|
| + }
|
| +
|
| + protected:
|
| + TestBackToBackBeginFrameSource(scoped_refptr<TestNowSource> now_src,
|
| + base::SingleThreadTaskRunner* task_runner)
|
| + : BackToBackBeginFrameSource(task_runner), now_src_(now_src) {}
|
| +
|
| + virtual base::TimeTicks Now() OVERRIDE { return now_src_->Now(); }
|
| +
|
| + scoped_refptr<TestNowSource> now_src_;
|
| +};
|
| +
|
| +class BackToBackBeginFrameSourceTest : public ::testing::Test {
|
| + public:
|
| + static int64_t kDeadline;
|
| + static int64_t kInterval;
|
| +
|
| + scoped_refptr<TestNowSource> now_src_;
|
| + scoped_refptr<OrderedSimpleTaskRunner> task_runner_;
|
| + scoped_ptr<TestBackToBackBeginFrameSource> source_;
|
| + scoped_ptr<MockBeginFrameObserver> obs_;
|
| +
|
| + virtual void SetUp() OVERRIDE {
|
| + now_src_ = TestNowSource::Create(1000);
|
| + task_runner_ =
|
| + make_scoped_refptr(new OrderedSimpleTaskRunner(now_src_, false));
|
| + task_runner_->SetRunTaskLimit(1);
|
| + source_ =
|
| + TestBackToBackBeginFrameSource::Create(now_src_, task_runner_.get());
|
| + obs_ = make_scoped_ptr(new ::testing::StrictMock<MockBeginFrameObserver>());
|
| + source_->AddObserver(obs_.get());
|
| + }
|
| +
|
| + virtual void TearDown() OVERRIDE { obs_.reset(); }
|
| +};
|
| +
|
| +int64_t BackToBackBeginFrameSourceTest::kDeadline =
|
| + BeginFrameArgs::DefaultInterval().ToInternalValue();
|
| +
|
| +int64_t BackToBackBeginFrameSourceTest::kInterval =
|
| + BeginFrameArgs::DefaultInterval().ToInternalValue();
|
| +
|
| +TEST_F(BackToBackBeginFrameSourceTest, SetNeedsBeginFramesSendsBeginFrame) {
|
| + EXPECT_BEGIN_FRAME_P(obs_, 1000, 1000 + kDeadline, kInterval);
|
| + source_->SetNeedsBeginFrames(true);
|
| + EXPECT_TRUE(task_runner_->HasPendingTasks());
|
| + task_runner_->RunUntilIdle();
|
| +
|
| + EXPECT_BEGIN_FRAME_P(obs_, 1100, 1100 + kDeadline, kInterval);
|
| + now_src_->AdvanceNowMicroseconds(100);
|
| + source_->DidFinishFrame(0);
|
| + task_runner_->RunUntilIdle();
|
| +}
|
| +
|
| +TEST_F(BackToBackBeginFrameSourceTest,
|
| + DidFinishFrameThenSetNeedsBeginFramesProducesNoFrame) {
|
| + EXPECT_BEGIN_FRAME_P(obs_, 1000, 1000 + kDeadline, kInterval);
|
| + source_->SetNeedsBeginFrames(true);
|
| + task_runner_->RunUntilIdle();
|
| +
|
| + source_->SetNeedsBeginFrames(false);
|
| + source_->DidFinishFrame(0);
|
| +
|
| + EXPECT_FALSE(task_runner_->HasPendingTasks());
|
| +}
|
| +
|
| +TEST_F(BackToBackBeginFrameSourceTest,
|
| + SetNeedsBeginFramesThenDidFinishFrameProducesNoFrame) {
|
| + EXPECT_BEGIN_FRAME_P(obs_, 1000, 1000 + kDeadline, kInterval);
|
| + source_->SetNeedsBeginFrames(true);
|
| + task_runner_->RunUntilIdle();
|
| +
|
| + now_src_->AdvanceNowMicroseconds(100);
|
| + source_->DidFinishFrame(0);
|
| + source_->SetNeedsBeginFrames(false);
|
| +
|
| + EXPECT_TRUE(task_runner_->HasPendingTasks());
|
| + task_runner_->RunUntilIdle();
|
| +}
|
| +
|
| +TEST_F(BackToBackBeginFrameSourceTest,
|
| + DidFinishFrameThenTogglingSetNeedsBeginFramesProducesCorrectFrame) {
|
| + EXPECT_BEGIN_FRAME_P(obs_, 1000, 1000 + kDeadline, kInterval);
|
| + source_->SetNeedsBeginFrames(true);
|
| + task_runner_->RunUntilIdle();
|
| +
|
| + now_src_->AdvanceNowMicroseconds(100);
|
| +
|
| + source_->SetNeedsBeginFrames(false);
|
| + now_src_->AdvanceNowMicroseconds(10);
|
| + source_->DidFinishFrame(0);
|
| + now_src_->AdvanceNowMicroseconds(10);
|
| + source_->SetNeedsBeginFrames(false);
|
| + now_src_->AdvanceNowMicroseconds(10);
|
| + source_->SetNeedsBeginFrames(true);
|
| +
|
| + EXPECT_BEGIN_FRAME_P(obs_, 1130, 1130 + kDeadline, kInterval);
|
| + EXPECT_TRUE(task_runner_->HasPendingTasks());
|
| + task_runner_->RunUntilIdle();
|
| +}
|
| +
|
| +TEST_F(BackToBackBeginFrameSourceTest,
|
| + TogglingSetNeedsBeginFramesThenDidFinishFrameProducesCorrectFrame) {
|
| + EXPECT_BEGIN_FRAME_P(obs_, 1000, 1000 + kDeadline, kInterval);
|
| + source_->SetNeedsBeginFrames(true);
|
| + task_runner_->RunUntilIdle();
|
| +
|
| + now_src_->AdvanceNowMicroseconds(100);
|
| + source_->DidFinishFrame(0);
|
| + now_src_->AdvanceNowMicroseconds(10);
|
| + source_->SetNeedsBeginFrames(false);
|
| + now_src_->AdvanceNowMicroseconds(10);
|
| + source_->SetNeedsBeginFrames(true);
|
| + now_src_->AdvanceNowMicroseconds(10);
|
| +
|
| + EXPECT_BEGIN_FRAME_P(obs_, 1130, 1130 + kDeadline, kInterval);
|
| + EXPECT_TRUE(task_runner_->HasPendingTasks());
|
| + task_runner_->RunUntilIdle();
|
| +}
|
| +
|
| +TEST_F(BackToBackBeginFrameSourceTest, DidFinishFrameNeedsBeginFrameFalse) {
|
| + source_->SetNeedsBeginFrames(false);
|
| + source_->DidFinishFrame(0);
|
| + EXPECT_FALSE(task_runner_->RunPendingTasks());
|
| +}
|
| +
|
| +TEST_F(BackToBackBeginFrameSourceTest, DidFinishFrameRemainingFrames) {
|
| + EXPECT_BEGIN_FRAME_P(obs_, 1000, 1000 + kDeadline, kInterval);
|
| + source_->SetNeedsBeginFrames(true);
|
| + task_runner_->RunUntilIdle();
|
| +
|
| + now_src_->AdvanceNowMicroseconds(100);
|
| +
|
| + source_->DidFinishFrame(3);
|
| + EXPECT_FALSE(task_runner_->HasPendingTasks());
|
| + source_->DidFinishFrame(2);
|
| + EXPECT_FALSE(task_runner_->HasPendingTasks());
|
| + source_->DidFinishFrame(1);
|
| + EXPECT_FALSE(task_runner_->HasPendingTasks());
|
| +
|
| + EXPECT_BEGIN_FRAME_P(obs_, 1100, 1100 + kDeadline, kInterval);
|
| + source_->DidFinishFrame(0);
|
| + EXPECT_EQ(base::TimeDelta(), task_runner_->DelayToNextTaskTime());
|
| + task_runner_->RunUntilIdle();
|
| +}
|
| +
|
| +TEST_F(BackToBackBeginFrameSourceTest, DidFinishFrameMultipleCallsIdempotent) {
|
| + source_->SetNeedsBeginFrames(true);
|
| + EXPECT_BEGIN_FRAME_P(obs_, 1000, 1000 + kDeadline, kInterval);
|
| + task_runner_->RunUntilIdle();
|
| +
|
| + now_src_->AdvanceNowMicroseconds(100);
|
| + source_->DidFinishFrame(0);
|
| + source_->DidFinishFrame(0);
|
| + source_->DidFinishFrame(0);
|
| + EXPECT_BEGIN_FRAME_P(obs_, 1100, 1100 + kDeadline, kInterval);
|
| + task_runner_->RunUntilIdle();
|
| +
|
| + now_src_->AdvanceNowMicroseconds(100);
|
| + source_->DidFinishFrame(0);
|
| + source_->DidFinishFrame(0);
|
| + source_->DidFinishFrame(0);
|
| + EXPECT_BEGIN_FRAME_P(obs_, 1200, 1200 + kDeadline, kInterval);
|
| + task_runner_->RunUntilIdle();
|
| +}
|
| +
|
| +TEST_F(BackToBackBeginFrameSourceTest, DelayInPostedTaskProducesCorrectFrame) {
|
| + EXPECT_BEGIN_FRAME_P(obs_, 1000, 1000 + kDeadline, kInterval);
|
| + source_->SetNeedsBeginFrames(true);
|
| + task_runner_->RunUntilIdle();
|
| +
|
| + now_src_->AdvanceNowMicroseconds(100);
|
| + source_->DidFinishFrame(0);
|
| + now_src_->AdvanceNowMicroseconds(50);
|
| + EXPECT_BEGIN_FRAME_P(obs_, 1150, 1150 + kDeadline, kInterval);
|
| +
|
| + EXPECT_TRUE(task_runner_->HasPendingTasks());
|
| + task_runner_->RunUntilIdle();
|
| +}
|
| +
|
| +// SyntheticBeginFrameSource testing ------------------------------------------
|
| +class SyntheticBeginFrameSourceTest : public ::testing::Test {
|
| + public:
|
| + scoped_refptr<TestNowSource> now_src_;
|
| + scoped_refptr<OrderedSimpleTaskRunner> task_runner_;
|
| + scoped_ptr<TestSyntheticBeginFrameSource> source_;
|
| + scoped_ptr<MockBeginFrameObserver> obs_;
|
| +
|
| + virtual void SetUp() OVERRIDE {
|
| + now_src_ = TestNowSource::Create(1000);
|
| + task_runner_ =
|
| + make_scoped_refptr(new OrderedSimpleTaskRunner(now_src_, false));
|
| + source_ = TestSyntheticBeginFrameSource::Create(
|
| + now_src_, task_runner_.get(), base::TimeDelta::FromMicroseconds(10000));
|
| + obs_ = make_scoped_ptr(new MockBeginFrameObserver());
|
| + source_->AddObserver(obs_.get());
|
| + }
|
| +
|
| + virtual void TearDown() OVERRIDE { obs_.reset(); }
|
| +};
|
| +
|
| +TEST_F(SyntheticBeginFrameSourceTest,
|
| + SetNeedsBeginFramesCallsOnBeginFrameWithMissedTick) {
|
| + now_src_->SetNowMicroseconds(10010);
|
| + EXPECT_BEGIN_FRAME_P(obs_, 10000, 20000, 10000);
|
| + source_->SetNeedsBeginFrames(true); // Should cause the last tick to be sent
|
| + // No tasks should need to be run for this to occur.
|
| +}
|
| +
|
| +TEST_F(SyntheticBeginFrameSourceTest,
|
| + SetNeedsBeginFramesCallsCausesOnBeginFrame) {
|
| + source_->SetNeedsBeginFrames(true);
|
| + EXPECT_EQ(10000, task_runner_->NextTaskTime().ToInternalValue());
|
| +
|
| + EXPECT_BEGIN_FRAME_P(obs_, 10000, 20000, 10000);
|
| + now_src_->SetNowMicroseconds(10010);
|
| + task_runner_->RunPendingTasks();
|
| +}
|
| +
|
| +TEST_F(SyntheticBeginFrameSourceTest, BasicOperation) {
|
| + task_runner_->SetAutoAdvanceNowToPendingTasks(true);
|
| +
|
| + source_->SetNeedsBeginFrames(true);
|
| + EXPECT_BEGIN_FRAME_P(obs_, 10000, 20000, 10000);
|
| + EXPECT_BEGIN_FRAME_P(obs_, 20000, 30000, 10000);
|
| + EXPECT_BEGIN_FRAME_P(obs_, 30000, 40000, 10000);
|
| + task_runner_->RunUntilTime(base::TimeTicks::FromInternalValue(30001));
|
| +
|
| + source_->SetNeedsBeginFrames(false);
|
| + // No new frames....
|
| + task_runner_->RunUntilTime(base::TimeTicks::FromInternalValue(60000));
|
| +}
|
| +
|
| +TEST_F(SyntheticBeginFrameSourceTest, VSyncChanges) {
|
| + task_runner_->SetAutoAdvanceNowToPendingTasks(true);
|
| + source_->SetNeedsBeginFrames(true);
|
| +
|
| + EXPECT_BEGIN_FRAME_P(obs_, 10000, 20000, 10000);
|
| + EXPECT_BEGIN_FRAME_P(obs_, 20000, 30000, 10000);
|
| + EXPECT_BEGIN_FRAME_P(obs_, 30000, 40000, 10000);
|
| + task_runner_->RunUntilTime(base::TimeTicks::FromInternalValue(30001));
|
| +
|
| + // Update the vsync information
|
| + source_->OnUpdateVSyncParameters(base::TimeTicks::FromInternalValue(27500),
|
| + base::TimeDelta::FromMicroseconds(10001));
|
| +
|
| + EXPECT_BEGIN_FRAME_P(obs_, 40000, 47502, 10001);
|
| + EXPECT_BEGIN_FRAME_P(obs_, 47502, 57503, 10001);
|
| + EXPECT_BEGIN_FRAME_P(obs_, 57503, 67504, 10001);
|
| + task_runner_->RunUntilTime(base::TimeTicks::FromInternalValue(60000));
|
| +}
|
| +
|
| +// BeginFrameSourceMultiplexer testing -----------------------------------
|
| +class BeginFrameSourceMultiplexerTest : public ::testing::Test {
|
| + protected:
|
| + virtual void SetUp() OVERRIDE {
|
| + mux_ = BeginFrameSourceMultiplexer::Create();
|
| +
|
| + source1_store_ = make_scoped_ptr(new FakeBeginFrameSource());
|
| + source2_store_ = make_scoped_ptr(new FakeBeginFrameSource());
|
| + source3_store_ = make_scoped_ptr(new FakeBeginFrameSource());
|
| +
|
| + source1_ = source1_store_.get();
|
| + source2_ = source2_store_.get();
|
| + source3_ = source3_store_.get();
|
| + }
|
| +
|
| + virtual void TearDown() OVERRIDE {
|
| + // Make sure the mux is torn down before the sources.
|
| + mux_.reset();
|
| + }
|
| +
|
| + scoped_ptr<BeginFrameSourceMultiplexer> mux_;
|
| + FakeBeginFrameSource* source1_;
|
| + FakeBeginFrameSource* source2_;
|
| + FakeBeginFrameSource* source3_;
|
| +
|
| + private:
|
| + scoped_ptr<FakeBeginFrameSource> source1_store_;
|
| + scoped_ptr<FakeBeginFrameSource> source2_store_;
|
| + scoped_ptr<FakeBeginFrameSource> source3_store_;
|
| +};
|
| +
|
| +TEST_F(BeginFrameSourceMultiplexerTest, SourcesManipulation) {
|
| + EXPECT_EQ(NULL, mux_->ActiveSource());
|
| +
|
| + mux_->AddSource(source1_);
|
| + EXPECT_EQ(source1_, mux_->ActiveSource());
|
| +
|
| + mux_->SetActiveSource(NULL);
|
| + EXPECT_EQ(NULL, mux_->ActiveSource());
|
| +
|
| + mux_->SetActiveSource(source1_);
|
| +
|
| +#ifndef NDEBUG
|
| + // Setting a source which isn't in the mux as active should DCHECK fail.
|
| + EXPECT_DEATH({ mux_->SetActiveSource(source2_); }, "");
|
| +
|
| + // Adding a source which is already added should DCHECK fail.
|
| + EXPECT_DEATH({ mux_->AddSource(source1_); }, "");
|
| +
|
| + // Removing a source which isn't in the mux should DCHECK fail.
|
| + EXPECT_DEATH({ mux_->RemoveSource(source2_); }, "");
|
| +
|
| + // Removing the active source fails
|
| + EXPECT_DEATH({ mux_->RemoveSource(source1_); }, "");
|
| +#endif
|
| +
|
| + // Test manipulation doesn't segfault.
|
| + mux_->AddSource(source2_);
|
| + mux_->RemoveSource(source2_);
|
| +
|
| + mux_->AddSource(source2_);
|
| + mux_->SetActiveSource(source2_);
|
| + EXPECT_EQ(source2_, mux_->ActiveSource());
|
| +
|
| + mux_->RemoveSource(source1_);
|
| +}
|
| +
|
| +TEST_F(BeginFrameSourceMultiplexerTest, NeedsBeginFrames) {
|
| + mux_->AddSource(source1_);
|
| + mux_->AddSource(source2_);
|
| + mux_->SetActiveSource(source1_);
|
| + EXPECT_EQ(source1_->needs_begin_frames_, false);
|
| + EXPECT_EQ(source2_->needs_begin_frames_, false);
|
| +
|
| + // Check SetNeedsFrames works
|
| + mux_->SetNeedsBeginFrames(true);
|
| + EXPECT_EQ(source1_->needs_begin_frames_, true);
|
| + EXPECT_EQ(source2_->needs_begin_frames_, false);
|
| +
|
| + mux_->SetNeedsBeginFrames(false);
|
| + EXPECT_EQ(source1_->needs_begin_frames_, false);
|
| + EXPECT_EQ(source2_->needs_begin_frames_, false);
|
| +
|
| + // Checking that switching the source makes SetNeedsFrames on the
|
| + // subsources correctly.
|
| + mux_->SetNeedsBeginFrames(true);
|
| +
|
| + mux_->SetActiveSource(source1_);
|
| + EXPECT_EQ(source1_->needs_begin_frames_, true);
|
| + EXPECT_EQ(source2_->needs_begin_frames_, false);
|
| +
|
| + mux_->SetActiveSource(source2_);
|
| + EXPECT_EQ(source1_->needs_begin_frames_, false);
|
| + EXPECT_EQ(source2_->needs_begin_frames_, true);
|
| +}
|
| +
|
| +TEST_F(BeginFrameSourceMultiplexerTest, BeginFramesSimple) {
|
| + mux_->AddSource(source1_);
|
| + mux_->AddSource(source2_);
|
| + mux_->SetActiveSource(source1_);
|
| +
|
| + MockBeginFrameObserver obs;
|
| + mux_->AddObserver(&obs);
|
| + EXPECT_BEGIN_FRAME(obs, 100, 200, 300);
|
| + EXPECT_BEGIN_FRAME(obs, 400, 600, 300);
|
| +
|
| + mux_->SetActiveSource(source1_);
|
| +
|
| + SEND_BEGIN_FRAME_P(source1_, 100, 200, 300);
|
| + SEND_BEGIN_FRAME_P(source2_, 200, 500, 300); // Not received
|
| +
|
| + mux_->SetActiveSource(source2_);
|
| + SEND_BEGIN_FRAME_P(source2_, 400, 600, 300);
|
| + SEND_BEGIN_FRAME_P(source1_, 500, 700, 300); // Not received
|
| +}
|
| +
|
| +TEST_F(BeginFrameSourceMultiplexerTest, BeginFramesBackwardsProtection) {
|
| + mux_->AddSource(source1_);
|
| + mux_->AddSource(source2_);
|
| +
|
| + MockBeginFrameObserver obs;
|
| + mux_->AddObserver(&obs);
|
| + EXPECT_BEGIN_FRAME(obs, 400, 600, 300);
|
| + EXPECT_BEGIN_FRAME(obs, 700, 900, 300);
|
| + EXPECT_BEGIN_FRAME(obs, 1000, 1200, 300);
|
| + EXPECT_BEGIN_FRAME(obs, 1001, 1201, 301);
|
| +
|
| + mux_->SetActiveSource(source1_);
|
| + SEND_BEGIN_FRAME_P(source1_, 400, 600, 300);
|
| + SEND_BEGIN_FRAME_P(source1_, 700, 900, 300);
|
| +
|
| + mux_->SetActiveSource(source2_);
|
| + SEND_BEGIN_FRAME_P(source2_, 699, 899, 300); // Skipped
|
| + SEND_BEGIN_FRAME_P(source2_, 1000, 1200, 300);
|
| +
|
| + mux_->SetActiveSource(source1_);
|
| + SEND_BEGIN_FRAME_P(source1_, 1001, 1201, 301);
|
| +}
|
| +
|
| +TEST_F(BeginFrameSourceMultiplexerTest, MinimumIntervalNegativeFails) {
|
| +#ifndef NDEBUG
|
| + EXPECT_DEATH(
|
| + { mux_->SetMinimumInterval(base::TimeDelta::FromInternalValue(-100)); },
|
| + "");
|
| +#endif
|
| +}
|
| +
|
| +TEST_F(BeginFrameSourceMultiplexerTest, MinimumIntervalZero) {
|
| + mux_->SetMinimumInterval(base::TimeDelta());
|
| + mux_->AddSource(source1_);
|
| +
|
| + MockBeginFrameObserver obs;
|
| + mux_->AddObserver(&obs);
|
| + EXPECT_BEGIN_FRAME(obs, 100, 200, 300);
|
| + EXPECT_BEGIN_FRAME(obs, 400, 600, 300);
|
| + EXPECT_BEGIN_FRAME(obs, 700, 900, 300);
|
| +
|
| + SEND_BEGIN_FRAME_P(source1_, 100, 200, 300);
|
| + SEND_BEGIN_FRAME_P(source1_, 400, 600, 300);
|
| + SEND_BEGIN_FRAME_P(source1_, 700, 900, 300);
|
| +}
|
| +
|
| +TEST_F(BeginFrameSourceMultiplexerTest, MinimumIntervalBasic) {
|
| + mux_->SetMinimumInterval(base::TimeDelta::FromInternalValue(600));
|
| + mux_->AddSource(source1_);
|
| +
|
| + MockBeginFrameObserver obs;
|
| + mux_->AddObserver(&obs);
|
| + EXPECT_BEGIN_FRAME(obs, 100, 200, 300);
|
| + EXPECT_BEGIN_FRAME(obs, 700, 900, 300);
|
| +
|
| + SEND_BEGIN_FRAME_P(source1_, 100, 200, 300);
|
| + SEND_BEGIN_FRAME_P(source1_, 400, 600, 300); // Skipped
|
| + SEND_BEGIN_FRAME_P(source1_, 700, 900, 300);
|
| +}
|
| +
|
| +TEST_F(BeginFrameSourceMultiplexerTest, MinimumIntervalWithMultipleSources) {
|
| + mux_->SetMinimumInterval(base::TimeDelta::FromMicroseconds(150));
|
| + mux_->AddSource(source1_);
|
| + mux_->AddSource(source2_);
|
| +
|
| + MockBeginFrameObserver obs;
|
| + mux_->AddObserver(&obs);
|
| + EXPECT_BEGIN_FRAME(obs, 400, 600, 300);
|
| + EXPECT_BEGIN_FRAME(obs, 700, 900, 300);
|
| + EXPECT_BEGIN_FRAME(obs, 1050, 1250, 300);
|
| +
|
| + mux_->SetActiveSource(source1_);
|
| + SEND_BEGIN_FRAME_P(source1_, 400, 600, 300);
|
| + SEND_BEGIN_FRAME_P(source1_, 700, 900, 300);
|
| +
|
| + mux_->SetActiveSource(source2_);
|
| + SEND_BEGIN_FRAME_P(source2_, 750, 1050, 300); // Skipped
|
| + SEND_BEGIN_FRAME_P(source2_, 1050, 1250, 300);
|
| +
|
| + mux_->SetActiveSource(source1_);
|
| + SEND_BEGIN_FRAME_P(source2_, 1100, 1400, 300); // Skipped
|
| +}
|
| +
|
| +} // namespace
|
| +} // namespace cc
|
|
|