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/layers/layer.h" |
| 12 #include "cc/output/begin_frame_args.h" |
| 13 #include "cc/test/fake_remote_compositor_bridge.h" |
| 14 #include "cc/test/stub_layer_tree_host_client.h" |
| 15 #include "cc/trees/layer_tree_settings.h" |
| 16 #include "testing/gmock/include/gmock/gmock.h" |
| 17 #include "testing/gtest/include/gtest/gtest.h" |
| 18 |
| 19 using testing::InSequence; |
| 20 using testing::Mock; |
| 21 using testing::StrictMock; |
| 22 |
| 23 #define EXPECT_BEGIN_MAIN_FRAME(client, num) \ |
| 24 EXPECT_CALL(client, WillBeginMainFrame()).Times(num); \ |
| 25 EXPECT_CALL(client, DidReceiveBeginMainFrame()).Times(num); \ |
| 26 EXPECT_CALL(client, DidUpdateLayerTreeHost()).Times(num); \ |
| 27 EXPECT_CALL(client, WillCommit()).Times(num); \ |
| 28 EXPECT_CALL(client, DidCommit()).Times(num); \ |
| 29 EXPECT_CALL(client, DidBeginMainFrame()).Times(num); |
| 30 |
| 31 #define EXPECT_BEGIN_MAIN_FRAME_AND_COMMIT(client, num) \ |
| 32 EXPECT_BEGIN_MAIN_FRAME(client, num) \ |
| 33 EXPECT_CALL(client, DidCommitAndDrawFrame()).Times(num); \ |
| 34 EXPECT_CALL(client, DidCompleteSwapBuffers()).Times(num); |
| 35 |
| 36 namespace cc { |
| 37 namespace { |
| 38 |
| 39 class UpdateTrackingRemoteCompositorBridge : public FakeRemoteCompositorBridge { |
| 40 public: |
| 41 UpdateTrackingRemoteCompositorBridge( |
| 42 scoped_refptr<base::SingleThreadTaskRunner> compositor_main_task_runner) |
| 43 : FakeRemoteCompositorBridge(std::move(compositor_main_task_runner)) {} |
| 44 |
| 45 ~UpdateTrackingRemoteCompositorBridge() 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 void BeginMainFrame(const BeginFrameArgs& args) override { |
| 73 DidReceiveBeginMainFrame(); |
| 74 } |
| 75 |
| 76 // LayerTreeHostClient implementation. |
| 77 MOCK_METHOD0(WillBeginMainFrame, void()); |
| 78 MOCK_METHOD0(DidBeginMainFrame, void()); |
| 79 MOCK_METHOD0(DidReceiveBeginMainFrame, void()); |
| 80 MOCK_METHOD0(DidUpdateLayerTreeHost, void()); |
| 81 MOCK_METHOD0(WillCommit, void()); |
| 82 MOCK_METHOD0(DidCommit, void()); |
| 83 MOCK_METHOD0(DidCommitAndDrawFrame, void()); |
| 84 MOCK_METHOD0(DidCompleteSwapBuffers, void()); |
| 85 |
| 86 private: |
| 87 base::Closure update_host_callback_; |
| 88 }; |
| 89 |
| 90 class MockLayer : public Layer { |
| 91 public: |
| 92 explicit MockLayer(bool update) : update_(update) {} |
| 93 |
| 94 bool Update() override { |
| 95 did_update_ = true; |
| 96 return update_; |
| 97 } |
| 98 |
| 99 bool did_update() const { return did_update_; } |
| 100 |
| 101 private: |
| 102 ~MockLayer() override {} |
| 103 |
| 104 bool update_; |
| 105 bool did_update_ = false; |
| 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. |
| 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 mock_layer_tree_host_client_.set_update_host_callback(base::Bind( |
| 133 &LayerTreeHostRemoteTest::UpdateLayerTreeHost, base::Unretained(this))); |
| 134 } |
| 135 ~LayerTreeHostRemoteTest() override {} |
| 136 |
| 137 void SetUp() override { |
| 138 LayerTreeHostRemote::InitParams params; |
| 139 params.client = &mock_layer_tree_host_client_; |
| 140 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner = |
| 141 base::ThreadTaskRunnerHandle::Get(); |
| 142 params.main_task_runner = main_task_runner; |
| 143 std::unique_ptr<UpdateTrackingRemoteCompositorBridge> |
| 144 remote_compositor_bridge = |
| 145 base::MakeUnique<UpdateTrackingRemoteCompositorBridge>( |
| 146 main_task_runner); |
| 147 remote_compositor_bridge_ = remote_compositor_bridge.get(); |
| 148 params.remote_compositor_bridge = std::move(remote_compositor_bridge); |
| 149 LayerTreeSettings settings; |
| 150 params.settings = &settings; |
| 151 |
| 152 layer_tree_host_ = base::MakeUnique<LayerTreeHostRemoteForTesting>(¶ms); |
| 153 root_layer_ = make_scoped_refptr(new MockLayer(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_ = nullptr; |
| 160 root_layer_ = nullptr; |
| 161 remote_compositor_bridge_ = 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 UpdateTrackingRemoteCompositorBridge* remote_compositor_bridge_ = nullptr; |
| 188 scoped_refptr<MockLayer> root_layer_; |
| 189 |
| 190 bool needs_animate_during_main_frame_ = false; |
| 191 bool needs_commit_during_main_frame_ = false; |
| 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 int num_of_frames = 1; |
| 201 EXPECT_BEGIN_MAIN_FRAME(mock_layer_tree_host_client_, num_of_frames); |
| 202 |
| 203 int previous_source_frame = layer_tree_host_->SourceFrameNumber(); |
| 204 layer_tree_host_->SetNeedsAnimate(); |
| 205 |
| 206 base::RunLoop().RunUntilIdle(); |
| 207 EXPECT_FALSE(root_layer_->did_update()); |
| 208 EXPECT_EQ(0, remote_compositor_bridge_->num_updates_received()); |
| 209 EXPECT_EQ(++previous_source_frame, layer_tree_host_->SourceFrameNumber()); |
| 210 } |
| 211 |
| 212 TEST_F(LayerTreeHostRemoteTest, BeginMainFrameUpdateLayers) { |
| 213 // The main frame should run until the update layers step only. |
| 214 InSequence s; |
| 215 int num_of_frames = 1; |
| 216 EXPECT_BEGIN_MAIN_FRAME(mock_layer_tree_host_client_, num_of_frames); |
| 217 |
| 218 int previous_source_frame = layer_tree_host_->SourceFrameNumber(); |
| 219 layer_tree_host_->SetNeedsUpdateLayers(); |
| 220 |
| 221 base::RunLoop().RunUntilIdle(); |
| 222 EXPECT_TRUE(root_layer_->did_update()); |
| 223 EXPECT_EQ(0, remote_compositor_bridge_->num_updates_received()); |
| 224 EXPECT_EQ(++previous_source_frame, layer_tree_host_->SourceFrameNumber()); |
| 225 } |
| 226 |
| 227 TEST_F(LayerTreeHostRemoteTest, BeginMainFrameCommit) { |
| 228 // The main frame should run until the commit step. |
| 229 InSequence s; |
| 230 int num_of_frames = 1; |
| 231 EXPECT_BEGIN_MAIN_FRAME_AND_COMMIT(mock_layer_tree_host_client_, |
| 232 num_of_frames); |
| 233 |
| 234 int previous_source_frame = layer_tree_host_->SourceFrameNumber(); |
| 235 layer_tree_host_->SetNeedsCommit(); |
| 236 |
| 237 base::RunLoop().RunUntilIdle(); |
| 238 EXPECT_TRUE(root_layer_->did_update()); |
| 239 EXPECT_EQ(1, remote_compositor_bridge_->num_updates_received()); |
| 240 EXPECT_EQ(++previous_source_frame, layer_tree_host_->SourceFrameNumber()); |
| 241 } |
| 242 |
| 243 TEST_F(LayerTreeHostRemoteTest, BeginMainFrameMultipleRequests) { |
| 244 // Multiple BeginMainFrame requests should result in a single main frame |
| 245 // update. |
| 246 InSequence s; |
| 247 int num_of_frames = 1; |
| 248 EXPECT_BEGIN_MAIN_FRAME_AND_COMMIT(mock_layer_tree_host_client_, |
| 249 num_of_frames); |
| 250 |
| 251 layer_tree_host_->SetNeedsAnimate(); |
| 252 layer_tree_host_->SetNeedsUpdateLayers(); |
| 253 layer_tree_host_->SetNeedsCommit(); |
| 254 |
| 255 base::RunLoop().RunUntilIdle(); |
| 256 EXPECT_TRUE(root_layer_->did_update()); |
| 257 EXPECT_EQ(1, remote_compositor_bridge_->num_updates_received()); |
| 258 } |
| 259 |
| 260 TEST_F(LayerTreeHostRemoteTest, CommitRequestThenDeferCommits) { |
| 261 // Make a commit request, followed by a request to defer commits. |
| 262 layer_tree_host_->SetNeedsCommit(); |
| 263 layer_tree_host_->SetDeferCommits(true); |
| 264 |
| 265 // We should not have seen any BeginMainFrames. |
| 266 base::RunLoop().RunUntilIdle(); |
| 267 Mock::VerifyAndClearExpectations(&mock_layer_tree_host_client_); |
| 268 EXPECT_FALSE(root_layer_->did_update()); |
| 269 EXPECT_EQ(0, remote_compositor_bridge_->num_updates_received()); |
| 270 |
| 271 // Now enable commits and ensure we see a BeginMainFrame. |
| 272 layer_tree_host_->SetDeferCommits(false); |
| 273 InSequence s; |
| 274 int num_of_frames = 1; |
| 275 EXPECT_BEGIN_MAIN_FRAME_AND_COMMIT(mock_layer_tree_host_client_, |
| 276 num_of_frames); |
| 277 base::RunLoop().RunUntilIdle(); |
| 278 EXPECT_TRUE(root_layer_->did_update()); |
| 279 EXPECT_EQ(1, remote_compositor_bridge_->num_updates_received()); |
| 280 } |
| 281 |
| 282 TEST_F(LayerTreeHostRemoteTest, DeferCommitsThenCommitRequest) { |
| 283 // Defer commits followed by a commit request. |
| 284 layer_tree_host_->SetDeferCommits(true); |
| 285 layer_tree_host_->SetNeedsCommit(); |
| 286 |
| 287 // We should not have seen any BeginMainFrames. |
| 288 base::RunLoop().RunUntilIdle(); |
| 289 Mock::VerifyAndClearExpectations(&mock_layer_tree_host_client_); |
| 290 EXPECT_FALSE(root_layer_->did_update()); |
| 291 EXPECT_EQ(0, remote_compositor_bridge_->num_updates_received()); |
| 292 |
| 293 // Now enable commits and ensure we see a BeginMainFrame. |
| 294 layer_tree_host_->SetDeferCommits(false); |
| 295 InSequence s; |
| 296 int num_of_frames = 1; |
| 297 EXPECT_BEGIN_MAIN_FRAME_AND_COMMIT(mock_layer_tree_host_client_, |
| 298 num_of_frames); |
| 299 base::RunLoop().RunUntilIdle(); |
| 300 EXPECT_TRUE(root_layer_->did_update()); |
| 301 EXPECT_EQ(1, remote_compositor_bridge_->num_updates_received()); |
| 302 } |
| 303 |
| 304 TEST_F(LayerTreeHostRemoteTest, RequestAnimateDuringMainFrame) { |
| 305 // An animate request during BeginMainFrame should result in a second main |
| 306 // frame being scheduled. |
| 307 set_needs_animate_during_main_frame(true); |
| 308 int num_of_frames = 2; |
| 309 EXPECT_BEGIN_MAIN_FRAME(mock_layer_tree_host_client_, num_of_frames); |
| 310 |
| 311 layer_tree_host_->SetNeedsAnimate(); |
| 312 |
| 313 base::RunLoop().RunUntilIdle(); |
| 314 EXPECT_FALSE(root_layer_->did_update()); |
| 315 EXPECT_EQ(0, remote_compositor_bridge_->num_updates_received()); |
| 316 } |
| 317 |
| 318 TEST_F(LayerTreeHostRemoteTest, RequestCommitDuringMainFrame) { |
| 319 // A commit request during a BeginMainFrame scheduled for an animate request |
| 320 // should go till the commit stage. |
| 321 set_needs_commit_during_main_frame(true); |
| 322 int num_of_frames = 1; |
| 323 EXPECT_BEGIN_MAIN_FRAME_AND_COMMIT(mock_layer_tree_host_client_, |
| 324 num_of_frames); |
| 325 |
| 326 layer_tree_host_->SetNeedsAnimate(); |
| 327 |
| 328 base::RunLoop().RunUntilIdle(); |
| 329 EXPECT_TRUE(root_layer_->did_update()); |
| 330 EXPECT_EQ(1, remote_compositor_bridge_->num_updates_received()); |
| 331 } |
| 332 |
| 333 TEST_F(LayerTreeHostRemoteTest, RequestCommitDuringLayerUpdates) { |
| 334 // A layer update during a main frame should result in a commit. |
| 335 scoped_refptr<Layer> child_layer = make_scoped_refptr(new MockLayer(true)); |
| 336 root_layer_->AddChild(child_layer); |
| 337 EXPECT_BEGIN_MAIN_FRAME_AND_COMMIT(mock_layer_tree_host_client_, 1); |
| 338 |
| 339 layer_tree_host_->SetNeedsUpdateLayers(); |
| 340 |
| 341 base::RunLoop().RunUntilIdle(); |
| 342 EXPECT_TRUE(root_layer_->did_update()); |
| 343 EXPECT_EQ(1, remote_compositor_bridge_->num_updates_received()); |
| 344 } |
| 345 |
| 346 } // namespace |
| 347 } // namespace cc |
OLD | NEW |