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()
193      : client_(FakeLayerTreeHostClient::DIRECT_3D),
194        host_(FakeLayerTreeHost::Create(&client_)) {}
195
196 protected:
197  FakeLayerTreeHostClient client_;
198  scoped_ptr<FakeLayerTreeHost> host_;
199};
200
201// Attempts to synchronizes a null tree. This should not crash, and should
202// return a null tree.
203TEST_F(TreeSynchronizerTest, SyncNullTree) {
204  scoped_ptr<LayerImpl> layer_impl_tree_root =
205      TreeSynchronizer::SynchronizeTrees(static_cast<Layer*>(NULL),
206                                         scoped_ptr<LayerImpl>(),
207                                         host_->active_tree());
208
209  EXPECT_TRUE(!layer_impl_tree_root.get());
210}
211
212// Constructs a very simple tree and synchronizes it without trying to reuse any
213// preexisting layers.
214TEST_F(TreeSynchronizerTest, SyncSimpleTreeFromEmpty) {
215  scoped_refptr<Layer> layer_tree_root = Layer::Create();
216  layer_tree_root->AddChild(Layer::Create());
217  layer_tree_root->AddChild(Layer::Create());
218
219  host_->SetRootLayer(layer_tree_root);
220
221  scoped_ptr<LayerImpl> layer_impl_tree_root =
222      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
223                                         scoped_ptr<LayerImpl>(),
224                                         host_->active_tree());
225
226  ExpectTreesAreIdentical(layer_tree_root.get(),
227                          layer_impl_tree_root.get(),
228                          host_->active_tree());
229}
230
231// Constructs a very simple tree and synchronizes it attempting to reuse some
232// layers
233TEST_F(TreeSynchronizerTest, SyncSimpleTreeReusingLayers) {
234  std::vector<int> layer_impl_destruction_list;
235
236  scoped_refptr<Layer> layer_tree_root =
237      MockLayer::Create(&layer_impl_destruction_list);
238  layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list));
239  layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list));
240
241  host_->SetRootLayer(layer_tree_root);
242
243  scoped_ptr<LayerImpl> layer_impl_tree_root =
244      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
245                                         scoped_ptr<LayerImpl>(),
246                                         host_->active_tree());
247  ExpectTreesAreIdentical(layer_tree_root.get(),
248                          layer_impl_tree_root.get(),
249                          host_->active_tree());
250
251  // We have to push properties to pick up the destruction list pointer.
252  TreeSynchronizer::PushProperties(layer_tree_root.get(),
253                                   layer_impl_tree_root.get());
254
255  // Add a new layer to the Layer side
256  layer_tree_root->children()[0]->
257      AddChild(MockLayer::Create(&layer_impl_destruction_list));
258  // Remove one.
259  layer_tree_root->children()[1]->RemoveFromParent();
260  int second_layer_impl_id = layer_impl_tree_root->children()[1]->id();
261
262  // Synchronize again. After the sync the trees should be equivalent and we
263  // should have created and destroyed one LayerImpl.
264  layer_impl_tree_root =
265      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
266                                         layer_impl_tree_root.Pass(),
267                                         host_->active_tree());
268  ExpectTreesAreIdentical(layer_tree_root.get(),
269                          layer_impl_tree_root.get(),
270                          host_->active_tree());
271
272  ASSERT_EQ(1u, layer_impl_destruction_list.size());
273  EXPECT_EQ(second_layer_impl_id, layer_impl_destruction_list[0]);
274}
275
276// Constructs a very simple tree and checks that a stacking-order change is
277// tracked properly.
278TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndTrackStackingOrderChange) {
279  std::vector<int> layer_impl_destruction_list;
280
281  // Set up the tree and sync once. child2 needs to be synced here, too, even
282  // though we remove it to set up the intended scenario.
283  scoped_refptr<Layer> layer_tree_root =
284      MockLayer::Create(&layer_impl_destruction_list);
285  scoped_refptr<Layer> child2 = MockLayer::Create(&layer_impl_destruction_list);
286  layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list));
287  layer_tree_root->AddChild(child2);
288
289  host_->SetRootLayer(layer_tree_root);
290
291  scoped_ptr<LayerImpl> layer_impl_tree_root =
292      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
293                                         scoped_ptr<LayerImpl>(),
294                                         host_->active_tree());
295  ExpectTreesAreIdentical(layer_tree_root.get(),
296                          layer_impl_tree_root.get(),
297                          host_->active_tree());
298
299  // We have to push properties to pick up the destruction list pointer.
300  TreeSynchronizer::PushProperties(layer_tree_root.get(),
301                                   layer_impl_tree_root.get());
302
303  layer_impl_tree_root->ResetAllChangeTrackingForSubtree();
304
305  // re-insert the layer and sync again.
306  child2->RemoveFromParent();
307  layer_tree_root->AddChild(child2);
308  layer_impl_tree_root =
309      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
310                                         layer_impl_tree_root.Pass(),
311                                         host_->active_tree());
312  ExpectTreesAreIdentical(layer_tree_root.get(),
313                          layer_impl_tree_root.get(),
314                          host_->active_tree());
315
316  TreeSynchronizer::PushProperties(layer_tree_root.get(),
317                                   layer_impl_tree_root.get());
318
319  // Check that the impl thread properly tracked the change.
320  EXPECT_FALSE(layer_impl_tree_root->LayerPropertyChanged());
321  EXPECT_FALSE(layer_impl_tree_root->children()[0]->LayerPropertyChanged());
322  EXPECT_TRUE(layer_impl_tree_root->children()[1]->LayerPropertyChanged());
323}
324
325TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndProperties) {
326  scoped_refptr<Layer> layer_tree_root = Layer::Create();
327  layer_tree_root->AddChild(Layer::Create());
328  layer_tree_root->AddChild(Layer::Create());
329
330  host_->SetRootLayer(layer_tree_root);
331
332  // Pick some random properties to set. The values are not important, we're
333  // just testing that at least some properties are making it through.
334  gfx::PointF root_position = gfx::PointF(2.3f, 7.4f);
335  layer_tree_root->SetPosition(root_position);
336
337  float first_child_opacity = 0.25f;
338  layer_tree_root->children()[0]->SetOpacity(first_child_opacity);
339
340  gfx::Size second_child_bounds = gfx::Size(25, 53);
341  layer_tree_root->children()[1]->SetBounds(second_child_bounds);
342  layer_tree_root->children()[1]->SavePaintProperties();
343
344  scoped_ptr<LayerImpl> layer_impl_tree_root =
345      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
346                                         scoped_ptr<LayerImpl>(),
347                                         host_->active_tree());
348  ExpectTreesAreIdentical(layer_tree_root.get(),
349                          layer_impl_tree_root.get(),
350                          host_->active_tree());
351
352  TreeSynchronizer::PushProperties(layer_tree_root.get(),
353                                   layer_impl_tree_root.get());
354
355  // Check that the property values we set on the Layer tree are reflected in
356  // the LayerImpl tree.
357  gfx::PointF root_layer_impl_position = layer_impl_tree_root->position();
358  EXPECT_EQ(root_position.x(), root_layer_impl_position.x());
359  EXPECT_EQ(root_position.y(), root_layer_impl_position.y());
360
361  EXPECT_EQ(first_child_opacity,
362            layer_impl_tree_root->children()[0]->opacity());
363
364  gfx::Size second_layer_impl_child_bounds =
365      layer_impl_tree_root->children()[1]->bounds();
366  EXPECT_EQ(second_child_bounds.width(),
367            second_layer_impl_child_bounds.width());
368  EXPECT_EQ(second_child_bounds.height(),
369            second_layer_impl_child_bounds.height());
370}
371
372TEST_F(TreeSynchronizerTest, ReuseLayerImplsAfterStructuralChange) {
373  std::vector<int> layer_impl_destruction_list;
374
375  // Set up a tree with this sort of structure:
376  // root --- A --- B ---+--- C
377  //                     |
378  //                     +--- D
379  scoped_refptr<Layer> layer_tree_root =
380      MockLayer::Create(&layer_impl_destruction_list);
381  layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list));
382
383  scoped_refptr<Layer> layer_a = layer_tree_root->children()[0].get();
384  layer_a->AddChild(MockLayer::Create(&layer_impl_destruction_list));
385
386  scoped_refptr<Layer> layer_b = layer_a->children()[0].get();
387  layer_b->AddChild(MockLayer::Create(&layer_impl_destruction_list));
388
389  scoped_refptr<Layer> layer_c = layer_b->children()[0].get();
390  layer_b->AddChild(MockLayer::Create(&layer_impl_destruction_list));
391  scoped_refptr<Layer> layer_d = layer_b->children()[1].get();
392
393  host_->SetRootLayer(layer_tree_root);
394
395  scoped_ptr<LayerImpl> layer_impl_tree_root =
396      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
397                                         scoped_ptr<LayerImpl>(),
398                                         host_->active_tree());
399  ExpectTreesAreIdentical(layer_tree_root.get(),
400                          layer_impl_tree_root.get(),
401                          host_->active_tree());
402
403  // We have to push properties to pick up the destruction list pointer.
404  TreeSynchronizer::PushProperties(layer_tree_root.get(),
405                                   layer_impl_tree_root.get());
406
407  // Now restructure the tree to look like this:
408  // root --- D ---+--- A
409  //               |
410  //               +--- C --- B
411  layer_tree_root->RemoveAllChildren();
412  layer_d->RemoveAllChildren();
413  layer_tree_root->AddChild(layer_d);
414  layer_a->RemoveAllChildren();
415  layer_d->AddChild(layer_a);
416  layer_c->RemoveAllChildren();
417  layer_d->AddChild(layer_c);
418  layer_b->RemoveAllChildren();
419  layer_c->AddChild(layer_b);
420
421  // After another synchronize our trees should match and we should not have
422  // destroyed any LayerImpls
423  layer_impl_tree_root =
424      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
425                                         layer_impl_tree_root.Pass(),
426                                         host_->active_tree());
427  ExpectTreesAreIdentical(layer_tree_root.get(),
428                          layer_impl_tree_root.get(),
429                          host_->active_tree());
430
431  EXPECT_EQ(0u, layer_impl_destruction_list.size());
432}
433
434// Constructs a very simple tree, synchronizes it, then synchronizes to a
435// totally new tree. All layers from the old tree should be deleted.
436TEST_F(TreeSynchronizerTest, SyncSimpleTreeThenDestroy) {
437  std::vector<int> layer_impl_destruction_list;
438
439  scoped_refptr<Layer> old_layer_tree_root =
440      MockLayer::Create(&layer_impl_destruction_list);
441  old_layer_tree_root->AddChild(
442      MockLayer::Create(&layer_impl_destruction_list));
443  old_layer_tree_root->AddChild(
444      MockLayer::Create(&layer_impl_destruction_list));
445
446  host_->SetRootLayer(old_layer_tree_root);
447
448  int old_tree_root_layer_id = old_layer_tree_root->id();
449  int old_tree_first_child_layer_id = old_layer_tree_root->children()[0]->id();
450  int old_tree_second_child_layer_id = old_layer_tree_root->children()[1]->id();
451
452  scoped_ptr<LayerImpl> layer_impl_tree_root =
453      TreeSynchronizer::SynchronizeTrees(old_layer_tree_root.get(),
454                                         scoped_ptr<LayerImpl>(),
455                                         host_->active_tree());
456  ExpectTreesAreIdentical(old_layer_tree_root.get(),
457                          layer_impl_tree_root.get(),
458                          host_->active_tree());
459
460  // We have to push properties to pick up the destruction list pointer.
461  TreeSynchronizer::PushProperties(old_layer_tree_root.get(),
462                                   layer_impl_tree_root.get());
463
464  // Remove all children on the Layer side.
465  old_layer_tree_root->RemoveAllChildren();
466
467  // Synchronize again. After the sync all LayerImpls from the old tree should
468  // be deleted.
469  scoped_refptr<Layer> new_layer_tree_root = Layer::Create();
470  host_->SetRootLayer(new_layer_tree_root);
471  layer_impl_tree_root =
472      TreeSynchronizer::SynchronizeTrees(new_layer_tree_root.get(),
473                                         layer_impl_tree_root.Pass(),
474                                         host_->active_tree());
475  ExpectTreesAreIdentical(new_layer_tree_root.get(),
476                          layer_impl_tree_root.get(),
477                          host_->active_tree());
478
479  ASSERT_EQ(3u, layer_impl_destruction_list.size());
480
481  EXPECT_TRUE(std::find(layer_impl_destruction_list.begin(),
482                        layer_impl_destruction_list.end(),
483                        old_tree_root_layer_id) !=
484              layer_impl_destruction_list.end());
485  EXPECT_TRUE(std::find(layer_impl_destruction_list.begin(),
486                        layer_impl_destruction_list.end(),
487                        old_tree_first_child_layer_id) !=
488              layer_impl_destruction_list.end());
489  EXPECT_TRUE(std::find(layer_impl_destruction_list.begin(),
490                        layer_impl_destruction_list.end(),
491                        old_tree_second_child_layer_id) !=
492              layer_impl_destruction_list.end());
493}
494
495// Constructs+syncs a tree with mask, replica, and replica mask layers.
496TEST_F(TreeSynchronizerTest, SyncMaskReplicaAndReplicaMaskLayers) {
497  scoped_refptr<Layer> layer_tree_root = Layer::Create();
498  layer_tree_root->AddChild(Layer::Create());
499  layer_tree_root->AddChild(Layer::Create());
500  layer_tree_root->AddChild(Layer::Create());
501
502  // First child gets a mask layer.
503  scoped_refptr<Layer> mask_layer = Layer::Create();
504  layer_tree_root->children()[0]->SetMaskLayer(mask_layer.get());
505
506  // Second child gets a replica layer.
507  scoped_refptr<Layer> replica_layer = Layer::Create();
508  layer_tree_root->children()[1]->SetReplicaLayer(replica_layer.get());
509
510  // Third child gets a replica layer with a mask layer.
511  scoped_refptr<Layer> replica_layer_with_mask = Layer::Create();
512  scoped_refptr<Layer> replica_mask_layer = Layer::Create();
513  replica_layer_with_mask->SetMaskLayer(replica_mask_layer.get());
514  layer_tree_root->children()[2]->
515      SetReplicaLayer(replica_layer_with_mask.get());
516
517  host_->SetRootLayer(layer_tree_root);
518
519  scoped_ptr<LayerImpl> layer_impl_tree_root =
520      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
521                                         scoped_ptr<LayerImpl>(),
522                                         host_->active_tree());
523
524  ExpectTreesAreIdentical(layer_tree_root.get(),
525                          layer_impl_tree_root.get(),
526                          host_->active_tree());
527
528  // Remove the mask layer.
529  layer_tree_root->children()[0]->SetMaskLayer(NULL);
530  layer_impl_tree_root =
531      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
532                                         layer_impl_tree_root.Pass(),
533                                         host_->active_tree());
534  ExpectTreesAreIdentical(layer_tree_root.get(),
535                          layer_impl_tree_root.get(),
536                          host_->active_tree());
537
538  // Remove the replica layer.
539  layer_tree_root->children()[1]->SetReplicaLayer(NULL);
540  layer_impl_tree_root =
541      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
542                                         layer_impl_tree_root.Pass(),
543                                         host_->active_tree());
544  ExpectTreesAreIdentical(layer_tree_root.get(),
545                          layer_impl_tree_root.get(),
546                          host_->active_tree());
547
548  // Remove the replica mask.
549  replica_layer_with_mask->SetMaskLayer(NULL);
550  layer_impl_tree_root =
551      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
552                                         layer_impl_tree_root.Pass(),
553                                         host_->active_tree());
554  ExpectTreesAreIdentical(layer_tree_root.get(),
555                          layer_impl_tree_root.get(),
556                          host_->active_tree());
557}
558
559TEST_F(TreeSynchronizerTest, SynchronizeAnimations) {
560  LayerTreeSettings settings;
561  FakeProxy proxy;
562  DebugScopedSetImplThread impl(&proxy);
563  FakeRenderingStatsInstrumentation stats_instrumentation;
564  scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
565      new TestSharedBitmapManager());
566  scoped_ptr<LayerTreeHostImpl> host_impl =
567      LayerTreeHostImpl::Create(settings,
568                                NULL,
569                                &proxy,
570                                &stats_instrumentation,
571                                shared_bitmap_manager.get(),
572                                0);
573
574  scoped_refptr<Layer> layer_tree_root = Layer::Create();
575  host_->SetRootLayer(layer_tree_root);
576
577  layer_tree_root->SetLayerAnimationControllerForTest(
578      FakeLayerAnimationController::Create());
579
580  EXPECT_FALSE(static_cast<FakeLayerAnimationController*>(
581      layer_tree_root->layer_animation_controller())->SynchronizedAnimations());
582
583  scoped_ptr<LayerImpl> layer_impl_tree_root =
584      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
585                                         scoped_ptr<LayerImpl>(),
586                                         host_->active_tree());
587  TreeSynchronizer::PushProperties(layer_tree_root.get(),
588                                   layer_impl_tree_root.get());
589  layer_impl_tree_root =
590      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
591                                         layer_impl_tree_root.Pass(),
592                                         host_->active_tree());
593
594  EXPECT_TRUE(static_cast<FakeLayerAnimationController*>(
595      layer_tree_root->layer_animation_controller())->SynchronizedAnimations());
596}
597
598TEST_F(TreeSynchronizerTest, SynchronizeScrollParent) {
599  LayerTreeSettings settings;
600  FakeProxy proxy;
601  DebugScopedSetImplThread impl(&proxy);
602  FakeRenderingStatsInstrumentation stats_instrumentation;
603  scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
604      new TestSharedBitmapManager());
605  scoped_ptr<LayerTreeHostImpl> host_impl =
606      LayerTreeHostImpl::Create(settings,
607                                NULL,
608                                &proxy,
609                                &stats_instrumentation,
610                                shared_bitmap_manager.get(),
611                                0);
612
613  scoped_refptr<Layer> layer_tree_root = Layer::Create();
614  scoped_refptr<Layer> scroll_parent = Layer::Create();
615  layer_tree_root->AddChild(scroll_parent);
616  layer_tree_root->AddChild(Layer::Create());
617  layer_tree_root->AddChild(Layer::Create());
618
619  host_->SetRootLayer(layer_tree_root);
620
621  // First child is the second and third child's scroll parent.
622  layer_tree_root->children()[1]->SetScrollParent(scroll_parent.get());
623  layer_tree_root->children()[2]->SetScrollParent(scroll_parent.get());
624
625  scoped_ptr<LayerImpl> layer_impl_tree_root =
626      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
627                                         scoped_ptr<LayerImpl>(),
628                                         host_impl->active_tree());
629  TreeSynchronizer::PushProperties(layer_tree_root.get(),
630                                   layer_impl_tree_root.get());
631  {
632    SCOPED_TRACE("case one");
633    ExpectTreesAreIdentical(layer_tree_root.get(),
634                            layer_impl_tree_root.get(),
635                            host_impl->active_tree());
636  }
637
638  // Remove the first scroll child.
639  layer_tree_root->children()[1]->RemoveFromParent();
640  layer_impl_tree_root =
641      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
642                                         layer_impl_tree_root.Pass(),
643                                         host_impl->active_tree());
644  TreeSynchronizer::PushProperties(layer_tree_root.get(),
645                                   layer_impl_tree_root.get());
646  {
647    SCOPED_TRACE("case two");
648    ExpectTreesAreIdentical(layer_tree_root.get(),
649                            layer_impl_tree_root.get(),
650                            host_impl->active_tree());
651  }
652
653  // Add an additional scroll layer.
654  scoped_refptr<Layer> additional_scroll_child = Layer::Create();
655  layer_tree_root->AddChild(additional_scroll_child);
656  additional_scroll_child->SetScrollParent(scroll_parent.get());
657  layer_impl_tree_root =
658      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
659                                         layer_impl_tree_root.Pass(),
660                                         host_impl->active_tree());
661  TreeSynchronizer::PushProperties(layer_tree_root.get(),
662                                   layer_impl_tree_root.get());
663  {
664    SCOPED_TRACE("case three");
665    ExpectTreesAreIdentical(layer_tree_root.get(),
666                            layer_impl_tree_root.get(),
667                            host_impl->active_tree());
668  }
669}
670
671TEST_F(TreeSynchronizerTest, SynchronizeClipParent) {
672  LayerTreeSettings settings;
673  FakeProxy proxy;
674  DebugScopedSetImplThread impl(&proxy);
675  FakeRenderingStatsInstrumentation stats_instrumentation;
676  scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
677      new TestSharedBitmapManager());
678  scoped_ptr<LayerTreeHostImpl> host_impl =
679      LayerTreeHostImpl::Create(settings,
680                                NULL,
681                                &proxy,
682                                &stats_instrumentation,
683                                shared_bitmap_manager.get(),
684                                0);
685
686  scoped_refptr<Layer> layer_tree_root = Layer::Create();
687  scoped_refptr<Layer> clip_parent = Layer::Create();
688  scoped_refptr<Layer> intervening = Layer::Create();
689  scoped_refptr<Layer> clip_child1 = Layer::Create();
690  scoped_refptr<Layer> clip_child2 = Layer::Create();
691  layer_tree_root->AddChild(clip_parent);
692  clip_parent->AddChild(intervening);
693  intervening->AddChild(clip_child1);
694  intervening->AddChild(clip_child2);
695
696  host_->SetRootLayer(layer_tree_root);
697
698  // First child is the second and third child's scroll parent.
699  clip_child1->SetClipParent(clip_parent.get());
700  clip_child2->SetClipParent(clip_parent.get());
701
702  scoped_ptr<LayerImpl> layer_impl_tree_root =
703      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
704                                         scoped_ptr<LayerImpl>(),
705                                         host_impl->active_tree());
706  TreeSynchronizer::PushProperties(layer_tree_root.get(),
707                                   layer_impl_tree_root.get());
708  ExpectTreesAreIdentical(layer_tree_root.get(),
709                          layer_impl_tree_root.get(),
710                          host_impl->active_tree());
711
712  // Remove the first clip child.
713  clip_child1->RemoveFromParent();
714  clip_child1 = NULL;
715
716  layer_impl_tree_root =
717      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
718                                         layer_impl_tree_root.Pass(),
719                                         host_impl->active_tree());
720  TreeSynchronizer::PushProperties(layer_tree_root.get(),
721                                   layer_impl_tree_root.get());
722  ExpectTreesAreIdentical(layer_tree_root.get(),
723                          layer_impl_tree_root.get(),
724                          host_impl->active_tree());
725
726  // Add an additional clip child.
727  scoped_refptr<Layer> additional_clip_child = Layer::Create();
728  intervening->AddChild(additional_clip_child);
729  additional_clip_child->SetClipParent(clip_parent.get());
730  layer_impl_tree_root =
731      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
732                                         layer_impl_tree_root.Pass(),
733                                         host_impl->active_tree());
734  TreeSynchronizer::PushProperties(layer_tree_root.get(),
735                                   layer_impl_tree_root.get());
736  ExpectTreesAreIdentical(layer_tree_root.get(),
737                          layer_impl_tree_root.get(),
738                          host_impl->active_tree());
739
740  // Remove the nearest clipping ancestor.
741  clip_parent->RemoveFromParent();
742  clip_parent = NULL;
743  layer_impl_tree_root =
744      TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
745                                         layer_impl_tree_root.Pass(),
746                                         host_impl->active_tree());
747  TreeSynchronizer::PushProperties(layer_tree_root.get(),
748                                   layer_impl_tree_root.get());
749  ExpectTreesAreIdentical(layer_tree_root.get(),
750                          layer_impl_tree_root.get(),
751                          host_impl->active_tree());
752
753  // The clip children should have been unhooked.
754  EXPECT_EQ(2u, intervening->children().size());
755  EXPECT_FALSE(clip_child2->clip_parent());
756  EXPECT_FALSE(additional_clip_child->clip_parent());
757}
758
759}  // namespace
760}  // namespace cc
761