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

Unified Diff: cc/blimp/layer_tree_host_remote_unittest.cc

Issue 2362073002: cc/blimp: Add a LayerTreeHostRemote implementation. (Closed)
Patch Set: source frame number Created 4 years, 3 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 side-by-side diff with in-line comments
Download patch
Index: cc/blimp/layer_tree_host_remote_unittest.cc
diff --git a/cc/blimp/layer_tree_host_remote_unittest.cc b/cc/blimp/layer_tree_host_remote_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..35681384bc78771f6ff78033ea9cb532a682ff57
--- /dev/null
+++ b/cc/blimp/layer_tree_host_remote_unittest.cc
@@ -0,0 +1,334 @@
+// Copyright 2016 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 "cc/blimp/layer_tree_host_remote.h"
+
+#include "base/bind.h"
+#include "base/run_loop.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "cc/animation/animation_host.h"
+#include "cc/blimp/compositor_proto_state_sink.h"
+#include "cc/layers/layer.h"
+#include "cc/output/begin_frame_args.h"
+#include "cc/test/fake_compositor_proto_state_sink.h"
+#include "cc/test/stub_layer_tree_host_client.h"
+#include "cc/trees/layer_tree_settings.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using ::testing::_;
+using testing::InSequence;
+using testing::Mock;
+using testing::StrictMock;
+
+#define EXPECT_BEGIN_MAIN_FRAME(client, num) \
+ EXPECT_CALL(client, WillBeginMainFrame()).Times(num); \
+ EXPECT_CALL(client, BeginMainFrame(_)).Times(num); \
+ EXPECT_CALL(client, DidUpdateLayerTreeHost()).Times(num); \
+ EXPECT_CALL(client, WillCommit()).Times(num); \
+ EXPECT_CALL(client, DidCommit()).Times(num); \
+ EXPECT_CALL(client, DidBeginMainFrame()).Times(num);
+
+#define EXPECT_BEGIN_MAIN_FRAME_AND_COMMIT(client, num) \
+ EXPECT_BEGIN_MAIN_FRAME(client, num) \
+ EXPECT_CALL(client, DidCommitAndDrawFrame()).Times(num); \
+ EXPECT_CALL(client, DidCompleteSwapBuffers()).Times(num);
+
+namespace cc {
+namespace {
+
+class UpdateTrackingCompositorProtoStateSink
+ : public FakeCompositorProtoStateSink {
+ public:
+ UpdateTrackingCompositorProtoStateSink() : num_updates_received_(0) {}
danakj 2016/09/26 21:36:54 = default
Khushal 2016/09/27 01:07:50 Done.
+ ~UpdateTrackingCompositorProtoStateSink() override {}
+
+ void ProcessCompositorStateUpdate(
+ std::unique_ptr<CompositorProtoState> compositor_proto_state) override {
+ num_updates_received_++;
+ };
+
+ int num_updates_received() const { return num_updates_received_; }
+
+ private:
+ int num_updates_received_;
danakj 2016/09/26 21:36:53 = 0
Khushal 2016/09/27 01:07:50 So this always confuses me, what is the preferred
+};
+
+class MockLayerTreeHostClient : public StubLayerTreeHostClient {
+ public:
+ MockLayerTreeHostClient() {}
danakj 2016/09/26 21:36:53 =default
Khushal 2016/09/27 23:46:56 Done.
+ ~MockLayerTreeHostClient() override {}
danakj 2016/09/26 21:36:53 = default?
Khushal 2016/09/27 23:46:56 Done.
+
+ // LayerTreeHostClient implementation.
+ MOCK_METHOD0(WillBeginMainFrame, void());
+ MOCK_METHOD1(BeginMainFrame, void(const BeginFrameArgs& args));
+ MOCK_METHOD0(DidBeginMainFrame, void());
+
+ void set_update_host_callback(base::Closure callback) {
danakj 2016/09/26 21:36:54 Move this so it's not in the middle of the client
Khushal 2016/09/27 23:46:56 Done.
+ update_host_callback_ = callback;
+ }
+
+ void UpdateLayerTreeHost() override {
+ update_host_callback_.Run();
+ DidUpdateLayerTreeHost();
+ }
+
+ MOCK_METHOD0(DidUpdateLayerTreeHost, void());
danakj 2016/09/26 21:36:53 Group together
Khushal 2016/09/27 01:07:50 Done.
+ MOCK_METHOD0(WillCommit, void());
+ MOCK_METHOD0(DidCommit, void());
+ MOCK_METHOD0(DidCommitAndDrawFrame, void());
+ MOCK_METHOD0(DidCompleteSwapBuffers, void());
+
+ private:
+ base::Closure update_host_callback_;
+};
+
+class MockLayer : public Layer {
+ public:
+ static scoped_refptr<MockLayer> Create(bool update) {
danakj 2016/09/26 21:36:54 Just make the constructor public pls, delete this
Khushal 2016/09/27 01:07:50 Done.
+ return make_scoped_refptr(new MockLayer(update));
+ }
+
+ bool Update() override {
+ did_update_ = true;
+ return update_;
+ }
+
+ bool did_update() const { return did_update_; }
+
+ private:
+ explicit MockLayer(bool update) : update_(update), did_update_(false) {}
danakj 2016/09/26 21:36:53 drop did_update from here
Khushal 2016/09/27 01:07:50 Done.
+ ~MockLayer() override {}
+
+ bool update_;
+ bool did_update_;
danakj 2016/09/26 21:36:53 = false
Khushal 2016/09/27 01:07:50 Done.
+};
+
+class MockLayerTree : public LayerTree {
+ public:
+ MockLayerTree(std::unique_ptr<AnimationHost> animation_host,
+ LayerTreeHost* layer_tree_host)
+ : LayerTree(std::move(animation_host), layer_tree_host) {}
+ ~MockLayerTree() override {}
+
+ // We don't want tree sync requests to trigger commits.
danakj 2016/09/26 21:36:54 Why not?
Khushal 2016/09/27 01:07:50 Because we always set the root layer at the beginn
+ void SetNeedsFullTreeSync() override {}
+};
+
+class LayerTreeHostRemoteForTesting : public LayerTreeHostRemote {
+ public:
+ explicit LayerTreeHostRemoteForTesting(InitParams* params)
+ : LayerTreeHostRemote(
+ params,
+ base::MakeUnique<MockLayerTree>(AnimationHost::CreateMainInstance(),
+ this)) {}
+ ~LayerTreeHostRemoteForTesting() override {}
+};
+
+class LayerTreeHostRemoteTest : public testing::Test {
+ public:
+ LayerTreeHostRemoteTest()
+ : compositor_proto_state_sink_(nullptr),
danakj 2016/09/26 21:36:53 init these where they defined
Khushal 2016/09/27 01:07:50 Done.
+ needs_animate_during_main_frame_(false),
+ needs_commit_during_main_frame_(false) {
+ mock_layer_tree_host_client_.set_update_host_callback(base::Bind(
+ &LayerTreeHostRemoteTest::UpdateLayerTreeHost, base::Unretained(this)));
+ }
+ ~LayerTreeHostRemoteTest() override {}
+
+ void SetUp() override {
+ LayerTreeHostRemote::InitParams params;
+ params.client = &mock_layer_tree_host_client_;
+ params.main_task_runner = base::ThreadTaskRunnerHandle::Get();
+ std::unique_ptr<UpdateTrackingCompositorProtoStateSink>
+ compositor_proto_state_sink =
+ base::MakeUnique<UpdateTrackingCompositorProtoStateSink>();
+ compositor_proto_state_sink_ = compositor_proto_state_sink.get();
+ params.compositor_proto_state_sink = std::move(compositor_proto_state_sink);
+ LayerTreeSettings settings;
+ params.settings = &settings;
+
+ layer_tree_host_ = base::MakeUnique<LayerTreeHostRemoteForTesting>(&params);
+ root_layer_ = MockLayer::Create(false);
+ layer_tree_host_->GetLayerTree()->SetRootLayer(root_layer_);
+ }
+
+ void TearDown() override {
+ Mock::VerifyAndClearExpectations(&mock_layer_tree_host_client_);
+ layer_tree_host_.reset();
danakj 2016/09/26 21:36:54 = nullptr?
Khushal 2016/09/27 01:07:50 Done.
+ root_layer_ = nullptr;
+ compositor_proto_state_sink_ = nullptr;
+ }
+
+ void UpdateLayerTreeHost() {
+ if (needs_animate_during_main_frame_) {
+ layer_tree_host_->SetNeedsAnimate();
+ needs_animate_during_main_frame_ = false;
+ }
+
+ if (needs_commit_during_main_frame_) {
+ layer_tree_host_->SetNeedsCommit();
+ needs_commit_during_main_frame_ = false;
+ }
+ }
+
+ void set_needs_animate_during_main_frame(bool needs) {
+ needs_animate_during_main_frame_ = needs;
+ }
+
+ void set_needs_commit_during_main_frame(bool needs) {
+ needs_commit_during_main_frame_ = needs;
+ }
+
+ protected:
+ std::unique_ptr<LayerTreeHostRemote> layer_tree_host_;
+ StrictMock<MockLayerTreeHostClient> mock_layer_tree_host_client_;
+ UpdateTrackingCompositorProtoStateSink* compositor_proto_state_sink_;
danakj 2016/09/26 21:36:53 = nullptr
Khushal 2016/09/27 01:07:50 Done.
+ scoped_refptr<MockLayer> root_layer_;
+
+ bool needs_animate_during_main_frame_;
danakj 2016/09/26 21:36:53 = false
Khushal 2016/09/27 01:07:50 Done.
+ bool needs_commit_during_main_frame_;
danakj 2016/09/26 21:36:53 = false
Khushal 2016/09/27 01:07:50 Done.
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(LayerTreeHostRemoteTest);
+};
+
+TEST_F(LayerTreeHostRemoteTest, BeginMainFrameAnimateOnly) {
+ // The main frame should run until the animate step only.
+ InSequence s;
+ EXPECT_BEGIN_MAIN_FRAME(mock_layer_tree_host_client_, 1);
+
+ int previous_source_frame = layer_tree_host_->SourceFrameNumber();
+ layer_tree_host_->SetNeedsAnimate();
+
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(root_layer_->did_update());
+ EXPECT_EQ(0, compositor_proto_state_sink_->num_updates_received());
+ EXPECT_EQ(++previous_source_frame, layer_tree_host_->SourceFrameNumber());
+}
+
+TEST_F(LayerTreeHostRemoteTest, BeginMainFrameUpdateLayers) {
+ // The main frame should run until the update layers step only.
+ InSequence s;
+ EXPECT_BEGIN_MAIN_FRAME(mock_layer_tree_host_client_, 1);
+
+ int previous_source_frame = layer_tree_host_->SourceFrameNumber();
+ layer_tree_host_->SetNeedsUpdateLayers();
+
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(root_layer_->did_update());
+ EXPECT_EQ(0, compositor_proto_state_sink_->num_updates_received());
+ EXPECT_EQ(++previous_source_frame, layer_tree_host_->SourceFrameNumber());
+}
+
+TEST_F(LayerTreeHostRemoteTest, BeginMainFrameCommit) {
+ // The main frame should run until the commit step.
+ InSequence s;
+ EXPECT_BEGIN_MAIN_FRAME_AND_COMMIT(mock_layer_tree_host_client_, 1);
+
+ int previous_source_frame = layer_tree_host_->SourceFrameNumber();
+ layer_tree_host_->SetNeedsCommit();
+
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(root_layer_->did_update());
+ EXPECT_EQ(1, compositor_proto_state_sink_->num_updates_received());
+ EXPECT_EQ(++previous_source_frame, layer_tree_host_->SourceFrameNumber());
+}
+
+TEST_F(LayerTreeHostRemoteTest, BeginMainFrameMultipleRequests) {
+ // Multiple BeginMainFrame requests should result in a single main frame
+ // update.
+ InSequence s;
+ EXPECT_BEGIN_MAIN_FRAME_AND_COMMIT(mock_layer_tree_host_client_, 1);
+
+ layer_tree_host_->SetNeedsAnimate();
+ layer_tree_host_->SetNeedsUpdateLayers();
+ layer_tree_host_->SetNeedsCommit();
+
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(root_layer_->did_update());
+ EXPECT_EQ(1, compositor_proto_state_sink_->num_updates_received());
+}
+
+TEST_F(LayerTreeHostRemoteTest, CommitRequestThenDeferCommits) {
+ // Make a commit request, followed by a request to defer commits.
+ layer_tree_host_->SetNeedsCommit();
+ layer_tree_host_->SetDeferCommits(true);
+
+ // We should not have seen any BeginMainFrames.
+ base::RunLoop().RunUntilIdle();
+ Mock::VerifyAndClearExpectations(&mock_layer_tree_host_client_);
+ EXPECT_FALSE(root_layer_->did_update());
+ EXPECT_EQ(0, compositor_proto_state_sink_->num_updates_received());
+
+ // Now enable commits and ensure we see a BeginMainFrame.
+ layer_tree_host_->SetDeferCommits(false);
+ InSequence s;
+ EXPECT_BEGIN_MAIN_FRAME_AND_COMMIT(mock_layer_tree_host_client_, 1);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(root_layer_->did_update());
+ EXPECT_EQ(1, compositor_proto_state_sink_->num_updates_received());
+}
+
+TEST_F(LayerTreeHostRemoteTest, DeferCommitsThenCommitRequest) {
+ // Defer commits followed by a commit request.
+ layer_tree_host_->SetDeferCommits(true);
+ layer_tree_host_->SetNeedsCommit();
+
+ // We should not have seen any BeginMainFrames.
+ base::RunLoop().RunUntilIdle();
+ Mock::VerifyAndClearExpectations(&mock_layer_tree_host_client_);
+ EXPECT_FALSE(root_layer_->did_update());
+ EXPECT_EQ(0, compositor_proto_state_sink_->num_updates_received());
+
+ // Now enable commits and ensure we see a BeginMainFrame.
+ layer_tree_host_->SetDeferCommits(false);
+ InSequence s;
+ EXPECT_BEGIN_MAIN_FRAME_AND_COMMIT(mock_layer_tree_host_client_, 1);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(root_layer_->did_update());
+ EXPECT_EQ(1, compositor_proto_state_sink_->num_updates_received());
+}
+
+TEST_F(LayerTreeHostRemoteTest, RequestAnimateDuringMainFrame) {
+ // An animate request during BeginMainFrame should result in a second main
+ // frame being scheduled.
+ set_needs_animate_during_main_frame(true);
+ EXPECT_BEGIN_MAIN_FRAME(mock_layer_tree_host_client_, 2);
danakj 2016/09/26 21:36:54 maybe use a temp var to point out what this 2 is a
Khushal 2016/09/27 01:07:50 Done.
+
+ layer_tree_host_->SetNeedsAnimate();
+
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(root_layer_->did_update());
+ EXPECT_EQ(0, compositor_proto_state_sink_->num_updates_received());
+}
+
+TEST_F(LayerTreeHostRemoteTest, RequestCommitDuringMainFrame) {
+ // A commit request during a BeginMainFrame scheduled for an animate request
+ // should go till the commit stage.
+ set_needs_commit_during_main_frame(true);
+ EXPECT_BEGIN_MAIN_FRAME_AND_COMMIT(mock_layer_tree_host_client_, 1);
+
+ layer_tree_host_->SetNeedsAnimate();
+
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(root_layer_->did_update());
+ EXPECT_EQ(1, compositor_proto_state_sink_->num_updates_received());
+}
+
+TEST_F(LayerTreeHostRemoteTest, RequestCommitDuringLayerUpdates) {
+ // A layer update during a main frame should result in a commit.
danakj 2016/09/26 21:36:54 The layer add isn't during the main frame here, is
Khushal 2016/09/27 01:07:50 Nope. The main frame wouldn't start until the runl
+ scoped_refptr<Layer> child_layer = MockLayer::Create(true);
+ root_layer_->AddChild(child_layer);
+ EXPECT_BEGIN_MAIN_FRAME_AND_COMMIT(mock_layer_tree_host_client_, 1);
+
+ layer_tree_host_->SetNeedsUpdateLayers();
+
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(root_layer_->did_update());
+ EXPECT_EQ(1, compositor_proto_state_sink_->num_updates_received());
+}
+
+} // namespace
+} // namespace cc

Powered by Google App Engine
This is Rietveld 408576698