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 |