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 <vector> 9 10 #include "cc/animation/layer_animation_controller.h" 11 #include "cc/layers/layer.h" 12 #include "cc/layers/layer_impl.h" 13 #include "cc/test/animation_test_common.h" 14 #include "cc/test/fake_impl_proxy.h" 15 #include "cc/test/fake_layer_tree_host.h" 16 #include "cc/trees/proxy.h" 17 #include "cc/trees/single_thread_proxy.h" 18 #include "testing/gtest/include/gtest/gtest.h" 19 20 namespace cc { 21 namespace { 22 23 class MockLayerImpl : public LayerImpl { 24 public: 25 static scoped_ptr<MockLayerImpl> Create(LayerTreeImpl* tree_impl, 26 int layer_id) { 27 return make_scoped_ptr(new MockLayerImpl(tree_impl, layer_id)); 28 } 29 virtual ~MockLayerImpl() { 30 if (layer_impl_destruction_list_) 31 layer_impl_destruction_list_->push_back(id()); 32 } 33 34 void SetLayerImplDestructionList(std::vector<int>* list) { 35 layer_impl_destruction_list_ = list; 36 } 37 38 private: 39 MockLayerImpl(LayerTreeImpl* tree_impl, int layer_id) 40 : LayerImpl(tree_impl, layer_id), 41 layer_impl_destruction_list_(NULL) {} 42 43 std::vector<int>* layer_impl_destruction_list_; 44 }; 45 46 class MockLayer : public Layer { 47 public: 48 static scoped_refptr<MockLayer> Create( 49 std::vector<int>* layer_impl_destruction_list) { 50 return make_scoped_refptr(new MockLayer(layer_impl_destruction_list)); 51 } 52 53 virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) 54 OVERRIDE { 55 return MockLayerImpl::Create(tree_impl, layer_id_).PassAs<LayerImpl>(); 56 } 57 58 virtual void PushPropertiesTo(LayerImpl* layer_impl) OVERRIDE { 59 Layer::PushPropertiesTo(layer_impl); 60 61 MockLayerImpl* mock_layer_impl = static_cast<MockLayerImpl*>(layer_impl); 62 mock_layer_impl->SetLayerImplDestructionList(layer_impl_destruction_list_); 63 } 64 65 private: 66 explicit MockLayer(std::vector<int>* layer_impl_destruction_list) 67 : Layer(), layer_impl_destruction_list_(layer_impl_destruction_list) {} 68 virtual ~MockLayer() {} 69 70 std::vector<int>* layer_impl_destruction_list_; 71 }; 72 73 class FakeLayerAnimationController : public LayerAnimationController { 74 public: 75 static scoped_refptr<LayerAnimationController> Create() { 76 return static_cast<LayerAnimationController*>( 77 new FakeLayerAnimationController); 78 } 79 80 bool SynchronizedAnimations() const { return synchronized_animations_; } 81 82 private: 83 FakeLayerAnimationController() 84 : LayerAnimationController(1), 85 synchronized_animations_(false) {} 86 87 virtual ~FakeLayerAnimationController() {} 88 89 virtual void PushAnimationUpdatesTo(LayerAnimationController* controller_impl) 90 OVERRIDE { 91 LayerAnimationController::PushAnimationUpdatesTo(controller_impl); 92 synchronized_animations_ = true; 93 } 94 95 bool synchronized_animations_; 96 }; 97 98 void ExpectTreesAreIdentical(Layer* layer, 99 LayerImpl* layer_impl, 100 LayerTreeImpl* tree_impl) { 101 ASSERT_TRUE(layer); 102 ASSERT_TRUE(layer_impl); 103 104 EXPECT_EQ(layer->id(), layer_impl->id()); 105 EXPECT_EQ(layer_impl->layer_tree_impl(), tree_impl); 106 107 EXPECT_EQ(layer->non_fast_scrollable_region(), 108 layer_impl->non_fast_scrollable_region()); 109 110 ASSERT_EQ(!!layer->mask_layer(), !!layer_impl->mask_layer()); 111 if (layer->mask_layer()) { 112 ExpectTreesAreIdentical( 113 layer->mask_layer(), layer_impl->mask_layer(), tree_impl); 114 } 115 116 ASSERT_EQ(!!layer->replica_layer(), !!layer_impl->replica_layer()); 117 if (layer->replica_layer()) { 118 ExpectTreesAreIdentical( 119 layer->replica_layer(), layer_impl->replica_layer(), tree_impl); 120 } 121 122 const LayerList& layer_children = layer->children(); 123 const OwnedLayerImplList& layer_impl_children = layer_impl->children(); 124 125 ASSERT_EQ(layer_children.size(), layer_impl_children.size()); 126 127 for (size_t i = 0; i < layer_children.size(); ++i) { 128 ExpectTreesAreIdentical( 129 layer_children[i].get(), layer_impl_children[i], tree_impl); 130 } 131 } 132 133 class TreeSynchronizerTest : public testing::Test { 134 public: 135 TreeSynchronizerTest() : host_(FakeLayerTreeHost::Create()) {} 136 137 protected: 138 scoped_ptr<FakeLayerTreeHost> host_; 139 }; 140 141 // Attempts to synchronizes a null tree. This should not crash, and should 142 // return a null tree. 143 TEST_F(TreeSynchronizerTest, SyncNullTree) { 144 scoped_ptr<LayerImpl> layer_impl_tree_root = 145 TreeSynchronizer::SynchronizeTrees(static_cast<Layer*>(NULL), 146 scoped_ptr<LayerImpl>(), 147 host_->active_tree()); 148 149 EXPECT_TRUE(!layer_impl_tree_root.get()); 150 } 151 152 // Constructs a very simple tree and synchronizes it without trying to reuse any 153 // preexisting layers. 154 TEST_F(TreeSynchronizerTest, SyncSimpleTreeFromEmpty) { 155 scoped_refptr<Layer> layer_tree_root = Layer::Create(); 156 layer_tree_root->AddChild(Layer::Create()); 157 layer_tree_root->AddChild(Layer::Create()); 158 159 host_->SetRootLayer(layer_tree_root); 160 161 scoped_ptr<LayerImpl> layer_impl_tree_root = 162 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), 163 scoped_ptr<LayerImpl>(), 164 host_->active_tree()); 165 166 ExpectTreesAreIdentical(layer_tree_root.get(), 167 layer_impl_tree_root.get(), 168 host_->active_tree()); 169 } 170 171 // Constructs a very simple tree and synchronizes it attempting to reuse some 172 // layers 173 TEST_F(TreeSynchronizerTest, SyncSimpleTreeReusingLayers) { 174 std::vector<int> layer_impl_destruction_list; 175 176 scoped_refptr<Layer> layer_tree_root = 177 MockLayer::Create(&layer_impl_destruction_list); 178 layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list)); 179 layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list)); 180 181 host_->SetRootLayer(layer_tree_root); 182 183 scoped_ptr<LayerImpl> layer_impl_tree_root = 184 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), 185 scoped_ptr<LayerImpl>(), 186 host_->active_tree()); 187 ExpectTreesAreIdentical(layer_tree_root.get(), 188 layer_impl_tree_root.get(), 189 host_->active_tree()); 190 191 // We have to push properties to pick up the destruction list pointer. 192 TreeSynchronizer::PushProperties(layer_tree_root.get(), 193 layer_impl_tree_root.get()); 194 195 // Add a new layer to the Layer side 196 layer_tree_root->children()[0]-> 197 AddChild(MockLayer::Create(&layer_impl_destruction_list)); 198 // Remove one. 199 layer_tree_root->children()[1]->RemoveFromParent(); 200 int second_layer_impl_id = layer_impl_tree_root->children()[1]->id(); 201 202 // Synchronize again. After the sync the trees should be equivalent and we 203 // should have created and destroyed one LayerImpl. 204 layer_impl_tree_root = 205 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), 206 layer_impl_tree_root.Pass(), 207 host_->active_tree()); 208 ExpectTreesAreIdentical(layer_tree_root.get(), 209 layer_impl_tree_root.get(), 210 host_->active_tree()); 211 212 ASSERT_EQ(1u, layer_impl_destruction_list.size()); 213 EXPECT_EQ(second_layer_impl_id, layer_impl_destruction_list[0]); 214 } 215 216 // Constructs a very simple tree and checks that a stacking-order change is 217 // tracked properly. 218 TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndTrackStackingOrderChange) { 219 std::vector<int> layer_impl_destruction_list; 220 221 // Set up the tree and sync once. child2 needs to be synced here, too, even 222 // though we remove it to set up the intended scenario. 223 scoped_refptr<Layer> layer_tree_root = 224 MockLayer::Create(&layer_impl_destruction_list); 225 scoped_refptr<Layer> child2 = MockLayer::Create(&layer_impl_destruction_list); 226 layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list)); 227 layer_tree_root->AddChild(child2); 228 229 host_->SetRootLayer(layer_tree_root); 230 231 scoped_ptr<LayerImpl> layer_impl_tree_root = 232 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), 233 scoped_ptr<LayerImpl>(), 234 host_->active_tree()); 235 ExpectTreesAreIdentical(layer_tree_root.get(), 236 layer_impl_tree_root.get(), 237 host_->active_tree()); 238 239 // We have to push properties to pick up the destruction list pointer. 240 TreeSynchronizer::PushProperties(layer_tree_root.get(), 241 layer_impl_tree_root.get()); 242 243 layer_impl_tree_root->ResetAllChangeTrackingForSubtree(); 244 245 // re-insert the layer and sync again. 246 child2->RemoveFromParent(); 247 layer_tree_root->AddChild(child2); 248 layer_impl_tree_root = 249 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), 250 layer_impl_tree_root.Pass(), 251 host_->active_tree()); 252 ExpectTreesAreIdentical(layer_tree_root.get(), 253 layer_impl_tree_root.get(), 254 host_->active_tree()); 255 256 TreeSynchronizer::PushProperties(layer_tree_root.get(), 257 layer_impl_tree_root.get()); 258 259 // Check that the impl thread properly tracked the change. 260 EXPECT_FALSE(layer_impl_tree_root->LayerPropertyChanged()); 261 EXPECT_FALSE(layer_impl_tree_root->children()[0]->LayerPropertyChanged()); 262 EXPECT_TRUE(layer_impl_tree_root->children()[1]->LayerPropertyChanged()); 263 } 264 265 TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndProperties) { 266 scoped_refptr<Layer> layer_tree_root = Layer::Create(); 267 layer_tree_root->AddChild(Layer::Create()); 268 layer_tree_root->AddChild(Layer::Create()); 269 270 host_->SetRootLayer(layer_tree_root); 271 272 // Pick some random properties to set. The values are not important, we're 273 // just testing that at least some properties are making it through. 274 gfx::PointF root_position = gfx::PointF(2.3f, 7.4f); 275 layer_tree_root->SetPosition(root_position); 276 277 float first_child_opacity = 0.25f; 278 layer_tree_root->children()[0]->SetOpacity(first_child_opacity); 279 280 gfx::Size second_child_bounds = gfx::Size(25, 53); 281 layer_tree_root->children()[1]->SetBounds(second_child_bounds); 282 layer_tree_root->children()[1]->SavePaintProperties(); 283 284 scoped_ptr<LayerImpl> layer_impl_tree_root = 285 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), 286 scoped_ptr<LayerImpl>(), 287 host_->active_tree()); 288 ExpectTreesAreIdentical(layer_tree_root.get(), 289 layer_impl_tree_root.get(), 290 host_->active_tree()); 291 292 TreeSynchronizer::PushProperties(layer_tree_root.get(), 293 layer_impl_tree_root.get()); 294 295 // Check that the property values we set on the Layer tree are reflected in 296 // the LayerImpl tree. 297 gfx::PointF root_layer_impl_position = layer_impl_tree_root->position(); 298 EXPECT_EQ(root_position.x(), root_layer_impl_position.x()); 299 EXPECT_EQ(root_position.y(), root_layer_impl_position.y()); 300 301 EXPECT_EQ(first_child_opacity, 302 layer_impl_tree_root->children()[0]->opacity()); 303 304 gfx::Size second_layer_impl_child_bounds = 305 layer_impl_tree_root->children()[1]->bounds(); 306 EXPECT_EQ(second_child_bounds.width(), 307 second_layer_impl_child_bounds.width()); 308 EXPECT_EQ(second_child_bounds.height(), 309 second_layer_impl_child_bounds.height()); 310 } 311 312 TEST_F(TreeSynchronizerTest, ReuseLayerImplsAfterStructuralChange) { 313 std::vector<int> layer_impl_destruction_list; 314 315 // Set up a tree with this sort of structure: 316 // root --- A --- B ---+--- C 317 // | 318 // +--- D 319 scoped_refptr<Layer> layer_tree_root = 320 MockLayer::Create(&layer_impl_destruction_list); 321 layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list)); 322 323 scoped_refptr<Layer> layer_a = layer_tree_root->children()[0].get(); 324 layer_a->AddChild(MockLayer::Create(&layer_impl_destruction_list)); 325 326 scoped_refptr<Layer> layer_b = layer_a->children()[0].get(); 327 layer_b->AddChild(MockLayer::Create(&layer_impl_destruction_list)); 328 329 scoped_refptr<Layer> layer_c = layer_b->children()[0].get(); 330 layer_b->AddChild(MockLayer::Create(&layer_impl_destruction_list)); 331 scoped_refptr<Layer> layer_d = layer_b->children()[1].get(); 332 333 host_->SetRootLayer(layer_tree_root); 334 335 scoped_ptr<LayerImpl> layer_impl_tree_root = 336 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), 337 scoped_ptr<LayerImpl>(), 338 host_->active_tree()); 339 ExpectTreesAreIdentical(layer_tree_root.get(), 340 layer_impl_tree_root.get(), 341 host_->active_tree()); 342 343 // We have to push properties to pick up the destruction list pointer. 344 TreeSynchronizer::PushProperties(layer_tree_root.get(), 345 layer_impl_tree_root.get()); 346 347 // Now restructure the tree to look like this: 348 // root --- D ---+--- A 349 // | 350 // +--- C --- B 351 layer_tree_root->RemoveAllChildren(); 352 layer_d->RemoveAllChildren(); 353 layer_tree_root->AddChild(layer_d); 354 layer_a->RemoveAllChildren(); 355 layer_d->AddChild(layer_a); 356 layer_c->RemoveAllChildren(); 357 layer_d->AddChild(layer_c); 358 layer_b->RemoveAllChildren(); 359 layer_c->AddChild(layer_b); 360 361 // After another synchronize our trees should match and we should not have 362 // destroyed any LayerImpls 363 layer_impl_tree_root = 364 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), 365 layer_impl_tree_root.Pass(), 366 host_->active_tree()); 367 ExpectTreesAreIdentical(layer_tree_root.get(), 368 layer_impl_tree_root.get(), 369 host_->active_tree()); 370 371 EXPECT_EQ(0u, layer_impl_destruction_list.size()); 372 } 373 374 // Constructs a very simple tree, synchronizes it, then synchronizes to a 375 // totally new tree. All layers from the old tree should be deleted. 376 TEST_F(TreeSynchronizerTest, SyncSimpleTreeThenDestroy) { 377 std::vector<int> layer_impl_destruction_list; 378 379 scoped_refptr<Layer> old_layer_tree_root = 380 MockLayer::Create(&layer_impl_destruction_list); 381 old_layer_tree_root->AddChild( 382 MockLayer::Create(&layer_impl_destruction_list)); 383 old_layer_tree_root->AddChild( 384 MockLayer::Create(&layer_impl_destruction_list)); 385 386 host_->SetRootLayer(old_layer_tree_root); 387 388 int old_tree_root_layer_id = old_layer_tree_root->id(); 389 int old_tree_first_child_layer_id = old_layer_tree_root->children()[0]->id(); 390 int old_tree_second_child_layer_id = old_layer_tree_root->children()[1]->id(); 391 392 scoped_ptr<LayerImpl> layer_impl_tree_root = 393 TreeSynchronizer::SynchronizeTrees(old_layer_tree_root.get(), 394 scoped_ptr<LayerImpl>(), 395 host_->active_tree()); 396 ExpectTreesAreIdentical(old_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(old_layer_tree_root.get(), 402 layer_impl_tree_root.get()); 403 404 // Remove all children on the Layer side. 405 old_layer_tree_root->RemoveAllChildren(); 406 407 // Synchronize again. After the sync all LayerImpls from the old tree should 408 // be deleted. 409 scoped_refptr<Layer> new_layer_tree_root = Layer::Create(); 410 host_->SetRootLayer(new_layer_tree_root); 411 layer_impl_tree_root = 412 TreeSynchronizer::SynchronizeTrees(new_layer_tree_root.get(), 413 layer_impl_tree_root.Pass(), 414 host_->active_tree()); 415 ExpectTreesAreIdentical(new_layer_tree_root.get(), 416 layer_impl_tree_root.get(), 417 host_->active_tree()); 418 419 ASSERT_EQ(3u, layer_impl_destruction_list.size()); 420 421 EXPECT_TRUE(std::find(layer_impl_destruction_list.begin(), 422 layer_impl_destruction_list.end(), 423 old_tree_root_layer_id) != 424 layer_impl_destruction_list.end()); 425 EXPECT_TRUE(std::find(layer_impl_destruction_list.begin(), 426 layer_impl_destruction_list.end(), 427 old_tree_first_child_layer_id) != 428 layer_impl_destruction_list.end()); 429 EXPECT_TRUE(std::find(layer_impl_destruction_list.begin(), 430 layer_impl_destruction_list.end(), 431 old_tree_second_child_layer_id) != 432 layer_impl_destruction_list.end()); 433 } 434 435 // Constructs+syncs a tree with mask, replica, and replica mask layers. 436 TEST_F(TreeSynchronizerTest, SyncMaskReplicaAndReplicaMaskLayers) { 437 scoped_refptr<Layer> layer_tree_root = Layer::Create(); 438 layer_tree_root->AddChild(Layer::Create()); 439 layer_tree_root->AddChild(Layer::Create()); 440 layer_tree_root->AddChild(Layer::Create()); 441 442 // First child gets a mask layer. 443 scoped_refptr<Layer> mask_layer = Layer::Create(); 444 layer_tree_root->children()[0]->SetMaskLayer(mask_layer.get()); 445 446 // Second child gets a replica layer. 447 scoped_refptr<Layer> replica_layer = Layer::Create(); 448 layer_tree_root->children()[1]->SetReplicaLayer(replica_layer.get()); 449 450 // Third child gets a replica layer with a mask layer. 451 scoped_refptr<Layer> replica_layer_with_mask = Layer::Create(); 452 scoped_refptr<Layer> replica_mask_layer = Layer::Create(); 453 replica_layer_with_mask->SetMaskLayer(replica_mask_layer.get()); 454 layer_tree_root->children()[2]-> 455 SetReplicaLayer(replica_layer_with_mask.get()); 456 457 host_->SetRootLayer(layer_tree_root); 458 459 scoped_ptr<LayerImpl> layer_impl_tree_root = 460 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), 461 scoped_ptr<LayerImpl>(), 462 host_->active_tree()); 463 464 ExpectTreesAreIdentical(layer_tree_root.get(), 465 layer_impl_tree_root.get(), 466 host_->active_tree()); 467 468 // Remove the mask layer. 469 layer_tree_root->children()[0]->SetMaskLayer(NULL); 470 layer_impl_tree_root = 471 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), 472 layer_impl_tree_root.Pass(), 473 host_->active_tree()); 474 ExpectTreesAreIdentical(layer_tree_root.get(), 475 layer_impl_tree_root.get(), 476 host_->active_tree()); 477 478 // Remove the replica layer. 479 layer_tree_root->children()[1]->SetReplicaLayer(NULL); 480 layer_impl_tree_root = 481 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), 482 layer_impl_tree_root.Pass(), 483 host_->active_tree()); 484 ExpectTreesAreIdentical(layer_tree_root.get(), 485 layer_impl_tree_root.get(), 486 host_->active_tree()); 487 488 // Remove the replica mask. 489 replica_layer_with_mask->SetMaskLayer(NULL); 490 layer_impl_tree_root = 491 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), 492 layer_impl_tree_root.Pass(), 493 host_->active_tree()); 494 ExpectTreesAreIdentical(layer_tree_root.get(), 495 layer_impl_tree_root.get(), 496 host_->active_tree()); 497 } 498 499 TEST_F(TreeSynchronizerTest, SynchronizeAnimations) { 500 LayerTreeSettings settings; 501 FakeProxy proxy; 502 DebugScopedSetImplThread impl(&proxy); 503 FakeRenderingStatsInstrumentation stats_instrumentation; 504 scoped_ptr<LayerTreeHostImpl> host_impl = 505 LayerTreeHostImpl::Create(settings, 506 NULL, 507 &proxy, 508 &stats_instrumentation); 509 510 scoped_refptr<Layer> layer_tree_root = Layer::Create(); 511 host_->SetRootLayer(layer_tree_root); 512 513 layer_tree_root->SetLayerAnimationControllerForTest( 514 FakeLayerAnimationController::Create()); 515 516 EXPECT_FALSE(static_cast<FakeLayerAnimationController*>( 517 layer_tree_root->layer_animation_controller())->SynchronizedAnimations()); 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 TreeSynchronizer::PushProperties(layer_tree_root.get(), 524 layer_impl_tree_root.get()); 525 layer_impl_tree_root = 526 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), 527 layer_impl_tree_root.Pass(), 528 host_->active_tree()); 529 530 EXPECT_TRUE(static_cast<FakeLayerAnimationController*>( 531 layer_tree_root->layer_animation_controller())->SynchronizedAnimations()); 532 } 533 534 } // namespace 535 } // namespace cc 536