In iossim, ignore harmless messages from launchd.
[chromium-blink-merge.git] / cc / tree_synchronizer_unittest.cc
blob1c7e9278c52b0157ae291862182088996afaa45e
1 // Copyright 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/tree_synchronizer.h"
7 #include <algorithm>
9 #include "cc/layer.h"
10 #include "cc/layer_animation_controller.h"
11 #include "cc/layer_impl.h"
12 #include "cc/proxy.h"
13 #include "cc/single_thread_proxy.h"
14 #include "cc/test/animation_test_common.h"
15 #include "cc/test/fake_impl_proxy.h"
16 #include "cc/test/fake_layer_tree_host_impl.h"
17 #include "testing/gtest/include/gtest/gtest.h"
19 namespace cc {
20 namespace {
22 class MockLayerImpl : public LayerImpl {
23 public:
24 static scoped_ptr<MockLayerImpl> create(LayerTreeImpl* treeImpl, int layerId)
26 return make_scoped_ptr(new MockLayerImpl(treeImpl, layerId));
28 virtual ~MockLayerImpl()
30 if (m_layerImplDestructionList)
31 m_layerImplDestructionList->push_back(id());
34 void setLayerImplDestructionList(std::vector<int>* list) { m_layerImplDestructionList = list; }
36 private:
37 MockLayerImpl(LayerTreeImpl* treeImpl, int layerId)
38 : LayerImpl(treeImpl, layerId)
39 , m_layerImplDestructionList(0)
43 std::vector<int>* m_layerImplDestructionList;
46 class MockLayer : public Layer {
47 public:
48 static scoped_refptr<MockLayer> create(std::vector<int>* layerImplDestructionList)
50 return make_scoped_refptr(new MockLayer(layerImplDestructionList));
53 virtual scoped_ptr<LayerImpl> createLayerImpl(LayerTreeImpl* treeImpl) OVERRIDE
55 return MockLayerImpl::create(treeImpl, m_layerId).PassAs<LayerImpl>();
58 virtual void pushPropertiesTo(LayerImpl* layerImpl) OVERRIDE
60 Layer::pushPropertiesTo(layerImpl);
62 MockLayerImpl* mockLayerImpl = static_cast<MockLayerImpl*>(layerImpl);
63 mockLayerImpl->setLayerImplDestructionList(m_layerImplDestructionList);
66 private:
67 MockLayer(std::vector<int>* layerImplDestructionList)
68 : Layer()
69 , m_layerImplDestructionList(layerImplDestructionList)
72 virtual ~MockLayer() { }
74 std::vector<int>* m_layerImplDestructionList;
77 class FakeLayerAnimationController : public LayerAnimationController {
78 public:
79 static scoped_refptr<LayerAnimationController> create()
81 return static_cast<LayerAnimationController*>(new FakeLayerAnimationController);
84 bool synchronizedAnimations() const { return m_synchronizedAnimations; }
86 private:
87 FakeLayerAnimationController()
88 : LayerAnimationController(1)
89 , m_synchronizedAnimations(false)
90 { }
92 virtual ~FakeLayerAnimationController() { }
94 virtual void pushAnimationUpdatesTo(LayerAnimationController* controllerImpl)
96 LayerAnimationController::pushAnimationUpdatesTo(controllerImpl);
97 m_synchronizedAnimations = true;
100 bool m_synchronizedAnimations;
103 void expectTreesAreIdentical(Layer* layer, LayerImpl* layerImpl, LayerTreeImpl* treeImpl)
105 ASSERT_TRUE(layer);
106 ASSERT_TRUE(layerImpl);
108 EXPECT_EQ(layer->id(), layerImpl->id());
109 EXPECT_EQ(layerImpl->layerTreeImpl(), treeImpl);
111 EXPECT_EQ(layer->nonFastScrollableRegion(), layerImpl->nonFastScrollableRegion());
113 ASSERT_EQ(!!layer->maskLayer(), !!layerImpl->maskLayer());
114 if (layer->maskLayer())
115 expectTreesAreIdentical(layer->maskLayer(), layerImpl->maskLayer(), treeImpl);
117 ASSERT_EQ(!!layer->replicaLayer(), !!layerImpl->replicaLayer());
118 if (layer->replicaLayer())
119 expectTreesAreIdentical(layer->replicaLayer(), layerImpl->replicaLayer(), treeImpl);
121 const std::vector<scoped_refptr<Layer> >& layerChildren = layer->children();
122 const ScopedPtrVector<LayerImpl>& layerImplChildren = layerImpl->children();
124 ASSERT_EQ(layerChildren.size(), layerImplChildren.size());
126 for (size_t i = 0; i < layerChildren.size(); ++i)
127 expectTreesAreIdentical(layerChildren[i].get(), layerImplChildren[i], treeImpl);
130 class TreeSynchronizerTest : public testing::Test {
131 public:
132 TreeSynchronizerTest()
133 : m_hostImpl(&m_proxy)
137 protected:
138 FakeImplProxy m_proxy;
139 FakeLayerTreeHostImpl m_hostImpl;
142 // Attempts to synchronizes a null tree. This should not crash, and should
143 // return a null tree.
144 TEST_F(TreeSynchronizerTest, syncNullTree)
146 scoped_ptr<LayerImpl> layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(0, scoped_ptr<LayerImpl>(), m_hostImpl.activeTree());
148 EXPECT_TRUE(!layerImplTreeRoot.get());
151 // Constructs a very simple tree and synchronizes it without trying to reuse any preexisting layers.
152 TEST_F(TreeSynchronizerTest, syncSimpleTreeFromEmpty)
154 scoped_refptr<Layer> layerTreeRoot = Layer::create();
155 layerTreeRoot->addChild(Layer::create());
156 layerTreeRoot->addChild(Layer::create());
158 scoped_ptr<LayerImpl> layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), scoped_ptr<LayerImpl>(), m_hostImpl.activeTree());
160 expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.activeTree());
163 // Constructs a very simple tree and synchronizes it attempting to reuse some layers
164 TEST_F(TreeSynchronizerTest, syncSimpleTreeReusingLayers)
166 std::vector<int> layerImplDestructionList;
168 scoped_refptr<Layer> layerTreeRoot = MockLayer::create(&layerImplDestructionList);
169 layerTreeRoot->addChild(MockLayer::create(&layerImplDestructionList));
170 layerTreeRoot->addChild(MockLayer::create(&layerImplDestructionList));
172 scoped_ptr<LayerImpl> layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), scoped_ptr<LayerImpl>(), m_hostImpl.activeTree());
173 expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.activeTree());
175 // Add a new layer to the Layer side
176 layerTreeRoot->children()[0]->addChild(MockLayer::create(&layerImplDestructionList));
177 // Remove one.
178 layerTreeRoot->children()[1]->removeFromParent();
179 int secondLayerImplId = layerImplTreeRoot->children()[1]->id();
181 // Synchronize again. After the sync the trees should be equivalent and we should have created and destroyed one LayerImpl.
182 layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), layerImplTreeRoot.Pass(), m_hostImpl.activeTree());
183 expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.activeTree());
185 ASSERT_EQ(1u, layerImplDestructionList.size());
186 EXPECT_EQ(secondLayerImplId, layerImplDestructionList[0]);
189 // Constructs a very simple tree and checks that a stacking-order change is tracked properly.
190 TEST_F(TreeSynchronizerTest, syncSimpleTreeAndTrackStackingOrderChange)
192 std::vector<int> layerImplDestructionList;
194 // Set up the tree and sync once. child2 needs to be synced here, too, even though we
195 // remove it to set up the intended scenario.
196 scoped_refptr<Layer> layerTreeRoot = MockLayer::create(&layerImplDestructionList);
197 scoped_refptr<Layer> child2 = MockLayer::create(&layerImplDestructionList);
198 layerTreeRoot->addChild(MockLayer::create(&layerImplDestructionList));
199 layerTreeRoot->addChild(child2);
200 scoped_ptr<LayerImpl> layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), scoped_ptr<LayerImpl>(), m_hostImpl.activeTree());
201 expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.activeTree());
202 layerImplTreeRoot->resetAllChangeTrackingForSubtree();
204 // re-insert the layer and sync again.
205 child2->removeFromParent();
206 layerTreeRoot->addChild(child2);
207 layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), layerImplTreeRoot.Pass(), m_hostImpl.activeTree());
208 expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.activeTree());
210 // Check that the impl thread properly tracked the change.
211 EXPECT_FALSE(layerImplTreeRoot->layerPropertyChanged());
212 EXPECT_FALSE(layerImplTreeRoot->children()[0]->layerPropertyChanged());
213 EXPECT_TRUE(layerImplTreeRoot->children()[1]->layerPropertyChanged());
216 TEST_F(TreeSynchronizerTest, syncSimpleTreeAndProperties)
218 scoped_refptr<Layer> layerTreeRoot = Layer::create();
219 layerTreeRoot->addChild(Layer::create());
220 layerTreeRoot->addChild(Layer::create());
222 // Pick some random properties to set. The values are not important, we're just testing that at least some properties are making it through.
223 gfx::PointF rootPosition = gfx::PointF(2.3f, 7.4f);
224 layerTreeRoot->setPosition(rootPosition);
226 float firstChildOpacity = 0.25f;
227 layerTreeRoot->children()[0]->setOpacity(firstChildOpacity);
229 gfx::Size secondChildBounds = gfx::Size(25, 53);
230 layerTreeRoot->children()[1]->setBounds(secondChildBounds);
232 scoped_ptr<LayerImpl> layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), scoped_ptr<LayerImpl>(), m_hostImpl.activeTree());
233 expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.activeTree());
235 // Check that the property values we set on the Layer tree are reflected in the LayerImpl tree.
236 gfx::PointF rootLayerImplPosition = layerImplTreeRoot->position();
237 EXPECT_EQ(rootPosition.x(), rootLayerImplPosition.x());
238 EXPECT_EQ(rootPosition.y(), rootLayerImplPosition.y());
240 EXPECT_EQ(firstChildOpacity, layerImplTreeRoot->children()[0]->opacity());
242 gfx::Size secondLayerImplChildBounds = layerImplTreeRoot->children()[1]->bounds();
243 EXPECT_EQ(secondChildBounds.width(), secondLayerImplChildBounds.width());
244 EXPECT_EQ(secondChildBounds.height(), secondLayerImplChildBounds.height());
247 TEST_F(TreeSynchronizerTest, reuseLayerImplsAfterStructuralChange)
249 std::vector<int> layerImplDestructionList;
251 // Set up a tree with this sort of structure:
252 // root --- A --- B ---+--- C
253 // |
254 // +--- D
255 scoped_refptr<Layer> layerTreeRoot = MockLayer::create(&layerImplDestructionList);
256 layerTreeRoot->addChild(MockLayer::create(&layerImplDestructionList));
258 scoped_refptr<Layer> layerA = layerTreeRoot->children()[0].get();
259 layerA->addChild(MockLayer::create(&layerImplDestructionList));
261 scoped_refptr<Layer> layerB = layerA->children()[0].get();
262 layerB->addChild(MockLayer::create(&layerImplDestructionList));
264 scoped_refptr<Layer> layerC = layerB->children()[0].get();
265 layerB->addChild(MockLayer::create(&layerImplDestructionList));
266 scoped_refptr<Layer> layerD = layerB->children()[1].get();
268 scoped_ptr<LayerImpl> layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), scoped_ptr<LayerImpl>(), m_hostImpl.activeTree());
269 expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.activeTree());
271 // Now restructure the tree to look like this:
272 // root --- D ---+--- A
273 // |
274 // +--- C --- B
275 layerTreeRoot->removeAllChildren();
276 layerD->removeAllChildren();
277 layerTreeRoot->addChild(layerD);
278 layerA->removeAllChildren();
279 layerD->addChild(layerA);
280 layerC->removeAllChildren();
281 layerD->addChild(layerC);
282 layerB->removeAllChildren();
283 layerC->addChild(layerB);
285 // After another synchronize our trees should match and we should not have destroyed any LayerImpls
286 layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), layerImplTreeRoot.Pass(), m_hostImpl.activeTree());
287 expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.activeTree());
289 EXPECT_EQ(0u, layerImplDestructionList.size());
292 // Constructs a very simple tree, synchronizes it, then synchronizes to a totally new tree. All layers from the old tree should be deleted.
293 TEST_F(TreeSynchronizerTest, syncSimpleTreeThenDestroy)
295 std::vector<int> layerImplDestructionList;
297 scoped_refptr<Layer> oldLayerTreeRoot = MockLayer::create(&layerImplDestructionList);
298 oldLayerTreeRoot->addChild(MockLayer::create(&layerImplDestructionList));
299 oldLayerTreeRoot->addChild(MockLayer::create(&layerImplDestructionList));
301 int oldTreeRootLayerId = oldLayerTreeRoot->id();
302 int oldTreeFirstChildLayerId = oldLayerTreeRoot->children()[0]->id();
303 int oldTreeSecondChildLayerId = oldLayerTreeRoot->children()[1]->id();
305 scoped_ptr<LayerImpl> layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(oldLayerTreeRoot.get(), scoped_ptr<LayerImpl>(), m_hostImpl.activeTree());
306 expectTreesAreIdentical(oldLayerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.activeTree());
308 // Remove all children on the Layer side.
309 oldLayerTreeRoot->removeAllChildren();
311 // Synchronize again. After the sync all LayerImpls from the old tree should be deleted.
312 scoped_refptr<Layer> newLayerTreeRoot = Layer::create();
313 layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(newLayerTreeRoot.get(), layerImplTreeRoot.Pass(), m_hostImpl.activeTree());
314 expectTreesAreIdentical(newLayerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.activeTree());
316 ASSERT_EQ(3u, layerImplDestructionList.size());
318 EXPECT_TRUE(std::find(layerImplDestructionList.begin(), layerImplDestructionList.end(), oldTreeRootLayerId) != layerImplDestructionList.end());
319 EXPECT_TRUE(std::find(layerImplDestructionList.begin(), layerImplDestructionList.end(), oldTreeFirstChildLayerId) != layerImplDestructionList.end());
320 EXPECT_TRUE(std::find(layerImplDestructionList.begin(), layerImplDestructionList.end(), oldTreeSecondChildLayerId) != layerImplDestructionList.end());
323 // Constructs+syncs a tree with mask, replica, and replica mask layers.
324 TEST_F(TreeSynchronizerTest, syncMaskReplicaAndReplicaMaskLayers)
326 scoped_refptr<Layer> layerTreeRoot = Layer::create();
327 layerTreeRoot->addChild(Layer::create());
328 layerTreeRoot->addChild(Layer::create());
329 layerTreeRoot->addChild(Layer::create());
331 // First child gets a mask layer.
332 scoped_refptr<Layer> maskLayer = Layer::create();
333 layerTreeRoot->children()[0]->setMaskLayer(maskLayer.get());
335 // Second child gets a replica layer.
336 scoped_refptr<Layer> replicaLayer = Layer::create();
337 layerTreeRoot->children()[1]->setReplicaLayer(replicaLayer.get());
339 // Third child gets a replica layer with a mask layer.
340 scoped_refptr<Layer> replicaLayerWithMask = Layer::create();
341 scoped_refptr<Layer> replicaMaskLayer = Layer::create();
342 replicaLayerWithMask->setMaskLayer(replicaMaskLayer.get());
343 layerTreeRoot->children()[2]->setReplicaLayer(replicaLayerWithMask.get());
345 scoped_ptr<LayerImpl> layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), scoped_ptr<LayerImpl>(), m_hostImpl.activeTree());
347 expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.activeTree());
349 // Remove the mask layer.
350 layerTreeRoot->children()[0]->setMaskLayer(0);
351 layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), layerImplTreeRoot.Pass(), m_hostImpl.activeTree());
352 expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.activeTree());
354 // Remove the replica layer.
355 layerTreeRoot->children()[1]->setReplicaLayer(0);
356 layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), layerImplTreeRoot.Pass(), m_hostImpl.activeTree());
357 expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.activeTree());
359 // Remove the replica mask.
360 replicaLayerWithMask->setMaskLayer(0);
361 layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), layerImplTreeRoot.Pass(), m_hostImpl.activeTree());
362 expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), m_hostImpl.activeTree());
365 TEST_F(TreeSynchronizerTest, synchronizeAnimations)
367 LayerTreeSettings settings;
368 FakeProxy proxy(scoped_ptr<Thread>(NULL));
369 DebugScopedSetImplThread impl(&proxy);
370 scoped_ptr<LayerTreeHostImpl> hostImpl = LayerTreeHostImpl::create(settings, 0, &proxy);
372 scoped_refptr<Layer> layerTreeRoot = Layer::create();
374 layerTreeRoot->setLayerAnimationController(FakeLayerAnimationController::create());
376 EXPECT_FALSE(static_cast<FakeLayerAnimationController*>(layerTreeRoot->layerAnimationController())->synchronizedAnimations());
378 scoped_ptr<LayerImpl> layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), scoped_ptr<LayerImpl>(), m_hostImpl.activeTree());
379 layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), layerImplTreeRoot.Pass(), m_hostImpl.activeTree());
381 EXPECT_TRUE(static_cast<FakeLayerAnimationController*>(layerTreeRoot->layerAnimationController())->synchronizedAnimations());
384 } // namespace
385 } // namespace cc