| 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 <memory> | |
| 8 #include <unordered_set> | |
| 9 | |
| 10 #include "base/bind.h" | |
| 11 #include "base/memory/ptr_util.h" | |
| 12 #include "base/run_loop.h" | |
| 13 #include "base/threading/thread_task_runner_handle.h" | |
| 14 #include "cc/animation/animation_host.h" | |
| 15 #include "cc/layers/layer.h" | |
| 16 #include "cc/output/begin_frame_args.h" | |
| 17 #include "cc/proto/client_state_update.pb.h" | |
| 18 #include "cc/proto/compositor_message.pb.h" | |
| 19 #include "cc/proto/gfx_conversions.h" | |
| 20 #include "cc/test/fake_image_serialization_processor.h" | |
| 21 #include "cc/test/fake_remote_compositor_bridge.h" | |
| 22 #include "cc/test/stub_layer_tree_host_client.h" | |
| 23 #include "cc/trees/layer_tree_settings.h" | |
| 24 #include "testing/gmock/include/gmock/gmock.h" | |
| 25 #include "testing/gtest/include/gtest/gtest.h" | |
| 26 | |
| 27 using testing::InSequence; | |
| 28 using testing::Mock; | |
| 29 using testing::StrictMock; | |
| 30 | |
| 31 #define EXPECT_BEGIN_MAIN_FRAME(client, num) \ | |
| 32 EXPECT_CALL(client, WillBeginMainFrame()).Times(num); \ | |
| 33 EXPECT_CALL(client, DidReceiveBeginMainFrame()).Times(num); \ | |
| 34 EXPECT_CALL(client, DidUpdateLayerTreeHost()).Times(num); \ | |
| 35 EXPECT_CALL(client, WillCommit()).Times(num); \ | |
| 36 EXPECT_CALL(client, DidCommit()).Times(num); \ | |
| 37 EXPECT_CALL(client, DidBeginMainFrame()).Times(num); | |
| 38 | |
| 39 #define EXPECT_BEGIN_MAIN_FRAME_AND_COMMIT(client, num) \ | |
| 40 EXPECT_BEGIN_MAIN_FRAME(client, num) \ | |
| 41 EXPECT_CALL(client, DidCommitAndDrawFrame()).Times(num); \ | |
| 42 EXPECT_CALL(client, DidReceiveCompositorFrameAck()).Times(num); | |
| 43 | |
| 44 namespace cc { | |
| 45 namespace { | |
| 46 | |
| 47 gfx::Vector2dF SerializeScrollUpdate( | |
| 48 proto::ClientStateUpdate* client_state_update, | |
| 49 Layer* layer, | |
| 50 const gfx::ScrollOffset& offset_after_update) { | |
| 51 proto::ScrollUpdate* scroll_update = | |
| 52 client_state_update->add_scroll_updates(); | |
| 53 scroll_update->set_layer_id(layer->id()); | |
| 54 gfx::ScrollOffset scroll_delta = offset_after_update - layer->scroll_offset(); | |
| 55 gfx::Vector2dF scroll_delta_vector = | |
| 56 gfx::ScrollOffsetToVector2dF(scroll_delta); | |
| 57 Vector2dFToProto(scroll_delta_vector, scroll_update->mutable_scroll_delta()); | |
| 58 return scroll_delta_vector; | |
| 59 } | |
| 60 | |
| 61 class UpdateTrackingRemoteCompositorBridge : public FakeRemoteCompositorBridge { | |
| 62 public: | |
| 63 UpdateTrackingRemoteCompositorBridge( | |
| 64 scoped_refptr<base::SingleThreadTaskRunner> compositor_main_task_runner) | |
| 65 : FakeRemoteCompositorBridge(std::move(compositor_main_task_runner)) {} | |
| 66 | |
| 67 ~UpdateTrackingRemoteCompositorBridge() override = default; | |
| 68 | |
| 69 void ProcessCompositorStateUpdate( | |
| 70 std::unique_ptr<CompositorProtoState> compositor_proto_state) override { | |
| 71 num_updates_received_++; | |
| 72 compositor_proto_state_ = std::move(compositor_proto_state); | |
| 73 }; | |
| 74 | |
| 75 void SendUpdates(const proto::ClientStateUpdate& client_state_update) { | |
| 76 client_->ApplyStateUpdateFromClient(client_state_update); | |
| 77 } | |
| 78 | |
| 79 int num_updates_received() const { return num_updates_received_; } | |
| 80 | |
| 81 CompositorProtoState* compositor_proto_state() { | |
| 82 return compositor_proto_state_.get(); | |
| 83 } | |
| 84 | |
| 85 private: | |
| 86 int num_updates_received_ = 0; | |
| 87 std::unique_ptr<CompositorProtoState> compositor_proto_state_; | |
| 88 }; | |
| 89 | |
| 90 class MockLayerTreeHostClient : public StubLayerTreeHostClient { | |
| 91 public: | |
| 92 MockLayerTreeHostClient() = default; | |
| 93 ~MockLayerTreeHostClient() override = default; | |
| 94 | |
| 95 void set_update_host_callback(base::Closure callback) { | |
| 96 update_host_callback_ = callback; | |
| 97 } | |
| 98 | |
| 99 void UpdateLayerTreeHost() override { | |
| 100 update_host_callback_.Run(); | |
| 101 DidUpdateLayerTreeHost(); | |
| 102 } | |
| 103 | |
| 104 void BeginMainFrame(const BeginFrameArgs& args) override { | |
| 105 DidReceiveBeginMainFrame(); | |
| 106 } | |
| 107 | |
| 108 // LayerTreeHostClient implementation. | |
| 109 MOCK_METHOD0(WillBeginMainFrame, void()); | |
| 110 MOCK_METHOD0(DidBeginMainFrame, void()); | |
| 111 MOCK_METHOD0(DidReceiveBeginMainFrame, void()); | |
| 112 MOCK_METHOD0(DidUpdateLayerTreeHost, void()); | |
| 113 MOCK_METHOD5(ApplyViewportDeltas, | |
| 114 void(const gfx::Vector2dF&, | |
| 115 const gfx::Vector2dF&, | |
| 116 const gfx::Vector2dF&, | |
| 117 float, | |
| 118 float)); | |
| 119 MOCK_METHOD0(WillCommit, void()); | |
| 120 MOCK_METHOD0(DidCommit, void()); | |
| 121 MOCK_METHOD0(DidCommitAndDrawFrame, void()); | |
| 122 MOCK_METHOD0(DidReceiveCompositorFrameAck, void()); | |
| 123 | |
| 124 private: | |
| 125 base::Closure update_host_callback_; | |
| 126 }; | |
| 127 | |
| 128 class MockLayer : public Layer { | |
| 129 public: | |
| 130 explicit MockLayer(bool update) : update_(update) {} | |
| 131 | |
| 132 bool Update() override { | |
| 133 did_update_ = true; | |
| 134 return update_; | |
| 135 } | |
| 136 | |
| 137 bool did_update() const { return did_update_; } | |
| 138 | |
| 139 private: | |
| 140 ~MockLayer() override {} | |
| 141 | |
| 142 bool update_; | |
| 143 bool did_update_ = false; | |
| 144 }; | |
| 145 | |
| 146 class MockLayerTree : public LayerTree { | |
| 147 public: | |
| 148 MockLayerTree(MutatorHost* mutator_host, LayerTreeHost* layer_tree_host) | |
| 149 : LayerTree(mutator_host, layer_tree_host) {} | |
| 150 ~MockLayerTree() override {} | |
| 151 | |
| 152 // We don't want tree sync requests to trigger commits. | |
| 153 void SetNeedsFullTreeSync() override {} | |
| 154 }; | |
| 155 | |
| 156 class LayerTreeHostRemoteForTesting : public LayerTreeHostRemote { | |
| 157 public: | |
| 158 explicit LayerTreeHostRemoteForTesting(InitParams* params) | |
| 159 : LayerTreeHostRemote( | |
| 160 params, | |
| 161 base::MakeUnique<MockLayerTree>(params->mutator_host, this)) {} | |
| 162 ~LayerTreeHostRemoteForTesting() override {} | |
| 163 }; | |
| 164 | |
| 165 class LayerTreeHostRemoteTest : public testing::Test { | |
| 166 public: | |
| 167 LayerTreeHostRemoteTest() { | |
| 168 mock_layer_tree_host_client_.set_update_host_callback(base::Bind( | |
| 169 &LayerTreeHostRemoteTest::UpdateLayerTreeHost, base::Unretained(this))); | |
| 170 } | |
| 171 ~LayerTreeHostRemoteTest() override {} | |
| 172 | |
| 173 void SetUp() override { | |
| 174 animation_host_ = AnimationHost::CreateForTesting(ThreadInstance::MAIN); | |
| 175 | |
| 176 LayerTreeHostRemote::InitParams params; | |
| 177 params.client = &mock_layer_tree_host_client_; | |
| 178 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner = | |
| 179 base::ThreadTaskRunnerHandle::Get(); | |
| 180 params.main_task_runner = main_task_runner; | |
| 181 std::unique_ptr<UpdateTrackingRemoteCompositorBridge> | |
| 182 remote_compositor_bridge = | |
| 183 base::MakeUnique<UpdateTrackingRemoteCompositorBridge>( | |
| 184 main_task_runner); | |
| 185 remote_compositor_bridge_ = remote_compositor_bridge.get(); | |
| 186 params.remote_compositor_bridge = std::move(remote_compositor_bridge); | |
| 187 params.engine_picture_cache = | |
| 188 image_serialization_processor_.CreateEnginePictureCache(); | |
| 189 LayerTreeSettings settings; | |
| 190 params.settings = &settings; | |
| 191 params.mutator_host = animation_host_.get(); | |
| 192 layer_tree_host_ = base::MakeUnique<LayerTreeHostRemoteForTesting>(¶ms); | |
| 193 | |
| 194 // Make sure the root layer always updates. | |
| 195 root_layer_ = make_scoped_refptr(new MockLayer(false)); | |
| 196 root_layer_->SetIsDrawable(true); | |
| 197 root_layer_->SetBounds(gfx::Size(5, 10)); | |
| 198 layer_tree_host_->GetLayerTree()->SetRootLayer(root_layer_); | |
| 199 } | |
| 200 | |
| 201 void TearDown() override { | |
| 202 Mock::VerifyAndClearExpectations(&mock_layer_tree_host_client_); | |
| 203 layer_tree_host_ = nullptr; | |
| 204 root_layer_ = nullptr; | |
| 205 remote_compositor_bridge_ = nullptr; | |
| 206 } | |
| 207 | |
| 208 void UpdateLayerTreeHost() { | |
| 209 if (needs_animate_during_main_frame_) { | |
| 210 layer_tree_host_->SetNeedsAnimate(); | |
| 211 needs_animate_during_main_frame_ = false; | |
| 212 } | |
| 213 | |
| 214 if (needs_commit_during_main_frame_) { | |
| 215 layer_tree_host_->SetNeedsCommit(); | |
| 216 needs_commit_during_main_frame_ = false; | |
| 217 } | |
| 218 } | |
| 219 | |
| 220 void set_needs_animate_during_main_frame(bool needs) { | |
| 221 needs_animate_during_main_frame_ = needs; | |
| 222 } | |
| 223 | |
| 224 void set_needs_commit_during_main_frame(bool needs) { | |
| 225 needs_commit_during_main_frame_ = needs; | |
| 226 } | |
| 227 | |
| 228 protected: | |
| 229 std::unique_ptr<AnimationHost> animation_host_; | |
| 230 std::unique_ptr<LayerTreeHostRemote> layer_tree_host_; | |
| 231 StrictMock<MockLayerTreeHostClient> mock_layer_tree_host_client_; | |
| 232 UpdateTrackingRemoteCompositorBridge* remote_compositor_bridge_ = nullptr; | |
| 233 scoped_refptr<MockLayer> root_layer_; | |
| 234 FakeImageSerializationProcessor image_serialization_processor_; | |
| 235 | |
| 236 bool needs_animate_during_main_frame_ = false; | |
| 237 bool needs_commit_during_main_frame_ = false; | |
| 238 | |
| 239 private: | |
| 240 DISALLOW_COPY_AND_ASSIGN(LayerTreeHostRemoteTest); | |
| 241 }; | |
| 242 | |
| 243 TEST_F(LayerTreeHostRemoteTest, BeginMainFrameAnimateOnly) { | |
| 244 // The main frame should run until the animate step only. | |
| 245 InSequence s; | |
| 246 int num_of_frames = 1; | |
| 247 EXPECT_BEGIN_MAIN_FRAME(mock_layer_tree_host_client_, num_of_frames); | |
| 248 | |
| 249 int previous_source_frame = layer_tree_host_->SourceFrameNumber(); | |
| 250 layer_tree_host_->SetNeedsAnimate(); | |
| 251 | |
| 252 base::RunLoop().RunUntilIdle(); | |
| 253 EXPECT_FALSE(root_layer_->did_update()); | |
| 254 EXPECT_EQ(0, remote_compositor_bridge_->num_updates_received()); | |
| 255 EXPECT_EQ(++previous_source_frame, layer_tree_host_->SourceFrameNumber()); | |
| 256 } | |
| 257 | |
| 258 TEST_F(LayerTreeHostRemoteTest, BeginMainFrameUpdateLayers) { | |
| 259 // The main frame should run until the update layers step only. | |
| 260 InSequence s; | |
| 261 int num_of_frames = 1; | |
| 262 EXPECT_BEGIN_MAIN_FRAME(mock_layer_tree_host_client_, num_of_frames); | |
| 263 | |
| 264 int previous_source_frame = layer_tree_host_->SourceFrameNumber(); | |
| 265 layer_tree_host_->SetNeedsUpdateLayers(); | |
| 266 | |
| 267 base::RunLoop().RunUntilIdle(); | |
| 268 EXPECT_TRUE(root_layer_->did_update()); | |
| 269 EXPECT_EQ(0, remote_compositor_bridge_->num_updates_received()); | |
| 270 EXPECT_EQ(++previous_source_frame, layer_tree_host_->SourceFrameNumber()); | |
| 271 } | |
| 272 | |
| 273 TEST_F(LayerTreeHostRemoteTest, BeginMainFrameCommit) { | |
| 274 // The main frame should run until the commit step. | |
| 275 InSequence s; | |
| 276 int num_of_frames = 1; | |
| 277 EXPECT_BEGIN_MAIN_FRAME_AND_COMMIT(mock_layer_tree_host_client_, | |
| 278 num_of_frames); | |
| 279 | |
| 280 int previous_source_frame = layer_tree_host_->SourceFrameNumber(); | |
| 281 layer_tree_host_->SetNeedsCommit(); | |
| 282 | |
| 283 base::RunLoop().RunUntilIdle(); | |
| 284 EXPECT_TRUE(root_layer_->did_update()); | |
| 285 EXPECT_EQ(1, remote_compositor_bridge_->num_updates_received()); | |
| 286 EXPECT_EQ(++previous_source_frame, layer_tree_host_->SourceFrameNumber()); | |
| 287 } | |
| 288 | |
| 289 TEST_F(LayerTreeHostRemoteTest, BeginMainFrameMultipleRequests) { | |
| 290 // Multiple BeginMainFrame requests should result in a single main frame | |
| 291 // update. | |
| 292 InSequence s; | |
| 293 int num_of_frames = 1; | |
| 294 EXPECT_BEGIN_MAIN_FRAME_AND_COMMIT(mock_layer_tree_host_client_, | |
| 295 num_of_frames); | |
| 296 | |
| 297 layer_tree_host_->SetNeedsAnimate(); | |
| 298 layer_tree_host_->SetNeedsUpdateLayers(); | |
| 299 layer_tree_host_->SetNeedsCommit(); | |
| 300 | |
| 301 base::RunLoop().RunUntilIdle(); | |
| 302 EXPECT_TRUE(root_layer_->did_update()); | |
| 303 EXPECT_EQ(1, remote_compositor_bridge_->num_updates_received()); | |
| 304 } | |
| 305 | |
| 306 TEST_F(LayerTreeHostRemoteTest, CommitRequestThenDeferCommits) { | |
| 307 // Make a commit request, followed by a request to defer commits. | |
| 308 layer_tree_host_->SetNeedsCommit(); | |
| 309 layer_tree_host_->SetDeferCommits(true); | |
| 310 | |
| 311 // We should not have seen any BeginMainFrames. | |
| 312 base::RunLoop().RunUntilIdle(); | |
| 313 Mock::VerifyAndClearExpectations(&mock_layer_tree_host_client_); | |
| 314 EXPECT_FALSE(root_layer_->did_update()); | |
| 315 EXPECT_EQ(0, remote_compositor_bridge_->num_updates_received()); | |
| 316 | |
| 317 // Now enable commits and ensure we see a BeginMainFrame. | |
| 318 layer_tree_host_->SetDeferCommits(false); | |
| 319 InSequence s; | |
| 320 int num_of_frames = 1; | |
| 321 EXPECT_BEGIN_MAIN_FRAME_AND_COMMIT(mock_layer_tree_host_client_, | |
| 322 num_of_frames); | |
| 323 base::RunLoop().RunUntilIdle(); | |
| 324 EXPECT_TRUE(root_layer_->did_update()); | |
| 325 EXPECT_EQ(1, remote_compositor_bridge_->num_updates_received()); | |
| 326 } | |
| 327 | |
| 328 TEST_F(LayerTreeHostRemoteTest, DeferCommitsThenCommitRequest) { | |
| 329 // Defer commits followed by a commit request. | |
| 330 layer_tree_host_->SetDeferCommits(true); | |
| 331 layer_tree_host_->SetNeedsCommit(); | |
| 332 | |
| 333 // We should not have seen any BeginMainFrames. | |
| 334 base::RunLoop().RunUntilIdle(); | |
| 335 Mock::VerifyAndClearExpectations(&mock_layer_tree_host_client_); | |
| 336 EXPECT_FALSE(root_layer_->did_update()); | |
| 337 EXPECT_EQ(0, remote_compositor_bridge_->num_updates_received()); | |
| 338 | |
| 339 // Now enable commits and ensure we see a BeginMainFrame. | |
| 340 layer_tree_host_->SetDeferCommits(false); | |
| 341 InSequence s; | |
| 342 int num_of_frames = 1; | |
| 343 EXPECT_BEGIN_MAIN_FRAME_AND_COMMIT(mock_layer_tree_host_client_, | |
| 344 num_of_frames); | |
| 345 base::RunLoop().RunUntilIdle(); | |
| 346 EXPECT_TRUE(root_layer_->did_update()); | |
| 347 EXPECT_EQ(1, remote_compositor_bridge_->num_updates_received()); | |
| 348 } | |
| 349 | |
| 350 TEST_F(LayerTreeHostRemoteTest, RequestAnimateDuringMainFrame) { | |
| 351 // An animate request during BeginMainFrame should result in a second main | |
| 352 // frame being scheduled. | |
| 353 set_needs_animate_during_main_frame(true); | |
| 354 int num_of_frames = 2; | |
| 355 EXPECT_BEGIN_MAIN_FRAME(mock_layer_tree_host_client_, num_of_frames); | |
| 356 | |
| 357 layer_tree_host_->SetNeedsAnimate(); | |
| 358 | |
| 359 base::RunLoop().RunUntilIdle(); | |
| 360 EXPECT_FALSE(root_layer_->did_update()); | |
| 361 EXPECT_EQ(0, remote_compositor_bridge_->num_updates_received()); | |
| 362 } | |
| 363 | |
| 364 TEST_F(LayerTreeHostRemoteTest, RequestCommitDuringMainFrame) { | |
| 365 // A commit request during a BeginMainFrame scheduled for an animate request | |
| 366 // should go till the commit stage. | |
| 367 set_needs_commit_during_main_frame(true); | |
| 368 int num_of_frames = 1; | |
| 369 EXPECT_BEGIN_MAIN_FRAME_AND_COMMIT(mock_layer_tree_host_client_, | |
| 370 num_of_frames); | |
| 371 | |
| 372 layer_tree_host_->SetNeedsAnimate(); | |
| 373 | |
| 374 base::RunLoop().RunUntilIdle(); | |
| 375 EXPECT_TRUE(root_layer_->did_update()); | |
| 376 EXPECT_EQ(1, remote_compositor_bridge_->num_updates_received()); | |
| 377 } | |
| 378 | |
| 379 TEST_F(LayerTreeHostRemoteTest, RequestCommitDuringLayerUpdates) { | |
| 380 // A layer update during a main frame should result in a commit. | |
| 381 scoped_refptr<Layer> child_layer = make_scoped_refptr(new MockLayer(true)); | |
| 382 child_layer->SetIsDrawable(true); | |
| 383 child_layer->SetBounds(gfx::Size(5, 10)); | |
| 384 root_layer_->AddChild(child_layer); | |
| 385 EXPECT_BEGIN_MAIN_FRAME_AND_COMMIT(mock_layer_tree_host_client_, 1); | |
| 386 | |
| 387 layer_tree_host_->SetNeedsUpdateLayers(); | |
| 388 | |
| 389 base::RunLoop().RunUntilIdle(); | |
| 390 EXPECT_TRUE(root_layer_->did_update()); | |
| 391 EXPECT_EQ(1, remote_compositor_bridge_->num_updates_received()); | |
| 392 } | |
| 393 | |
| 394 TEST_F(LayerTreeHostRemoteTest, ScrollAndScaleSync) { | |
| 395 scoped_refptr<Layer> child_layer1 = make_scoped_refptr(new MockLayer(false)); | |
| 396 root_layer_->AddChild(child_layer1); | |
| 397 | |
| 398 scoped_refptr<Layer> child_layer2 = make_scoped_refptr(new MockLayer(false)); | |
| 399 child_layer1->AddChild(child_layer2); | |
| 400 child_layer2->SetScrollOffset(gfx::ScrollOffset(3, 9)); | |
| 401 | |
| 402 scoped_refptr<Layer> inner_viewport_layer = | |
| 403 make_scoped_refptr(new MockLayer(false)); | |
| 404 inner_viewport_layer->SetScrollOffset(gfx::ScrollOffset(5, 10)); | |
| 405 root_layer_->AddChild(inner_viewport_layer); | |
| 406 layer_tree_host_->GetLayerTree()->RegisterViewportLayers( | |
| 407 nullptr, nullptr, inner_viewport_layer, nullptr); | |
| 408 | |
| 409 // First test case. | |
| 410 gfx::ScrollOffset expected_child1_offset(4, 5); | |
| 411 gfx::ScrollOffset expected_child2_offset(3, 10); | |
| 412 gfx::ScrollOffset expected_inner_viewport_offset(-2, 5); | |
| 413 float expected_page_scale = 2.0f; | |
| 414 | |
| 415 proto::ClientStateUpdate client_state_update; | |
| 416 SerializeScrollUpdate(&client_state_update, child_layer1.get(), | |
| 417 expected_child1_offset); | |
| 418 SerializeScrollUpdate(&client_state_update, child_layer2.get(), | |
| 419 expected_child2_offset); | |
| 420 gfx::Vector2dF inner_viewport_delta = | |
| 421 SerializeScrollUpdate(&client_state_update, inner_viewport_layer.get(), | |
| 422 expected_inner_viewport_offset); | |
| 423 float page_scale_delta = | |
| 424 expected_page_scale / | |
| 425 layer_tree_host_->GetLayerTree()->page_scale_factor(); | |
| 426 client_state_update.set_page_scale_delta(page_scale_delta); | |
| 427 | |
| 428 EXPECT_CALL(mock_layer_tree_host_client_, | |
| 429 ApplyViewportDeltas(inner_viewport_delta, gfx::Vector2dF(), | |
| 430 gfx::Vector2dF(), page_scale_delta, 0.0f)) | |
| 431 .Times(1); | |
| 432 | |
| 433 remote_compositor_bridge_->SendUpdates(client_state_update); | |
| 434 | |
| 435 // The host should have pre-emtively applied the changes. | |
| 436 EXPECT_EQ(expected_page_scale, | |
| 437 layer_tree_host_->GetLayerTree()->page_scale_factor()); | |
| 438 EXPECT_EQ(expected_child1_offset, child_layer1->scroll_offset()); | |
| 439 EXPECT_EQ(expected_child2_offset, child_layer2->scroll_offset()); | |
| 440 EXPECT_EQ(expected_inner_viewport_offset, | |
| 441 inner_viewport_layer->scroll_offset()); | |
| 442 | |
| 443 // Remove a layer from the tree and send a scroll update for it. | |
| 444 child_layer1->RemoveAllChildren(); | |
| 445 proto::ClientStateUpdate client_state_update2; | |
| 446 SerializeScrollUpdate(&client_state_update2, child_layer2.get(), | |
| 447 gfx::ScrollOffset(9, 10)); | |
| 448 remote_compositor_bridge_->SendUpdates(client_state_update2); | |
| 449 } | |
| 450 | |
| 451 TEST_F(LayerTreeHostRemoteTest, IdentifiedLayersToSkipUpdates) { | |
| 452 EXPECT_BEGIN_MAIN_FRAME_AND_COMMIT(mock_layer_tree_host_client_, 1); | |
| 453 | |
| 454 scoped_refptr<MockLayer> non_drawable_layer = new MockLayer(true); | |
| 455 non_drawable_layer->SetIsDrawable(false); | |
| 456 non_drawable_layer->SetBounds(gfx::Size(5, 5)); | |
| 457 | |
| 458 scoped_refptr<MockLayer> empty_bound_layer = new MockLayer(true); | |
| 459 empty_bound_layer->SetIsDrawable(true); | |
| 460 empty_bound_layer->SetBounds(gfx::Size()); | |
| 461 | |
| 462 scoped_refptr<MockLayer> transparent_layer = new MockLayer(true); | |
| 463 transparent_layer->SetIsDrawable(true); | |
| 464 transparent_layer->SetBounds(gfx::Size(5, 5)); | |
| 465 transparent_layer->SetOpacity(0.f); | |
| 466 | |
| 467 scoped_refptr<MockLayer> updated_layer = new MockLayer(true); | |
| 468 updated_layer->SetIsDrawable(true); | |
| 469 updated_layer->SetBounds(gfx::Size(5, 5)); | |
| 470 | |
| 471 root_layer_->AddChild(non_drawable_layer); | |
| 472 root_layer_->AddChild(empty_bound_layer); | |
| 473 empty_bound_layer->SetMaskLayer(transparent_layer.get()); | |
| 474 empty_bound_layer->AddChild(updated_layer); | |
| 475 DCHECK(updated_layer->GetLayerTreeHostForTesting()); | |
| 476 | |
| 477 // Commit and serialize. | |
| 478 layer_tree_host_->SetNeedsCommit(); | |
| 479 base::RunLoop().RunUntilIdle(); | |
| 480 | |
| 481 // Only the updated_layer should have been updated. | |
| 482 EXPECT_FALSE(non_drawable_layer->did_update()); | |
| 483 EXPECT_FALSE(empty_bound_layer->did_update()); | |
| 484 EXPECT_FALSE(transparent_layer->did_update()); | |
| 485 EXPECT_TRUE(updated_layer->did_update()); | |
| 486 } | |
| 487 | |
| 488 TEST_F(LayerTreeHostRemoteTest, OnlyPushPropertiesOnChangingLayers) { | |
| 489 EXPECT_BEGIN_MAIN_FRAME_AND_COMMIT(mock_layer_tree_host_client_, 2); | |
| 490 | |
| 491 // Setup a tree with 3 nodes. | |
| 492 scoped_refptr<Layer> child_layer = Layer::Create(); | |
| 493 scoped_refptr<Layer> grandchild_layer = Layer::Create(); | |
| 494 root_layer_->AddChild(child_layer); | |
| 495 child_layer->AddChild(grandchild_layer); | |
| 496 layer_tree_host_->SetNeedsCommit(); | |
| 497 | |
| 498 base::RunLoop().RunUntilIdle(); | |
| 499 | |
| 500 // Ensure the first proto contains all layer updates. | |
| 501 EXPECT_EQ(1, remote_compositor_bridge_->num_updates_received()); | |
| 502 CompositorProtoState* compositor_proto_state = | |
| 503 remote_compositor_bridge_->compositor_proto_state(); | |
| 504 const proto::LayerUpdate& layer_updates_first_commit = | |
| 505 compositor_proto_state->compositor_message->layer_tree_host() | |
| 506 .layer_updates(); | |
| 507 | |
| 508 std::unordered_set<int> layer_updates_id_set; | |
| 509 for (int i = 0; i < layer_updates_first_commit.layers_size(); ++i) { | |
| 510 layer_updates_id_set.insert(layer_updates_first_commit.layers(i).id()); | |
| 511 } | |
| 512 | |
| 513 EXPECT_TRUE(layer_updates_id_set.find(root_layer_->id()) != | |
| 514 layer_updates_id_set.end()); | |
| 515 EXPECT_TRUE(layer_updates_id_set.find(child_layer->id()) != | |
| 516 layer_updates_id_set.end()); | |
| 517 EXPECT_TRUE(layer_updates_id_set.find(grandchild_layer->id()) != | |
| 518 layer_updates_id_set.end()); | |
| 519 EXPECT_EQ(3, layer_updates_first_commit.layers_size()); | |
| 520 | |
| 521 // Modify the |child_layer|, and run the second frame. | |
| 522 child_layer->SetNeedsPushProperties(); | |
| 523 layer_tree_host_->SetNeedsCommit(); | |
| 524 base::RunLoop().RunUntilIdle(); | |
| 525 | |
| 526 // Ensure the second proto only contains |child_layer|. | |
| 527 EXPECT_EQ(2, remote_compositor_bridge_->num_updates_received()); | |
| 528 compositor_proto_state = remote_compositor_bridge_->compositor_proto_state(); | |
| 529 DCHECK(compositor_proto_state); | |
| 530 const proto::LayerUpdate& layer_updates_second_commit = | |
| 531 compositor_proto_state->compositor_message->layer_tree_host() | |
| 532 .layer_updates(); | |
| 533 EXPECT_EQ(1, layer_updates_second_commit.layers_size()); | |
| 534 EXPECT_EQ(child_layer->id(), layer_updates_second_commit.layers(0).id()); | |
| 535 } | |
| 536 | |
| 537 } // namespace | |
| 538 } // namespace cc | |
| OLD | NEW |