blob: cc9409edf7a931f9f0ad69998dfdf7cd7f86b730 [file] [log] [blame]
[email protected]c0dd24c2012-08-30 23:25:271// 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
[email protected]a8461d82012-10-16 21:11:145#include "cc/tree_synchronizer.h"
[email protected]c0dd24c2012-08-30 23:25:276
[email protected]ac7c7f52012-11-08 06:26:507#include <algorithm>
8
[email protected]a8461d82012-10-16 21:11:149#include "cc/layer.h"
[email protected]d50c6862012-10-23 02:08:3110#include "cc/layer_animation_controller.h"
11#include "cc/layer_impl.h"
[email protected]55a124d02012-10-22 03:07:1312#include "cc/proxy.h"
[email protected]4456eee22012-10-19 18:16:3813#include "cc/single_thread_proxy.h"
[email protected]101441ce2012-10-16 01:45:0314#include "cc/test/animation_test_common.h"
[email protected]c2282382012-12-16 00:46:0315#include "cc/test/fake_impl_proxy.h"
16#include "cc/test/fake_layer_tree_host_impl.h"
[email protected]7f0c53db2012-10-02 00:23:1817#include "testing/gtest/include/gtest/gtest.h"
[email protected]c0dd24c2012-08-30 23:25:2718
[email protected]ba565742012-11-10 09:29:4819namespace cc {
[email protected]c0dd24c2012-08-30 23:25:2720namespace {
21
[email protected]96baf3e2012-10-22 23:09:5522class MockLayerImpl : public LayerImpl {
[email protected]c0dd24c2012-08-30 23:25:2723public:
[email protected]8bef40572012-12-11 21:38:0824 static scoped_ptr<MockLayerImpl> create(LayerTreeImpl* treeImpl, int layerId)
[email protected]c0dd24c2012-08-30 23:25:2725 {
[email protected]8bef40572012-12-11 21:38:0826 return make_scoped_ptr(new MockLayerImpl(treeImpl, layerId));
[email protected]c0dd24c2012-08-30 23:25:2727 }
[email protected]96baf3e2012-10-22 23:09:5528 virtual ~MockLayerImpl()
[email protected]c0dd24c2012-08-30 23:25:2729 {
[email protected]96baf3e2012-10-22 23:09:5530 if (m_layerImplDestructionList)
[email protected]2cdbdba2012-10-28 13:15:0531 m_layerImplDestructionList->push_back(id());
[email protected]c0dd24c2012-08-30 23:25:2732 }
33
[email protected]2cdbdba2012-10-28 13:15:0534 void setLayerImplDestructionList(std::vector<int>* list) { m_layerImplDestructionList = list; }
[email protected]c0dd24c2012-08-30 23:25:2735
36private:
[email protected]8bef40572012-12-11 21:38:0837 MockLayerImpl(LayerTreeImpl* treeImpl, int layerId)
38 : LayerImpl(treeImpl, layerId)
[email protected]96baf3e2012-10-22 23:09:5539 , m_layerImplDestructionList(0)
[email protected]c0dd24c2012-08-30 23:25:2740 {
41 }
42
[email protected]2cdbdba2012-10-28 13:15:0543 std::vector<int>* m_layerImplDestructionList;
[email protected]c0dd24c2012-08-30 23:25:2744};
45
[email protected]96baf3e2012-10-22 23:09:5546class MockLayer : public Layer {
[email protected]c0dd24c2012-08-30 23:25:2747public:
[email protected]2cdbdba2012-10-28 13:15:0548 static scoped_refptr<MockLayer> create(std::vector<int>* layerImplDestructionList)
[email protected]c0dd24c2012-08-30 23:25:2749 {
[email protected]96baf3e2012-10-22 23:09:5550 return make_scoped_refptr(new MockLayer(layerImplDestructionList));
[email protected]c0dd24c2012-08-30 23:25:2751 }
52
[email protected]8bef40572012-12-11 21:38:0853 virtual scoped_ptr<LayerImpl> createLayerImpl(LayerTreeImpl* treeImpl) OVERRIDE
[email protected]c0dd24c2012-08-30 23:25:2754 {
[email protected]8bef40572012-12-11 21:38:0855 return MockLayerImpl::create(treeImpl, m_layerId).PassAs<LayerImpl>();
[email protected]c0dd24c2012-08-30 23:25:2756 }
57
[email protected]96baf3e2012-10-22 23:09:5558 virtual void pushPropertiesTo(LayerImpl* layerImpl) OVERRIDE
[email protected]c0dd24c2012-08-30 23:25:2759 {
[email protected]96baf3e2012-10-22 23:09:5560 Layer::pushPropertiesTo(layerImpl);
[email protected]c0dd24c2012-08-30 23:25:2761
[email protected]96baf3e2012-10-22 23:09:5562 MockLayerImpl* mockLayerImpl = static_cast<MockLayerImpl*>(layerImpl);
63 mockLayerImpl->setLayerImplDestructionList(m_layerImplDestructionList);
[email protected]c0dd24c2012-08-30 23:25:2764 }
[email protected]d58499a2012-10-09 22:27:4765
[email protected]c0dd24c2012-08-30 23:25:2766private:
[email protected]2cdbdba2012-10-28 13:15:0567 MockLayer(std::vector<int>* layerImplDestructionList)
[email protected]96baf3e2012-10-22 23:09:5568 : Layer()
69 , m_layerImplDestructionList(layerImplDestructionList)
[email protected]c0dd24c2012-08-30 23:25:2770 {
71 }
[email protected]96baf3e2012-10-22 23:09:5572 virtual ~MockLayer() { }
[email protected]c0dd24c2012-08-30 23:25:2773
[email protected]2cdbdba2012-10-28 13:15:0574 std::vector<int>* m_layerImplDestructionList;
[email protected]c0dd24c2012-08-30 23:25:2775};
76
[email protected]96baf3e2012-10-22 23:09:5577class FakeLayerAnimationController : public LayerAnimationController {
[email protected]c0dd24c2012-08-30 23:25:2778public:
[email protected]de4afb5e2012-12-20 00:11:3479 static scoped_refptr<LayerAnimationController> create()
[email protected]c0dd24c2012-08-30 23:25:2780 {
[email protected]de4afb5e2012-12-20 00:11:3481 return static_cast<LayerAnimationController*>(new FakeLayerAnimationController);
[email protected]c0dd24c2012-08-30 23:25:2782 }
83
84 bool synchronizedAnimations() const { return m_synchronizedAnimations; }
85
86private:
[email protected]de4afb5e2012-12-20 00:11:3487 FakeLayerAnimationController()
88 : LayerAnimationController(1)
[email protected]c0dd24c2012-08-30 23:25:2789 , m_synchronizedAnimations(false)
[email protected]de4afb5e2012-12-20 00:11:3490 { }
91
92 virtual ~FakeLayerAnimationController() { }
[email protected]c0dd24c2012-08-30 23:25:2793
[email protected]96baf3e2012-10-22 23:09:5594 virtual void pushAnimationUpdatesTo(LayerAnimationController* controllerImpl)
[email protected]c0dd24c2012-08-30 23:25:2795 {
[email protected]96baf3e2012-10-22 23:09:5596 LayerAnimationController::pushAnimationUpdatesTo(controllerImpl);
[email protected]c0dd24c2012-08-30 23:25:2797 m_synchronizedAnimations = true;
98 }
99
100 bool m_synchronizedAnimations;
101};
102
[email protected]8bef40572012-12-11 21:38:08103void expectTreesAreIdentical(Layer* layer, LayerImpl* layerImpl, LayerTreeImpl* treeImpl)
[email protected]c0dd24c2012-08-30 23:25:27104{
105 ASSERT_TRUE(layer);
[email protected]96baf3e2012-10-22 23:09:55106 ASSERT_TRUE(layerImpl);
[email protected]c0dd24c2012-08-30 23:25:27107
[email protected]96baf3e2012-10-22 23:09:55108 EXPECT_EQ(layer->id(), layerImpl->id());
[email protected]8bef40572012-12-11 21:38:08109 EXPECT_EQ(layerImpl->layerTreeImpl(), treeImpl);
[email protected]c0dd24c2012-08-30 23:25:27110
[email protected]96baf3e2012-10-22 23:09:55111 EXPECT_EQ(layer->nonFastScrollableRegion(), layerImpl->nonFastScrollableRegion());
[email protected]c0dd24c2012-08-30 23:25:27112
[email protected]96baf3e2012-10-22 23:09:55113 ASSERT_EQ(!!layer->maskLayer(), !!layerImpl->maskLayer());
[email protected]c0dd24c2012-08-30 23:25:27114 if (layer->maskLayer())
[email protected]8bef40572012-12-11 21:38:08115 expectTreesAreIdentical(layer->maskLayer(), layerImpl->maskLayer(), treeImpl);
[email protected]c0dd24c2012-08-30 23:25:27116
[email protected]96baf3e2012-10-22 23:09:55117 ASSERT_EQ(!!layer->replicaLayer(), !!layerImpl->replicaLayer());
[email protected]c0dd24c2012-08-30 23:25:27118 if (layer->replicaLayer())
[email protected]8bef40572012-12-11 21:38:08119 expectTreesAreIdentical(layer->replicaLayer(), layerImpl->replicaLayer(), treeImpl);
[email protected]c0dd24c2012-08-30 23:25:27120
[email protected]96baf3e2012-10-22 23:09:55121 const std::vector<scoped_refptr<Layer> >& layerChildren = layer->children();
122 const ScopedPtrVector<LayerImpl>& layerImplChildren = layerImpl->children();
[email protected]c0dd24c2012-08-30 23:25:27123
[email protected]96baf3e2012-10-22 23:09:55124 ASSERT_EQ(layerChildren.size(), layerImplChildren.size());
[email protected]c0dd24c2012-08-30 23:25:27125
126 for (size_t i = 0; i < layerChildren.size(); ++i)
[email protected]8bef40572012-12-11 21:38:08127 expectTreesAreIdentical(layerChildren[i].get(), layerImplChildren[i], treeImpl);
[email protected]c0dd24c2012-08-30 23:25:27128}
129
[email protected]c2282382012-12-16 00:46:03130class TreeSynchronizerTest : public testing::Test {
131public:
132 TreeSynchronizerTest()
133 : m_hostImpl(&m_proxy)
134 {
135 }
136
137protected:
138 FakeImplProxy m_proxy;
139 FakeLayerTreeHostImpl m_hostImpl;
140};
141
[email protected]c0dd24c2012-08-30 23:25:27142// Attempts to synchronizes a null tree. This should not crash, and should
143// return a null tree.
[email protected]c2282382012-12-16 00:46:03144TEST_F(TreeSynchronizerTest, syncNullTree)
[email protected]c0dd24c2012-08-30 23:25:27145{
[email protected]c2282382012-12-16 00:46:03146 scoped_ptr<LayerImpl> layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(0, scoped_ptr<LayerImpl>(), m_hostImpl.activeTree());
[email protected]c0dd24c2012-08-30 23:25:27147
[email protected]96baf3e2012-10-22 23:09:55148 EXPECT_TRUE(!layerImplTreeRoot.get());
[email protected]c0dd24c2012-08-30 23:25:27149}
150
151// Constructs a very simple tree and synchronizes it without trying to reuse any preexisting layers.
[email protected]c2282382012-12-16 00:46:03152TEST_F(TreeSynchronizerTest, syncSimpleTreeFromEmpty)
[email protected]c0dd24c2012-08-30 23:25:27153{
[email protected]96baf3e2012-10-22 23:09:55154 scoped_refptr<Layer> layerTreeRoot = Layer::create();
155 layerTreeRoot->addChild(Layer::create());
156 layerTreeRoot->addChild(Layer::create());
[email protected]c0dd24c2012-08-30 23:25:27157
[email protected]c2282382012-12-16 00:46:03158 scoped_ptr<LayerImpl> layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), scoped_ptr<LayerImpl>(), m_hostImpl.activeTree());
[email protected]c0dd24c2012-08-30 23:25:27159
[email protected]c2282382012-12-16 00:46:03160 expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.activeTree());
[email protected]c0dd24c2012-08-30 23:25:27161}
162
163// Constructs a very simple tree and synchronizes it attempting to reuse some layers
[email protected]c2282382012-12-16 00:46:03164TEST_F(TreeSynchronizerTest, syncSimpleTreeReusingLayers)
[email protected]c0dd24c2012-08-30 23:25:27165{
[email protected]2cdbdba2012-10-28 13:15:05166 std::vector<int> layerImplDestructionList;
[email protected]c0dd24c2012-08-30 23:25:27167
[email protected]96baf3e2012-10-22 23:09:55168 scoped_refptr<Layer> layerTreeRoot = MockLayer::create(&layerImplDestructionList);
169 layerTreeRoot->addChild(MockLayer::create(&layerImplDestructionList));
170 layerTreeRoot->addChild(MockLayer::create(&layerImplDestructionList));
[email protected]c0dd24c2012-08-30 23:25:27171
[email protected]c2282382012-12-16 00:46:03172 scoped_ptr<LayerImpl> layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), scoped_ptr<LayerImpl>(), m_hostImpl.activeTree());
173 expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.activeTree());
[email protected]c0dd24c2012-08-30 23:25:27174
[email protected]5c4824e12013-01-12 16:34:53175 // We have to push properties to pick up the destruction list pointer.
176 TreeSynchronizer::pushProperties(layerTreeRoot.get(), layerImplTreeRoot.get());
177
[email protected]96baf3e2012-10-22 23:09:55178 // Add a new layer to the Layer side
179 layerTreeRoot->children()[0]->addChild(MockLayer::create(&layerImplDestructionList));
[email protected]c0dd24c2012-08-30 23:25:27180 // Remove one.
181 layerTreeRoot->children()[1]->removeFromParent();
[email protected]96baf3e2012-10-22 23:09:55182 int secondLayerImplId = layerImplTreeRoot->children()[1]->id();
[email protected]c0dd24c2012-08-30 23:25:27183
[email protected]96baf3e2012-10-22 23:09:55184 // Synchronize again. After the sync the trees should be equivalent and we should have created and destroyed one LayerImpl.
[email protected]c2282382012-12-16 00:46:03185 layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), layerImplTreeRoot.Pass(), m_hostImpl.activeTree());
186 expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.activeTree());
[email protected]c0dd24c2012-08-30 23:25:27187
[email protected]96baf3e2012-10-22 23:09:55188 ASSERT_EQ(1u, layerImplDestructionList.size());
189 EXPECT_EQ(secondLayerImplId, layerImplDestructionList[0]);
[email protected]c0dd24c2012-08-30 23:25:27190}
191
192// Constructs a very simple tree and checks that a stacking-order change is tracked properly.
[email protected]c2282382012-12-16 00:46:03193TEST_F(TreeSynchronizerTest, syncSimpleTreeAndTrackStackingOrderChange)
[email protected]c0dd24c2012-08-30 23:25:27194{
[email protected]2cdbdba2012-10-28 13:15:05195 std::vector<int> layerImplDestructionList;
[email protected]c0dd24c2012-08-30 23:25:27196
[email protected]c0dd24c2012-08-30 23:25:27197 // Set up the tree and sync once. child2 needs to be synced here, too, even though we
198 // remove it to set up the intended scenario.
[email protected]96baf3e2012-10-22 23:09:55199 scoped_refptr<Layer> layerTreeRoot = MockLayer::create(&layerImplDestructionList);
200 scoped_refptr<Layer> child2 = MockLayer::create(&layerImplDestructionList);
201 layerTreeRoot->addChild(MockLayer::create(&layerImplDestructionList));
[email protected]c0dd24c2012-08-30 23:25:27202 layerTreeRoot->addChild(child2);
[email protected]c2282382012-12-16 00:46:03203 scoped_ptr<LayerImpl> layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), scoped_ptr<LayerImpl>(), m_hostImpl.activeTree());
204 expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.activeTree());
[email protected]5c4824e12013-01-12 16:34:53205
206 // We have to push properties to pick up the destruction list pointer.
207 TreeSynchronizer::pushProperties(layerTreeRoot.get(), layerImplTreeRoot.get());
208
[email protected]96baf3e2012-10-22 23:09:55209 layerImplTreeRoot->resetAllChangeTrackingForSubtree();
[email protected]c0dd24c2012-08-30 23:25:27210
211 // re-insert the layer and sync again.
212 child2->removeFromParent();
213 layerTreeRoot->addChild(child2);
[email protected]c2282382012-12-16 00:46:03214 layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), layerImplTreeRoot.Pass(), m_hostImpl.activeTree());
215 expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.activeTree());
[email protected]c0dd24c2012-08-30 23:25:27216
[email protected]5c4824e12013-01-12 16:34:53217 TreeSynchronizer::pushProperties(layerTreeRoot.get(), layerImplTreeRoot.get());
218
[email protected]c0dd24c2012-08-30 23:25:27219 // Check that the impl thread properly tracked the change.
[email protected]96baf3e2012-10-22 23:09:55220 EXPECT_FALSE(layerImplTreeRoot->layerPropertyChanged());
221 EXPECT_FALSE(layerImplTreeRoot->children()[0]->layerPropertyChanged());
222 EXPECT_TRUE(layerImplTreeRoot->children()[1]->layerPropertyChanged());
[email protected]c0dd24c2012-08-30 23:25:27223}
224
[email protected]c2282382012-12-16 00:46:03225TEST_F(TreeSynchronizerTest, syncSimpleTreeAndProperties)
[email protected]c0dd24c2012-08-30 23:25:27226{
[email protected]96baf3e2012-10-22 23:09:55227 scoped_refptr<Layer> layerTreeRoot = Layer::create();
228 layerTreeRoot->addChild(Layer::create());
229 layerTreeRoot->addChild(Layer::create());
[email protected]c0dd24c2012-08-30 23:25:27230
231 // Pick some random properties to set. The values are not important, we're just testing that at least some properties are making it through.
[email protected]aad0a0072012-11-01 18:15:58232 gfx::PointF rootPosition = gfx::PointF(2.3f, 7.4f);
[email protected]c0dd24c2012-08-30 23:25:27233 layerTreeRoot->setPosition(rootPosition);
234
235 float firstChildOpacity = 0.25f;
236 layerTreeRoot->children()[0]->setOpacity(firstChildOpacity);
237
[email protected]aad0a0072012-11-01 18:15:58238 gfx::Size secondChildBounds = gfx::Size(25, 53);
[email protected]c0dd24c2012-08-30 23:25:27239 layerTreeRoot->children()[1]->setBounds(secondChildBounds);
240
[email protected]c2282382012-12-16 00:46:03241 scoped_ptr<LayerImpl> layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), scoped_ptr<LayerImpl>(), m_hostImpl.activeTree());
242 expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.activeTree());
[email protected]c0dd24c2012-08-30 23:25:27243
[email protected]5c4824e12013-01-12 16:34:53244 TreeSynchronizer::pushProperties(layerTreeRoot.get(), layerImplTreeRoot.get());
245
[email protected]96baf3e2012-10-22 23:09:55246 // Check that the property values we set on the Layer tree are reflected in the LayerImpl tree.
[email protected]aad0a0072012-11-01 18:15:58247 gfx::PointF rootLayerImplPosition = layerImplTreeRoot->position();
[email protected]96baf3e2012-10-22 23:09:55248 EXPECT_EQ(rootPosition.x(), rootLayerImplPosition.x());
249 EXPECT_EQ(rootPosition.y(), rootLayerImplPosition.y());
[email protected]c0dd24c2012-08-30 23:25:27250
[email protected]96baf3e2012-10-22 23:09:55251 EXPECT_EQ(firstChildOpacity, layerImplTreeRoot->children()[0]->opacity());
[email protected]c0dd24c2012-08-30 23:25:27252
[email protected]aad0a0072012-11-01 18:15:58253 gfx::Size secondLayerImplChildBounds = layerImplTreeRoot->children()[1]->bounds();
[email protected]96baf3e2012-10-22 23:09:55254 EXPECT_EQ(secondChildBounds.width(), secondLayerImplChildBounds.width());
255 EXPECT_EQ(secondChildBounds.height(), secondLayerImplChildBounds.height());
[email protected]c0dd24c2012-08-30 23:25:27256}
257
[email protected]c2282382012-12-16 00:46:03258TEST_F(TreeSynchronizerTest, reuseLayerImplsAfterStructuralChange)
[email protected]c0dd24c2012-08-30 23:25:27259{
[email protected]2cdbdba2012-10-28 13:15:05260 std::vector<int> layerImplDestructionList;
[email protected]c0dd24c2012-08-30 23:25:27261
[email protected]c0dd24c2012-08-30 23:25:27262 // Set up a tree with this sort of structure:
263 // root --- A --- B ---+--- C
264 // |
265 // +--- D
[email protected]96baf3e2012-10-22 23:09:55266 scoped_refptr<Layer> layerTreeRoot = MockLayer::create(&layerImplDestructionList);
267 layerTreeRoot->addChild(MockLayer::create(&layerImplDestructionList));
[email protected]c0dd24c2012-08-30 23:25:27268
[email protected]96baf3e2012-10-22 23:09:55269 scoped_refptr<Layer> layerA = layerTreeRoot->children()[0].get();
270 layerA->addChild(MockLayer::create(&layerImplDestructionList));
[email protected]c0dd24c2012-08-30 23:25:27271
[email protected]96baf3e2012-10-22 23:09:55272 scoped_refptr<Layer> layerB = layerA->children()[0].get();
273 layerB->addChild(MockLayer::create(&layerImplDestructionList));
[email protected]c0dd24c2012-08-30 23:25:27274
[email protected]96baf3e2012-10-22 23:09:55275 scoped_refptr<Layer> layerC = layerB->children()[0].get();
276 layerB->addChild(MockLayer::create(&layerImplDestructionList));
277 scoped_refptr<Layer> layerD = layerB->children()[1].get();
[email protected]c0dd24c2012-08-30 23:25:27278
[email protected]c2282382012-12-16 00:46:03279 scoped_ptr<LayerImpl> layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), scoped_ptr<LayerImpl>(), m_hostImpl.activeTree());
280 expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.activeTree());
[email protected]c0dd24c2012-08-30 23:25:27281
[email protected]5c4824e12013-01-12 16:34:53282 // We have to push properties to pick up the destruction list pointer.
283 TreeSynchronizer::pushProperties(layerTreeRoot.get(), layerImplTreeRoot.get());
284
[email protected]c0dd24c2012-08-30 23:25:27285 // Now restructure the tree to look like this:
286 // root --- D ---+--- A
287 // |
288 // +--- C --- B
289 layerTreeRoot->removeAllChildren();
290 layerD->removeAllChildren();
291 layerTreeRoot->addChild(layerD);
292 layerA->removeAllChildren();
293 layerD->addChild(layerA);
294 layerC->removeAllChildren();
295 layerD->addChild(layerC);
296 layerB->removeAllChildren();
297 layerC->addChild(layerB);
298
[email protected]96baf3e2012-10-22 23:09:55299 // After another synchronize our trees should match and we should not have destroyed any LayerImpls
[email protected]c2282382012-12-16 00:46:03300 layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), layerImplTreeRoot.Pass(), m_hostImpl.activeTree());
301 expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.activeTree());
[email protected]c0dd24c2012-08-30 23:25:27302
[email protected]96baf3e2012-10-22 23:09:55303 EXPECT_EQ(0u, layerImplDestructionList.size());
[email protected]c0dd24c2012-08-30 23:25:27304}
305
306// Constructs a very simple tree, synchronizes it, then synchronizes to a totally new tree. All layers from the old tree should be deleted.
[email protected]c2282382012-12-16 00:46:03307TEST_F(TreeSynchronizerTest, syncSimpleTreeThenDestroy)
[email protected]c0dd24c2012-08-30 23:25:27308{
[email protected]2cdbdba2012-10-28 13:15:05309 std::vector<int> layerImplDestructionList;
[email protected]c0dd24c2012-08-30 23:25:27310
[email protected]96baf3e2012-10-22 23:09:55311 scoped_refptr<Layer> oldLayerTreeRoot = MockLayer::create(&layerImplDestructionList);
312 oldLayerTreeRoot->addChild(MockLayer::create(&layerImplDestructionList));
313 oldLayerTreeRoot->addChild(MockLayer::create(&layerImplDestructionList));
[email protected]c0dd24c2012-08-30 23:25:27314
315 int oldTreeRootLayerId = oldLayerTreeRoot->id();
316 int oldTreeFirstChildLayerId = oldLayerTreeRoot->children()[0]->id();
317 int oldTreeSecondChildLayerId = oldLayerTreeRoot->children()[1]->id();
318
[email protected]c2282382012-12-16 00:46:03319 scoped_ptr<LayerImpl> layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(oldLayerTreeRoot.get(), scoped_ptr<LayerImpl>(), m_hostImpl.activeTree());
320 expectTreesAreIdentical(oldLayerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.activeTree());
[email protected]c0dd24c2012-08-30 23:25:27321
[email protected]5c4824e12013-01-12 16:34:53322 // We have to push properties to pick up the destruction list pointer.
323 TreeSynchronizer::pushProperties(oldLayerTreeRoot.get(), layerImplTreeRoot.get());
324
[email protected]96baf3e2012-10-22 23:09:55325 // Remove all children on the Layer side.
[email protected]c0dd24c2012-08-30 23:25:27326 oldLayerTreeRoot->removeAllChildren();
327
[email protected]96baf3e2012-10-22 23:09:55328 // Synchronize again. After the sync all LayerImpls from the old tree should be deleted.
329 scoped_refptr<Layer> newLayerTreeRoot = Layer::create();
[email protected]c2282382012-12-16 00:46:03330 layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(newLayerTreeRoot.get(), layerImplTreeRoot.Pass(), m_hostImpl.activeTree());
331 expectTreesAreIdentical(newLayerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.activeTree());
[email protected]c0dd24c2012-08-30 23:25:27332
[email protected]96baf3e2012-10-22 23:09:55333 ASSERT_EQ(3u, layerImplDestructionList.size());
[email protected]2cdbdba2012-10-28 13:15:05334
335 EXPECT_TRUE(std::find(layerImplDestructionList.begin(), layerImplDestructionList.end(), oldTreeRootLayerId) != layerImplDestructionList.end());
336 EXPECT_TRUE(std::find(layerImplDestructionList.begin(), layerImplDestructionList.end(), oldTreeFirstChildLayerId) != layerImplDestructionList.end());
337 EXPECT_TRUE(std::find(layerImplDestructionList.begin(), layerImplDestructionList.end(), oldTreeSecondChildLayerId) != layerImplDestructionList.end());
[email protected]c0dd24c2012-08-30 23:25:27338}
339
340// Constructs+syncs a tree with mask, replica, and replica mask layers.
[email protected]c2282382012-12-16 00:46:03341TEST_F(TreeSynchronizerTest, syncMaskReplicaAndReplicaMaskLayers)
[email protected]c0dd24c2012-08-30 23:25:27342{
[email protected]96baf3e2012-10-22 23:09:55343 scoped_refptr<Layer> layerTreeRoot = Layer::create();
344 layerTreeRoot->addChild(Layer::create());
345 layerTreeRoot->addChild(Layer::create());
346 layerTreeRoot->addChild(Layer::create());
[email protected]c0dd24c2012-08-30 23:25:27347
348 // First child gets a mask layer.
[email protected]96baf3e2012-10-22 23:09:55349 scoped_refptr<Layer> maskLayer = Layer::create();
[email protected]c0dd24c2012-08-30 23:25:27350 layerTreeRoot->children()[0]->setMaskLayer(maskLayer.get());
351
352 // Second child gets a replica layer.
[email protected]96baf3e2012-10-22 23:09:55353 scoped_refptr<Layer> replicaLayer = Layer::create();
[email protected]c0dd24c2012-08-30 23:25:27354 layerTreeRoot->children()[1]->setReplicaLayer(replicaLayer.get());
355
356 // Third child gets a replica layer with a mask layer.
[email protected]96baf3e2012-10-22 23:09:55357 scoped_refptr<Layer> replicaLayerWithMask = Layer::create();
358 scoped_refptr<Layer> replicaMaskLayer = Layer::create();
[email protected]c0dd24c2012-08-30 23:25:27359 replicaLayerWithMask->setMaskLayer(replicaMaskLayer.get());
360 layerTreeRoot->children()[2]->setReplicaLayer(replicaLayerWithMask.get());
361
[email protected]c2282382012-12-16 00:46:03362 scoped_ptr<LayerImpl> layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), scoped_ptr<LayerImpl>(), m_hostImpl.activeTree());
[email protected]c0dd24c2012-08-30 23:25:27363
[email protected]c2282382012-12-16 00:46:03364 expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.activeTree());
[email protected]c0dd24c2012-08-30 23:25:27365
366 // Remove the mask layer.
367 layerTreeRoot->children()[0]->setMaskLayer(0);
[email protected]c2282382012-12-16 00:46:03368 layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), layerImplTreeRoot.Pass(), m_hostImpl.activeTree());
369 expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.activeTree());
[email protected]c0dd24c2012-08-30 23:25:27370
371 // Remove the replica layer.
372 layerTreeRoot->children()[1]->setReplicaLayer(0);
[email protected]c2282382012-12-16 00:46:03373 layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), layerImplTreeRoot.Pass(), m_hostImpl.activeTree());
374 expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.activeTree());
[email protected]c0dd24c2012-08-30 23:25:27375
376 // Remove the replica mask.
377 replicaLayerWithMask->setMaskLayer(0);
[email protected]c2282382012-12-16 00:46:03378 layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), layerImplTreeRoot.Pass(), m_hostImpl.activeTree());
379 expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.activeTree());
[email protected]c0dd24c2012-08-30 23:25:27380}
381
[email protected]c2282382012-12-16 00:46:03382TEST_F(TreeSynchronizerTest, synchronizeAnimations)
[email protected]c0dd24c2012-08-30 23:25:27383{
[email protected]96baf3e2012-10-22 23:09:55384 LayerTreeSettings settings;
[email protected]61de5812012-11-08 07:03:44385 FakeProxy proxy(scoped_ptr<Thread>(NULL));
386 DebugScopedSetImplThread impl(&proxy);
387 scoped_ptr<LayerTreeHostImpl> hostImpl = LayerTreeHostImpl::create(settings, 0, &proxy);
[email protected]c0dd24c2012-08-30 23:25:27388
[email protected]96baf3e2012-10-22 23:09:55389 scoped_refptr<Layer> layerTreeRoot = Layer::create();
[email protected]c0dd24c2012-08-30 23:25:27390
[email protected]de4afb5e2012-12-20 00:11:34391 layerTreeRoot->setLayerAnimationController(FakeLayerAnimationController::create());
[email protected]c0dd24c2012-08-30 23:25:27392
393 EXPECT_FALSE(static_cast<FakeLayerAnimationController*>(layerTreeRoot->layerAnimationController())->synchronizedAnimations());
394
[email protected]c2282382012-12-16 00:46:03395 scoped_ptr<LayerImpl> layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), scoped_ptr<LayerImpl>(), m_hostImpl.activeTree());
[email protected]5c4824e12013-01-12 16:34:53396 TreeSynchronizer::pushProperties(layerTreeRoot.get(), layerImplTreeRoot.get());
[email protected]c2282382012-12-16 00:46:03397 layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), layerImplTreeRoot.Pass(), m_hostImpl.activeTree());
[email protected]c0dd24c2012-08-30 23:25:27398
399 EXPECT_TRUE(static_cast<FakeLayerAnimationController*>(layerTreeRoot->layerAnimationController())->synchronizedAnimations());
400}
401
[email protected]ba565742012-11-10 09:29:48402} // namespace
403} // namespace cc