Support HTTP/2 drafts 14 and 15 simultaneously.
[chromium-blink-merge.git] / cc / trees / tree_synchronizer_unittest.cc
blobd48f8213c7081c6cbfd4d0a21e6a5a4b0ca442c0
1 // Copyright 2011 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.
5 #include "cc/trees/tree_synchronizer.h"
7 #include <algorithm>
8 #include <set>
9 #include <vector>
11 #include "base/format_macros.h"
12 #include "base/strings/stringprintf.h"
13 #include "cc/animation/layer_animation_controller.h"
14 #include "cc/layers/layer.h"
15 #include "cc/layers/layer_impl.h"
16 #include "cc/test/animation_test_common.h"
17 #include "cc/test/fake_impl_proxy.h"
18 #include "cc/test/fake_layer_tree_host.h"
19 #include "cc/test/fake_rendering_stats_instrumentation.h"
20 #include "cc/test/test_shared_bitmap_manager.h"
21 #include "cc/trees/proxy.h"
22 #include "cc/trees/single_thread_proxy.h"
23 #include "testing/gtest/include/gtest/gtest.h"
25 namespace cc {
26 namespace {
28 class MockLayerImpl : public LayerImpl {
29 public:
30 static scoped_ptr<MockLayerImpl> Create(LayerTreeImpl* tree_impl,
31 int layer_id) {
32 return make_scoped_ptr(new MockLayerImpl(tree_impl, layer_id));
34 ~MockLayerImpl() override {
35 if (layer_impl_destruction_list_)
36 layer_impl_destruction_list_->push_back(id());
39 void SetLayerImplDestructionList(std::vector<int>* list) {
40 layer_impl_destruction_list_ = list;
43 private:
44 MockLayerImpl(LayerTreeImpl* tree_impl, int layer_id)
45 : LayerImpl(tree_impl, layer_id),
46 layer_impl_destruction_list_(NULL) {}
48 std::vector<int>* layer_impl_destruction_list_;
51 class MockLayer : public Layer {
52 public:
53 static scoped_refptr<MockLayer> Create(
54 std::vector<int>* layer_impl_destruction_list) {
55 return make_scoped_refptr(new MockLayer(layer_impl_destruction_list));
58 scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override {
59 return MockLayerImpl::Create(tree_impl, layer_id_);
62 void PushPropertiesTo(LayerImpl* layer_impl) override {
63 Layer::PushPropertiesTo(layer_impl);
65 MockLayerImpl* mock_layer_impl = static_cast<MockLayerImpl*>(layer_impl);
66 mock_layer_impl->SetLayerImplDestructionList(layer_impl_destruction_list_);
69 private:
70 explicit MockLayer(std::vector<int>* layer_impl_destruction_list)
71 : Layer(), layer_impl_destruction_list_(layer_impl_destruction_list) {}
72 ~MockLayer() override {}
74 std::vector<int>* layer_impl_destruction_list_;
77 class FakeLayerAnimationController : public LayerAnimationController {
78 public:
79 static scoped_refptr<LayerAnimationController> Create() {
80 return static_cast<LayerAnimationController*>(
81 new FakeLayerAnimationController);
84 bool SynchronizedAnimations() const { return synchronized_animations_; }
86 private:
87 FakeLayerAnimationController()
88 : LayerAnimationController(1),
89 synchronized_animations_(false) {}
91 ~FakeLayerAnimationController() override {}
93 void PushAnimationUpdatesTo(
94 LayerAnimationController* controller_impl) override {
95 LayerAnimationController::PushAnimationUpdatesTo(controller_impl);
96 synchronized_animations_ = true;
99 bool synchronized_animations_;
102 void ExpectTreesAreIdentical(Layer* layer,
103 LayerImpl* layer_impl,
104 LayerTreeImpl* tree_impl) {
105 ASSERT_TRUE(layer);
106 ASSERT_TRUE(layer_impl);
108 EXPECT_EQ(layer->id(), layer_impl->id());
109 EXPECT_EQ(layer_impl->layer_tree_impl(), tree_impl);
111 EXPECT_EQ(layer->non_fast_scrollable_region(),
112 layer_impl->non_fast_scrollable_region());
114 ASSERT_EQ(!!layer->mask_layer(), !!layer_impl->mask_layer());
115 if (layer->mask_layer()) {
116 SCOPED_TRACE("mask_layer");
117 ExpectTreesAreIdentical(
118 layer->mask_layer(), layer_impl->mask_layer(), tree_impl);
121 ASSERT_EQ(!!layer->replica_layer(), !!layer_impl->replica_layer());
122 if (layer->replica_layer()) {
123 SCOPED_TRACE("replica_layer");
124 ExpectTreesAreIdentical(
125 layer->replica_layer(), layer_impl->replica_layer(), tree_impl);
128 const LayerList& layer_children = layer->children();
129 const OwnedLayerImplList& layer_impl_children = layer_impl->children();
131 ASSERT_EQ(layer_children.size(), layer_impl_children.size());
133 const std::set<Layer*>* layer_scroll_children = layer->scroll_children();
134 const std::set<LayerImpl*>* layer_impl_scroll_children =
135 layer_impl->scroll_children();
137 ASSERT_EQ(!!layer_scroll_children, !!layer_impl_scroll_children);
139 if (layer_scroll_children) {
140 ASSERT_EQ(
141 layer_scroll_children->size(),
142 layer_impl_scroll_children->size());
145 const Layer* layer_scroll_parent = layer->scroll_parent();
146 const LayerImpl* layer_impl_scroll_parent = layer_impl->scroll_parent();
148 ASSERT_EQ(!!layer_scroll_parent, !!layer_impl_scroll_parent);
150 if (layer_scroll_parent) {
151 ASSERT_EQ(layer_scroll_parent->id(), layer_impl_scroll_parent->id());
152 ASSERT_TRUE(layer_scroll_parent->scroll_children()->find(layer) !=
153 layer_scroll_parent->scroll_children()->end());
154 ASSERT_TRUE(layer_impl_scroll_parent->scroll_children()->find(layer_impl) !=
155 layer_impl_scroll_parent->scroll_children()->end());
158 const std::set<Layer*>* layer_clip_children = layer->clip_children();
159 const std::set<LayerImpl*>* layer_impl_clip_children =
160 layer_impl->clip_children();
162 ASSERT_EQ(!!layer_clip_children, !!layer_impl_clip_children);
164 if (layer_clip_children)
165 ASSERT_EQ(layer_clip_children->size(), layer_impl_clip_children->size());
167 const Layer* layer_clip_parent = layer->clip_parent();
168 const LayerImpl* layer_impl_clip_parent = layer_impl->clip_parent();
170 ASSERT_EQ(!!layer_clip_parent, !!layer_impl_clip_parent);
172 if (layer_clip_parent) {
173 const std::set<LayerImpl*>* clip_children_impl =
174 layer_impl_clip_parent->clip_children();
175 const std::set<Layer*>* clip_children =
176 layer_clip_parent->clip_children();
177 ASSERT_EQ(layer_clip_parent->id(), layer_impl_clip_parent->id());
178 ASSERT_TRUE(clip_children->find(layer) != clip_children->end());
179 ASSERT_TRUE(clip_children_impl->find(layer_impl) !=
180 clip_children_impl->end());
183 for (size_t i = 0; i < layer_children.size(); ++i) {
184 SCOPED_TRACE(base::StringPrintf("child layer %" PRIuS, i).c_str());
185 ExpectTreesAreIdentical(
186 layer_children[i].get(), layer_impl_children[i], tree_impl);
190 class TreeSynchronizerTest : public testing::Test {
191 public:
192 TreeSynchronizerTest()
193 : client_(FakeLayerTreeHostClient::DIRECT_3D),
194 host_(FakeLayerTreeHost::Create(&client_)) {}
196 protected:
197 FakeLayerTreeHostClient client_;
198 scoped_ptr<FakeLayerTreeHost> host_;
201 // Attempts to synchronizes a null tree. This should not crash, and should
202 // return a null tree.
203 TEST_F(TreeSynchronizerTest, SyncNullTree) {
204 scoped_ptr<LayerImpl> layer_impl_tree_root =
205 TreeSynchronizer::SynchronizeTrees(
206 static_cast<Layer*>(NULL), nullptr, host_->active_tree());
208 EXPECT_TRUE(!layer_impl_tree_root.get());
211 // Constructs a very simple tree and synchronizes it without trying to reuse any
212 // preexisting layers.
213 TEST_F(TreeSynchronizerTest, SyncSimpleTreeFromEmpty) {
214 scoped_refptr<Layer> layer_tree_root = Layer::Create();
215 layer_tree_root->AddChild(Layer::Create());
216 layer_tree_root->AddChild(Layer::Create());
218 host_->SetRootLayer(layer_tree_root);
220 scoped_ptr<LayerImpl> layer_impl_tree_root =
221 TreeSynchronizer::SynchronizeTrees(
222 layer_tree_root.get(), nullptr, host_->active_tree());
224 ExpectTreesAreIdentical(layer_tree_root.get(),
225 layer_impl_tree_root.get(),
226 host_->active_tree());
229 // Constructs a very simple tree and synchronizes it attempting to reuse some
230 // layers
231 TEST_F(TreeSynchronizerTest, SyncSimpleTreeReusingLayers) {
232 std::vector<int> layer_impl_destruction_list;
234 scoped_refptr<Layer> layer_tree_root =
235 MockLayer::Create(&layer_impl_destruction_list);
236 layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list));
237 layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list));
239 host_->SetRootLayer(layer_tree_root);
241 scoped_ptr<LayerImpl> layer_impl_tree_root =
242 TreeSynchronizer::SynchronizeTrees(
243 layer_tree_root.get(), nullptr, host_->active_tree());
244 ExpectTreesAreIdentical(layer_tree_root.get(),
245 layer_impl_tree_root.get(),
246 host_->active_tree());
248 // We have to push properties to pick up the destruction list pointer.
249 TreeSynchronizer::PushProperties(layer_tree_root.get(),
250 layer_impl_tree_root.get());
252 // Add a new layer to the Layer side
253 layer_tree_root->children()[0]->
254 AddChild(MockLayer::Create(&layer_impl_destruction_list));
255 // Remove one.
256 layer_tree_root->children()[1]->RemoveFromParent();
257 int second_layer_impl_id = layer_impl_tree_root->children()[1]->id();
259 // Synchronize again. After the sync the trees should be equivalent and we
260 // should have created and destroyed one LayerImpl.
261 layer_impl_tree_root =
262 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
263 layer_impl_tree_root.Pass(),
264 host_->active_tree());
265 ExpectTreesAreIdentical(layer_tree_root.get(),
266 layer_impl_tree_root.get(),
267 host_->active_tree());
269 ASSERT_EQ(1u, layer_impl_destruction_list.size());
270 EXPECT_EQ(second_layer_impl_id, layer_impl_destruction_list[0]);
273 // Constructs a very simple tree and checks that a stacking-order change is
274 // tracked properly.
275 TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndTrackStackingOrderChange) {
276 std::vector<int> layer_impl_destruction_list;
278 // Set up the tree and sync once. child2 needs to be synced here, too, even
279 // though we remove it to set up the intended scenario.
280 scoped_refptr<Layer> layer_tree_root =
281 MockLayer::Create(&layer_impl_destruction_list);
282 scoped_refptr<Layer> child2 = MockLayer::Create(&layer_impl_destruction_list);
283 layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list));
284 layer_tree_root->AddChild(child2);
286 host_->SetRootLayer(layer_tree_root);
288 scoped_ptr<LayerImpl> layer_impl_tree_root =
289 TreeSynchronizer::SynchronizeTrees(
290 layer_tree_root.get(), nullptr, host_->active_tree());
291 ExpectTreesAreIdentical(layer_tree_root.get(),
292 layer_impl_tree_root.get(),
293 host_->active_tree());
295 // We have to push properties to pick up the destruction list pointer.
296 TreeSynchronizer::PushProperties(layer_tree_root.get(),
297 layer_impl_tree_root.get());
299 layer_impl_tree_root->ResetAllChangeTrackingForSubtree();
301 // re-insert the layer and sync again.
302 child2->RemoveFromParent();
303 layer_tree_root->AddChild(child2);
304 layer_impl_tree_root =
305 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
306 layer_impl_tree_root.Pass(),
307 host_->active_tree());
308 ExpectTreesAreIdentical(layer_tree_root.get(),
309 layer_impl_tree_root.get(),
310 host_->active_tree());
312 TreeSynchronizer::PushProperties(layer_tree_root.get(),
313 layer_impl_tree_root.get());
315 // Check that the impl thread properly tracked the change.
316 EXPECT_FALSE(layer_impl_tree_root->LayerPropertyChanged());
317 EXPECT_FALSE(layer_impl_tree_root->children()[0]->LayerPropertyChanged());
318 EXPECT_TRUE(layer_impl_tree_root->children()[1]->LayerPropertyChanged());
321 TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndProperties) {
322 scoped_refptr<Layer> layer_tree_root = Layer::Create();
323 layer_tree_root->AddChild(Layer::Create());
324 layer_tree_root->AddChild(Layer::Create());
326 host_->SetRootLayer(layer_tree_root);
328 // Pick some random properties to set. The values are not important, we're
329 // just testing that at least some properties are making it through.
330 gfx::PointF root_position = gfx::PointF(2.3f, 7.4f);
331 layer_tree_root->SetPosition(root_position);
333 float first_child_opacity = 0.25f;
334 layer_tree_root->children()[0]->SetOpacity(first_child_opacity);
336 gfx::Size second_child_bounds = gfx::Size(25, 53);
337 layer_tree_root->children()[1]->SetBounds(second_child_bounds);
338 layer_tree_root->children()[1]->SavePaintProperties();
340 scoped_ptr<LayerImpl> layer_impl_tree_root =
341 TreeSynchronizer::SynchronizeTrees(
342 layer_tree_root.get(), nullptr, host_->active_tree());
343 ExpectTreesAreIdentical(layer_tree_root.get(),
344 layer_impl_tree_root.get(),
345 host_->active_tree());
347 TreeSynchronizer::PushProperties(layer_tree_root.get(),
348 layer_impl_tree_root.get());
350 // Check that the property values we set on the Layer tree are reflected in
351 // the LayerImpl tree.
352 gfx::PointF root_layer_impl_position = layer_impl_tree_root->position();
353 EXPECT_EQ(root_position.x(), root_layer_impl_position.x());
354 EXPECT_EQ(root_position.y(), root_layer_impl_position.y());
356 EXPECT_EQ(first_child_opacity,
357 layer_impl_tree_root->children()[0]->opacity());
359 gfx::Size second_layer_impl_child_bounds =
360 layer_impl_tree_root->children()[1]->bounds();
361 EXPECT_EQ(second_child_bounds.width(),
362 second_layer_impl_child_bounds.width());
363 EXPECT_EQ(second_child_bounds.height(),
364 second_layer_impl_child_bounds.height());
367 TEST_F(TreeSynchronizerTest, ReuseLayerImplsAfterStructuralChange) {
368 std::vector<int> layer_impl_destruction_list;
370 // Set up a tree with this sort of structure:
371 // root --- A --- B ---+--- C
372 // |
373 // +--- D
374 scoped_refptr<Layer> layer_tree_root =
375 MockLayer::Create(&layer_impl_destruction_list);
376 layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list));
378 scoped_refptr<Layer> layer_a = layer_tree_root->children()[0].get();
379 layer_a->AddChild(MockLayer::Create(&layer_impl_destruction_list));
381 scoped_refptr<Layer> layer_b = layer_a->children()[0].get();
382 layer_b->AddChild(MockLayer::Create(&layer_impl_destruction_list));
384 scoped_refptr<Layer> layer_c = layer_b->children()[0].get();
385 layer_b->AddChild(MockLayer::Create(&layer_impl_destruction_list));
386 scoped_refptr<Layer> layer_d = layer_b->children()[1].get();
388 host_->SetRootLayer(layer_tree_root);
390 scoped_ptr<LayerImpl> layer_impl_tree_root =
391 TreeSynchronizer::SynchronizeTrees(
392 layer_tree_root.get(), nullptr, host_->active_tree());
393 ExpectTreesAreIdentical(layer_tree_root.get(),
394 layer_impl_tree_root.get(),
395 host_->active_tree());
397 // We have to push properties to pick up the destruction list pointer.
398 TreeSynchronizer::PushProperties(layer_tree_root.get(),
399 layer_impl_tree_root.get());
401 // Now restructure the tree to look like this:
402 // root --- D ---+--- A
403 // |
404 // +--- C --- B
405 layer_tree_root->RemoveAllChildren();
406 layer_d->RemoveAllChildren();
407 layer_tree_root->AddChild(layer_d);
408 layer_a->RemoveAllChildren();
409 layer_d->AddChild(layer_a);
410 layer_c->RemoveAllChildren();
411 layer_d->AddChild(layer_c);
412 layer_b->RemoveAllChildren();
413 layer_c->AddChild(layer_b);
415 // After another synchronize our trees should match and we should not have
416 // destroyed any LayerImpls
417 layer_impl_tree_root =
418 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
419 layer_impl_tree_root.Pass(),
420 host_->active_tree());
421 ExpectTreesAreIdentical(layer_tree_root.get(),
422 layer_impl_tree_root.get(),
423 host_->active_tree());
425 EXPECT_EQ(0u, layer_impl_destruction_list.size());
428 // Constructs a very simple tree, synchronizes it, then synchronizes to a
429 // totally new tree. All layers from the old tree should be deleted.
430 TEST_F(TreeSynchronizerTest, SyncSimpleTreeThenDestroy) {
431 std::vector<int> layer_impl_destruction_list;
433 scoped_refptr<Layer> old_layer_tree_root =
434 MockLayer::Create(&layer_impl_destruction_list);
435 old_layer_tree_root->AddChild(
436 MockLayer::Create(&layer_impl_destruction_list));
437 old_layer_tree_root->AddChild(
438 MockLayer::Create(&layer_impl_destruction_list));
440 host_->SetRootLayer(old_layer_tree_root);
442 int old_tree_root_layer_id = old_layer_tree_root->id();
443 int old_tree_first_child_layer_id = old_layer_tree_root->children()[0]->id();
444 int old_tree_second_child_layer_id = old_layer_tree_root->children()[1]->id();
446 scoped_ptr<LayerImpl> layer_impl_tree_root =
447 TreeSynchronizer::SynchronizeTrees(
448 old_layer_tree_root.get(), nullptr, host_->active_tree());
449 ExpectTreesAreIdentical(old_layer_tree_root.get(),
450 layer_impl_tree_root.get(),
451 host_->active_tree());
453 // We have to push properties to pick up the destruction list pointer.
454 TreeSynchronizer::PushProperties(old_layer_tree_root.get(),
455 layer_impl_tree_root.get());
457 // Remove all children on the Layer side.
458 old_layer_tree_root->RemoveAllChildren();
460 // Synchronize again. After the sync all LayerImpls from the old tree should
461 // be deleted.
462 scoped_refptr<Layer> new_layer_tree_root = Layer::Create();
463 host_->SetRootLayer(new_layer_tree_root);
464 layer_impl_tree_root =
465 TreeSynchronizer::SynchronizeTrees(new_layer_tree_root.get(),
466 layer_impl_tree_root.Pass(),
467 host_->active_tree());
468 ExpectTreesAreIdentical(new_layer_tree_root.get(),
469 layer_impl_tree_root.get(),
470 host_->active_tree());
472 ASSERT_EQ(3u, layer_impl_destruction_list.size());
474 EXPECT_TRUE(std::find(layer_impl_destruction_list.begin(),
475 layer_impl_destruction_list.end(),
476 old_tree_root_layer_id) !=
477 layer_impl_destruction_list.end());
478 EXPECT_TRUE(std::find(layer_impl_destruction_list.begin(),
479 layer_impl_destruction_list.end(),
480 old_tree_first_child_layer_id) !=
481 layer_impl_destruction_list.end());
482 EXPECT_TRUE(std::find(layer_impl_destruction_list.begin(),
483 layer_impl_destruction_list.end(),
484 old_tree_second_child_layer_id) !=
485 layer_impl_destruction_list.end());
488 // Constructs+syncs a tree with mask, replica, and replica mask layers.
489 TEST_F(TreeSynchronizerTest, SyncMaskReplicaAndReplicaMaskLayers) {
490 scoped_refptr<Layer> layer_tree_root = Layer::Create();
491 layer_tree_root->AddChild(Layer::Create());
492 layer_tree_root->AddChild(Layer::Create());
493 layer_tree_root->AddChild(Layer::Create());
495 // First child gets a mask layer.
496 scoped_refptr<Layer> mask_layer = Layer::Create();
497 layer_tree_root->children()[0]->SetMaskLayer(mask_layer.get());
499 // Second child gets a replica layer.
500 scoped_refptr<Layer> replica_layer = Layer::Create();
501 layer_tree_root->children()[1]->SetReplicaLayer(replica_layer.get());
503 // Third child gets a replica layer with a mask layer.
504 scoped_refptr<Layer> replica_layer_with_mask = Layer::Create();
505 scoped_refptr<Layer> replica_mask_layer = Layer::Create();
506 replica_layer_with_mask->SetMaskLayer(replica_mask_layer.get());
507 layer_tree_root->children()[2]->
508 SetReplicaLayer(replica_layer_with_mask.get());
510 host_->SetRootLayer(layer_tree_root);
512 scoped_ptr<LayerImpl> layer_impl_tree_root =
513 TreeSynchronizer::SynchronizeTrees(
514 layer_tree_root.get(), nullptr, host_->active_tree());
516 ExpectTreesAreIdentical(layer_tree_root.get(),
517 layer_impl_tree_root.get(),
518 host_->active_tree());
520 // Remove the mask layer.
521 layer_tree_root->children()[0]->SetMaskLayer(NULL);
522 layer_impl_tree_root =
523 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
524 layer_impl_tree_root.Pass(),
525 host_->active_tree());
526 ExpectTreesAreIdentical(layer_tree_root.get(),
527 layer_impl_tree_root.get(),
528 host_->active_tree());
530 // Remove the replica layer.
531 layer_tree_root->children()[1]->SetReplicaLayer(NULL);
532 layer_impl_tree_root =
533 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
534 layer_impl_tree_root.Pass(),
535 host_->active_tree());
536 ExpectTreesAreIdentical(layer_tree_root.get(),
537 layer_impl_tree_root.get(),
538 host_->active_tree());
540 // Remove the replica mask.
541 replica_layer_with_mask->SetMaskLayer(NULL);
542 layer_impl_tree_root =
543 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
544 layer_impl_tree_root.Pass(),
545 host_->active_tree());
546 ExpectTreesAreIdentical(layer_tree_root.get(),
547 layer_impl_tree_root.get(),
548 host_->active_tree());
551 TEST_F(TreeSynchronizerTest, SynchronizeAnimations) {
552 LayerTreeSettings settings;
553 FakeProxy proxy;
554 DebugScopedSetImplThread impl(&proxy);
555 FakeRenderingStatsInstrumentation stats_instrumentation;
556 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
557 new TestSharedBitmapManager());
558 scoped_ptr<LayerTreeHostImpl> host_impl =
559 LayerTreeHostImpl::Create(settings,
560 NULL,
561 &proxy,
562 &stats_instrumentation,
563 shared_bitmap_manager.get(),
564 NULL,
567 scoped_refptr<Layer> layer_tree_root = Layer::Create();
568 host_->SetRootLayer(layer_tree_root);
570 layer_tree_root->SetLayerAnimationControllerForTest(
571 FakeLayerAnimationController::Create());
573 EXPECT_FALSE(static_cast<FakeLayerAnimationController*>(
574 layer_tree_root->layer_animation_controller())->SynchronizedAnimations());
576 scoped_ptr<LayerImpl> layer_impl_tree_root =
577 TreeSynchronizer::SynchronizeTrees(
578 layer_tree_root.get(), nullptr, host_->active_tree());
579 TreeSynchronizer::PushProperties(layer_tree_root.get(),
580 layer_impl_tree_root.get());
581 layer_impl_tree_root =
582 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
583 layer_impl_tree_root.Pass(),
584 host_->active_tree());
586 EXPECT_TRUE(static_cast<FakeLayerAnimationController*>(
587 layer_tree_root->layer_animation_controller())->SynchronizedAnimations());
590 TEST_F(TreeSynchronizerTest, SynchronizeScrollParent) {
591 LayerTreeSettings settings;
592 FakeProxy proxy;
593 DebugScopedSetImplThread impl(&proxy);
594 FakeRenderingStatsInstrumentation stats_instrumentation;
595 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
596 new TestSharedBitmapManager());
597 scoped_ptr<LayerTreeHostImpl> host_impl =
598 LayerTreeHostImpl::Create(settings,
599 NULL,
600 &proxy,
601 &stats_instrumentation,
602 shared_bitmap_manager.get(),
603 NULL,
606 scoped_refptr<Layer> layer_tree_root = Layer::Create();
607 scoped_refptr<Layer> scroll_parent = Layer::Create();
608 layer_tree_root->AddChild(scroll_parent);
609 layer_tree_root->AddChild(Layer::Create());
610 layer_tree_root->AddChild(Layer::Create());
612 host_->SetRootLayer(layer_tree_root);
614 // First child is the second and third child's scroll parent.
615 layer_tree_root->children()[1]->SetScrollParent(scroll_parent.get());
616 layer_tree_root->children()[2]->SetScrollParent(scroll_parent.get());
618 scoped_ptr<LayerImpl> layer_impl_tree_root =
619 TreeSynchronizer::SynchronizeTrees(
620 layer_tree_root.get(), nullptr, host_impl->active_tree());
621 TreeSynchronizer::PushProperties(layer_tree_root.get(),
622 layer_impl_tree_root.get());
624 SCOPED_TRACE("case one");
625 ExpectTreesAreIdentical(layer_tree_root.get(),
626 layer_impl_tree_root.get(),
627 host_impl->active_tree());
630 // Remove the first scroll child.
631 layer_tree_root->children()[1]->RemoveFromParent();
632 layer_impl_tree_root =
633 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
634 layer_impl_tree_root.Pass(),
635 host_impl->active_tree());
636 TreeSynchronizer::PushProperties(layer_tree_root.get(),
637 layer_impl_tree_root.get());
639 SCOPED_TRACE("case two");
640 ExpectTreesAreIdentical(layer_tree_root.get(),
641 layer_impl_tree_root.get(),
642 host_impl->active_tree());
645 // Add an additional scroll layer.
646 scoped_refptr<Layer> additional_scroll_child = Layer::Create();
647 layer_tree_root->AddChild(additional_scroll_child);
648 additional_scroll_child->SetScrollParent(scroll_parent.get());
649 layer_impl_tree_root =
650 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
651 layer_impl_tree_root.Pass(),
652 host_impl->active_tree());
653 TreeSynchronizer::PushProperties(layer_tree_root.get(),
654 layer_impl_tree_root.get());
656 SCOPED_TRACE("case three");
657 ExpectTreesAreIdentical(layer_tree_root.get(),
658 layer_impl_tree_root.get(),
659 host_impl->active_tree());
663 TEST_F(TreeSynchronizerTest, SynchronizeClipParent) {
664 LayerTreeSettings settings;
665 FakeProxy proxy;
666 DebugScopedSetImplThread impl(&proxy);
667 FakeRenderingStatsInstrumentation stats_instrumentation;
668 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
669 new TestSharedBitmapManager());
670 scoped_ptr<LayerTreeHostImpl> host_impl =
671 LayerTreeHostImpl::Create(settings,
672 NULL,
673 &proxy,
674 &stats_instrumentation,
675 shared_bitmap_manager.get(),
676 NULL,
679 scoped_refptr<Layer> layer_tree_root = Layer::Create();
680 scoped_refptr<Layer> clip_parent = Layer::Create();
681 scoped_refptr<Layer> intervening = Layer::Create();
682 scoped_refptr<Layer> clip_child1 = Layer::Create();
683 scoped_refptr<Layer> clip_child2 = Layer::Create();
684 layer_tree_root->AddChild(clip_parent);
685 clip_parent->AddChild(intervening);
686 intervening->AddChild(clip_child1);
687 intervening->AddChild(clip_child2);
689 host_->SetRootLayer(layer_tree_root);
691 // First child is the second and third child's scroll parent.
692 clip_child1->SetClipParent(clip_parent.get());
693 clip_child2->SetClipParent(clip_parent.get());
695 scoped_ptr<LayerImpl> layer_impl_tree_root =
696 TreeSynchronizer::SynchronizeTrees(
697 layer_tree_root.get(), nullptr, host_impl->active_tree());
698 TreeSynchronizer::PushProperties(layer_tree_root.get(),
699 layer_impl_tree_root.get());
700 ExpectTreesAreIdentical(layer_tree_root.get(),
701 layer_impl_tree_root.get(),
702 host_impl->active_tree());
704 // Remove the first clip child.
705 clip_child1->RemoveFromParent();
706 clip_child1 = NULL;
708 layer_impl_tree_root =
709 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
710 layer_impl_tree_root.Pass(),
711 host_impl->active_tree());
712 TreeSynchronizer::PushProperties(layer_tree_root.get(),
713 layer_impl_tree_root.get());
714 ExpectTreesAreIdentical(layer_tree_root.get(),
715 layer_impl_tree_root.get(),
716 host_impl->active_tree());
718 // Add an additional clip child.
719 scoped_refptr<Layer> additional_clip_child = Layer::Create();
720 intervening->AddChild(additional_clip_child);
721 additional_clip_child->SetClipParent(clip_parent.get());
722 layer_impl_tree_root =
723 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
724 layer_impl_tree_root.Pass(),
725 host_impl->active_tree());
726 TreeSynchronizer::PushProperties(layer_tree_root.get(),
727 layer_impl_tree_root.get());
728 ExpectTreesAreIdentical(layer_tree_root.get(),
729 layer_impl_tree_root.get(),
730 host_impl->active_tree());
732 // Remove the nearest clipping ancestor.
733 clip_parent->RemoveFromParent();
734 clip_parent = NULL;
735 layer_impl_tree_root =
736 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
737 layer_impl_tree_root.Pass(),
738 host_impl->active_tree());
739 TreeSynchronizer::PushProperties(layer_tree_root.get(),
740 layer_impl_tree_root.get());
741 ExpectTreesAreIdentical(layer_tree_root.get(),
742 layer_impl_tree_root.get(),
743 host_impl->active_tree());
745 // The clip children should have been unhooked.
746 EXPECT_EQ(2u, intervening->children().size());
747 EXPECT_FALSE(clip_child2->clip_parent());
748 EXPECT_FALSE(additional_clip_child->clip_parent());
751 } // namespace
752 } // namespace cc