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 24 namespace cc { 25 namespace { 26 27 class 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 50 class 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 77 class 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 102 void 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 190 class 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. 203 TEST_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. 214 TEST_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 233 TEST_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. 278 TEST_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 325 TEST_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 372 TEST_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. 436 TEST_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. 496 TEST_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 559 TEST_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 598 TEST_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 671 TEST_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