diff options
author | enne@chromium.org <enne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-14 15:06:33 +0000 |
---|---|---|
committer | enne@chromium.org <enne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-14 15:06:33 +0000 |
commit | b5651c24642703469ea7059a59af72acbc5520c5 (patch) | |
tree | 5d423a3ce6f6dbdd46673b01fe9d6fce6bc5a4ab | |
parent | 2f67b439d86916fad3abd6dc6d4a55a32d2596f6 (diff) | |
download | chromium_src-b5651c24642703469ea7059a59af72acbc5520c5.zip chromium_src-b5651c24642703469ea7059a59af72acbc5520c5.tar.gz chromium_src-b5651c24642703469ea7059a59af72acbc5520c5.tar.bz2 |
cc: Chromify tree synchronizer and test
R=danakj@chromium.org
BUG=none
Review URL: https://chromiumcodereview.appspot.com/12837004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@188076 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | cc/layer_tree_host.cc | 4 | ||||
-rw-r--r-- | cc/layer_tree_host_impl.cc | 4 | ||||
-rw-r--r-- | cc/scrollbar_layer_unittest.cc | 12 | ||||
-rw-r--r-- | cc/tree_synchronizer.cc | 263 | ||||
-rw-r--r-- | cc/tree_synchronizer.h | 39 | ||||
-rw-r--r-- | cc/tree_synchronizer_unittest.cc | 775 |
6 files changed, 625 insertions, 472 deletions
diff --git a/cc/layer_tree_host.cc b/cc/layer_tree_host.cc index fd8b13a..cccc83a 100644 --- a/cc/layer_tree_host.cc +++ b/cc/layer_tree_host.cc @@ -275,10 +275,10 @@ void LayerTreeHost::FinishCommitOnImplThread(LayerTreeHostImpl* host_impl) { } if (needs_full_tree_sync_) - sync_tree->SetRootLayer(TreeSynchronizer::synchronizeTrees( + sync_tree->SetRootLayer(TreeSynchronizer::SynchronizeTrees( root_layer(), sync_tree->DetachLayerTree(), sync_tree)); { TRACE_EVENT0("cc", "LayerTreeHost::PushProperties"); - TreeSynchronizer::pushProperties(root_layer(), sync_tree->root_layer()); + TreeSynchronizer::PushProperties(root_layer(), sync_tree->root_layer()); } sync_tree->set_needs_full_tree_sync(needs_full_tree_sync_); diff --git a/cc/layer_tree_host_impl.cc b/cc/layer_tree_host_impl.cc index 7c42e04..bcd3248 100644 --- a/cc/layer_tree_host_impl.cc +++ b/cc/layer_tree_host_impl.cc @@ -1134,11 +1134,11 @@ void LayerTreeHostImpl::ActivatePendingTree() { active_tree_->PushPersistedState(pending_tree_.get()); if (pending_tree_->needs_full_tree_sync()) { active_tree_->SetRootLayer( - TreeSynchronizer::synchronizeTrees(pending_tree_->root_layer(), + TreeSynchronizer::SynchronizeTrees(pending_tree_->root_layer(), active_tree_->DetachLayerTree(), active_tree_.get())); } - TreeSynchronizer::pushProperties(pending_tree_->root_layer(), + TreeSynchronizer::PushProperties(pending_tree_->root_layer(), active_tree_->root_layer()); DCHECK(!recycle_tree_); diff --git a/cc/scrollbar_layer_unittest.cc b/cc/scrollbar_layer_unittest.cc index cdb4cc9..77d206a 100644 --- a/cc/scrollbar_layer_unittest.cc +++ b/cc/scrollbar_layer_unittest.cc @@ -41,8 +41,8 @@ scoped_ptr<LayerImpl> layerImplForScrollAreaAndScrollbar( scoped_refptr<Layer> child2 = ScrollbarLayer::Create(scrollbar.Pass(), FakeScrollbarThemePainter::Create(false).PassAs<ScrollbarThemePainter>(), FakeWebScrollbarThemeGeometry::create(true), child1->id()); layerTreeRoot->AddChild(child1); layerTreeRoot->InsertChild(child2, reverse_order ? 0 : 1); - scoped_ptr<LayerImpl> layerImpl = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), scoped_ptr<LayerImpl>(), host_impl->active_tree()); - TreeSynchronizer::pushProperties(layerTreeRoot.get(), layerImpl.get()); + scoped_ptr<LayerImpl> layerImpl = TreeSynchronizer::SynchronizeTrees(layerTreeRoot.get(), scoped_ptr<LayerImpl>(), host_impl->active_tree()); + TreeSynchronizer::PushProperties(layerTreeRoot.get(), layerImpl.get()); return layerImpl.Pass(); } @@ -117,8 +117,8 @@ TEST(ScrollbarLayerTest, scrollOffsetSynchronization) layerTreeRoot->SetBounds(gfx::Size(100, 200)); contentLayer->SetBounds(gfx::Size(100, 200)); - scoped_ptr<LayerImpl> layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), scoped_ptr<LayerImpl>(), hostImpl.active_tree()); - TreeSynchronizer::pushProperties(layerTreeRoot.get(), layerImplTreeRoot.get()); + scoped_ptr<LayerImpl> layerImplTreeRoot = TreeSynchronizer::SynchronizeTrees(layerTreeRoot.get(), scoped_ptr<LayerImpl>(), hostImpl.active_tree()); + TreeSynchronizer::PushProperties(layerTreeRoot.get(), layerImplTreeRoot.get()); ScrollbarLayerImpl* ccScrollbarLayer = static_cast<ScrollbarLayerImpl*>(layerImplTreeRoot->children()[1]); @@ -132,8 +132,8 @@ TEST(ScrollbarLayerTest, scrollOffsetSynchronization) contentLayer->SetBounds(gfx::Size(1000, 2000)); ScrollbarAnimationController* scrollbarController = layerImplTreeRoot->scrollbar_animation_controller(); - layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), layerImplTreeRoot.Pass(), hostImpl.active_tree()); - TreeSynchronizer::pushProperties(layerTreeRoot.get(), layerImplTreeRoot.get()); + layerImplTreeRoot = TreeSynchronizer::SynchronizeTrees(layerTreeRoot.get(), layerImplTreeRoot.Pass(), hostImpl.active_tree()); + TreeSynchronizer::PushProperties(layerTreeRoot.get(), layerImplTreeRoot.get()); EXPECT_EQ(scrollbarController, layerImplTreeRoot->scrollbar_animation_controller()); EXPECT_EQ(100, ccScrollbarLayer->CurrentPos()); diff --git a/cc/tree_synchronizer.cc b/cc/tree_synchronizer.cc index dfea08e..ecae10d 100644 --- a/cc/tree_synchronizer.cc +++ b/cc/tree_synchronizer.cc @@ -17,162 +17,197 @@ namespace cc { typedef ScopedPtrHashMap<int, LayerImpl> ScopedPtrLayerImplMap; typedef base::hash_map<int, LayerImpl*> RawPtrLayerImplMap; -void collectExistingLayerImplRecursive(ScopedPtrLayerImplMap& oldLayers, scoped_ptr<LayerImpl> layerImpl) -{ - if (!layerImpl) - return; - - ScopedPtrVector<LayerImpl>& children = layerImpl->children(); - for (ScopedPtrVector<LayerImpl>::iterator it = children.begin(); it != children.end(); ++it) - collectExistingLayerImplRecursive(oldLayers, children.take(it)); - - collectExistingLayerImplRecursive(oldLayers, layerImpl->TakeMaskLayer()); - collectExistingLayerImplRecursive(oldLayers, layerImpl->TakeReplicaLayer()); - - int id = layerImpl->id(); - oldLayers.set(id, layerImpl.Pass()); +void CollectExistingLayerImplRecursive(ScopedPtrLayerImplMap* old_layers, + scoped_ptr<LayerImpl> layer_impl) { + if (!layer_impl) + return; + + ScopedPtrVector<LayerImpl>& children = layer_impl->children(); + for (ScopedPtrVector<LayerImpl>::iterator it = children.begin(); + it != children.end(); + ++it) + CollectExistingLayerImplRecursive(old_layers, children.take(it)); + + CollectExistingLayerImplRecursive(old_layers, layer_impl->TakeMaskLayer()); + CollectExistingLayerImplRecursive(old_layers, layer_impl->TakeReplicaLayer()); + + int id = layer_impl->id(); + old_layers->set(id, layer_impl.Pass()); } template <typename LayerType> -scoped_ptr<LayerImpl> synchronizeTreesInternal(LayerType* layerRoot, scoped_ptr<LayerImpl> oldLayerImplRoot, LayerTreeImpl* treeImpl) -{ - DCHECK(treeImpl); +scoped_ptr<LayerImpl> SynchronizeTreesInternal( + LayerType* layer_root, + scoped_ptr<LayerImpl> old_layer_impl_root, + LayerTreeImpl* tree_impl) { + DCHECK(tree_impl); - TRACE_EVENT0("cc", "TreeSynchronizer::synchronizeTrees"); - ScopedPtrLayerImplMap oldLayers; - RawPtrLayerImplMap newLayers; + TRACE_EVENT0("cc", "TreeSynchronizer::SynchronizeTrees"); + ScopedPtrLayerImplMap old_layers; + RawPtrLayerImplMap new_layers; - collectExistingLayerImplRecursive(oldLayers, oldLayerImplRoot.Pass()); + CollectExistingLayerImplRecursive(&old_layers, old_layer_impl_root.Pass()); - scoped_ptr<LayerImpl> newTree = synchronizeTreesRecursive(newLayers, oldLayers, layerRoot, treeImpl); + scoped_ptr<LayerImpl> new_tree = SynchronizeTreesRecursive( + &new_layers, &old_layers, layer_root, tree_impl); - updateScrollbarLayerPointersRecursive(newLayers, layerRoot); + UpdateScrollbarLayerPointersRecursive(&new_layers, layer_root); - return newTree.Pass(); + return new_tree.Pass(); } -scoped_ptr<LayerImpl> TreeSynchronizer::synchronizeTrees(Layer* layerRoot, scoped_ptr<LayerImpl> oldLayerImplRoot, LayerTreeImpl* treeImpl) -{ - return synchronizeTreesInternal(layerRoot, oldLayerImplRoot.Pass(), treeImpl); +scoped_ptr<LayerImpl> TreeSynchronizer::SynchronizeTrees( + Layer* layer_root, + scoped_ptr<LayerImpl> old_layer_impl_root, + LayerTreeImpl* tree_impl) { + return SynchronizeTreesInternal( + layer_root, old_layer_impl_root.Pass(), tree_impl); } -scoped_ptr<LayerImpl> TreeSynchronizer::synchronizeTrees(LayerImpl* layerRoot, scoped_ptr<LayerImpl> oldLayerImplRoot, LayerTreeImpl* treeImpl) -{ - return synchronizeTreesInternal(layerRoot, oldLayerImplRoot.Pass(), treeImpl); +scoped_ptr<LayerImpl> TreeSynchronizer::SynchronizeTrees( + LayerImpl* layer_root, + scoped_ptr<LayerImpl> old_layer_impl_root, + LayerTreeImpl* tree_impl) { + return SynchronizeTreesInternal( + layer_root, old_layer_impl_root.Pass(), tree_impl); } template <typename LayerType> -scoped_ptr<LayerImpl> reuseOrCreateLayerImpl(RawPtrLayerImplMap& newLayers, ScopedPtrLayerImplMap& oldLayers, LayerType* layer, LayerTreeImpl* treeImpl) -{ - scoped_ptr<LayerImpl> layerImpl = oldLayers.take(layer->id()); +scoped_ptr<LayerImpl> ReuseOrCreateLayerImpl(RawPtrLayerImplMap* new_layers, + ScopedPtrLayerImplMap* old_layers, + LayerType* layer, + LayerTreeImpl* tree_impl) { + scoped_ptr<LayerImpl> layer_impl = old_layers->take(layer->id()); - if (!layerImpl) - layerImpl = layer->CreateLayerImpl(treeImpl); + if (!layer_impl) + layer_impl = layer->CreateLayerImpl(tree_impl); - newLayers[layer->id()] = layerImpl.get(); - return layerImpl.Pass(); + (*new_layers)[layer->id()] = layer_impl.get(); + return layer_impl.Pass(); } template <typename LayerType> -scoped_ptr<LayerImpl> synchronizeTreesRecursiveInternal(RawPtrLayerImplMap& newLayers, ScopedPtrLayerImplMap& oldLayers, LayerType* layer, LayerTreeImpl* treeImpl) -{ - if (!layer) - return scoped_ptr<LayerImpl>(); - - scoped_ptr<LayerImpl> layerImpl = reuseOrCreateLayerImpl(newLayers, oldLayers, layer, treeImpl); - - layerImpl->ClearChildList(); - for (size_t i = 0; i < layer->children().size(); ++i) - layerImpl->AddChild(synchronizeTreesRecursiveInternal(newLayers, oldLayers, layer->child_at(i), treeImpl)); - - layerImpl->SetMaskLayer(synchronizeTreesRecursiveInternal(newLayers, oldLayers, layer->mask_layer(), treeImpl)); - layerImpl->SetReplicaLayer(synchronizeTreesRecursiveInternal(newLayers, oldLayers, layer->replica_layer(), treeImpl)); - - // Remove all dangling pointers. The pointers will be setup later in updateScrollbarLayerPointersRecursive phase - layerImpl->SetHorizontalScrollbarLayer(NULL); - layerImpl->SetVerticalScrollbarLayer(NULL); - - return layerImpl.Pass(); +scoped_ptr<LayerImpl> SynchronizeTreesRecursiveInternal( + RawPtrLayerImplMap* new_layers, + ScopedPtrLayerImplMap* old_layers, + LayerType* layer, + LayerTreeImpl* tree_impl) { + if (!layer) + return scoped_ptr<LayerImpl>(); + + scoped_ptr<LayerImpl> layer_impl = + ReuseOrCreateLayerImpl(new_layers, old_layers, layer, tree_impl); + + layer_impl->ClearChildList(); + for (size_t i = 0; i < layer->children().size(); ++i) { + layer_impl->AddChild(SynchronizeTreesRecursiveInternal( + new_layers, old_layers, layer->child_at(i), tree_impl)); + } + + layer_impl->SetMaskLayer(SynchronizeTreesRecursiveInternal( + new_layers, old_layers, layer->mask_layer(), tree_impl)); + layer_impl->SetReplicaLayer(SynchronizeTreesRecursiveInternal( + new_layers, old_layers, layer->replica_layer(), tree_impl)); + + // Remove all dangling pointers. The pointers will be setup later in + // UpdateScrollbarLayerPointersRecursive phase + layer_impl->SetHorizontalScrollbarLayer(NULL); + layer_impl->SetVerticalScrollbarLayer(NULL); + + return layer_impl.Pass(); } -scoped_ptr<LayerImpl> synchronizeTreesRecursive(RawPtrLayerImplMap& newLayers, ScopedPtrLayerImplMap& oldLayers, Layer* layer, LayerTreeImpl* treeImpl) -{ - return synchronizeTreesRecursiveInternal(newLayers, oldLayers, layer, treeImpl); +scoped_ptr<LayerImpl> SynchronizeTreesRecursive( + RawPtrLayerImplMap* new_layers, + ScopedPtrLayerImplMap* old_layers, + Layer* layer, + LayerTreeImpl* tree_impl) { + return SynchronizeTreesRecursiveInternal( + new_layers, old_layers, layer, tree_impl); } -scoped_ptr<LayerImpl> synchronizeTreesRecursive(RawPtrLayerImplMap& newLayers, ScopedPtrLayerImplMap& oldLayers, LayerImpl* layer, LayerTreeImpl* treeImpl) -{ - return synchronizeTreesRecursiveInternal(newLayers, oldLayers, layer, treeImpl); +scoped_ptr<LayerImpl> SynchronizeTreesRecursive( + RawPtrLayerImplMap* new_layers, + ScopedPtrLayerImplMap* old_layers, + LayerImpl* layer, + LayerTreeImpl* tree_impl) { + return SynchronizeTreesRecursiveInternal( + new_layers, old_layers, layer, tree_impl); } template <typename LayerType, typename ScrollbarLayerType> -void updateScrollbarLayerPointersRecursiveInternal(const RawPtrLayerImplMap& newLayers, LayerType* layer) -{ - if (!layer) - return; - - for (size_t i = 0; i < layer->children().size(); ++i) - updateScrollbarLayerPointersRecursiveInternal<LayerType, ScrollbarLayerType>(newLayers, layer->child_at(i)); - - ScrollbarLayerType* scrollbarLayer = layer->ToScrollbarLayer(); - if (!scrollbarLayer) - return; - - RawPtrLayerImplMap::const_iterator iter = newLayers.find(scrollbarLayer->id()); - ScrollbarLayerImpl* scrollbarLayerImpl = iter != newLayers.end() ? static_cast<ScrollbarLayerImpl*>(iter->second) : NULL; - iter = newLayers.find(scrollbarLayer->scroll_layer_id()); - LayerImpl* scrollLayerImpl = iter != newLayers.end() ? iter->second : NULL; - - DCHECK(scrollbarLayerImpl); - DCHECK(scrollLayerImpl); - - if (scrollbarLayer->Orientation() == WebKit::WebScrollbar::Horizontal) - scrollLayerImpl->SetHorizontalScrollbarLayer(scrollbarLayerImpl); - else - scrollLayerImpl->SetVerticalScrollbarLayer(scrollbarLayerImpl); +void UpdateScrollbarLayerPointersRecursiveInternal( + const RawPtrLayerImplMap* new_layers, + LayerType* layer) { + if (!layer) + return; + + for (size_t i = 0; i < layer->children().size(); ++i) { + UpdateScrollbarLayerPointersRecursiveInternal< + LayerType, ScrollbarLayerType>(new_layers, layer->child_at(i)); + } + + ScrollbarLayerType* scrollbar_layer = layer->ToScrollbarLayer(); + if (!scrollbar_layer) + return; + + RawPtrLayerImplMap::const_iterator iter = + new_layers->find(scrollbar_layer->id()); + ScrollbarLayerImpl* scrollbar_layer_impl = + iter != new_layers->end() ? static_cast<ScrollbarLayerImpl*>(iter->second) + : NULL; + iter = new_layers->find(scrollbar_layer->scroll_layer_id()); + LayerImpl* scroll_layer_impl = + iter != new_layers->end() ? iter->second : NULL; + + DCHECK(scrollbar_layer_impl); + DCHECK(scroll_layer_impl); + + if (scrollbar_layer->Orientation() == WebKit::WebScrollbar::Horizontal) + scroll_layer_impl->SetHorizontalScrollbarLayer(scrollbar_layer_impl); + else + scroll_layer_impl->SetVerticalScrollbarLayer(scrollbar_layer_impl); } -void updateScrollbarLayerPointersRecursive(const RawPtrLayerImplMap& newLayers, Layer* layer) -{ - updateScrollbarLayerPointersRecursiveInternal<Layer, ScrollbarLayer>(newLayers, layer); +void UpdateScrollbarLayerPointersRecursive(const RawPtrLayerImplMap* new_layers, + Layer* layer) { + UpdateScrollbarLayerPointersRecursiveInternal<Layer, ScrollbarLayer>( + new_layers, layer); } -void updateScrollbarLayerPointersRecursive(const RawPtrLayerImplMap& newLayers, LayerImpl* layer) -{ - updateScrollbarLayerPointersRecursiveInternal<LayerImpl, ScrollbarLayerImpl>(newLayers, layer); +void UpdateScrollbarLayerPointersRecursive(const RawPtrLayerImplMap* new_layers, + LayerImpl* layer) { + UpdateScrollbarLayerPointersRecursiveInternal<LayerImpl, ScrollbarLayerImpl>( + new_layers, layer); } template <typename LayerType> -void pushPropertiesInternal(LayerType* layer, LayerImpl* layerImpl) -{ - if (!layer) { - DCHECK(!layerImpl); - return; - } +void PushPropertiesInternal(LayerType* layer, LayerImpl* layer_impl) { + if (!layer) { + DCHECK(!layer_impl); + return; + } - DCHECK_EQ(layer->id(), layerImpl->id()); - layer->PushPropertiesTo(layerImpl); + DCHECK_EQ(layer->id(), layer_impl->id()); + layer->PushPropertiesTo(layer_impl); - pushPropertiesInternal(layer->mask_layer(), layerImpl->mask_layer()); - pushPropertiesInternal(layer->replica_layer(), layerImpl->replica_layer()); + PushPropertiesInternal(layer->mask_layer(), layer_impl->mask_layer()); + PushPropertiesInternal(layer->replica_layer(), layer_impl->replica_layer()); - const ScopedPtrVector<LayerImpl>& implChildren = layerImpl->children(); - DCHECK_EQ(layer->children().size(), implChildren.size()); + const ScopedPtrVector<LayerImpl>& impl_children = layer_impl->children(); + DCHECK_EQ(layer->children().size(), impl_children.size()); - for (size_t i = 0; i < layer->children().size(); ++i) { - pushPropertiesInternal(layer->child_at(i), implChildren[i]); - } + for (size_t i = 0; i < layer->children().size(); ++i) { + PushPropertiesInternal(layer->child_at(i), impl_children[i]); + } } -void TreeSynchronizer::pushProperties(Layer* layer, LayerImpl* layerImpl) -{ - pushPropertiesInternal(layer, layerImpl); +void TreeSynchronizer::PushProperties(Layer* layer, LayerImpl* layer_impl) { + PushPropertiesInternal(layer, layer_impl); } -void TreeSynchronizer::pushProperties(LayerImpl* layer, LayerImpl* layerImpl) -{ - pushPropertiesInternal(layer, layerImpl); +void TreeSynchronizer::PushProperties(LayerImpl* layer, LayerImpl* layer_impl) { + PushPropertiesInternal(layer, layer_impl); } - } // namespace cc diff --git a/cc/tree_synchronizer.h b/cc/tree_synchronizer.h index d0349c0..2bc8adf 100644 --- a/cc/tree_synchronizer.h +++ b/cc/tree_synchronizer.h @@ -17,23 +17,30 @@ class LayerTreeImpl; class Layer; class CC_EXPORT TreeSynchronizer { -public: - // Accepts a Layer tree and returns a reference to a LayerImpl tree that duplicates the structure - // of the Layer tree, reusing the LayerImpls in the tree provided by oldLayerImplRoot if possible. - static scoped_ptr<LayerImpl> synchronizeTrees(Layer* layerRoot, scoped_ptr<LayerImpl> oldLayerImplRoot, LayerTreeImpl*); - static scoped_ptr<LayerImpl> synchronizeTrees(LayerImpl* layerRoot, scoped_ptr<LayerImpl> oldLayerImplRoot, LayerTreeImpl*); - - // Pushes properties from a Layer or LayerImpl tree to a structurally equivalent - // LayerImpl tree. - static void pushProperties(Layer* layerRoot, LayerImpl* layerImplRoot); - static void pushProperties(LayerImpl* layerRoot, LayerImpl* layerImplRoot); - -private: - TreeSynchronizer(); // Not instantiable. - - DISALLOW_COPY_AND_ASSIGN(TreeSynchronizer); + public: + // Accepts a Layer tree and returns a reference to a LayerImpl tree that + // duplicates the structure of the Layer tree, reusing the LayerImpls in the + // tree provided by old_layer_impl_root if possible. + static scoped_ptr<LayerImpl> SynchronizeTrees( + Layer* layer_root, + scoped_ptr<LayerImpl> old_layer_impl_root, + LayerTreeImpl* tree_impl); + static scoped_ptr<LayerImpl> SynchronizeTrees( + LayerImpl* layer_root, + scoped_ptr<LayerImpl> old_layer_impl_root, + LayerTreeImpl* tree_impl); + + // Pushes properties from a Layer or LayerImpl tree to a structurally + // equivalent LayerImpl tree. + static void PushProperties(Layer* layer_root, LayerImpl* layer_impl_root); + static void PushProperties(LayerImpl* layer_root, LayerImpl* layer_impl_root); + + private: + TreeSynchronizer(); // Not instantiable. + + DISALLOW_COPY_AND_ASSIGN(TreeSynchronizer); }; -} // namespace cc +} // namespace cc #endif // CC_TREE_SYNCHRONIZER_H_ diff --git a/cc/tree_synchronizer_unittest.cc b/cc/tree_synchronizer_unittest.cc index 88d4436..d2acd186 100644 --- a/cc/tree_synchronizer_unittest.cc +++ b/cc/tree_synchronizer_unittest.cc @@ -20,383 +20,494 @@ namespace cc { namespace { class MockLayerImpl : public LayerImpl { -public: - static scoped_ptr<MockLayerImpl> Create(LayerTreeImpl* treeImpl, int layerId) - { - return make_scoped_ptr(new MockLayerImpl(treeImpl, layerId)); - } - virtual ~MockLayerImpl() - { - if (m_layerImplDestructionList) - m_layerImplDestructionList->push_back(id()); - } - - void setLayerImplDestructionList(std::vector<int>* list) { m_layerImplDestructionList = list; } - -private: - MockLayerImpl(LayerTreeImpl* treeImpl, int layerId) - : LayerImpl(treeImpl, layerId) - , m_layerImplDestructionList(0) - { - } - - std::vector<int>* m_layerImplDestructionList; + public: + static scoped_ptr<MockLayerImpl> Create(LayerTreeImpl* tree_impl, + int layer_id) { + return make_scoped_ptr(new MockLayerImpl(tree_impl, layer_id)); + } + virtual ~MockLayerImpl() { + if (layer_impl_destruction_list_) + layer_impl_destruction_list_->push_back(id()); + } + + void SetLayerImplDestructionList(std::vector<int>* list) { + layer_impl_destruction_list_ = list; + } + + private: + MockLayerImpl(LayerTreeImpl* tree_impl, int layer_id) + : LayerImpl(tree_impl, layer_id), + layer_impl_destruction_list_(NULL) {} + + std::vector<int>* layer_impl_destruction_list_; }; class MockLayer : public Layer { -public: - static scoped_refptr<MockLayer> Create(std::vector<int>* layerImplDestructionList) - { - return make_scoped_refptr(new MockLayer(layerImplDestructionList)); - } - - virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* treeImpl) OVERRIDE - { - return MockLayerImpl::Create(treeImpl, layer_id_).PassAs<LayerImpl>(); - } - - virtual void PushPropertiesTo(LayerImpl* layerImpl) OVERRIDE - { - Layer::PushPropertiesTo(layerImpl); - - MockLayerImpl* mockLayerImpl = static_cast<MockLayerImpl*>(layerImpl); - mockLayerImpl->setLayerImplDestructionList(m_layerImplDestructionList); - } - -private: - MockLayer(std::vector<int>* layerImplDestructionList) - : Layer() - , m_layerImplDestructionList(layerImplDestructionList) - { - } - virtual ~MockLayer() { } - - std::vector<int>* m_layerImplDestructionList; + public: + static scoped_refptr<MockLayer> Create( + std::vector<int>* layer_impl_destruction_list) { + return make_scoped_refptr(new MockLayer(layer_impl_destruction_list)); + } + + virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) + OVERRIDE { + return MockLayerImpl::Create(tree_impl, layer_id_).PassAs<LayerImpl>(); + } + + virtual void PushPropertiesTo(LayerImpl* layer_impl) OVERRIDE { + Layer::PushPropertiesTo(layer_impl); + + MockLayerImpl* mock_layer_impl = static_cast<MockLayerImpl*>(layer_impl); + mock_layer_impl->SetLayerImplDestructionList(layer_impl_destruction_list_); + } + + private: + MockLayer(std::vector<int>* layer_impl_destruction_list) + : Layer(), layer_impl_destruction_list_(layer_impl_destruction_list) {} + virtual ~MockLayer() {} + + std::vector<int>* layer_impl_destruction_list_; }; class FakeLayerAnimationController : public LayerAnimationController { -public: - static scoped_refptr<LayerAnimationController> Create() - { - return static_cast<LayerAnimationController*>(new FakeLayerAnimationController); - } + public: + static scoped_refptr<LayerAnimationController> Create() { + return static_cast<LayerAnimationController*>( + new FakeLayerAnimationController); + } - bool synchronizedAnimations() const { return m_synchronizedAnimations; } + bool SynchronizedAnimations() const { return synchronized_animations_; } -private: - FakeLayerAnimationController() - : LayerAnimationController(1) - , m_synchronizedAnimations(false) - { } + private: + FakeLayerAnimationController() + : LayerAnimationController(1), + synchronized_animations_(false) {} - virtual ~FakeLayerAnimationController() { } + virtual ~FakeLayerAnimationController() {} - virtual void PushAnimationUpdatesTo(LayerAnimationController* controllerImpl) OVERRIDE - { - LayerAnimationController::PushAnimationUpdatesTo(controllerImpl); - m_synchronizedAnimations = true; - } + virtual void PushAnimationUpdatesTo(LayerAnimationController* controller_impl) + OVERRIDE { + LayerAnimationController::PushAnimationUpdatesTo(controller_impl); + synchronized_animations_ = true; + } - bool m_synchronizedAnimations; + bool synchronized_animations_; }; -void expectTreesAreIdentical(Layer* layer, LayerImpl* layerImpl, LayerTreeImpl* treeImpl) -{ - ASSERT_TRUE(layer); - ASSERT_TRUE(layerImpl); +void ExpectTreesAreIdentical(Layer* layer, + LayerImpl* layer_impl, + LayerTreeImpl* tree_impl) { + ASSERT_TRUE(layer); + ASSERT_TRUE(layer_impl); - EXPECT_EQ(layer->id(), layerImpl->id()); - EXPECT_EQ(layerImpl->layer_tree_impl(), treeImpl); + EXPECT_EQ(layer->id(), layer_impl->id()); + EXPECT_EQ(layer_impl->layer_tree_impl(), tree_impl); - EXPECT_EQ(layer->non_fast_scrollable_region(), layerImpl->non_fast_scrollable_region()); + EXPECT_EQ(layer->non_fast_scrollable_region(), + layer_impl->non_fast_scrollable_region()); - ASSERT_EQ(!!layer->mask_layer(), !!layerImpl->mask_layer()); - if (layer->mask_layer()) - expectTreesAreIdentical(layer->mask_layer(), layerImpl->mask_layer(), treeImpl); + ASSERT_EQ(!!layer->mask_layer(), !!layer_impl->mask_layer()); + if (layer->mask_layer()) { + ExpectTreesAreIdentical( + layer->mask_layer(), layer_impl->mask_layer(), tree_impl); + } - ASSERT_EQ(!!layer->replica_layer(), !!layerImpl->replica_layer()); - if (layer->replica_layer()) - expectTreesAreIdentical(layer->replica_layer(), layerImpl->replica_layer(), treeImpl); + ASSERT_EQ(!!layer->replica_layer(), !!layer_impl->replica_layer()); + if (layer->replica_layer()) { + ExpectTreesAreIdentical( + layer->replica_layer(), layer_impl->replica_layer(), tree_impl); + } - const std::vector<scoped_refptr<Layer> >& layerChildren = layer->children(); - const ScopedPtrVector<LayerImpl>& layerImplChildren = layerImpl->children(); + const std::vector<scoped_refptr<Layer> >& layer_children = layer->children(); + const ScopedPtrVector<LayerImpl>& layer_impl_children = + layer_impl->children(); - ASSERT_EQ(layerChildren.size(), layerImplChildren.size()); + ASSERT_EQ(layer_children.size(), layer_impl_children.size()); - for (size_t i = 0; i < layerChildren.size(); ++i) - expectTreesAreIdentical(layerChildren[i].get(), layerImplChildren[i], treeImpl); + for (size_t i = 0; i < layer_children.size(); ++i) { + ExpectTreesAreIdentical( + layer_children[i].get(), layer_impl_children[i], tree_impl); + } } class TreeSynchronizerTest : public testing::Test { -public: - TreeSynchronizerTest() - : m_hostImpl(&m_proxy) - { - } - -protected: - FakeImplProxy m_proxy; - FakeLayerTreeHostImpl m_hostImpl; + public: + TreeSynchronizerTest() : host_impl_(&proxy_) {} + + protected: + FakeImplProxy proxy_; + FakeLayerTreeHostImpl host_impl_; }; // Attempts to synchronizes a null tree. This should not crash, and should // return a null tree. -TEST_F(TreeSynchronizerTest, syncNullTree) -{ - scoped_ptr<LayerImpl> layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(static_cast<Layer*>(NULL), scoped_ptr<LayerImpl>(), m_hostImpl.active_tree()); +TEST_F(TreeSynchronizerTest, SyncNullTree) { + scoped_ptr<LayerImpl> layer_impl_tree_root = + TreeSynchronizer::SynchronizeTrees(static_cast<Layer*>(NULL), + scoped_ptr<LayerImpl>(), + host_impl_.active_tree()); - EXPECT_TRUE(!layerImplTreeRoot.get()); + EXPECT_TRUE(!layer_impl_tree_root.get()); } -// Constructs a very simple tree and synchronizes it without trying to reuse any preexisting layers. -TEST_F(TreeSynchronizerTest, syncSimpleTreeFromEmpty) -{ - scoped_refptr<Layer> layerTreeRoot = Layer::Create(); - layerTreeRoot->AddChild(Layer::Create()); - layerTreeRoot->AddChild(Layer::Create()); - - scoped_ptr<LayerImpl> layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), scoped_ptr<LayerImpl>(), m_hostImpl.active_tree()); - - expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.active_tree()); +// Constructs a very simple tree and synchronizes it without trying to reuse any +// preexisting layers. +TEST_F(TreeSynchronizerTest, SyncSimpleTreeFromEmpty) { + scoped_refptr<Layer> layer_tree_root = Layer::Create(); + layer_tree_root->AddChild(Layer::Create()); + layer_tree_root->AddChild(Layer::Create()); + + scoped_ptr<LayerImpl> layer_impl_tree_root = + TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), + scoped_ptr<LayerImpl>(), + host_impl_.active_tree()); + + ExpectTreesAreIdentical(layer_tree_root.get(), + layer_impl_tree_root.get(), + host_impl_.active_tree()); } -// Constructs a very simple tree and synchronizes it attempting to reuse some layers -TEST_F(TreeSynchronizerTest, syncSimpleTreeReusingLayers) -{ - std::vector<int> layerImplDestructionList; - - scoped_refptr<Layer> layerTreeRoot = MockLayer::Create(&layerImplDestructionList); - layerTreeRoot->AddChild(MockLayer::Create(&layerImplDestructionList)); - layerTreeRoot->AddChild(MockLayer::Create(&layerImplDestructionList)); - - scoped_ptr<LayerImpl> layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), scoped_ptr<LayerImpl>(), m_hostImpl.active_tree()); - expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.active_tree()); - - // We have to push properties to pick up the destruction list pointer. - TreeSynchronizer::pushProperties(layerTreeRoot.get(), layerImplTreeRoot.get()); - - // Add a new layer to the Layer side - layerTreeRoot->children()[0]->AddChild(MockLayer::Create(&layerImplDestructionList)); - // Remove one. - layerTreeRoot->children()[1]->RemoveFromParent(); - int secondLayerImplId = layerImplTreeRoot->children()[1]->id(); - - // Synchronize again. After the sync the trees should be equivalent and we should have created and destroyed one LayerImpl. - layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), layerImplTreeRoot.Pass(), m_hostImpl.active_tree()); - expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.active_tree()); - - ASSERT_EQ(1u, layerImplDestructionList.size()); - EXPECT_EQ(secondLayerImplId, layerImplDestructionList[0]); +// Constructs a very simple tree and synchronizes it attempting to reuse some +// layers +TEST_F(TreeSynchronizerTest, SyncSimpleTreeReusingLayers) { + std::vector<int> layer_impl_destruction_list; + + scoped_refptr<Layer> layer_tree_root = + MockLayer::Create(&layer_impl_destruction_list); + layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list)); + layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list)); + + scoped_ptr<LayerImpl> layer_impl_tree_root = + TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), + scoped_ptr<LayerImpl>(), + host_impl_.active_tree()); + ExpectTreesAreIdentical(layer_tree_root.get(), + layer_impl_tree_root.get(), + host_impl_.active_tree()); + + // We have to push properties to pick up the destruction list pointer. + TreeSynchronizer::PushProperties(layer_tree_root.get(), + layer_impl_tree_root.get()); + + // Add a new layer to the Layer side + layer_tree_root->children()[0]-> + AddChild(MockLayer::Create(&layer_impl_destruction_list)); + // Remove one. + layer_tree_root->children()[1]->RemoveFromParent(); + int second_layer_impl_id = layer_impl_tree_root->children()[1]->id(); + + // Synchronize again. After the sync the trees should be equivalent and we + // should have created and destroyed one LayerImpl. + layer_impl_tree_root = + TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), + layer_impl_tree_root.Pass(), + host_impl_.active_tree()); + ExpectTreesAreIdentical(layer_tree_root.get(), + layer_impl_tree_root.get(), + host_impl_.active_tree()); + + ASSERT_EQ(1u, layer_impl_destruction_list.size()); + EXPECT_EQ(second_layer_impl_id, layer_impl_destruction_list[0]); } -// Constructs a very simple tree and checks that a stacking-order change is tracked properly. -TEST_F(TreeSynchronizerTest, syncSimpleTreeAndTrackStackingOrderChange) -{ - std::vector<int> layerImplDestructionList; - - // Set up the tree and sync once. child2 needs to be synced here, too, even though we - // remove it to set up the intended scenario. - scoped_refptr<Layer> layerTreeRoot = MockLayer::Create(&layerImplDestructionList); - scoped_refptr<Layer> child2 = MockLayer::Create(&layerImplDestructionList); - layerTreeRoot->AddChild(MockLayer::Create(&layerImplDestructionList)); - layerTreeRoot->AddChild(child2); - scoped_ptr<LayerImpl> layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), scoped_ptr<LayerImpl>(), m_hostImpl.active_tree()); - expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.active_tree()); - - // We have to push properties to pick up the destruction list pointer. - TreeSynchronizer::pushProperties(layerTreeRoot.get(), layerImplTreeRoot.get()); - - layerImplTreeRoot->ResetAllChangeTrackingForSubtree(); - - // re-insert the layer and sync again. - child2->RemoveFromParent(); - layerTreeRoot->AddChild(child2); - layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), layerImplTreeRoot.Pass(), m_hostImpl.active_tree()); - expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.active_tree()); - - TreeSynchronizer::pushProperties(layerTreeRoot.get(), layerImplTreeRoot.get()); - - // Check that the impl thread properly tracked the change. - EXPECT_FALSE(layerImplTreeRoot->LayerPropertyChanged()); - EXPECT_FALSE(layerImplTreeRoot->children()[0]->LayerPropertyChanged()); - EXPECT_TRUE(layerImplTreeRoot->children()[1]->LayerPropertyChanged()); +// Constructs a very simple tree and checks that a stacking-order change is +// tracked properly. +TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndTrackStackingOrderChange) { + std::vector<int> layer_impl_destruction_list; + + // Set up the tree and sync once. child2 needs to be synced here, too, even + // though we remove it to set up the intended scenario. + scoped_refptr<Layer> layer_tree_root = + MockLayer::Create(&layer_impl_destruction_list); + scoped_refptr<Layer> child2 = MockLayer::Create(&layer_impl_destruction_list); + layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list)); + layer_tree_root->AddChild(child2); + scoped_ptr<LayerImpl> layer_impl_tree_root = + TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), + scoped_ptr<LayerImpl>(), + host_impl_.active_tree()); + ExpectTreesAreIdentical(layer_tree_root.get(), + layer_impl_tree_root.get(), + host_impl_.active_tree()); + + // We have to push properties to pick up the destruction list pointer. + TreeSynchronizer::PushProperties(layer_tree_root.get(), + layer_impl_tree_root.get()); + + layer_impl_tree_root->ResetAllChangeTrackingForSubtree(); + + // re-insert the layer and sync again. + child2->RemoveFromParent(); + layer_tree_root->AddChild(child2); + layer_impl_tree_root = + TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), + layer_impl_tree_root.Pass(), + host_impl_.active_tree()); + ExpectTreesAreIdentical(layer_tree_root.get(), + layer_impl_tree_root.get(), + host_impl_.active_tree()); + + TreeSynchronizer::PushProperties(layer_tree_root.get(), + layer_impl_tree_root.get()); + + // Check that the impl thread properly tracked the change. + EXPECT_FALSE(layer_impl_tree_root->LayerPropertyChanged()); + EXPECT_FALSE(layer_impl_tree_root->children()[0]->LayerPropertyChanged()); + EXPECT_TRUE(layer_impl_tree_root->children()[1]->LayerPropertyChanged()); } -TEST_F(TreeSynchronizerTest, syncSimpleTreeAndProperties) -{ - scoped_refptr<Layer> layerTreeRoot = Layer::Create(); - layerTreeRoot->AddChild(Layer::Create()); - layerTreeRoot->AddChild(Layer::Create()); - - // Pick some random properties to set. The values are not important, we're just testing that at least some properties are making it through. - gfx::PointF rootPosition = gfx::PointF(2.3f, 7.4f); - layerTreeRoot->SetPosition(rootPosition); - - float firstChildOpacity = 0.25f; - layerTreeRoot->children()[0]->SetOpacity(firstChildOpacity); - - gfx::Size secondChildBounds = gfx::Size(25, 53); - layerTreeRoot->children()[1]->SetBounds(secondChildBounds); - - scoped_ptr<LayerImpl> layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), scoped_ptr<LayerImpl>(), m_hostImpl.active_tree()); - expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.active_tree()); - - TreeSynchronizer::pushProperties(layerTreeRoot.get(), layerImplTreeRoot.get()); - - // Check that the property values we set on the Layer tree are reflected in the LayerImpl tree. - gfx::PointF rootLayerImplPosition = layerImplTreeRoot->position(); - EXPECT_EQ(rootPosition.x(), rootLayerImplPosition.x()); - EXPECT_EQ(rootPosition.y(), rootLayerImplPosition.y()); - - EXPECT_EQ(firstChildOpacity, layerImplTreeRoot->children()[0]->opacity()); - - gfx::Size secondLayerImplChildBounds = layerImplTreeRoot->children()[1]->bounds(); - EXPECT_EQ(secondChildBounds.width(), secondLayerImplChildBounds.width()); - EXPECT_EQ(secondChildBounds.height(), secondLayerImplChildBounds.height()); +TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndProperties) { + scoped_refptr<Layer> layer_tree_root = Layer::Create(); + layer_tree_root->AddChild(Layer::Create()); + layer_tree_root->AddChild(Layer::Create()); + + // Pick some random properties to set. The values are not important, we're + // just testing that at least some properties are making it through. + gfx::PointF root_position = gfx::PointF(2.3f, 7.4f); + layer_tree_root->SetPosition(root_position); + + float first_child_opacity = 0.25f; + layer_tree_root->children()[0]->SetOpacity(first_child_opacity); + + gfx::Size second_child_bounds = gfx::Size(25, 53); + layer_tree_root->children()[1]->SetBounds(second_child_bounds); + + scoped_ptr<LayerImpl> layer_impl_tree_root = + TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), + scoped_ptr<LayerImpl>(), + host_impl_.active_tree()); + ExpectTreesAreIdentical(layer_tree_root.get(), + layer_impl_tree_root.get(), + host_impl_.active_tree()); + + TreeSynchronizer::PushProperties(layer_tree_root.get(), + layer_impl_tree_root.get()); + + // Check that the property values we set on the Layer tree are reflected in + // the LayerImpl tree. + gfx::PointF root_layer_impl_position = layer_impl_tree_root->position(); + EXPECT_EQ(root_position.x(), root_layer_impl_position.x()); + EXPECT_EQ(root_position.y(), root_layer_impl_position.y()); + + EXPECT_EQ(first_child_opacity, + layer_impl_tree_root->children()[0]->opacity()); + + gfx::Size second_layer_impl_child_bounds = + layer_impl_tree_root->children()[1]->bounds(); + EXPECT_EQ(second_child_bounds.width(), + second_layer_impl_child_bounds.width()); + EXPECT_EQ(second_child_bounds.height(), + second_layer_impl_child_bounds.height()); } -TEST_F(TreeSynchronizerTest, reuseLayerImplsAfterStructuralChange) -{ - std::vector<int> layerImplDestructionList; - - // Set up a tree with this sort of structure: - // root --- A --- B ---+--- C - // | - // +--- D - scoped_refptr<Layer> layerTreeRoot = MockLayer::Create(&layerImplDestructionList); - layerTreeRoot->AddChild(MockLayer::Create(&layerImplDestructionList)); - - scoped_refptr<Layer> layerA = layerTreeRoot->children()[0].get(); - layerA->AddChild(MockLayer::Create(&layerImplDestructionList)); - - scoped_refptr<Layer> layerB = layerA->children()[0].get(); - layerB->AddChild(MockLayer::Create(&layerImplDestructionList)); - - scoped_refptr<Layer> layerC = layerB->children()[0].get(); - layerB->AddChild(MockLayer::Create(&layerImplDestructionList)); - scoped_refptr<Layer> layerD = layerB->children()[1].get(); - - scoped_ptr<LayerImpl> layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), scoped_ptr<LayerImpl>(), m_hostImpl.active_tree()); - expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.active_tree()); - - // We have to push properties to pick up the destruction list pointer. - TreeSynchronizer::pushProperties(layerTreeRoot.get(), layerImplTreeRoot.get()); - - // Now restructure the tree to look like this: - // root --- D ---+--- A - // | - // +--- C --- B - layerTreeRoot->RemoveAllChildren(); - layerD->RemoveAllChildren(); - layerTreeRoot->AddChild(layerD); - layerA->RemoveAllChildren(); - layerD->AddChild(layerA); - layerC->RemoveAllChildren(); - layerD->AddChild(layerC); - layerB->RemoveAllChildren(); - layerC->AddChild(layerB); - - // After another synchronize our trees should match and we should not have destroyed any LayerImpls - layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), layerImplTreeRoot.Pass(), m_hostImpl.active_tree()); - expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.active_tree()); - - EXPECT_EQ(0u, layerImplDestructionList.size()); +TEST_F(TreeSynchronizerTest, ReuseLayerImplsAfterStructuralChange) { + std::vector<int> layer_impl_destruction_list; + + // Set up a tree with this sort of structure: + // root --- A --- B ---+--- C + // | + // +--- D + scoped_refptr<Layer> layer_tree_root = + MockLayer::Create(&layer_impl_destruction_list); + layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list)); + + scoped_refptr<Layer> layer_a = layer_tree_root->children()[0].get(); + layer_a->AddChild(MockLayer::Create(&layer_impl_destruction_list)); + + scoped_refptr<Layer> layer_b = layer_a->children()[0].get(); + layer_b->AddChild(MockLayer::Create(&layer_impl_destruction_list)); + + scoped_refptr<Layer> layer_c = layer_b->children()[0].get(); + layer_b->AddChild(MockLayer::Create(&layer_impl_destruction_list)); + scoped_refptr<Layer> layer_d = layer_b->children()[1].get(); + + scoped_ptr<LayerImpl> layer_impl_tree_root = + TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), + scoped_ptr<LayerImpl>(), + host_impl_.active_tree()); + ExpectTreesAreIdentical(layer_tree_root.get(), + layer_impl_tree_root.get(), + host_impl_.active_tree()); + + // We have to push properties to pick up the destruction list pointer. + TreeSynchronizer::PushProperties(layer_tree_root.get(), + layer_impl_tree_root.get()); + + // Now restructure the tree to look like this: + // root --- D ---+--- A + // | + // +--- C --- B + layer_tree_root->RemoveAllChildren(); + layer_d->RemoveAllChildren(); + layer_tree_root->AddChild(layer_d); + layer_a->RemoveAllChildren(); + layer_d->AddChild(layer_a); + layer_c->RemoveAllChildren(); + layer_d->AddChild(layer_c); + layer_b->RemoveAllChildren(); + layer_c->AddChild(layer_b); + + // After another synchronize our trees should match and we should not have + // destroyed any LayerImpls + layer_impl_tree_root = + TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), + layer_impl_tree_root.Pass(), + host_impl_.active_tree()); + ExpectTreesAreIdentical(layer_tree_root.get(), + layer_impl_tree_root.get(), + host_impl_.active_tree()); + + EXPECT_EQ(0u, layer_impl_destruction_list.size()); } -// Constructs a very simple tree, synchronizes it, then synchronizes to a totally new tree. All layers from the old tree should be deleted. -TEST_F(TreeSynchronizerTest, syncSimpleTreeThenDestroy) -{ - std::vector<int> layerImplDestructionList; - - scoped_refptr<Layer> oldLayerTreeRoot = MockLayer::Create(&layerImplDestructionList); - oldLayerTreeRoot->AddChild(MockLayer::Create(&layerImplDestructionList)); - oldLayerTreeRoot->AddChild(MockLayer::Create(&layerImplDestructionList)); - - int oldTreeRootLayerId = oldLayerTreeRoot->id(); - int oldTreeFirstChildLayerId = oldLayerTreeRoot->children()[0]->id(); - int oldTreeSecondChildLayerId = oldLayerTreeRoot->children()[1]->id(); - - scoped_ptr<LayerImpl> layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(oldLayerTreeRoot.get(), scoped_ptr<LayerImpl>(), m_hostImpl.active_tree()); - expectTreesAreIdentical(oldLayerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.active_tree()); - - // We have to push properties to pick up the destruction list pointer. - TreeSynchronizer::pushProperties(oldLayerTreeRoot.get(), layerImplTreeRoot.get()); - - // Remove all children on the Layer side. - oldLayerTreeRoot->RemoveAllChildren(); - - // Synchronize again. After the sync all LayerImpls from the old tree should be deleted. - scoped_refptr<Layer> newLayerTreeRoot = Layer::Create(); - layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(newLayerTreeRoot.get(), layerImplTreeRoot.Pass(), m_hostImpl.active_tree()); - expectTreesAreIdentical(newLayerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.active_tree()); - - ASSERT_EQ(3u, layerImplDestructionList.size()); - - EXPECT_TRUE(std::find(layerImplDestructionList.begin(), layerImplDestructionList.end(), oldTreeRootLayerId) != layerImplDestructionList.end()); - EXPECT_TRUE(std::find(layerImplDestructionList.begin(), layerImplDestructionList.end(), oldTreeFirstChildLayerId) != layerImplDestructionList.end()); - EXPECT_TRUE(std::find(layerImplDestructionList.begin(), layerImplDestructionList.end(), oldTreeSecondChildLayerId) != layerImplDestructionList.end()); +// Constructs a very simple tree, synchronizes it, then synchronizes to a +// totally new tree. All layers from the old tree should be deleted. +TEST_F(TreeSynchronizerTest, SyncSimpleTreeThenDestroy) { + std::vector<int> layer_impl_destruction_list; + + scoped_refptr<Layer> old_layer_tree_root = + MockLayer::Create(&layer_impl_destruction_list); + old_layer_tree_root->AddChild( + MockLayer::Create(&layer_impl_destruction_list)); + old_layer_tree_root->AddChild( + MockLayer::Create(&layer_impl_destruction_list)); + + int old_tree_root_layer_id = old_layer_tree_root->id(); + int old_tree_first_child_layer_id = old_layer_tree_root->children()[0]->id(); + int old_tree_second_child_layer_id = old_layer_tree_root->children()[1]->id(); + + scoped_ptr<LayerImpl> layer_impl_tree_root = + TreeSynchronizer::SynchronizeTrees(old_layer_tree_root.get(), + scoped_ptr<LayerImpl>(), + host_impl_.active_tree()); + ExpectTreesAreIdentical(old_layer_tree_root.get(), + layer_impl_tree_root.get(), + host_impl_.active_tree()); + + // We have to push properties to pick up the destruction list pointer. + TreeSynchronizer::PushProperties(old_layer_tree_root.get(), + layer_impl_tree_root.get()); + + // Remove all children on the Layer side. + old_layer_tree_root->RemoveAllChildren(); + + // Synchronize again. After the sync all LayerImpls from the old tree should + // be deleted. + scoped_refptr<Layer> new_layer_tree_root = Layer::Create(); + layer_impl_tree_root = + TreeSynchronizer::SynchronizeTrees(new_layer_tree_root.get(), + layer_impl_tree_root.Pass(), + host_impl_.active_tree()); + ExpectTreesAreIdentical(new_layer_tree_root.get(), + layer_impl_tree_root.get(), + host_impl_.active_tree()); + + ASSERT_EQ(3u, layer_impl_destruction_list.size()); + + EXPECT_TRUE(std::find(layer_impl_destruction_list.begin(), + layer_impl_destruction_list.end(), + old_tree_root_layer_id) != + layer_impl_destruction_list.end()); + EXPECT_TRUE(std::find(layer_impl_destruction_list.begin(), + layer_impl_destruction_list.end(), + old_tree_first_child_layer_id) != + layer_impl_destruction_list.end()); + EXPECT_TRUE(std::find(layer_impl_destruction_list.begin(), + layer_impl_destruction_list.end(), + old_tree_second_child_layer_id) != + layer_impl_destruction_list.end()); } // Constructs+syncs a tree with mask, replica, and replica mask layers. -TEST_F(TreeSynchronizerTest, syncMaskReplicaAndReplicaMaskLayers) -{ - scoped_refptr<Layer> layerTreeRoot = Layer::Create(); - layerTreeRoot->AddChild(Layer::Create()); - layerTreeRoot->AddChild(Layer::Create()); - layerTreeRoot->AddChild(Layer::Create()); - - // First child gets a mask layer. - scoped_refptr<Layer> maskLayer = Layer::Create(); - layerTreeRoot->children()[0]->SetMaskLayer(maskLayer.get()); - - // Second child gets a replica layer. - scoped_refptr<Layer> replicaLayer = Layer::Create(); - layerTreeRoot->children()[1]->SetReplicaLayer(replicaLayer.get()); - - // Third child gets a replica layer with a mask layer. - scoped_refptr<Layer> replicaLayerWithMask = Layer::Create(); - scoped_refptr<Layer> replicaMaskLayer = Layer::Create(); - replicaLayerWithMask->SetMaskLayer(replicaMaskLayer.get()); - layerTreeRoot->children()[2]->SetReplicaLayer(replicaLayerWithMask.get()); - - scoped_ptr<LayerImpl> layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), scoped_ptr<LayerImpl>(), m_hostImpl.active_tree()); - - expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.active_tree()); - - // Remove the mask layer. - layerTreeRoot->children()[0]->SetMaskLayer(0); - layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), layerImplTreeRoot.Pass(), m_hostImpl.active_tree()); - expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.active_tree()); - - // Remove the replica layer. - layerTreeRoot->children()[1]->SetReplicaLayer(0); - layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), layerImplTreeRoot.Pass(), m_hostImpl.active_tree()); - expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.active_tree()); - - // Remove the replica mask. - replicaLayerWithMask->SetMaskLayer(0); - layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), layerImplTreeRoot.Pass(), m_hostImpl.active_tree()); - expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.active_tree()); +TEST_F(TreeSynchronizerTest, SyncMaskReplicaAndReplicaMaskLayers) { + scoped_refptr<Layer> layer_tree_root = Layer::Create(); + layer_tree_root->AddChild(Layer::Create()); + layer_tree_root->AddChild(Layer::Create()); + layer_tree_root->AddChild(Layer::Create()); + + // First child gets a mask layer. + scoped_refptr<Layer> mask_layer = Layer::Create(); + layer_tree_root->children()[0]->SetMaskLayer(mask_layer.get()); + + // Second child gets a replica layer. + scoped_refptr<Layer> replica_layer = Layer::Create(); + layer_tree_root->children()[1]->SetReplicaLayer(replica_layer.get()); + + // Third child gets a replica layer with a mask layer. + scoped_refptr<Layer> replica_layer_with_mask = Layer::Create(); + scoped_refptr<Layer> replica_mask_layer = Layer::Create(); + replica_layer_with_mask->SetMaskLayer(replica_mask_layer.get()); + layer_tree_root->children()[2]-> + SetReplicaLayer(replica_layer_with_mask.get()); + + scoped_ptr<LayerImpl> layer_impl_tree_root = + TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), + scoped_ptr<LayerImpl>(), + host_impl_.active_tree()); + + ExpectTreesAreIdentical(layer_tree_root.get(), + layer_impl_tree_root.get(), + host_impl_.active_tree()); + + // Remove the mask layer. + layer_tree_root->children()[0]->SetMaskLayer(NULL); + layer_impl_tree_root = + TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), + layer_impl_tree_root.Pass(), + host_impl_.active_tree()); + ExpectTreesAreIdentical(layer_tree_root.get(), + layer_impl_tree_root.get(), + host_impl_.active_tree()); + + // Remove the replica layer. + layer_tree_root->children()[1]->SetReplicaLayer(NULL); + layer_impl_tree_root = + TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), + layer_impl_tree_root.Pass(), + host_impl_.active_tree()); + ExpectTreesAreIdentical(layer_tree_root.get(), + layer_impl_tree_root.get(), + host_impl_.active_tree()); + + // Remove the replica mask. + replica_layer_with_mask->SetMaskLayer(NULL); + layer_impl_tree_root = + TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), + layer_impl_tree_root.Pass(), + host_impl_.active_tree()); + ExpectTreesAreIdentical(layer_tree_root.get(), + layer_impl_tree_root.get(), + host_impl_.active_tree()); } -TEST_F(TreeSynchronizerTest, synchronizeAnimations) -{ - LayerTreeSettings settings; - FakeProxy proxy(scoped_ptr<Thread>(NULL)); - DebugScopedSetImplThread impl(&proxy); - scoped_ptr<LayerTreeHostImpl> hostImpl = LayerTreeHostImpl::Create(settings, NULL, &proxy); - - scoped_refptr<Layer> layerTreeRoot = Layer::Create(); - - layerTreeRoot->SetLayerAnimationController(FakeLayerAnimationController::Create()); - - EXPECT_FALSE(static_cast<FakeLayerAnimationController*>(layerTreeRoot->layer_animation_controller())->synchronizedAnimations()); - - scoped_ptr<LayerImpl> layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), scoped_ptr<LayerImpl>(), m_hostImpl.active_tree()); - TreeSynchronizer::pushProperties(layerTreeRoot.get(), layerImplTreeRoot.get()); - layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), layerImplTreeRoot.Pass(), m_hostImpl.active_tree()); - - EXPECT_TRUE(static_cast<FakeLayerAnimationController*>(layerTreeRoot->layer_animation_controller())->synchronizedAnimations()); +TEST_F(TreeSynchronizerTest, SynchronizeAnimations) { + LayerTreeSettings settings; + FakeProxy proxy(scoped_ptr<Thread>(NULL)); + DebugScopedSetImplThread impl(&proxy); + scoped_ptr<LayerTreeHostImpl> host_impl = + LayerTreeHostImpl::Create(settings, NULL, &proxy); + + scoped_refptr<Layer> layer_tree_root = Layer::Create(); + + layer_tree_root->SetLayerAnimationController( + FakeLayerAnimationController::Create()); + + EXPECT_FALSE(static_cast<FakeLayerAnimationController*>( + layer_tree_root->layer_animation_controller())->SynchronizedAnimations()); + + scoped_ptr<LayerImpl> layer_impl_tree_root = + TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), + scoped_ptr<LayerImpl>(), + host_impl_.active_tree()); + TreeSynchronizer::PushProperties(layer_tree_root.get(), + layer_impl_tree_root.get()); + layer_impl_tree_root = + TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), + layer_impl_tree_root.Pass(), + host_impl_.active_tree()); + + EXPECT_TRUE(static_cast<FakeLayerAnimationController*>( + layer_tree_root->layer_animation_controller())->SynchronizedAnimations()); } } // namespace |