[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 1 | // Copyright 2011 The Chromium Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "config.h" |
| 6 | |
[email protected] | a8461d8 | 2012-10-16 21:11:14 | [diff] [blame] | 7 | #include "cc/tree_synchronizer.h" |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 8 | |
[email protected] | ac7c7f5 | 2012-11-08 06:26:50 | [diff] [blame^] | 9 | #include <algorithm> |
| 10 | |
[email protected] | a8461d8 | 2012-10-16 21:11:14 | [diff] [blame] | 11 | #include "cc/layer.h" |
[email protected] | d50c686 | 2012-10-23 02:08:31 | [diff] [blame] | 12 | #include "cc/layer_animation_controller.h" |
| 13 | #include "cc/layer_impl.h" |
[email protected] | 55a124d0 | 2012-10-22 03:07:13 | [diff] [blame] | 14 | #include "cc/proxy.h" |
[email protected] | 4456eee2 | 2012-10-19 18:16:38 | [diff] [blame] | 15 | #include "cc/single_thread_proxy.h" |
[email protected] | 101441ce | 2012-10-16 01:45:03 | [diff] [blame] | 16 | #include "cc/test/animation_test_common.h" |
[email protected] | 7f0c53db | 2012-10-02 00:23:18 | [diff] [blame] | 17 | #include "testing/gtest/include/gtest/gtest.h" |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 18 | |
[email protected] | 9c88e56 | 2012-09-14 22:21:30 | [diff] [blame] | 19 | using namespace cc; |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 20 | using namespace WebKitTests; |
| 21 | |
| 22 | namespace { |
| 23 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 24 | class MockLayerImpl : public LayerImpl { |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 25 | public: |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 26 | static scoped_ptr<MockLayerImpl> create(int layerId) |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 27 | { |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 28 | return make_scoped_ptr(new MockLayerImpl(layerId)); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 29 | } |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 30 | virtual ~MockLayerImpl() |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 31 | { |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 32 | if (m_layerImplDestructionList) |
[email protected] | 2cdbdba | 2012-10-28 13:15:05 | [diff] [blame] | 33 | m_layerImplDestructionList->push_back(id()); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 34 | } |
| 35 | |
[email protected] | 2cdbdba | 2012-10-28 13:15:05 | [diff] [blame] | 36 | void setLayerImplDestructionList(std::vector<int>* list) { m_layerImplDestructionList = list; } |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 37 | |
| 38 | private: |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 39 | MockLayerImpl(int layerId) |
| 40 | : LayerImpl(layerId) |
| 41 | , m_layerImplDestructionList(0) |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 42 | { |
| 43 | } |
| 44 | |
[email protected] | 2cdbdba | 2012-10-28 13:15:05 | [diff] [blame] | 45 | std::vector<int>* m_layerImplDestructionList; |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 46 | }; |
| 47 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 48 | class MockLayer : public Layer { |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 49 | public: |
[email protected] | 2cdbdba | 2012-10-28 13:15:05 | [diff] [blame] | 50 | static scoped_refptr<MockLayer> create(std::vector<int>* layerImplDestructionList) |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 51 | { |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 52 | return make_scoped_refptr(new MockLayer(layerImplDestructionList)); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 53 | } |
| 54 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 55 | virtual scoped_ptr<LayerImpl> createLayerImpl() OVERRIDE |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 56 | { |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 57 | return MockLayerImpl::create(m_layerId).PassAs<LayerImpl>(); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 58 | } |
| 59 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 60 | virtual void pushPropertiesTo(LayerImpl* layerImpl) OVERRIDE |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 61 | { |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 62 | Layer::pushPropertiesTo(layerImpl); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 63 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 64 | MockLayerImpl* mockLayerImpl = static_cast<MockLayerImpl*>(layerImpl); |
| 65 | mockLayerImpl->setLayerImplDestructionList(m_layerImplDestructionList); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 66 | } |
[email protected] | d58499a | 2012-10-09 22:27:47 | [diff] [blame] | 67 | |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 68 | private: |
[email protected] | 2cdbdba | 2012-10-28 13:15:05 | [diff] [blame] | 69 | MockLayer(std::vector<int>* layerImplDestructionList) |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 70 | : Layer() |
| 71 | , m_layerImplDestructionList(layerImplDestructionList) |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 72 | { |
| 73 | } |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 74 | virtual ~MockLayer() { } |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 75 | |
[email protected] | 2cdbdba | 2012-10-28 13:15:05 | [diff] [blame] | 76 | std::vector<int>* m_layerImplDestructionList; |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 77 | }; |
| 78 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 79 | class FakeLayerAnimationController : public LayerAnimationController { |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 80 | public: |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 81 | static scoped_ptr<FakeLayerAnimationController> create(LayerAnimationControllerClient* client) |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 82 | { |
[email protected] | 9aca359 | 2012-10-12 15:57:09 | [diff] [blame] | 83 | return make_scoped_ptr(new FakeLayerAnimationController(client)); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 84 | } |
| 85 | |
| 86 | bool synchronizedAnimations() const { return m_synchronizedAnimations; } |
| 87 | |
| 88 | private: |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 89 | explicit FakeLayerAnimationController(LayerAnimationControllerClient* client) |
| 90 | : LayerAnimationController(client) |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 91 | , m_synchronizedAnimations(false) |
| 92 | { |
| 93 | } |
| 94 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 95 | virtual void pushAnimationUpdatesTo(LayerAnimationController* controllerImpl) |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 96 | { |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 97 | LayerAnimationController::pushAnimationUpdatesTo(controllerImpl); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 98 | m_synchronizedAnimations = true; |
| 99 | } |
| 100 | |
| 101 | bool m_synchronizedAnimations; |
| 102 | }; |
| 103 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 104 | void expectTreesAreIdentical(Layer* layer, LayerImpl* layerImpl, LayerTreeHostImpl* hostImpl) |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 105 | { |
| 106 | ASSERT_TRUE(layer); |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 107 | ASSERT_TRUE(layerImpl); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 108 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 109 | EXPECT_EQ(layer->id(), layerImpl->id()); |
| 110 | EXPECT_EQ(layerImpl->layerTreeHostImpl(), hostImpl); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 111 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 112 | EXPECT_EQ(layer->nonFastScrollableRegion(), layerImpl->nonFastScrollableRegion()); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 113 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 114 | ASSERT_EQ(!!layer->maskLayer(), !!layerImpl->maskLayer()); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 115 | if (layer->maskLayer()) |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 116 | expectTreesAreIdentical(layer->maskLayer(), layerImpl->maskLayer(), hostImpl); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 117 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 118 | ASSERT_EQ(!!layer->replicaLayer(), !!layerImpl->replicaLayer()); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 119 | if (layer->replicaLayer()) |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 120 | expectTreesAreIdentical(layer->replicaLayer(), layerImpl->replicaLayer(), hostImpl); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 121 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 122 | const std::vector<scoped_refptr<Layer> >& layerChildren = layer->children(); |
| 123 | const ScopedPtrVector<LayerImpl>& layerImplChildren = layerImpl->children(); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 124 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 125 | ASSERT_EQ(layerChildren.size(), layerImplChildren.size()); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 126 | |
| 127 | for (size_t i = 0; i < layerChildren.size(); ++i) |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 128 | expectTreesAreIdentical(layerChildren[i].get(), layerImplChildren[i], hostImpl); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 129 | } |
| 130 | |
| 131 | // Attempts to synchronizes a null tree. This should not crash, and should |
| 132 | // return a null tree. |
| 133 | TEST(TreeSynchronizerTest, syncNullTree) |
| 134 | { |
[email protected] | 068d7ef | 2012-11-05 07:17:46 | [diff] [blame] | 135 | DebugScopedSetImplThread impl; |
| 136 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 137 | scoped_ptr<LayerImpl> layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(0, scoped_ptr<LayerImpl>(), 0); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 138 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 139 | EXPECT_TRUE(!layerImplTreeRoot.get()); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 140 | } |
| 141 | |
| 142 | // Constructs a very simple tree and synchronizes it without trying to reuse any preexisting layers. |
| 143 | TEST(TreeSynchronizerTest, syncSimpleTreeFromEmpty) |
| 144 | { |
[email protected] | 068d7ef | 2012-11-05 07:17:46 | [diff] [blame] | 145 | DebugScopedSetImplThread impl; |
| 146 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 147 | LayerTreeSettings settings; |
[email protected] | 068d7ef | 2012-11-05 07:17:46 | [diff] [blame] | 148 | scoped_ptr<LayerTreeHostImpl> hostImpl = LayerTreeHostImpl::create(settings, 0); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 149 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 150 | scoped_refptr<Layer> layerTreeRoot = Layer::create(); |
| 151 | layerTreeRoot->addChild(Layer::create()); |
| 152 | layerTreeRoot->addChild(Layer::create()); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 153 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 154 | scoped_ptr<LayerImpl> layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), scoped_ptr<LayerImpl>(), hostImpl.get()); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 155 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 156 | expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), hostImpl.get()); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 157 | } |
| 158 | |
| 159 | // Constructs a very simple tree and synchronizes it attempting to reuse some layers |
| 160 | TEST(TreeSynchronizerTest, syncSimpleTreeReusingLayers) |
| 161 | { |
[email protected] | 068d7ef | 2012-11-05 07:17:46 | [diff] [blame] | 162 | DebugScopedSetImplThread impl; |
[email protected] | 2cdbdba | 2012-10-28 13:15:05 | [diff] [blame] | 163 | std::vector<int> layerImplDestructionList; |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 164 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 165 | LayerTreeSettings settings; |
[email protected] | 068d7ef | 2012-11-05 07:17:46 | [diff] [blame] | 166 | scoped_ptr<LayerTreeHostImpl> hostImpl = LayerTreeHostImpl::create(settings, 0); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 167 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 168 | scoped_refptr<Layer> layerTreeRoot = MockLayer::create(&layerImplDestructionList); |
| 169 | layerTreeRoot->addChild(MockLayer::create(&layerImplDestructionList)); |
| 170 | layerTreeRoot->addChild(MockLayer::create(&layerImplDestructionList)); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 171 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 172 | scoped_ptr<LayerImpl> layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), scoped_ptr<LayerImpl>(), hostImpl.get()); |
| 173 | expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), hostImpl.get()); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 174 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 175 | // Add a new layer to the Layer side |
| 176 | layerTreeRoot->children()[0]->addChild(MockLayer::create(&layerImplDestructionList)); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 177 | // Remove one. |
| 178 | layerTreeRoot->children()[1]->removeFromParent(); |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 179 | int secondLayerImplId = layerImplTreeRoot->children()[1]->id(); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 180 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 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(), hostImpl.get()); |
| 183 | expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), hostImpl.get()); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 184 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 185 | ASSERT_EQ(1u, layerImplDestructionList.size()); |
| 186 | EXPECT_EQ(secondLayerImplId, layerImplDestructionList[0]); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 187 | } |
| 188 | |
| 189 | // Constructs a very simple tree and checks that a stacking-order change is tracked properly. |
| 190 | TEST(TreeSynchronizerTest, syncSimpleTreeAndTrackStackingOrderChange) |
| 191 | { |
[email protected] | 068d7ef | 2012-11-05 07:17:46 | [diff] [blame] | 192 | DebugScopedSetImplThread impl; |
[email protected] | 2cdbdba | 2012-10-28 13:15:05 | [diff] [blame] | 193 | std::vector<int> layerImplDestructionList; |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 194 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 195 | LayerTreeSettings settings; |
[email protected] | 068d7ef | 2012-11-05 07:17:46 | [diff] [blame] | 196 | scoped_ptr<LayerTreeHostImpl> hostImpl = LayerTreeHostImpl::create(settings, 0); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 197 | |
| 198 | // Set up the tree and sync once. child2 needs to be synced here, too, even though we |
| 199 | // remove it to set up the intended scenario. |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 200 | scoped_refptr<Layer> layerTreeRoot = MockLayer::create(&layerImplDestructionList); |
| 201 | scoped_refptr<Layer> child2 = MockLayer::create(&layerImplDestructionList); |
| 202 | layerTreeRoot->addChild(MockLayer::create(&layerImplDestructionList)); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 203 | layerTreeRoot->addChild(child2); |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 204 | scoped_ptr<LayerImpl> layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), scoped_ptr<LayerImpl>(), hostImpl.get()); |
| 205 | expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), hostImpl.get()); |
| 206 | layerImplTreeRoot->resetAllChangeTrackingForSubtree(); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 207 | |
| 208 | // re-insert the layer and sync again. |
| 209 | child2->removeFromParent(); |
| 210 | layerTreeRoot->addChild(child2); |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 211 | layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), layerImplTreeRoot.Pass(), hostImpl.get()); |
| 212 | expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), hostImpl.get()); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 213 | |
| 214 | // Check that the impl thread properly tracked the change. |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 215 | EXPECT_FALSE(layerImplTreeRoot->layerPropertyChanged()); |
| 216 | EXPECT_FALSE(layerImplTreeRoot->children()[0]->layerPropertyChanged()); |
| 217 | EXPECT_TRUE(layerImplTreeRoot->children()[1]->layerPropertyChanged()); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 218 | } |
| 219 | |
| 220 | TEST(TreeSynchronizerTest, syncSimpleTreeAndProperties) |
| 221 | { |
[email protected] | 068d7ef | 2012-11-05 07:17:46 | [diff] [blame] | 222 | DebugScopedSetImplThread impl; |
| 223 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 224 | LayerTreeSettings settings; |
[email protected] | 068d7ef | 2012-11-05 07:17:46 | [diff] [blame] | 225 | scoped_ptr<LayerTreeHostImpl> hostImpl = LayerTreeHostImpl::create(settings, 0); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 226 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 227 | scoped_refptr<Layer> layerTreeRoot = Layer::create(); |
| 228 | layerTreeRoot->addChild(Layer::create()); |
| 229 | layerTreeRoot->addChild(Layer::create()); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 230 | |
| 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] | aad0a007 | 2012-11-01 18:15:58 | [diff] [blame] | 232 | gfx::PointF rootPosition = gfx::PointF(2.3f, 7.4f); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 233 | layerTreeRoot->setPosition(rootPosition); |
| 234 | |
| 235 | float firstChildOpacity = 0.25f; |
| 236 | layerTreeRoot->children()[0]->setOpacity(firstChildOpacity); |
| 237 | |
[email protected] | aad0a007 | 2012-11-01 18:15:58 | [diff] [blame] | 238 | gfx::Size secondChildBounds = gfx::Size(25, 53); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 239 | layerTreeRoot->children()[1]->setBounds(secondChildBounds); |
| 240 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 241 | scoped_ptr<LayerImpl> layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), scoped_ptr<LayerImpl>(), hostImpl.get()); |
| 242 | expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), hostImpl.get()); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 243 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 244 | // Check that the property values we set on the Layer tree are reflected in the LayerImpl tree. |
[email protected] | aad0a007 | 2012-11-01 18:15:58 | [diff] [blame] | 245 | gfx::PointF rootLayerImplPosition = layerImplTreeRoot->position(); |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 246 | EXPECT_EQ(rootPosition.x(), rootLayerImplPosition.x()); |
| 247 | EXPECT_EQ(rootPosition.y(), rootLayerImplPosition.y()); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 248 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 249 | EXPECT_EQ(firstChildOpacity, layerImplTreeRoot->children()[0]->opacity()); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 250 | |
[email protected] | aad0a007 | 2012-11-01 18:15:58 | [diff] [blame] | 251 | gfx::Size secondLayerImplChildBounds = layerImplTreeRoot->children()[1]->bounds(); |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 252 | EXPECT_EQ(secondChildBounds.width(), secondLayerImplChildBounds.width()); |
| 253 | EXPECT_EQ(secondChildBounds.height(), secondLayerImplChildBounds.height()); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 254 | } |
| 255 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 256 | TEST(TreeSynchronizerTest, reuseLayerImplsAfterStructuralChange) |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 257 | { |
[email protected] | 068d7ef | 2012-11-05 07:17:46 | [diff] [blame] | 258 | DebugScopedSetImplThread impl; |
[email protected] | 2cdbdba | 2012-10-28 13:15:05 | [diff] [blame] | 259 | std::vector<int> layerImplDestructionList; |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 260 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 261 | LayerTreeSettings settings; |
[email protected] | 068d7ef | 2012-11-05 07:17:46 | [diff] [blame] | 262 | scoped_ptr<LayerTreeHostImpl> hostImpl = LayerTreeHostImpl::create(settings, 0); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 263 | |
| 264 | // Set up a tree with this sort of structure: |
| 265 | // root --- A --- B ---+--- C |
| 266 | // | |
| 267 | // +--- D |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 268 | scoped_refptr<Layer> layerTreeRoot = MockLayer::create(&layerImplDestructionList); |
| 269 | layerTreeRoot->addChild(MockLayer::create(&layerImplDestructionList)); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 270 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 271 | scoped_refptr<Layer> layerA = layerTreeRoot->children()[0].get(); |
| 272 | layerA->addChild(MockLayer::create(&layerImplDestructionList)); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 273 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 274 | scoped_refptr<Layer> layerB = layerA->children()[0].get(); |
| 275 | layerB->addChild(MockLayer::create(&layerImplDestructionList)); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 276 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 277 | scoped_refptr<Layer> layerC = layerB->children()[0].get(); |
| 278 | layerB->addChild(MockLayer::create(&layerImplDestructionList)); |
| 279 | scoped_refptr<Layer> layerD = layerB->children()[1].get(); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 280 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 281 | scoped_ptr<LayerImpl> layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), scoped_ptr<LayerImpl>(), hostImpl.get()); |
| 282 | expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), hostImpl.get()); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 283 | |
| 284 | // Now restructure the tree to look like this: |
| 285 | // root --- D ---+--- A |
| 286 | // | |
| 287 | // +--- C --- B |
| 288 | layerTreeRoot->removeAllChildren(); |
| 289 | layerD->removeAllChildren(); |
| 290 | layerTreeRoot->addChild(layerD); |
| 291 | layerA->removeAllChildren(); |
| 292 | layerD->addChild(layerA); |
| 293 | layerC->removeAllChildren(); |
| 294 | layerD->addChild(layerC); |
| 295 | layerB->removeAllChildren(); |
| 296 | layerC->addChild(layerB); |
| 297 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 298 | // After another synchronize our trees should match and we should not have destroyed any LayerImpls |
| 299 | layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), layerImplTreeRoot.Pass(), hostImpl.get()); |
| 300 | expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), hostImpl.get()); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 301 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 302 | EXPECT_EQ(0u, layerImplDestructionList.size()); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 303 | } |
| 304 | |
| 305 | // Constructs a very simple tree, synchronizes it, then synchronizes to a totally new tree. All layers from the old tree should be deleted. |
| 306 | TEST(TreeSynchronizerTest, syncSimpleTreeThenDestroy) |
| 307 | { |
[email protected] | 068d7ef | 2012-11-05 07:17:46 | [diff] [blame] | 308 | DebugScopedSetImplThread impl; |
[email protected] | 2cdbdba | 2012-10-28 13:15:05 | [diff] [blame] | 309 | std::vector<int> layerImplDestructionList; |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 310 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 311 | LayerTreeSettings settings; |
[email protected] | 068d7ef | 2012-11-05 07:17:46 | [diff] [blame] | 312 | scoped_ptr<LayerTreeHostImpl> hostImpl = LayerTreeHostImpl::create(settings, 0); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 313 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 314 | scoped_refptr<Layer> oldLayerTreeRoot = MockLayer::create(&layerImplDestructionList); |
| 315 | oldLayerTreeRoot->addChild(MockLayer::create(&layerImplDestructionList)); |
| 316 | oldLayerTreeRoot->addChild(MockLayer::create(&layerImplDestructionList)); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 317 | |
| 318 | int oldTreeRootLayerId = oldLayerTreeRoot->id(); |
| 319 | int oldTreeFirstChildLayerId = oldLayerTreeRoot->children()[0]->id(); |
| 320 | int oldTreeSecondChildLayerId = oldLayerTreeRoot->children()[1]->id(); |
| 321 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 322 | scoped_ptr<LayerImpl> layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(oldLayerTreeRoot.get(), scoped_ptr<LayerImpl>(), hostImpl.get()); |
| 323 | expectTreesAreIdentical(oldLayerTreeRoot.get(), layerImplTreeRoot.get(), hostImpl.get()); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 324 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 325 | // Remove all children on the Layer side. |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 326 | oldLayerTreeRoot->removeAllChildren(); |
| 327 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 328 | // Synchronize again. After the sync all LayerImpls from the old tree should be deleted. |
| 329 | scoped_refptr<Layer> newLayerTreeRoot = Layer::create(); |
| 330 | layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(newLayerTreeRoot.get(), layerImplTreeRoot.Pass(), hostImpl.get()); |
| 331 | expectTreesAreIdentical(newLayerTreeRoot.get(), layerImplTreeRoot.get(), hostImpl.get()); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 332 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 333 | ASSERT_EQ(3u, layerImplDestructionList.size()); |
[email protected] | 2cdbdba | 2012-10-28 13:15:05 | [diff] [blame] | 334 | |
| 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] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 338 | } |
| 339 | |
| 340 | // Constructs+syncs a tree with mask, replica, and replica mask layers. |
| 341 | TEST(TreeSynchronizerTest, syncMaskReplicaAndReplicaMaskLayers) |
| 342 | { |
[email protected] | 068d7ef | 2012-11-05 07:17:46 | [diff] [blame] | 343 | DebugScopedSetImplThread impl; |
| 344 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 345 | LayerTreeSettings settings; |
[email protected] | 068d7ef | 2012-11-05 07:17:46 | [diff] [blame] | 346 | scoped_ptr<LayerTreeHostImpl> hostImpl = LayerTreeHostImpl::create(settings, 0); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 347 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 348 | scoped_refptr<Layer> layerTreeRoot = Layer::create(); |
| 349 | layerTreeRoot->addChild(Layer::create()); |
| 350 | layerTreeRoot->addChild(Layer::create()); |
| 351 | layerTreeRoot->addChild(Layer::create()); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 352 | |
| 353 | // First child gets a mask layer. |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 354 | scoped_refptr<Layer> maskLayer = Layer::create(); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 355 | layerTreeRoot->children()[0]->setMaskLayer(maskLayer.get()); |
| 356 | |
| 357 | // Second child gets a replica layer. |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 358 | scoped_refptr<Layer> replicaLayer = Layer::create(); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 359 | layerTreeRoot->children()[1]->setReplicaLayer(replicaLayer.get()); |
| 360 | |
| 361 | // Third child gets a replica layer with a mask layer. |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 362 | scoped_refptr<Layer> replicaLayerWithMask = Layer::create(); |
| 363 | scoped_refptr<Layer> replicaMaskLayer = Layer::create(); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 364 | replicaLayerWithMask->setMaskLayer(replicaMaskLayer.get()); |
| 365 | layerTreeRoot->children()[2]->setReplicaLayer(replicaLayerWithMask.get()); |
| 366 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 367 | scoped_ptr<LayerImpl> layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), scoped_ptr<LayerImpl>(), hostImpl.get()); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 368 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 369 | expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), hostImpl.get()); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 370 | |
| 371 | // Remove the mask layer. |
| 372 | layerTreeRoot->children()[0]->setMaskLayer(0); |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 373 | layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), layerImplTreeRoot.Pass(), hostImpl.get()); |
| 374 | expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), hostImpl.get()); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 375 | |
| 376 | // Remove the replica layer. |
| 377 | layerTreeRoot->children()[1]->setReplicaLayer(0); |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 378 | layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), layerImplTreeRoot.Pass(), hostImpl.get()); |
| 379 | expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), hostImpl.get()); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 380 | |
| 381 | // Remove the replica mask. |
| 382 | replicaLayerWithMask->setMaskLayer(0); |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 383 | layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), layerImplTreeRoot.Pass(), hostImpl.get()); |
| 384 | expectTreesAreIdentical(layerTreeRoot.get(), layerImplTreeRoot.get(), hostImpl.get()); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 385 | } |
| 386 | |
| 387 | TEST(TreeSynchronizerTest, synchronizeAnimations) |
| 388 | { |
[email protected] | 068d7ef | 2012-11-05 07:17:46 | [diff] [blame] | 389 | DebugScopedSetImplThread impl; |
| 390 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 391 | LayerTreeSettings settings; |
[email protected] | 068d7ef | 2012-11-05 07:17:46 | [diff] [blame] | 392 | scoped_ptr<LayerTreeHostImpl> hostImpl = LayerTreeHostImpl::create(settings, 0); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 393 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 394 | scoped_refptr<Layer> layerTreeRoot = Layer::create(); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 395 | |
| 396 | FakeLayerAnimationControllerClient dummy; |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 397 | layerTreeRoot->setLayerAnimationController(FakeLayerAnimationController::create(&dummy).PassAs<LayerAnimationController>()); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 398 | |
| 399 | EXPECT_FALSE(static_cast<FakeLayerAnimationController*>(layerTreeRoot->layerAnimationController())->synchronizedAnimations()); |
| 400 | |
[email protected] | 96baf3e | 2012-10-22 23:09:55 | [diff] [blame] | 401 | scoped_ptr<LayerImpl> layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), scoped_ptr<LayerImpl>(), hostImpl.get()); |
| 402 | layerImplTreeRoot = TreeSynchronizer::synchronizeTrees(layerTreeRoot.get(), layerImplTreeRoot.Pass(), hostImpl.get()); |
[email protected] | c0dd24c | 2012-08-30 23:25:27 | [diff] [blame] | 403 | |
| 404 | EXPECT_TRUE(static_cast<FakeLayerAnimationController*>(layerTreeRoot->layerAnimationController())->synchronizedAnimations()); |
| 405 | } |
| 406 | |
[email protected] | bc5e77c | 2012-11-05 20:00:49 | [diff] [blame] | 407 | } // anonymous namespace |