| OLD | NEW |
| 1 // Copyright 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "cc/trees/tree_synchronizer.h" | 5 #include "cc/trees/tree_synchronizer.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <set> | 10 #include <set> |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 71 } | 71 } |
| 72 | 72 |
| 73 private: | 73 private: |
| 74 explicit MockLayer(std::vector<int>* layer_impl_destruction_list) | 74 explicit MockLayer(std::vector<int>* layer_impl_destruction_list) |
| 75 : layer_impl_destruction_list_(layer_impl_destruction_list) {} | 75 : layer_impl_destruction_list_(layer_impl_destruction_list) {} |
| 76 ~MockLayer() override {} | 76 ~MockLayer() override {} |
| 77 | 77 |
| 78 std::vector<int>* layer_impl_destruction_list_; | 78 std::vector<int>* layer_impl_destruction_list_; |
| 79 }; | 79 }; |
| 80 | 80 |
| 81 void ExpectTreesAreIdentical(Layer* layer, | 81 void ExpectTreesAreIdentical(Layer* root_layer, |
| 82 LayerImpl* layer_impl, | 82 LayerImpl* root_layer_impl, |
| 83 LayerTreeImpl* tree_impl) { | 83 LayerTreeImpl* tree_impl) { |
| 84 ASSERT_TRUE(layer); | 84 auto layer_iter = root_layer->layer_tree_host()->begin(); |
| 85 ASSERT_TRUE(layer_impl); | 85 auto layer_impl_iter = tree_impl->begin(); |
| 86 for (; layer_iter != root_layer->layer_tree_host()->end(); |
| 87 ++layer_iter, ++layer_impl_iter) { |
| 88 Layer* layer = *layer_iter; |
| 89 LayerImpl* layer_impl = *layer_impl_iter; |
| 90 ASSERT_TRUE(layer); |
| 91 ASSERT_TRUE(layer_impl); |
| 86 | 92 |
| 87 EXPECT_EQ(layer->id(), layer_impl->id()); | 93 EXPECT_EQ(layer->id(), layer_impl->id()); |
| 88 EXPECT_EQ(layer_impl->layer_tree_impl(), tree_impl); | 94 EXPECT_EQ(layer_impl->layer_tree_impl(), tree_impl); |
| 89 | 95 |
| 90 EXPECT_EQ(layer->non_fast_scrollable_region(), | 96 EXPECT_EQ(layer->non_fast_scrollable_region(), |
| 91 layer_impl->non_fast_scrollable_region()); | 97 layer_impl->non_fast_scrollable_region()); |
| 92 | 98 |
| 93 ASSERT_EQ(!!layer->mask_layer(), !!layer_impl->mask_layer()); | 99 ASSERT_EQ(!!layer->mask_layer(), !!layer_impl->mask_layer()); |
| 94 if (layer->mask_layer()) { | 100 if (layer->mask_layer()) { |
| 95 SCOPED_TRACE("mask_layer"); | 101 SCOPED_TRACE("mask_layer"); |
| 96 ExpectTreesAreIdentical(layer->mask_layer(), layer_impl->mask_layer(), | 102 EXPECT_EQ(layer->mask_layer()->id(), layer_impl->mask_layer()->id()); |
| 97 tree_impl); | 103 } |
| 98 } | |
| 99 | 104 |
| 100 ASSERT_EQ(!!layer->replica_layer(), !!layer_impl->replica_layer()); | 105 ASSERT_EQ(!!layer->replica_layer(), !!layer_impl->replica_layer()); |
| 101 if (layer->replica_layer()) { | 106 if (layer->replica_layer()) { |
| 102 SCOPED_TRACE("replica_layer"); | 107 SCOPED_TRACE("replica_layer"); |
| 103 ExpectTreesAreIdentical(layer->replica_layer(), layer_impl->replica_layer(), | 108 EXPECT_EQ(layer->replica_layer()->id(), |
| 104 tree_impl); | 109 layer_impl->replica_layer()->id()); |
| 105 } | 110 ASSERT_EQ(!!layer->replica_layer()->mask_layer(), |
| 111 !!layer_impl->replica_layer()->mask_layer()); |
| 112 if (layer->replica_layer()->mask_layer()) { |
| 113 SCOPED_TRACE("mask_layer"); |
| 114 EXPECT_EQ(layer->replica_layer()->mask_layer()->id(), |
| 115 layer_impl->replica_layer()->mask_layer()->id()); |
| 116 } |
| 117 } |
| 106 | 118 |
| 107 const LayerList& layer_children = layer->children(); | 119 const Layer* layer_scroll_parent = layer->scroll_parent(); |
| 108 const LayerImplList& layer_impl_children = layer_impl->children(); | |
| 109 | 120 |
| 110 ASSERT_EQ(layer_children.size(), layer_impl_children.size()); | 121 if (layer_scroll_parent) { |
| 122 ASSERT_TRUE(layer_scroll_parent->scroll_children()->find(layer) != |
| 123 layer_scroll_parent->scroll_children()->end()); |
| 124 } |
| 111 | 125 |
| 112 const Layer* layer_scroll_parent = layer->scroll_parent(); | 126 const Layer* layer_clip_parent = layer->clip_parent(); |
| 113 | 127 |
| 114 if (layer_scroll_parent) { | 128 if (layer_clip_parent) { |
| 115 ASSERT_TRUE(layer_scroll_parent->scroll_children()->find(layer) != | 129 const std::set<Layer*>* clip_children = |
| 116 layer_scroll_parent->scroll_children()->end()); | 130 layer_clip_parent->clip_children(); |
| 117 } | 131 ASSERT_TRUE(clip_children->find(layer) != clip_children->end()); |
| 118 | 132 } |
| 119 const Layer* layer_clip_parent = layer->clip_parent(); | |
| 120 | |
| 121 if (layer_clip_parent) { | |
| 122 const std::set<Layer*>* clip_children = layer_clip_parent->clip_children(); | |
| 123 ASSERT_TRUE(clip_children->find(layer) != clip_children->end()); | |
| 124 } | |
| 125 | |
| 126 for (size_t i = 0; i < layer_children.size(); ++i) { | |
| 127 SCOPED_TRACE(base::StringPrintf("child layer %" PRIuS, i).c_str()); | |
| 128 ExpectTreesAreIdentical(layer_children[i].get(), layer_impl_children[i], | |
| 129 tree_impl); | |
| 130 } | 133 } |
| 131 } | 134 } |
| 132 | 135 |
| 133 class TreeSynchronizerTest : public testing::Test { | 136 class TreeSynchronizerTest : public testing::Test { |
| 134 public: | 137 public: |
| 135 TreeSynchronizerTest() | 138 TreeSynchronizerTest() |
| 136 : client_(FakeLayerTreeHostClient::DIRECT_3D), | 139 : client_(FakeLayerTreeHostClient::DIRECT_3D), |
| 137 host_(FakeLayerTreeHost::Create(&client_, &task_graph_runner_)) {} | 140 host_(FakeLayerTreeHost::Create(&client_, &task_graph_runner_)) {} |
| 138 | 141 |
| 139 protected: | 142 protected: |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 187 | 190 |
| 188 // Constructs a very simple tree and synchronizes it attempting to reuse some | 191 // Constructs a very simple tree and synchronizes it attempting to reuse some |
| 189 // layers | 192 // layers |
| 190 TEST_F(TreeSynchronizerTest, SyncSimpleTreeReusingLayers) { | 193 TEST_F(TreeSynchronizerTest, SyncSimpleTreeReusingLayers) { |
| 191 std::vector<int> layer_impl_destruction_list; | 194 std::vector<int> layer_impl_destruction_list; |
| 192 | 195 |
| 193 scoped_refptr<Layer> layer_tree_root = | 196 scoped_refptr<Layer> layer_tree_root = |
| 194 MockLayer::Create(&layer_impl_destruction_list); | 197 MockLayer::Create(&layer_impl_destruction_list); |
| 195 layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list)); | 198 layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list)); |
| 196 layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list)); | 199 layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list)); |
| 200 int second_layer_impl_id = layer_tree_root->children()[1]->id(); |
| 197 | 201 |
| 198 host_->SetRootLayer(layer_tree_root); | 202 host_->SetRootLayer(layer_tree_root); |
| 199 | 203 |
| 200 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), | 204 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), |
| 201 host_->active_tree()); | 205 host_->active_tree()); |
| 202 LayerImpl* layer_impl_tree_root = host_->active_tree()->root_layer(); | 206 LayerImpl* layer_impl_tree_root = host_->active_tree()->root_layer(); |
| 203 ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root, | 207 ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root, |
| 204 host_->active_tree()); | 208 host_->active_tree()); |
| 205 | 209 |
| 206 // We have to push properties to pick up the destruction list pointer. | 210 // We have to push properties to pick up the destruction list pointer. |
| 207 TreeSynchronizer::PushLayerProperties(layer_tree_root->layer_tree_host(), | 211 TreeSynchronizer::PushLayerProperties(layer_tree_root->layer_tree_host(), |
| 208 host_->active_tree()); | 212 host_->active_tree()); |
| 209 | 213 |
| 210 // Add a new layer to the Layer side | 214 // Add a new layer to the Layer side |
| 211 layer_tree_root->children()[0]->AddChild( | 215 layer_tree_root->children()[0]->AddChild( |
| 212 MockLayer::Create(&layer_impl_destruction_list)); | 216 MockLayer::Create(&layer_impl_destruction_list)); |
| 213 // Remove one. | 217 // Remove one. |
| 214 layer_tree_root->children()[1]->RemoveFromParent(); | 218 layer_tree_root->children()[1]->RemoveFromParent(); |
| 215 int second_layer_impl_id = layer_impl_tree_root->children()[1]->id(); | |
| 216 | 219 |
| 217 // Synchronize again. After the sync the trees should be equivalent and we | 220 // Synchronize again. After the sync the trees should be equivalent and we |
| 218 // should have created and destroyed one LayerImpl. | 221 // should have created and destroyed one LayerImpl. |
| 219 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), | 222 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), |
| 220 host_->active_tree()); | 223 host_->active_tree()); |
| 221 layer_impl_tree_root = host_->active_tree()->root_layer(); | 224 layer_impl_tree_root = host_->active_tree()->root_layer(); |
| 222 | 225 |
| 223 ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root, | 226 ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root, |
| 224 host_->active_tree()); | 227 host_->active_tree()); |
| 225 | 228 |
| 226 ASSERT_EQ(1u, layer_impl_destruction_list.size()); | 229 ASSERT_EQ(1u, layer_impl_destruction_list.size()); |
| 227 EXPECT_EQ(second_layer_impl_id, layer_impl_destruction_list[0]); | 230 EXPECT_EQ(second_layer_impl_id, layer_impl_destruction_list[0]); |
| 228 | 231 |
| 229 host_->active_tree()->DetachLayers(); | 232 host_->active_tree()->DetachLayers(); |
| 230 } | 233 } |
| 231 | 234 |
| 232 // Constructs a very simple tree and checks that a stacking-order change is | 235 // Constructs a very simple tree and checks that a stacking-order change is |
| 233 // tracked properly. | 236 // tracked properly. |
| 234 TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndTrackStackingOrderChange) { | 237 TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndTrackStackingOrderChange) { |
| 235 std::vector<int> layer_impl_destruction_list; | 238 std::vector<int> layer_impl_destruction_list; |
| 236 | 239 |
| 237 // Set up the tree and sync once. child2 needs to be synced here, too, even | 240 // Set up the tree and sync once. child2 needs to be synced here, too, even |
| 238 // though we remove it to set up the intended scenario. | 241 // though we remove it to set up the intended scenario. |
| 239 scoped_refptr<Layer> layer_tree_root = | 242 scoped_refptr<Layer> layer_tree_root = |
| 240 MockLayer::Create(&layer_impl_destruction_list); | 243 MockLayer::Create(&layer_impl_destruction_list); |
| 241 scoped_refptr<Layer> child2 = MockLayer::Create(&layer_impl_destruction_list); | 244 scoped_refptr<Layer> child2 = MockLayer::Create(&layer_impl_destruction_list); |
| 242 layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list)); | 245 layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list)); |
| 243 layer_tree_root->AddChild(child2); | 246 layer_tree_root->AddChild(child2); |
| 247 int child1_id = layer_tree_root->children()[0]->id(); |
| 248 int child2_id = layer_tree_root->children()[1]->id(); |
| 244 | 249 |
| 245 host_->SetRootLayer(layer_tree_root); | 250 host_->SetRootLayer(layer_tree_root); |
| 246 | 251 |
| 247 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), | 252 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), |
| 248 host_->active_tree()); | 253 host_->active_tree()); |
| 249 LayerImpl* layer_impl_tree_root = host_->active_tree()->root_layer(); | 254 LayerImpl* layer_impl_tree_root = host_->active_tree()->root_layer(); |
| 250 ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root, | 255 ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root, |
| 251 host_->active_tree()); | 256 host_->active_tree()); |
| 252 | 257 |
| 253 // We have to push properties to pick up the destruction list pointer. | 258 // We have to push properties to pick up the destruction list pointer. |
| 254 TreeSynchronizer::PushLayerProperties(layer_tree_root->layer_tree_host(), | 259 TreeSynchronizer::PushLayerProperties(layer_tree_root->layer_tree_host(), |
| 255 host_->active_tree()); | 260 host_->active_tree()); |
| 256 | 261 |
| 257 host_->active_tree()->ResetAllChangeTracking(); | 262 host_->active_tree()->ResetAllChangeTracking(); |
| 258 | 263 |
| 259 // re-insert the layer and sync again. | 264 // re-insert the layer and sync again. |
| 260 child2->RemoveFromParent(); | 265 child2->RemoveFromParent(); |
| 261 layer_tree_root->AddChild(child2); | 266 layer_tree_root->AddChild(child2); |
| 262 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), | 267 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), |
| 263 host_->active_tree()); | 268 host_->active_tree()); |
| 264 layer_impl_tree_root = host_->active_tree()->root_layer(); | 269 layer_impl_tree_root = host_->active_tree()->root_layer(); |
| 265 ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root, | 270 ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root, |
| 266 host_->active_tree()); | 271 host_->active_tree()); |
| 267 | 272 |
| 268 TreeSynchronizer::PushLayerProperties(layer_tree_root->layer_tree_host(), | 273 TreeSynchronizer::PushLayerProperties(layer_tree_root->layer_tree_host(), |
| 269 host_->active_tree()); | 274 host_->active_tree()); |
| 270 | 275 |
| 271 // Check that the impl thread properly tracked the change. | 276 // Check that the impl thread properly tracked the change. |
| 272 EXPECT_FALSE(layer_impl_tree_root->LayerPropertyChanged()); | 277 EXPECT_FALSE(layer_impl_tree_root->LayerPropertyChanged()); |
| 273 EXPECT_FALSE(layer_impl_tree_root->children()[0]->LayerPropertyChanged()); | 278 EXPECT_FALSE( |
| 274 EXPECT_TRUE(layer_impl_tree_root->children()[1]->LayerPropertyChanged()); | 279 host_->active_tree()->LayerById(child1_id)->LayerPropertyChanged()); |
| 280 EXPECT_TRUE( |
| 281 host_->active_tree()->LayerById(child2_id)->LayerPropertyChanged()); |
| 275 host_->active_tree()->DetachLayers(); | 282 host_->active_tree()->DetachLayers(); |
| 276 } | 283 } |
| 277 | 284 |
| 278 TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndProperties) { | 285 TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndProperties) { |
| 279 scoped_refptr<Layer> layer_tree_root = Layer::Create(); | 286 scoped_refptr<Layer> layer_tree_root = Layer::Create(); |
| 280 layer_tree_root->AddChild(Layer::Create()); | 287 layer_tree_root->AddChild(Layer::Create()); |
| 281 layer_tree_root->AddChild(Layer::Create()); | 288 layer_tree_root->AddChild(Layer::Create()); |
| 282 | 289 |
| 283 host_->SetRootLayer(layer_tree_root); | 290 host_->SetRootLayer(layer_tree_root); |
| 284 | 291 |
| 285 // Pick some random properties to set. The values are not important, we're | 292 // Pick some random properties to set. The values are not important, we're |
| 286 // just testing that at least some properties are making it through. | 293 // just testing that at least some properties are making it through. |
| 287 gfx::PointF root_position = gfx::PointF(2.3f, 7.4f); | 294 gfx::PointF root_position = gfx::PointF(2.3f, 7.4f); |
| 288 layer_tree_root->SetPosition(root_position); | 295 layer_tree_root->SetPosition(root_position); |
| 289 | 296 |
| 290 gfx::Size second_child_bounds = gfx::Size(25, 53); | 297 gfx::Size second_child_bounds = gfx::Size(25, 53); |
| 291 layer_tree_root->children()[1]->SetBounds(second_child_bounds); | 298 layer_tree_root->children()[1]->SetBounds(second_child_bounds); |
| 292 layer_tree_root->children()[1]->SavePaintProperties(); | 299 layer_tree_root->children()[1]->SavePaintProperties(); |
| 300 int second_child_id = layer_tree_root->children()[1]->id(); |
| 293 | 301 |
| 294 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), | 302 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), |
| 295 host_->active_tree()); | 303 host_->active_tree()); |
| 296 LayerImpl* layer_impl_tree_root = host_->active_tree()->root_layer(); | 304 LayerImpl* layer_impl_tree_root = host_->active_tree()->root_layer(); |
| 297 ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root, | 305 ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root, |
| 298 host_->active_tree()); | 306 host_->active_tree()); |
| 299 | 307 |
| 300 TreeSynchronizer::PushLayerProperties(layer_tree_root->layer_tree_host(), | 308 TreeSynchronizer::PushLayerProperties(layer_tree_root->layer_tree_host(), |
| 301 host_->active_tree()); | 309 host_->active_tree()); |
| 302 | 310 |
| 303 // Check that the property values we set on the Layer tree are reflected in | 311 // Check that the property values we set on the Layer tree are reflected in |
| 304 // the LayerImpl tree. | 312 // the LayerImpl tree. |
| 305 gfx::PointF root_layer_impl_position = layer_impl_tree_root->position(); | 313 gfx::PointF root_layer_impl_position = layer_impl_tree_root->position(); |
| 306 EXPECT_EQ(root_position.x(), root_layer_impl_position.x()); | 314 EXPECT_EQ(root_position.x(), root_layer_impl_position.x()); |
| 307 EXPECT_EQ(root_position.y(), root_layer_impl_position.y()); | 315 EXPECT_EQ(root_position.y(), root_layer_impl_position.y()); |
| 308 | 316 |
| 309 gfx::Size second_layer_impl_child_bounds = | 317 gfx::Size second_layer_impl_child_bounds = |
| 310 layer_impl_tree_root->children()[1]->bounds(); | 318 layer_impl_tree_root->layer_tree_impl() |
| 319 ->LayerById(second_child_id) |
| 320 ->bounds(); |
| 311 EXPECT_EQ(second_child_bounds.width(), | 321 EXPECT_EQ(second_child_bounds.width(), |
| 312 second_layer_impl_child_bounds.width()); | 322 second_layer_impl_child_bounds.width()); |
| 313 EXPECT_EQ(second_child_bounds.height(), | 323 EXPECT_EQ(second_child_bounds.height(), |
| 314 second_layer_impl_child_bounds.height()); | 324 second_layer_impl_child_bounds.height()); |
| 315 } | 325 } |
| 316 | 326 |
| 317 TEST_F(TreeSynchronizerTest, ReuseLayerImplsAfterStructuralChange) { | 327 TEST_F(TreeSynchronizerTest, ReuseLayerImplsAfterStructuralChange) { |
| 318 std::vector<int> layer_impl_destruction_list; | 328 std::vector<int> layer_impl_destruction_list; |
| 319 | 329 |
| 320 // Set up a tree with this sort of structure: | 330 // Set up a tree with this sort of structure: |
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 626 scroll_offset_map[scroll_layer->id()]->PullDeltaForMainThread(); | 636 scroll_offset_map[scroll_layer->id()]->PullDeltaForMainThread(); |
| 627 scroll_offset_map[scroll_layer->id()]->SetCurrent(gfx::ScrollOffset(40, 50)); | 637 scroll_offset_map[scroll_layer->id()]->SetCurrent(gfx::ScrollOffset(40, 50)); |
| 628 scroll_offset_map[scroll_layer->id()]->PushFromMainThread( | 638 scroll_offset_map[scroll_layer->id()]->PushFromMainThread( |
| 629 gfx::ScrollOffset(100, 100)); | 639 gfx::ScrollOffset(100, 100)); |
| 630 scroll_offset_map[scroll_layer->id()]->PushPendingToActive(); | 640 scroll_offset_map[scroll_layer->id()]->PushPendingToActive(); |
| 631 EXPECT_TRUE(is_equal(scroll_offset_map, scroll_tree.scroll_offset_map())); | 641 EXPECT_TRUE(is_equal(scroll_offset_map, scroll_tree.scroll_offset_map())); |
| 632 } | 642 } |
| 633 | 643 |
| 634 } // namespace | 644 } // namespace |
| 635 } // namespace cc | 645 } // namespace cc |
| OLD | NEW |