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