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() = default; |
| 45 ~UpdateTrackingCompositorProtoStateSink() override = default; |
| 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_ = 0; |
| 56 }; |
| 57 |
| 58 class MockLayerTreeHostClient : public StubLayerTreeHostClient { |
| 59 public: |
| 60 MockLayerTreeHostClient() = default; |
| 61 ~MockLayerTreeHostClient() override = default; |
| 62 |
| 63 void set_update_host_callback(base::Closure callback) { |
| 64 update_host_callback_ = callback; |
| 65 } |
| 66 |
| 67 void UpdateLayerTreeHost() override { |
| 68 update_host_callback_.Run(); |
| 69 DidUpdateLayerTreeHost(); |
| 70 } |
| 71 |
| 72 // LayerTreeHostClient implementation. |
| 73 MOCK_METHOD0(WillBeginMainFrame, void()); |
| 74 MOCK_METHOD1(BeginMainFrame, void(const BeginFrameArgs& args)); |
| 75 MOCK_METHOD0(DidBeginMainFrame, void()); |
| 76 MOCK_METHOD0(DidUpdateLayerTreeHost, void()); |
| 77 MOCK_METHOD0(WillCommit, void()); |
| 78 MOCK_METHOD0(DidCommit, void()); |
| 79 MOCK_METHOD0(DidCommitAndDrawFrame, void()); |
| 80 MOCK_METHOD0(DidCompleteSwapBuffers, void()); |
| 81 |
| 82 private: |
| 83 base::Closure update_host_callback_; |
| 84 }; |
| 85 |
| 86 class MockLayer : public Layer { |
| 87 public: |
| 88 explicit MockLayer(bool update) : update_(update) {} |
| 89 |
| 90 bool Update() override { |
| 91 did_update_ = true; |
| 92 return update_; |
| 93 } |
| 94 |
| 95 bool did_update() const { return did_update_; } |
| 96 |
| 97 private: |
| 98 ~MockLayer() override {} |
| 99 |
| 100 bool update_; |
| 101 bool did_update_ = false; |
| 102 }; |
| 103 |
| 104 class MockLayerTree : public LayerTree { |
| 105 public: |
| 106 MockLayerTree(std::unique_ptr<AnimationHost> animation_host, |
| 107 LayerTreeHost* layer_tree_host) |
| 108 : LayerTree(std::move(animation_host), layer_tree_host) {} |
| 109 ~MockLayerTree() override {} |
| 110 |
| 111 // We don't want tree sync requests to trigger commits. |
| 112 void SetNeedsFullTreeSync() override {} |
| 113 }; |
| 114 |
| 115 class LayerTreeHostRemoteForTesting : public LayerTreeHostRemote { |
| 116 public: |
| 117 explicit LayerTreeHostRemoteForTesting(InitParams* params) |
| 118 : LayerTreeHostRemote( |
| 119 params, |
| 120 base::MakeUnique<MockLayerTree>(AnimationHost::CreateMainInstance(), |
| 121 this)) {} |
| 122 ~LayerTreeHostRemoteForTesting() override {} |
| 123 }; |
| 124 |
| 125 class LayerTreeHostRemoteTest : public testing::Test { |
| 126 public: |
| 127 LayerTreeHostRemoteTest() { |
| 128 mock_layer_tree_host_client_.set_update_host_callback(base::Bind( |
| 129 &LayerTreeHostRemoteTest::UpdateLayerTreeHost, base::Unretained(this))); |
| 130 } |
| 131 ~LayerTreeHostRemoteTest() override {} |
| 132 |
| 133 void SetUp() override { |
| 134 LayerTreeHostRemote::InitParams params; |
| 135 params.client = &mock_layer_tree_host_client_; |
| 136 params.main_task_runner = base::ThreadTaskRunnerHandle::Get(); |
| 137 std::unique_ptr<UpdateTrackingCompositorProtoStateSink> |
| 138 compositor_proto_state_sink = |
| 139 base::MakeUnique<UpdateTrackingCompositorProtoStateSink>(); |
| 140 compositor_proto_state_sink_ = compositor_proto_state_sink.get(); |
| 141 params.compositor_proto_state_sink = std::move(compositor_proto_state_sink); |
| 142 LayerTreeSettings settings; |
| 143 params.settings = &settings; |
| 144 |
| 145 layer_tree_host_ = base::MakeUnique<LayerTreeHostRemoteForTesting>(¶ms); |
| 146 root_layer_ = make_scoped_refptr(new MockLayer(false)); |
| 147 layer_tree_host_->GetLayerTree()->SetRootLayer(root_layer_); |
| 148 } |
| 149 |
| 150 void TearDown() override { |
| 151 Mock::VerifyAndClearExpectations(&mock_layer_tree_host_client_); |
| 152 layer_tree_host_ = nullptr; |
| 153 root_layer_ = nullptr; |
| 154 compositor_proto_state_sink_ = nullptr; |
| 155 } |
| 156 |
| 157 void UpdateLayerTreeHost() { |
| 158 if (needs_animate_during_main_frame_) { |
| 159 layer_tree_host_->SetNeedsAnimate(); |
| 160 needs_animate_during_main_frame_ = false; |
| 161 } |
| 162 |
| 163 if (needs_commit_during_main_frame_) { |
| 164 layer_tree_host_->SetNeedsCommit(); |
| 165 needs_commit_during_main_frame_ = false; |
| 166 } |
| 167 } |
| 168 |
| 169 void set_needs_animate_during_main_frame(bool needs) { |
| 170 needs_animate_during_main_frame_ = needs; |
| 171 } |
| 172 |
| 173 void set_needs_commit_during_main_frame(bool needs) { |
| 174 needs_commit_during_main_frame_ = needs; |
| 175 } |
| 176 |
| 177 protected: |
| 178 std::unique_ptr<LayerTreeHostRemote> layer_tree_host_; |
| 179 StrictMock<MockLayerTreeHostClient> mock_layer_tree_host_client_; |
| 180 UpdateTrackingCompositorProtoStateSink* compositor_proto_state_sink_ = |
| 181 nullptr; |
| 182 scoped_refptr<MockLayer> root_layer_; |
| 183 |
| 184 bool needs_animate_during_main_frame_ = false; |
| 185 bool needs_commit_during_main_frame_ = false; |
| 186 |
| 187 private: |
| 188 DISALLOW_COPY_AND_ASSIGN(LayerTreeHostRemoteTest); |
| 189 }; |
| 190 |
| 191 TEST_F(LayerTreeHostRemoteTest, BeginMainFrameAnimateOnly) { |
| 192 // The main frame should run until the animate step only. |
| 193 InSequence s; |
| 194 int num_of_frames = 1; |
| 195 EXPECT_BEGIN_MAIN_FRAME(mock_layer_tree_host_client_, num_of_frames); |
| 196 |
| 197 int previous_source_frame = layer_tree_host_->SourceFrameNumber(); |
| 198 layer_tree_host_->SetNeedsAnimate(); |
| 199 |
| 200 base::RunLoop().RunUntilIdle(); |
| 201 EXPECT_FALSE(root_layer_->did_update()); |
| 202 EXPECT_EQ(0, compositor_proto_state_sink_->num_updates_received()); |
| 203 EXPECT_EQ(++previous_source_frame, layer_tree_host_->SourceFrameNumber()); |
| 204 } |
| 205 |
| 206 TEST_F(LayerTreeHostRemoteTest, BeginMainFrameUpdateLayers) { |
| 207 // The main frame should run until the update layers step only. |
| 208 InSequence s; |
| 209 int num_of_frames = 1; |
| 210 EXPECT_BEGIN_MAIN_FRAME(mock_layer_tree_host_client_, num_of_frames); |
| 211 |
| 212 int previous_source_frame = layer_tree_host_->SourceFrameNumber(); |
| 213 layer_tree_host_->SetNeedsUpdateLayers(); |
| 214 |
| 215 base::RunLoop().RunUntilIdle(); |
| 216 EXPECT_TRUE(root_layer_->did_update()); |
| 217 EXPECT_EQ(0, compositor_proto_state_sink_->num_updates_received()); |
| 218 EXPECT_EQ(++previous_source_frame, layer_tree_host_->SourceFrameNumber()); |
| 219 } |
| 220 |
| 221 TEST_F(LayerTreeHostRemoteTest, BeginMainFrameCommit) { |
| 222 // The main frame should run until the commit step. |
| 223 InSequence s; |
| 224 int num_of_frames = 1; |
| 225 EXPECT_BEGIN_MAIN_FRAME_AND_COMMIT(mock_layer_tree_host_client_, |
| 226 num_of_frames); |
| 227 |
| 228 int previous_source_frame = layer_tree_host_->SourceFrameNumber(); |
| 229 layer_tree_host_->SetNeedsCommit(); |
| 230 |
| 231 base::RunLoop().RunUntilIdle(); |
| 232 EXPECT_TRUE(root_layer_->did_update()); |
| 233 EXPECT_EQ(1, compositor_proto_state_sink_->num_updates_received()); |
| 234 EXPECT_EQ(++previous_source_frame, layer_tree_host_->SourceFrameNumber()); |
| 235 } |
| 236 |
| 237 TEST_F(LayerTreeHostRemoteTest, BeginMainFrameMultipleRequests) { |
| 238 // Multiple BeginMainFrame requests should result in a single main frame |
| 239 // update. |
| 240 InSequence s; |
| 241 int num_of_frames = 1; |
| 242 EXPECT_BEGIN_MAIN_FRAME_AND_COMMIT(mock_layer_tree_host_client_, |
| 243 num_of_frames); |
| 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 int num_of_frames = 1; |
| 269 EXPECT_BEGIN_MAIN_FRAME_AND_COMMIT(mock_layer_tree_host_client_, |
| 270 num_of_frames); |
| 271 base::RunLoop().RunUntilIdle(); |
| 272 EXPECT_TRUE(root_layer_->did_update()); |
| 273 EXPECT_EQ(1, compositor_proto_state_sink_->num_updates_received()); |
| 274 } |
| 275 |
| 276 TEST_F(LayerTreeHostRemoteTest, DeferCommitsThenCommitRequest) { |
| 277 // Defer commits followed by a commit request. |
| 278 layer_tree_host_->SetDeferCommits(true); |
| 279 layer_tree_host_->SetNeedsCommit(); |
| 280 |
| 281 // We should not have seen any BeginMainFrames. |
| 282 base::RunLoop().RunUntilIdle(); |
| 283 Mock::VerifyAndClearExpectations(&mock_layer_tree_host_client_); |
| 284 EXPECT_FALSE(root_layer_->did_update()); |
| 285 EXPECT_EQ(0, compositor_proto_state_sink_->num_updates_received()); |
| 286 |
| 287 // Now enable commits and ensure we see a BeginMainFrame. |
| 288 layer_tree_host_->SetDeferCommits(false); |
| 289 InSequence s; |
| 290 int num_of_frames = 1; |
| 291 EXPECT_BEGIN_MAIN_FRAME_AND_COMMIT(mock_layer_tree_host_client_, |
| 292 num_of_frames); |
| 293 base::RunLoop().RunUntilIdle(); |
| 294 EXPECT_TRUE(root_layer_->did_update()); |
| 295 EXPECT_EQ(1, compositor_proto_state_sink_->num_updates_received()); |
| 296 } |
| 297 |
| 298 TEST_F(LayerTreeHostRemoteTest, RequestAnimateDuringMainFrame) { |
| 299 // An animate request during BeginMainFrame should result in a second main |
| 300 // frame being scheduled. |
| 301 set_needs_animate_during_main_frame(true); |
| 302 int num_of_frames = 2; |
| 303 EXPECT_BEGIN_MAIN_FRAME(mock_layer_tree_host_client_, num_of_frames); |
| 304 |
| 305 layer_tree_host_->SetNeedsAnimate(); |
| 306 |
| 307 base::RunLoop().RunUntilIdle(); |
| 308 EXPECT_FALSE(root_layer_->did_update()); |
| 309 EXPECT_EQ(0, compositor_proto_state_sink_->num_updates_received()); |
| 310 } |
| 311 |
| 312 TEST_F(LayerTreeHostRemoteTest, RequestCommitDuringMainFrame) { |
| 313 // A commit request during a BeginMainFrame scheduled for an animate request |
| 314 // should go till the commit stage. |
| 315 set_needs_commit_during_main_frame(true); |
| 316 int num_of_frames = 1; |
| 317 EXPECT_BEGIN_MAIN_FRAME_AND_COMMIT(mock_layer_tree_host_client_, |
| 318 num_of_frames); |
| 319 |
| 320 layer_tree_host_->SetNeedsAnimate(); |
| 321 |
| 322 base::RunLoop().RunUntilIdle(); |
| 323 EXPECT_TRUE(root_layer_->did_update()); |
| 324 EXPECT_EQ(1, compositor_proto_state_sink_->num_updates_received()); |
| 325 } |
| 326 |
| 327 TEST_F(LayerTreeHostRemoteTest, RequestCommitDuringLayerUpdates) { |
| 328 // A layer update during a main frame should result in a commit. |
| 329 scoped_refptr<Layer> child_layer = make_scoped_refptr(new MockLayer(true)); |
| 330 root_layer_->AddChild(child_layer); |
| 331 EXPECT_BEGIN_MAIN_FRAME_AND_COMMIT(mock_layer_tree_host_client_, 1); |
| 332 |
| 333 layer_tree_host_->SetNeedsUpdateLayers(); |
| 334 |
| 335 base::RunLoop().RunUntilIdle(); |
| 336 EXPECT_TRUE(root_layer_->did_update()); |
| 337 EXPECT_EQ(1, compositor_proto_state_sink_->num_updates_received()); |
| 338 } |
| 339 |
| 340 } // namespace |
| 341 } // namespace cc |
OLD | NEW |