Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "cc/blimp/layer_tree_host_remote.h" | |
| 6 | |
| 7 #include "base/bind.h" | |
| 8 #include "base/run_loop.h" | |
| 9 #include "base/threading/thread_task_runner_handle.h" | |
| 10 #include "cc/animation/animation_host.h" | |
| 11 #include "cc/blimp/compositor_proto_state_sink.h" | |
| 12 #include "cc/layers/layer.h" | |
| 13 #include "cc/output/begin_frame_args.h" | |
| 14 #include "cc/test/fake_compositor_proto_state_sink.h" | |
| 15 #include "cc/test/stub_layer_tree_host_client.h" | |
| 16 #include "cc/trees/layer_tree_settings.h" | |
| 17 #include "testing/gmock/include/gmock/gmock.h" | |
| 18 #include "testing/gtest/include/gtest/gtest.h" | |
| 19 | |
| 20 using ::testing::_; | |
| 21 using testing::InSequence; | |
| 22 using testing::Mock; | |
| 23 using testing::StrictMock; | |
| 24 | |
| 25 #define EXPECT_BEGIN_MAIN_FRAME(client, num) \ | |
| 26 EXPECT_CALL(client, WillBeginMainFrame()).Times(num); \ | |
| 27 EXPECT_CALL(client, BeginMainFrame(_)).Times(num); \ | |
| 28 EXPECT_CALL(client, DidUpdateLayerTreeHost()).Times(num); \ | |
| 29 EXPECT_CALL(client, WillCommit()).Times(num); \ | |
| 30 EXPECT_CALL(client, DidCommit()).Times(num); \ | |
| 31 EXPECT_CALL(client, DidBeginMainFrame()).Times(num); | |
| 32 | |
| 33 #define EXPECT_BEGIN_MAIN_FRAME_AND_COMMIT(client, num) \ | |
| 34 EXPECT_BEGIN_MAIN_FRAME(client, num) \ | |
| 35 EXPECT_CALL(client, DidCommitAndDrawFrame()).Times(num); \ | |
| 36 EXPECT_CALL(client, DidCompleteSwapBuffers()).Times(num); | |
| 37 | |
| 38 namespace cc { | |
| 39 namespace { | |
| 40 | |
| 41 class UpdateTrackingCompositorProtoStateSink | |
| 42 : public FakeCompositorProtoStateSink { | |
| 43 public: | |
| 44 UpdateTrackingCompositorProtoStateSink() : num_updates_received_(0) {} | |
|
danakj
2016/09/26 21:36:54
= default
Khushal
2016/09/27 01:07:50
Done.
| |
| 45 ~UpdateTrackingCompositorProtoStateSink() override {} | |
| 46 | |
| 47 void ProcessCompositorStateUpdate( | |
| 48 std::unique_ptr<CompositorProtoState> compositor_proto_state) override { | |
| 49 num_updates_received_++; | |
| 50 }; | |
| 51 | |
| 52 int num_updates_received() const { return num_updates_received_; } | |
| 53 | |
| 54 private: | |
| 55 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
| |
| 56 }; | |
| 57 | |
| 58 class MockLayerTreeHostClient : public StubLayerTreeHostClient { | |
| 59 public: | |
| 60 MockLayerTreeHostClient() {} | |
|
danakj
2016/09/26 21:36:53
=default
Khushal
2016/09/27 23:46:56
Done.
| |
| 61 ~MockLayerTreeHostClient() override {} | |
|
danakj
2016/09/26 21:36:53
= default?
Khushal
2016/09/27 23:46:56
Done.
| |
| 62 | |
| 63 // LayerTreeHostClient implementation. | |
| 64 MOCK_METHOD0(WillBeginMainFrame, void()); | |
| 65 MOCK_METHOD1(BeginMainFrame, void(const BeginFrameArgs& args)); | |
| 66 MOCK_METHOD0(DidBeginMainFrame, void()); | |
| 67 | |
| 68 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.
| |
| 69 update_host_callback_ = callback; | |
| 70 } | |
| 71 | |
| 72 void UpdateLayerTreeHost() override { | |
| 73 update_host_callback_.Run(); | |
| 74 DidUpdateLayerTreeHost(); | |
| 75 } | |
| 76 | |
| 77 MOCK_METHOD0(DidUpdateLayerTreeHost, void()); | |
|
danakj
2016/09/26 21:36:53
Group together
Khushal
2016/09/27 01:07:50
Done.
| |
| 78 MOCK_METHOD0(WillCommit, void()); | |
| 79 MOCK_METHOD0(DidCommit, void()); | |
| 80 MOCK_METHOD0(DidCommitAndDrawFrame, void()); | |
| 81 MOCK_METHOD0(DidCompleteSwapBuffers, void()); | |
| 82 | |
| 83 private: | |
| 84 base::Closure update_host_callback_; | |
| 85 }; | |
| 86 | |
| 87 class MockLayer : public Layer { | |
| 88 public: | |
| 89 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.
| |
| 90 return make_scoped_refptr(new MockLayer(update)); | |
| 91 } | |
| 92 | |
| 93 bool Update() override { | |
| 94 did_update_ = true; | |
| 95 return update_; | |
| 96 } | |
| 97 | |
| 98 bool did_update() const { return did_update_; } | |
| 99 | |
| 100 private: | |
| 101 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.
| |
| 102 ~MockLayer() override {} | |
| 103 | |
| 104 bool update_; | |
| 105 bool did_update_; | |
|
danakj
2016/09/26 21:36:53
= false
Khushal
2016/09/27 01:07:50
Done.
| |
| 106 }; | |
| 107 | |
| 108 class MockLayerTree : public LayerTree { | |
| 109 public: | |
| 110 MockLayerTree(std::unique_ptr<AnimationHost> animation_host, | |
| 111 LayerTreeHost* layer_tree_host) | |
| 112 : LayerTree(std::move(animation_host), layer_tree_host) {} | |
| 113 ~MockLayerTree() override {} | |
| 114 | |
| 115 // 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
| |
| 116 void SetNeedsFullTreeSync() override {} | |
| 117 }; | |
| 118 | |
| 119 class LayerTreeHostRemoteForTesting : public LayerTreeHostRemote { | |
| 120 public: | |
| 121 explicit LayerTreeHostRemoteForTesting(InitParams* params) | |
| 122 : LayerTreeHostRemote( | |
| 123 params, | |
| 124 base::MakeUnique<MockLayerTree>(AnimationHost::CreateMainInstance(), | |
| 125 this)) {} | |
| 126 ~LayerTreeHostRemoteForTesting() override {} | |
| 127 }; | |
| 128 | |
| 129 class LayerTreeHostRemoteTest : public testing::Test { | |
| 130 public: | |
| 131 LayerTreeHostRemoteTest() | |
| 132 : 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.
| |
| 133 needs_animate_during_main_frame_(false), | |
| 134 needs_commit_during_main_frame_(false) { | |
| 135 mock_layer_tree_host_client_.set_update_host_callback(base::Bind( | |
| 136 &LayerTreeHostRemoteTest::UpdateLayerTreeHost, base::Unretained(this))); | |
| 137 } | |
| 138 ~LayerTreeHostRemoteTest() override {} | |
| 139 | |
| 140 void SetUp() override { | |
| 141 LayerTreeHostRemote::InitParams params; | |
| 142 params.client = &mock_layer_tree_host_client_; | |
| 143 params.main_task_runner = base::ThreadTaskRunnerHandle::Get(); | |
| 144 std::unique_ptr<UpdateTrackingCompositorProtoStateSink> | |
| 145 compositor_proto_state_sink = | |
| 146 base::MakeUnique<UpdateTrackingCompositorProtoStateSink>(); | |
| 147 compositor_proto_state_sink_ = compositor_proto_state_sink.get(); | |
| 148 params.compositor_proto_state_sink = std::move(compositor_proto_state_sink); | |
| 149 LayerTreeSettings settings; | |
| 150 params.settings = &settings; | |
| 151 | |
| 152 layer_tree_host_ = base::MakeUnique<LayerTreeHostRemoteForTesting>(¶ms); | |
| 153 root_layer_ = MockLayer::Create(false); | |
| 154 layer_tree_host_->GetLayerTree()->SetRootLayer(root_layer_); | |
| 155 } | |
| 156 | |
| 157 void TearDown() override { | |
| 158 Mock::VerifyAndClearExpectations(&mock_layer_tree_host_client_); | |
| 159 layer_tree_host_.reset(); | |
|
danakj
2016/09/26 21:36:54
= nullptr?
Khushal
2016/09/27 01:07:50
Done.
| |
| 160 root_layer_ = nullptr; | |
| 161 compositor_proto_state_sink_ = nullptr; | |
| 162 } | |
| 163 | |
| 164 void UpdateLayerTreeHost() { | |
| 165 if (needs_animate_during_main_frame_) { | |
| 166 layer_tree_host_->SetNeedsAnimate(); | |
| 167 needs_animate_during_main_frame_ = false; | |
| 168 } | |
| 169 | |
| 170 if (needs_commit_during_main_frame_) { | |
| 171 layer_tree_host_->SetNeedsCommit(); | |
| 172 needs_commit_during_main_frame_ = false; | |
| 173 } | |
| 174 } | |
| 175 | |
| 176 void set_needs_animate_during_main_frame(bool needs) { | |
| 177 needs_animate_during_main_frame_ = needs; | |
| 178 } | |
| 179 | |
| 180 void set_needs_commit_during_main_frame(bool needs) { | |
| 181 needs_commit_during_main_frame_ = needs; | |
| 182 } | |
| 183 | |
| 184 protected: | |
| 185 std::unique_ptr<LayerTreeHostRemote> layer_tree_host_; | |
| 186 StrictMock<MockLayerTreeHostClient> mock_layer_tree_host_client_; | |
| 187 UpdateTrackingCompositorProtoStateSink* compositor_proto_state_sink_; | |
|
danakj
2016/09/26 21:36:53
= nullptr
Khushal
2016/09/27 01:07:50
Done.
| |
| 188 scoped_refptr<MockLayer> root_layer_; | |
| 189 | |
| 190 bool needs_animate_during_main_frame_; | |
|
danakj
2016/09/26 21:36:53
= false
Khushal
2016/09/27 01:07:50
Done.
| |
| 191 bool needs_commit_during_main_frame_; | |
|
danakj
2016/09/26 21:36:53
= false
Khushal
2016/09/27 01:07:50
Done.
| |
| 192 | |
| 193 private: | |
| 194 DISALLOW_COPY_AND_ASSIGN(LayerTreeHostRemoteTest); | |
| 195 }; | |
| 196 | |
| 197 TEST_F(LayerTreeHostRemoteTest, BeginMainFrameAnimateOnly) { | |
| 198 // The main frame should run until the animate step only. | |
| 199 InSequence s; | |
| 200 EXPECT_BEGIN_MAIN_FRAME(mock_layer_tree_host_client_, 1); | |
| 201 | |
| 202 int previous_source_frame = layer_tree_host_->SourceFrameNumber(); | |
| 203 layer_tree_host_->SetNeedsAnimate(); | |
| 204 | |
| 205 base::RunLoop().RunUntilIdle(); | |
| 206 EXPECT_FALSE(root_layer_->did_update()); | |
| 207 EXPECT_EQ(0, compositor_proto_state_sink_->num_updates_received()); | |
| 208 EXPECT_EQ(++previous_source_frame, layer_tree_host_->SourceFrameNumber()); | |
| 209 } | |
| 210 | |
| 211 TEST_F(LayerTreeHostRemoteTest, BeginMainFrameUpdateLayers) { | |
| 212 // The main frame should run until the update layers step only. | |
| 213 InSequence s; | |
| 214 EXPECT_BEGIN_MAIN_FRAME(mock_layer_tree_host_client_, 1); | |
| 215 | |
| 216 int previous_source_frame = layer_tree_host_->SourceFrameNumber(); | |
| 217 layer_tree_host_->SetNeedsUpdateLayers(); | |
| 218 | |
| 219 base::RunLoop().RunUntilIdle(); | |
| 220 EXPECT_TRUE(root_layer_->did_update()); | |
| 221 EXPECT_EQ(0, compositor_proto_state_sink_->num_updates_received()); | |
| 222 EXPECT_EQ(++previous_source_frame, layer_tree_host_->SourceFrameNumber()); | |
| 223 } | |
| 224 | |
| 225 TEST_F(LayerTreeHostRemoteTest, BeginMainFrameCommit) { | |
| 226 // The main frame should run until the commit step. | |
| 227 InSequence s; | |
| 228 EXPECT_BEGIN_MAIN_FRAME_AND_COMMIT(mock_layer_tree_host_client_, 1); | |
| 229 | |
| 230 int previous_source_frame = layer_tree_host_->SourceFrameNumber(); | |
| 231 layer_tree_host_->SetNeedsCommit(); | |
| 232 | |
| 233 base::RunLoop().RunUntilIdle(); | |
| 234 EXPECT_TRUE(root_layer_->did_update()); | |
| 235 EXPECT_EQ(1, compositor_proto_state_sink_->num_updates_received()); | |
| 236 EXPECT_EQ(++previous_source_frame, layer_tree_host_->SourceFrameNumber()); | |
| 237 } | |
| 238 | |
| 239 TEST_F(LayerTreeHostRemoteTest, BeginMainFrameMultipleRequests) { | |
| 240 // Multiple BeginMainFrame requests should result in a single main frame | |
| 241 // update. | |
| 242 InSequence s; | |
| 243 EXPECT_BEGIN_MAIN_FRAME_AND_COMMIT(mock_layer_tree_host_client_, 1); | |
| 244 | |
| 245 layer_tree_host_->SetNeedsAnimate(); | |
| 246 layer_tree_host_->SetNeedsUpdateLayers(); | |
| 247 layer_tree_host_->SetNeedsCommit(); | |
| 248 | |
| 249 base::RunLoop().RunUntilIdle(); | |
| 250 EXPECT_TRUE(root_layer_->did_update()); | |
| 251 EXPECT_EQ(1, compositor_proto_state_sink_->num_updates_received()); | |
| 252 } | |
| 253 | |
| 254 TEST_F(LayerTreeHostRemoteTest, CommitRequestThenDeferCommits) { | |
| 255 // Make a commit request, followed by a request to defer commits. | |
| 256 layer_tree_host_->SetNeedsCommit(); | |
| 257 layer_tree_host_->SetDeferCommits(true); | |
| 258 | |
| 259 // We should not have seen any BeginMainFrames. | |
| 260 base::RunLoop().RunUntilIdle(); | |
| 261 Mock::VerifyAndClearExpectations(&mock_layer_tree_host_client_); | |
| 262 EXPECT_FALSE(root_layer_->did_update()); | |
| 263 EXPECT_EQ(0, compositor_proto_state_sink_->num_updates_received()); | |
| 264 | |
| 265 // Now enable commits and ensure we see a BeginMainFrame. | |
| 266 layer_tree_host_->SetDeferCommits(false); | |
| 267 InSequence s; | |
| 268 EXPECT_BEGIN_MAIN_FRAME_AND_COMMIT(mock_layer_tree_host_client_, 1); | |
| 269 base::RunLoop().RunUntilIdle(); | |
| 270 EXPECT_TRUE(root_layer_->did_update()); | |
| 271 EXPECT_EQ(1, compositor_proto_state_sink_->num_updates_received()); | |
| 272 } | |
| 273 | |
| 274 TEST_F(LayerTreeHostRemoteTest, DeferCommitsThenCommitRequest) { | |
| 275 // Defer commits followed by a commit request. | |
| 276 layer_tree_host_->SetDeferCommits(true); | |
| 277 layer_tree_host_->SetNeedsCommit(); | |
| 278 | |
| 279 // We should not have seen any BeginMainFrames. | |
| 280 base::RunLoop().RunUntilIdle(); | |
| 281 Mock::VerifyAndClearExpectations(&mock_layer_tree_host_client_); | |
| 282 EXPECT_FALSE(root_layer_->did_update()); | |
| 283 EXPECT_EQ(0, compositor_proto_state_sink_->num_updates_received()); | |
| 284 | |
| 285 // Now enable commits and ensure we see a BeginMainFrame. | |
| 286 layer_tree_host_->SetDeferCommits(false); | |
| 287 InSequence s; | |
| 288 EXPECT_BEGIN_MAIN_FRAME_AND_COMMIT(mock_layer_tree_host_client_, 1); | |
| 289 base::RunLoop().RunUntilIdle(); | |
| 290 EXPECT_TRUE(root_layer_->did_update()); | |
| 291 EXPECT_EQ(1, compositor_proto_state_sink_->num_updates_received()); | |
| 292 } | |
| 293 | |
| 294 TEST_F(LayerTreeHostRemoteTest, RequestAnimateDuringMainFrame) { | |
| 295 // An animate request during BeginMainFrame should result in a second main | |
| 296 // frame being scheduled. | |
| 297 set_needs_animate_during_main_frame(true); | |
| 298 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.
| |
| 299 | |
| 300 layer_tree_host_->SetNeedsAnimate(); | |
| 301 | |
| 302 base::RunLoop().RunUntilIdle(); | |
| 303 EXPECT_FALSE(root_layer_->did_update()); | |
| 304 EXPECT_EQ(0, compositor_proto_state_sink_->num_updates_received()); | |
| 305 } | |
| 306 | |
| 307 TEST_F(LayerTreeHostRemoteTest, RequestCommitDuringMainFrame) { | |
| 308 // A commit request during a BeginMainFrame scheduled for an animate request | |
| 309 // should go till the commit stage. | |
| 310 set_needs_commit_during_main_frame(true); | |
| 311 EXPECT_BEGIN_MAIN_FRAME_AND_COMMIT(mock_layer_tree_host_client_, 1); | |
| 312 | |
| 313 layer_tree_host_->SetNeedsAnimate(); | |
| 314 | |
| 315 base::RunLoop().RunUntilIdle(); | |
| 316 EXPECT_TRUE(root_layer_->did_update()); | |
| 317 EXPECT_EQ(1, compositor_proto_state_sink_->num_updates_received()); | |
| 318 } | |
| 319 | |
| 320 TEST_F(LayerTreeHostRemoteTest, RequestCommitDuringLayerUpdates) { | |
| 321 // 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
| |
| 322 scoped_refptr<Layer> child_layer = MockLayer::Create(true); | |
| 323 root_layer_->AddChild(child_layer); | |
| 324 EXPECT_BEGIN_MAIN_FRAME_AND_COMMIT(mock_layer_tree_host_client_, 1); | |
| 325 | |
| 326 layer_tree_host_->SetNeedsUpdateLayers(); | |
| 327 | |
| 328 base::RunLoop().RunUntilIdle(); | |
| 329 EXPECT_TRUE(root_layer_->did_update()); | |
| 330 EXPECT_EQ(1, compositor_proto_state_sink_->num_updates_received()); | |
| 331 } | |
| 332 | |
| 333 } // namespace | |
| 334 } // namespace cc | |
| OLD | NEW |