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