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