blob: 2c77ef6bab9a7a240d4049ac46be61fd259f135c [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]556fd292013-03-18 08:03:045#include "cc/trees/tree_synchronizer.h"
[email protected]c0dd24c2012-08-30 23:25:276
avi02a4d172015-12-21 06:14:367#include <stddef.h>
8
[email protected]ac7c7f52012-11-08 06:26:509#include <algorithm>
[email protected]0e98cdd2013-08-23 00:44:3010#include <set>
[email protected]bf691c22013-03-26 21:15:0611#include <vector>
[email protected]ac7c7f52012-11-08 06:26:5012
[email protected]d097e242014-02-28 21:51:1113#include "base/format_macros.h"
danakj60bc3bc2016-04-09 00:24:4814#include "base/memory/ptr_util.h"
[email protected]d097e242014-02-28 21:51:1115#include "base/strings/stringprintf.h"
[email protected]cc3cfaa2013-03-18 09:05:5216#include "cc/layers/layer.h"
17#include "cc/layers/layer_impl.h"
[email protected]101441ce2012-10-16 01:45:0318#include "cc/test/animation_test_common.h"
khushalsagarb64b360d2015-10-21 19:25:1619#include "cc/test/fake_impl_task_runner_provider.h"
[email protected]f4e25f92013-07-13 20:54:5320#include "cc/test/fake_layer_tree_host.h"
hendrikw9b7f6d982014-11-04 22:28:3521#include "cc/test/fake_rendering_stats_instrumentation.h"
[email protected]4e2eb352014-03-20 17:25:4522#include "cc/test/test_shared_bitmap_manager.h"
danakjcf610582015-06-16 22:48:5623#include "cc/test/test_task_graph_runner.h"
jaydasika13c05062016-04-01 18:12:2724#include "cc/trees/layer_tree_host_common.h"
[email protected]556fd292013-03-18 08:03:0425#include "cc/trees/single_thread_proxy.h"
khushalsagarb64b360d2015-10-21 19:25:1626#include "cc/trees/task_runner_provider.h"
[email protected]7f0c53db2012-10-02 00:23:1827#include "testing/gtest/include/gtest/gtest.h"
[email protected]c0dd24c2012-08-30 23:25:2728
[email protected]ba565742012-11-10 09:29:4829namespace cc {
[email protected]c0dd24c2012-08-30 23:25:2730namespace {
31
[email protected]96baf3e2012-10-22 23:09:5532class MockLayerImpl : public LayerImpl {
[email protected]b5651c22013-03-14 15:06:3333 public:
danakj60bc3bc2016-04-09 00:24:4834 static std::unique_ptr<MockLayerImpl> Create(LayerTreeImpl* tree_impl,
35 int layer_id) {
36 return base::WrapUnique(new MockLayerImpl(tree_impl, layer_id));
[email protected]b5651c22013-03-14 15:06:3337 }
dcheng716bedf2014-10-21 09:51:0838 ~MockLayerImpl() override {
[email protected]b5651c22013-03-14 15:06:3339 if (layer_impl_destruction_list_)
40 layer_impl_destruction_list_->push_back(id());
41 }
[email protected]c0dd24c2012-08-30 23:25:2742
[email protected]b5651c22013-03-14 15:06:3343 void SetLayerImplDestructionList(std::vector<int>* list) {
44 layer_impl_destruction_list_ = list;
45 }
[email protected]c0dd24c2012-08-30 23:25:2746
[email protected]b5651c22013-03-14 15:06:3347 private:
48 MockLayerImpl(LayerTreeImpl* tree_impl, int layer_id)
vollick83fbfc82016-03-22 18:33:2749 : LayerImpl(tree_impl, layer_id), layer_impl_destruction_list_(NULL) {}
[email protected]c0dd24c2012-08-30 23:25:2750
[email protected]b5651c22013-03-14 15:06:3351 std::vector<int>* layer_impl_destruction_list_;
[email protected]c0dd24c2012-08-30 23:25:2752};
53
[email protected]96baf3e2012-10-22 23:09:5554class MockLayer : public Layer {
[email protected]b5651c22013-03-14 15:06:3355 public:
56 static scoped_refptr<MockLayer> Create(
57 std::vector<int>* layer_impl_destruction_list) {
loyso0940d412016-03-14 01:30:3158 return make_scoped_refptr(new MockLayer(layer_impl_destruction_list));
[email protected]b5651c22013-03-14 15:06:3359 }
[email protected]c0dd24c2012-08-30 23:25:2760
danakj60bc3bc2016-04-09 00:24:4861 std::unique_ptr<LayerImpl> CreateLayerImpl(
62 LayerTreeImpl* tree_impl) override {
danakjf446a072014-09-27 21:55:4863 return MockLayerImpl::Create(tree_impl, layer_id_);
[email protected]b5651c22013-03-14 15:06:3364 }
[email protected]c0dd24c2012-08-30 23:25:2765
dcheng716bedf2014-10-21 09:51:0866 void PushPropertiesTo(LayerImpl* layer_impl) override {
[email protected]b5651c22013-03-14 15:06:3367 Layer::PushPropertiesTo(layer_impl);
[email protected]c0dd24c2012-08-30 23:25:2768
[email protected]b5651c22013-03-14 15:06:3369 MockLayerImpl* mock_layer_impl = static_cast<MockLayerImpl*>(layer_impl);
70 mock_layer_impl->SetLayerImplDestructionList(layer_impl_destruction_list_);
71 }
[email protected]d58499a2012-10-09 22:27:4772
[email protected]b5651c22013-03-14 15:06:3373 private:
loyso0940d412016-03-14 01:30:3174 explicit MockLayer(std::vector<int>* layer_impl_destruction_list)
75 : layer_impl_destruction_list_(layer_impl_destruction_list) {}
dcheng716bedf2014-10-21 09:51:0876 ~MockLayer() override {}
[email protected]c0dd24c2012-08-30 23:25:2777
[email protected]b5651c22013-03-14 15:06:3378 std::vector<int>* layer_impl_destruction_list_;
[email protected]c0dd24c2012-08-30 23:25:2779};
80
[email protected]b5651c22013-03-14 15:06:3381void ExpectTreesAreIdentical(Layer* layer,
82 LayerImpl* layer_impl,
83 LayerTreeImpl* tree_impl) {
84 ASSERT_TRUE(layer);
85 ASSERT_TRUE(layer_impl);
[email protected]c0dd24c2012-08-30 23:25:2786
[email protected]b5651c22013-03-14 15:06:3387 EXPECT_EQ(layer->id(), layer_impl->id());
88 EXPECT_EQ(layer_impl->layer_tree_impl(), tree_impl);
[email protected]c0dd24c2012-08-30 23:25:2789
[email protected]b5651c22013-03-14 15:06:3390 EXPECT_EQ(layer->non_fast_scrollable_region(),
91 layer_impl->non_fast_scrollable_region());
[email protected]c0dd24c2012-08-30 23:25:2792
[email protected]b5651c22013-03-14 15:06:3393 ASSERT_EQ(!!layer->mask_layer(), !!layer_impl->mask_layer());
94 if (layer->mask_layer()) {
[email protected]d097e242014-02-28 21:51:1195 SCOPED_TRACE("mask_layer");
vollick83fbfc82016-03-22 18:33:2796 ExpectTreesAreIdentical(layer->mask_layer(), layer_impl->mask_layer(),
97 tree_impl);
[email protected]b5651c22013-03-14 15:06:3398 }
[email protected]c0dd24c2012-08-30 23:25:2799
[email protected]b5651c22013-03-14 15:06:33100 ASSERT_EQ(!!layer->replica_layer(), !!layer_impl->replica_layer());
101 if (layer->replica_layer()) {
[email protected]d097e242014-02-28 21:51:11102 SCOPED_TRACE("replica_layer");
vollick83fbfc82016-03-22 18:33:27103 ExpectTreesAreIdentical(layer->replica_layer(), layer_impl->replica_layer(),
104 tree_impl);
[email protected]b5651c22013-03-14 15:06:33105 }
[email protected]c0dd24c2012-08-30 23:25:27106
[email protected]50761e92013-03-29 20:51:28107 const LayerList& layer_children = layer->children();
vollick83fbfc82016-03-22 18:33:27108 const LayerImplList& layer_impl_children = layer_impl->children();
[email protected]c0dd24c2012-08-30 23:25:27109
[email protected]b5651c22013-03-14 15:06:33110 ASSERT_EQ(layer_children.size(), layer_impl_children.size());
[email protected]c0dd24c2012-08-30 23:25:27111
[email protected]0e98cdd2013-08-23 00:44:30112 const Layer* layer_scroll_parent = layer->scroll_parent();
[email protected]0e98cdd2013-08-23 00:44:30113
114 if (layer_scroll_parent) {
[email protected]0e98cdd2013-08-23 00:44:30115 ASSERT_TRUE(layer_scroll_parent->scroll_children()->find(layer) !=
vollick83fbfc82016-03-22 18:33:27116 layer_scroll_parent->scroll_children()->end());
[email protected]0e98cdd2013-08-23 00:44:30117 }
118
[email protected]0e98cdd2013-08-23 00:44:30119 const Layer* layer_clip_parent = layer->clip_parent();
[email protected]0e98cdd2013-08-23 00:44:30120
121 if (layer_clip_parent) {
vollick83fbfc82016-03-22 18:33:27122 const std::set<Layer*>* clip_children = layer_clip_parent->clip_children();
[email protected]0e98cdd2013-08-23 00:44:30123 ASSERT_TRUE(clip_children->find(layer) != clip_children->end());
[email protected]0e98cdd2013-08-23 00:44:30124 }
125
[email protected]b5651c22013-03-14 15:06:33126 for (size_t i = 0; i < layer_children.size(); ++i) {
[email protected]d097e242014-02-28 21:51:11127 SCOPED_TRACE(base::StringPrintf("child layer %" PRIuS, i).c_str());
vollick83fbfc82016-03-22 18:33:27128 ExpectTreesAreIdentical(layer_children[i].get(), layer_impl_children[i],
129 tree_impl);
[email protected]b5651c22013-03-14 15:06:33130 }
[email protected]c0dd24c2012-08-30 23:25:27131}
132
[email protected]c2282382012-12-16 00:46:03133class TreeSynchronizerTest : public testing::Test {
[email protected]b5651c22013-03-14 15:06:33134 public:
enne2097cab2014-09-25 20:16:31135 TreeSynchronizerTest()
136 : client_(FakeLayerTreeHostClient::DIRECT_3D),
loyso0940d412016-03-14 01:30:31137 host_(FakeLayerTreeHost::Create(&client_, &task_graph_runner_)) {}
[email protected]c2282382012-12-16 00:46:03138
[email protected]b5651c22013-03-14 15:06:33139 protected:
enne2097cab2014-09-25 20:16:31140 FakeLayerTreeHostClient client_;
danakjcf610582015-06-16 22:48:56141 TestTaskGraphRunner task_graph_runner_;
danakj60bc3bc2016-04-09 00:24:48142 std::unique_ptr<FakeLayerTreeHost> host_;
sunxdc36713a2016-03-03 22:31:10143
144 bool is_equal(ScrollTree::ScrollOffsetMap map,
145 ScrollTree::ScrollOffsetMap other) {
146 if (map.size() != other.size())
147 return false;
148 for (auto& map_entry : map) {
149 if (other.find(map_entry.first) == other.end())
150 return false;
151 SyncedScrollOffset& from_map = *map_entry.second.get();
152 SyncedScrollOffset& from_other = *other[map_entry.first].get();
153 if (from_map.PendingBase() != from_other.PendingBase() ||
154 from_map.ActiveBase() != from_other.ActiveBase() ||
155 from_map.Delta() != from_other.Delta() ||
156 from_map.PendingDelta().get() != from_other.PendingDelta().get())
157 return false;
158 }
159 return true;
160 }
[email protected]c2282382012-12-16 00:46:03161};
162
[email protected]c0dd24c2012-08-30 23:25:27163// Attempts to synchronizes a null tree. This should not crash, and should
164// return a null tree.
[email protected]b5651c22013-03-14 15:06:33165TEST_F(TreeSynchronizerTest, SyncNullTree) {
vollick83fbfc82016-03-22 18:33:27166 TreeSynchronizer::SynchronizeTrees(static_cast<Layer*>(NULL),
167 host_->active_tree());
168 EXPECT_TRUE(!host_->active_tree()->root_layer());
[email protected]c0dd24c2012-08-30 23:25:27169}
170
[email protected]b5651c22013-03-14 15:06:33171// Constructs a very simple tree and synchronizes it without trying to reuse any
172// preexisting layers.
173TEST_F(TreeSynchronizerTest, SyncSimpleTreeFromEmpty) {
loyso0940d412016-03-14 01:30:31174 scoped_refptr<Layer> layer_tree_root = Layer::Create();
175 layer_tree_root->AddChild(Layer::Create());
176 layer_tree_root->AddChild(Layer::Create());
[email protected]c0dd24c2012-08-30 23:25:27177
[email protected]f4e25f92013-07-13 20:54:53178 host_->SetRootLayer(layer_tree_root);
179
vollick83fbfc82016-03-22 18:33:27180 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
181 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27182
[email protected]b5651c22013-03-14 15:06:33183 ExpectTreesAreIdentical(layer_tree_root.get(),
vollick83fbfc82016-03-22 18:33:27184 host_->active_tree()->root_layer(),
[email protected]f4e25f92013-07-13 20:54:53185 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27186}
187
[email protected]b5651c22013-03-14 15:06:33188// Constructs a very simple tree and synchronizes it attempting to reuse some
189// layers
190TEST_F(TreeSynchronizerTest, SyncSimpleTreeReusingLayers) {
191 std::vector<int> layer_impl_destruction_list;
[email protected]c0dd24c2012-08-30 23:25:27192
[email protected]b5651c22013-03-14 15:06:33193 scoped_refptr<Layer> layer_tree_root =
loyso0940d412016-03-14 01:30:31194 MockLayer::Create(&layer_impl_destruction_list);
195 layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list));
196 layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list));
[email protected]c0dd24c2012-08-30 23:25:27197
[email protected]f4e25f92013-07-13 20:54:53198 host_->SetRootLayer(layer_tree_root);
199
vollick83fbfc82016-03-22 18:33:27200 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
201 host_->active_tree());
202 LayerImpl* layer_impl_tree_root = host_->active_tree()->root_layer();
203 ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root,
[email protected]f4e25f92013-07-13 20:54:53204 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27205
[email protected]b5651c22013-03-14 15:06:33206 // We have to push properties to pick up the destruction list pointer.
jaydasika9234e402016-03-21 20:44:22207 TreeSynchronizer::PushLayerProperties(layer_tree_root->layer_tree_host(),
208 host_->active_tree());
[email protected]5c4824e12013-01-12 16:34:53209
[email protected]b5651c22013-03-14 15:06:33210 // Add a new layer to the Layer side
loysoa6edaaff2015-05-25 03:26:44211 layer_tree_root->children()[0]->AddChild(
loyso0940d412016-03-14 01:30:31212 MockLayer::Create(&layer_impl_destruction_list));
[email protected]b5651c22013-03-14 15:06:33213 // Remove one.
214 layer_tree_root->children()[1]->RemoveFromParent();
215 int second_layer_impl_id = layer_impl_tree_root->children()[1]->id();
[email protected]c0dd24c2012-08-30 23:25:27216
[email protected]b5651c22013-03-14 15:06:33217 // Synchronize again. After the sync the trees should be equivalent and we
218 // should have created and destroyed one LayerImpl.
vollick83fbfc82016-03-22 18:33:27219 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
220 host_->active_tree());
221 layer_impl_tree_root = host_->active_tree()->root_layer();
222
223 ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root,
[email protected]f4e25f92013-07-13 20:54:53224 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27225
[email protected]b5651c22013-03-14 15:06:33226 ASSERT_EQ(1u, layer_impl_destruction_list.size());
227 EXPECT_EQ(second_layer_impl_id, layer_impl_destruction_list[0]);
vollick83fbfc82016-03-22 18:33:27228
rockot2176f922016-06-08 19:18:32229 host_->active_tree()->DetachLayers();
[email protected]c0dd24c2012-08-30 23:25:27230}
231
[email protected]b5651c22013-03-14 15:06:33232// Constructs a very simple tree and checks that a stacking-order change is
233// tracked properly.
234TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndTrackStackingOrderChange) {
235 std::vector<int> layer_impl_destruction_list;
[email protected]c0dd24c2012-08-30 23:25:27236
[email protected]b5651c22013-03-14 15:06:33237 // Set up the tree and sync once. child2 needs to be synced here, too, even
238 // though we remove it to set up the intended scenario.
239 scoped_refptr<Layer> layer_tree_root =
loyso0940d412016-03-14 01:30:31240 MockLayer::Create(&layer_impl_destruction_list);
241 scoped_refptr<Layer> child2 = MockLayer::Create(&layer_impl_destruction_list);
242 layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list));
[email protected]b5651c22013-03-14 15:06:33243 layer_tree_root->AddChild(child2);
[email protected]f4e25f92013-07-13 20:54:53244
245 host_->SetRootLayer(layer_tree_root);
246
vollick83fbfc82016-03-22 18:33:27247 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
248 host_->active_tree());
jaydasikaef64f9e42016-03-12 01:08:18249 LayerImpl* layer_impl_tree_root = host_->active_tree()->root_layer();
250 ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root,
[email protected]f4e25f92013-07-13 20:54:53251 host_->active_tree());
[email protected]5c4824e12013-01-12 16:34:53252
[email protected]b5651c22013-03-14 15:06:33253 // We have to push properties to pick up the destruction list pointer.
jaydasika9234e402016-03-21 20:44:22254 TreeSynchronizer::PushLayerProperties(layer_tree_root->layer_tree_host(),
255 host_->active_tree());
[email protected]5c4824e12013-01-12 16:34:53256
jaydasikad6f778b2016-05-19 22:51:26257 host_->active_tree()->ResetAllChangeTracking();
[email protected]c0dd24c2012-08-30 23:25:27258
[email protected]b5651c22013-03-14 15:06:33259 // re-insert the layer and sync again.
260 child2->RemoveFromParent();
261 layer_tree_root->AddChild(child2);
vollick83fbfc82016-03-22 18:33:27262 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
263 host_->active_tree());
jaydasikaef64f9e42016-03-12 01:08:18264 layer_impl_tree_root = host_->active_tree()->root_layer();
265 ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root,
[email protected]f4e25f92013-07-13 20:54:53266 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27267
jaydasika9234e402016-03-21 20:44:22268 TreeSynchronizer::PushLayerProperties(layer_tree_root->layer_tree_host(),
269 host_->active_tree());
[email protected]5c4824e12013-01-12 16:34:53270
[email protected]b5651c22013-03-14 15:06:33271 // Check that the impl thread properly tracked the change.
272 EXPECT_FALSE(layer_impl_tree_root->LayerPropertyChanged());
273 EXPECT_FALSE(layer_impl_tree_root->children()[0]->LayerPropertyChanged());
274 EXPECT_TRUE(layer_impl_tree_root->children()[1]->LayerPropertyChanged());
rockot2176f922016-06-08 19:18:32275 host_->active_tree()->DetachLayers();
[email protected]c0dd24c2012-08-30 23:25:27276}
277
[email protected]b5651c22013-03-14 15:06:33278TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndProperties) {
loyso0940d412016-03-14 01:30:31279 scoped_refptr<Layer> layer_tree_root = Layer::Create();
280 layer_tree_root->AddChild(Layer::Create());
281 layer_tree_root->AddChild(Layer::Create());
[email protected]c0dd24c2012-08-30 23:25:27282
[email protected]f4e25f92013-07-13 20:54:53283 host_->SetRootLayer(layer_tree_root);
284
[email protected]b5651c22013-03-14 15:06:33285 // Pick some random properties to set. The values are not important, we're
286 // just testing that at least some properties are making it through.
287 gfx::PointF root_position = gfx::PointF(2.3f, 7.4f);
288 layer_tree_root->SetPosition(root_position);
[email protected]c0dd24c2012-08-30 23:25:27289
[email protected]b5651c22013-03-14 15:06:33290 gfx::Size second_child_bounds = gfx::Size(25, 53);
291 layer_tree_root->children()[1]->SetBounds(second_child_bounds);
[email protected]445881f2013-04-16 01:11:59292 layer_tree_root->children()[1]->SavePaintProperties();
[email protected]c0dd24c2012-08-30 23:25:27293
vollick83fbfc82016-03-22 18:33:27294 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
295 host_->active_tree());
296 LayerImpl* layer_impl_tree_root = host_->active_tree()->root_layer();
297 ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root,
[email protected]f4e25f92013-07-13 20:54:53298 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27299
jaydasika9234e402016-03-21 20:44:22300 TreeSynchronizer::PushLayerProperties(layer_tree_root->layer_tree_host(),
301 host_->active_tree());
[email protected]5c4824e12013-01-12 16:34:53302
[email protected]b5651c22013-03-14 15:06:33303 // Check that the property values we set on the Layer tree are reflected in
304 // the LayerImpl tree.
305 gfx::PointF root_layer_impl_position = layer_impl_tree_root->position();
306 EXPECT_EQ(root_position.x(), root_layer_impl_position.x());
307 EXPECT_EQ(root_position.y(), root_layer_impl_position.y());
[email protected]c0dd24c2012-08-30 23:25:27308
bokancccfde72014-10-08 15:15:22309 gfx::Size second_layer_impl_child_bounds =
[email protected]b5651c22013-03-14 15:06:33310 layer_impl_tree_root->children()[1]->bounds();
311 EXPECT_EQ(second_child_bounds.width(),
312 second_layer_impl_child_bounds.width());
313 EXPECT_EQ(second_child_bounds.height(),
314 second_layer_impl_child_bounds.height());
[email protected]c0dd24c2012-08-30 23:25:27315}
316
[email protected]b5651c22013-03-14 15:06:33317TEST_F(TreeSynchronizerTest, ReuseLayerImplsAfterStructuralChange) {
318 std::vector<int> layer_impl_destruction_list;
[email protected]c0dd24c2012-08-30 23:25:27319
[email protected]b5651c22013-03-14 15:06:33320 // Set up a tree with this sort of structure:
321 // root --- A --- B ---+--- C
322 // |
323 // +--- D
324 scoped_refptr<Layer> layer_tree_root =
loyso0940d412016-03-14 01:30:31325 MockLayer::Create(&layer_impl_destruction_list);
326 layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list));
[email protected]c0dd24c2012-08-30 23:25:27327
vollick83fbfc82016-03-22 18:33:27328 scoped_refptr<Layer> layer_a = layer_tree_root->children()[0];
loyso0940d412016-03-14 01:30:31329 layer_a->AddChild(MockLayer::Create(&layer_impl_destruction_list));
[email protected]c0dd24c2012-08-30 23:25:27330
vollick83fbfc82016-03-22 18:33:27331 scoped_refptr<Layer> layer_b = layer_a->children()[0];
loyso0940d412016-03-14 01:30:31332 layer_b->AddChild(MockLayer::Create(&layer_impl_destruction_list));
[email protected]c0dd24c2012-08-30 23:25:27333
vollick83fbfc82016-03-22 18:33:27334 scoped_refptr<Layer> layer_c = layer_b->children()[0];
loyso0940d412016-03-14 01:30:31335 layer_b->AddChild(MockLayer::Create(&layer_impl_destruction_list));
vollick83fbfc82016-03-22 18:33:27336 scoped_refptr<Layer> layer_d = layer_b->children()[1];
[email protected]c0dd24c2012-08-30 23:25:27337
[email protected]f4e25f92013-07-13 20:54:53338 host_->SetRootLayer(layer_tree_root);
339
vollick83fbfc82016-03-22 18:33:27340 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
341 host_->active_tree());
342 LayerImpl* layer_impl_tree_root = host_->active_tree()->root_layer();
343 ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root,
[email protected]f4e25f92013-07-13 20:54:53344 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27345
[email protected]b5651c22013-03-14 15:06:33346 // We have to push properties to pick up the destruction list pointer.
jaydasika9234e402016-03-21 20:44:22347 TreeSynchronizer::PushLayerProperties(layer_tree_root->layer_tree_host(),
348 host_->active_tree());
[email protected]5c4824e12013-01-12 16:34:53349
[email protected]b5651c22013-03-14 15:06:33350 // Now restructure the tree to look like this:
351 // root --- D ---+--- A
352 // |
353 // +--- C --- B
354 layer_tree_root->RemoveAllChildren();
355 layer_d->RemoveAllChildren();
356 layer_tree_root->AddChild(layer_d);
357 layer_a->RemoveAllChildren();
358 layer_d->AddChild(layer_a);
359 layer_c->RemoveAllChildren();
360 layer_d->AddChild(layer_c);
361 layer_b->RemoveAllChildren();
362 layer_c->AddChild(layer_b);
[email protected]c0dd24c2012-08-30 23:25:27363
[email protected]b5651c22013-03-14 15:06:33364 // After another synchronize our trees should match and we should not have
365 // destroyed any LayerImpls
vollick83fbfc82016-03-22 18:33:27366 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
367 host_->active_tree());
368 layer_impl_tree_root = host_->active_tree()->root_layer();
369 ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root,
[email protected]f4e25f92013-07-13 20:54:53370 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27371
[email protected]b5651c22013-03-14 15:06:33372 EXPECT_EQ(0u, layer_impl_destruction_list.size());
vollick83fbfc82016-03-22 18:33:27373
rockot2176f922016-06-08 19:18:32374 host_->active_tree()->DetachLayers();
[email protected]c0dd24c2012-08-30 23:25:27375}
376
[email protected]b5651c22013-03-14 15:06:33377// Constructs a very simple tree, synchronizes it, then synchronizes to a
378// totally new tree. All layers from the old tree should be deleted.
379TEST_F(TreeSynchronizerTest, SyncSimpleTreeThenDestroy) {
380 std::vector<int> layer_impl_destruction_list;
[email protected]c0dd24c2012-08-30 23:25:27381
[email protected]b5651c22013-03-14 15:06:33382 scoped_refptr<Layer> old_layer_tree_root =
loyso0940d412016-03-14 01:30:31383 MockLayer::Create(&layer_impl_destruction_list);
[email protected]b5651c22013-03-14 15:06:33384 old_layer_tree_root->AddChild(
loyso0940d412016-03-14 01:30:31385 MockLayer::Create(&layer_impl_destruction_list));
[email protected]b5651c22013-03-14 15:06:33386 old_layer_tree_root->AddChild(
loyso0940d412016-03-14 01:30:31387 MockLayer::Create(&layer_impl_destruction_list));
[email protected]c0dd24c2012-08-30 23:25:27388
[email protected]f4e25f92013-07-13 20:54:53389 host_->SetRootLayer(old_layer_tree_root);
390
[email protected]b5651c22013-03-14 15:06:33391 int old_tree_root_layer_id = old_layer_tree_root->id();
392 int old_tree_first_child_layer_id = old_layer_tree_root->children()[0]->id();
393 int old_tree_second_child_layer_id = old_layer_tree_root->children()[1]->id();
[email protected]c0dd24c2012-08-30 23:25:27394
vollick83fbfc82016-03-22 18:33:27395 TreeSynchronizer::SynchronizeTrees(old_layer_tree_root.get(),
396 host_->active_tree());
397 LayerImpl* layer_impl_tree_root = host_->active_tree()->root_layer();
398 ExpectTreesAreIdentical(old_layer_tree_root.get(), layer_impl_tree_root,
[email protected]f4e25f92013-07-13 20:54:53399 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27400
[email protected]b5651c22013-03-14 15:06:33401 // We have to push properties to pick up the destruction list pointer.
jaydasika9234e402016-03-21 20:44:22402 TreeSynchronizer::PushLayerProperties(old_layer_tree_root->layer_tree_host(),
403 host_->active_tree());
[email protected]5c4824e12013-01-12 16:34:53404
[email protected]b5651c22013-03-14 15:06:33405 // Remove all children on the Layer side.
406 old_layer_tree_root->RemoveAllChildren();
[email protected]c0dd24c2012-08-30 23:25:27407
[email protected]b5651c22013-03-14 15:06:33408 // Synchronize again. After the sync all LayerImpls from the old tree should
409 // be deleted.
loyso0940d412016-03-14 01:30:31410 scoped_refptr<Layer> new_layer_tree_root = Layer::Create();
[email protected]f4e25f92013-07-13 20:54:53411 host_->SetRootLayer(new_layer_tree_root);
vollick83fbfc82016-03-22 18:33:27412
413 TreeSynchronizer::SynchronizeTrees(new_layer_tree_root.get(),
414 host_->active_tree());
415 layer_impl_tree_root = host_->active_tree()->root_layer();
416 ExpectTreesAreIdentical(new_layer_tree_root.get(), layer_impl_tree_root,
[email protected]f4e25f92013-07-13 20:54:53417 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27418
[email protected]b5651c22013-03-14 15:06:33419 ASSERT_EQ(3u, layer_impl_destruction_list.size());
[email protected]2cdbdba2012-10-28 13:15:05420
[email protected]b5651c22013-03-14 15:06:33421 EXPECT_TRUE(std::find(layer_impl_destruction_list.begin(),
422 layer_impl_destruction_list.end(),
423 old_tree_root_layer_id) !=
424 layer_impl_destruction_list.end());
425 EXPECT_TRUE(std::find(layer_impl_destruction_list.begin(),
426 layer_impl_destruction_list.end(),
427 old_tree_first_child_layer_id) !=
428 layer_impl_destruction_list.end());
429 EXPECT_TRUE(std::find(layer_impl_destruction_list.begin(),
430 layer_impl_destruction_list.end(),
431 old_tree_second_child_layer_id) !=
432 layer_impl_destruction_list.end());
[email protected]c0dd24c2012-08-30 23:25:27433}
434
435// Constructs+syncs a tree with mask, replica, and replica mask layers.
[email protected]b5651c22013-03-14 15:06:33436TEST_F(TreeSynchronizerTest, SyncMaskReplicaAndReplicaMaskLayers) {
loyso0940d412016-03-14 01:30:31437 scoped_refptr<Layer> layer_tree_root = Layer::Create();
438 layer_tree_root->AddChild(Layer::Create());
439 layer_tree_root->AddChild(Layer::Create());
440 layer_tree_root->AddChild(Layer::Create());
[email protected]c0dd24c2012-08-30 23:25:27441
[email protected]b5651c22013-03-14 15:06:33442 // First child gets a mask layer.
loyso0940d412016-03-14 01:30:31443 scoped_refptr<Layer> mask_layer = Layer::Create();
[email protected]b5651c22013-03-14 15:06:33444 layer_tree_root->children()[0]->SetMaskLayer(mask_layer.get());
[email protected]c0dd24c2012-08-30 23:25:27445
[email protected]b5651c22013-03-14 15:06:33446 // Second child gets a replica layer.
loyso0940d412016-03-14 01:30:31447 scoped_refptr<Layer> replica_layer = Layer::Create();
[email protected]b5651c22013-03-14 15:06:33448 layer_tree_root->children()[1]->SetReplicaLayer(replica_layer.get());
[email protected]c0dd24c2012-08-30 23:25:27449
[email protected]b5651c22013-03-14 15:06:33450 // Third child gets a replica layer with a mask layer.
loyso0940d412016-03-14 01:30:31451 scoped_refptr<Layer> replica_layer_with_mask = Layer::Create();
452 scoped_refptr<Layer> replica_mask_layer = Layer::Create();
[email protected]b5651c22013-03-14 15:06:33453 replica_layer_with_mask->SetMaskLayer(replica_mask_layer.get());
vollick83fbfc82016-03-22 18:33:27454 layer_tree_root->children()[2]->SetReplicaLayer(
455 replica_layer_with_mask.get());
[email protected]c0dd24c2012-08-30 23:25:27456
[email protected]f4e25f92013-07-13 20:54:53457 host_->SetRootLayer(layer_tree_root);
458
vollick83fbfc82016-03-22 18:33:27459 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
460 host_->active_tree());
461 LayerImpl* layer_impl_tree_root = host_->active_tree()->root_layer();
462 ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root,
[email protected]f4e25f92013-07-13 20:54:53463 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27464
[email protected]b5651c22013-03-14 15:06:33465 // Remove the mask layer.
466 layer_tree_root->children()[0]->SetMaskLayer(NULL);
vollick83fbfc82016-03-22 18:33:27467 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
468 host_->active_tree());
469 layer_impl_tree_root = host_->active_tree()->root_layer();
470 ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root,
[email protected]f4e25f92013-07-13 20:54:53471 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27472
[email protected]b5651c22013-03-14 15:06:33473 // Remove the replica layer.
474 layer_tree_root->children()[1]->SetReplicaLayer(NULL);
vollick83fbfc82016-03-22 18:33:27475 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
476 host_->active_tree());
477 layer_impl_tree_root = host_->active_tree()->root_layer();
478 ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root,
[email protected]f4e25f92013-07-13 20:54:53479 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27480
[email protected]b5651c22013-03-14 15:06:33481 // Remove the replica mask.
482 replica_layer_with_mask->SetMaskLayer(NULL);
vollick83fbfc82016-03-22 18:33:27483 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
484 host_->active_tree());
485 layer_impl_tree_root = host_->active_tree()->root_layer();
486 ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root,
[email protected]f4e25f92013-07-13 20:54:53487 host_->active_tree());
vollick83fbfc82016-03-22 18:33:27488
rockot2176f922016-06-08 19:18:32489 host_->active_tree()->DetachLayers();
[email protected]c0dd24c2012-08-30 23:25:27490}
491
sunxd54e08e9d2016-02-22 23:01:28492TEST_F(TreeSynchronizerTest, SynchronizeCurrentlyScrollingNode) {
493 LayerTreeSettings settings;
494 FakeLayerTreeHostImplClient client;
495 FakeImplTaskRunnerProvider task_runner_provider;
496 FakeRenderingStatsInstrumentation stats_instrumentation;
497 TestSharedBitmapManager shared_bitmap_manager;
498 TestTaskGraphRunner task_graph_runner;
499 FakeLayerTreeHostImpl* host_impl = host_->host_impl();
500 host_impl->CreatePendingTree();
501
loyso0940d412016-03-14 01:30:31502 scoped_refptr<Layer> layer_tree_root = Layer::Create();
503 scoped_refptr<Layer> scroll_clip_layer = Layer::Create();
504 scoped_refptr<Layer> scroll_layer = Layer::Create();
505 scoped_refptr<Layer> transient_scroll_clip_layer = Layer::Create();
506 scoped_refptr<Layer> transient_scroll_layer = Layer::Create();
sunxd54e08e9d2016-02-22 23:01:28507
508 layer_tree_root->AddChild(transient_scroll_clip_layer);
509 transient_scroll_clip_layer->AddChild(transient_scroll_layer);
510 transient_scroll_layer->AddChild(scroll_clip_layer);
511 scroll_clip_layer->AddChild(scroll_layer);
512
513 transient_scroll_layer->SetScrollClipLayerId(
514 transient_scroll_clip_layer->id());
515 scroll_layer->SetScrollClipLayerId(scroll_clip_layer->id());
516 host_->SetRootLayer(layer_tree_root);
517 host_->BuildPropertyTreesForTesting();
518 host_->CommitAndCreatePendingTree();
519 host_impl->ActivateSyncTree();
520
521 ExpectTreesAreIdentical(layer_tree_root.get(),
522 host_impl->active_tree()->root_layer(),
523 host_impl->active_tree());
524
525 host_impl->active_tree()->SetCurrentlyScrollingLayer(
vollickcb3f6b12016-03-01 23:44:10526 host_impl->active_tree()->LayerById(scroll_layer->id()));
sunxd54e08e9d2016-02-22 23:01:28527 transient_scroll_layer->SetScrollClipLayerId(Layer::INVALID_ID);
528 host_->BuildPropertyTreesForTesting();
529
530 host_impl->CreatePendingTree();
531 host_->CommitAndCreatePendingTree();
532 host_impl->ActivateSyncTree();
533
534 EXPECT_EQ(scroll_layer->id(),
535 host_impl->active_tree()->CurrentlyScrollingLayer()->id());
536}
537
sunxdc36713a2016-03-03 22:31:10538TEST_F(TreeSynchronizerTest, SynchronizeScrollTreeScrollOffsetMap) {
539 host_->InitializeSingleThreaded(&client_, base::ThreadTaskRunnerHandle::Get(),
540 nullptr);
541 LayerTreeSettings settings;
542 FakeLayerTreeHostImplClient client;
543 FakeImplTaskRunnerProvider task_runner_provider;
544 FakeRenderingStatsInstrumentation stats_instrumentation;
545 TestSharedBitmapManager shared_bitmap_manager;
546 TestTaskGraphRunner task_graph_runner;
547 FakeLayerTreeHostImpl* host_impl = host_->host_impl();
548 host_impl->CreatePendingTree();
549
loyso0940d412016-03-14 01:30:31550 scoped_refptr<Layer> layer_tree_root = Layer::Create();
551 scoped_refptr<Layer> scroll_clip_layer = Layer::Create();
552 scoped_refptr<Layer> scroll_layer = Layer::Create();
553 scoped_refptr<Layer> transient_scroll_clip_layer = Layer::Create();
554 scoped_refptr<Layer> transient_scroll_layer = Layer::Create();
sunxdc36713a2016-03-03 22:31:10555
556 layer_tree_root->AddChild(transient_scroll_clip_layer);
557 transient_scroll_clip_layer->AddChild(transient_scroll_layer);
558 transient_scroll_layer->AddChild(scroll_clip_layer);
559 scroll_clip_layer->AddChild(scroll_layer);
560
561 transient_scroll_layer->SetScrollClipLayerId(
562 transient_scroll_clip_layer->id());
563 scroll_layer->SetScrollClipLayerId(scroll_clip_layer->id());
564 transient_scroll_layer->SetScrollOffset(gfx::ScrollOffset(1, 2));
565 scroll_layer->SetScrollOffset(gfx::ScrollOffset(10, 20));
566
567 host_->SetRootLayer(layer_tree_root);
568 host_->BuildPropertyTreesForTesting();
569 host_->CommitAndCreatePendingTree();
570 host_impl->ActivateSyncTree();
571
572 ExpectTreesAreIdentical(layer_tree_root.get(),
573 host_impl->active_tree()->root_layer(),
574 host_impl->active_tree());
575
576 // After the initial commit, scroll_offset_map in scroll_tree is expected to
577 // have one entry for scroll_layer and one entry for transient_scroll_layer,
578 // the pending base and active base must be the same at this stage.
579 ScrollTree::ScrollOffsetMap scroll_offset_map;
580 scroll_offset_map[scroll_layer->id()] = new SyncedScrollOffset;
581 scroll_offset_map[transient_scroll_layer->id()] = new SyncedScrollOffset;
582 scroll_offset_map[scroll_layer->id()]->PushFromMainThread(
583 scroll_layer->scroll_offset());
584 scroll_offset_map[scroll_layer->id()]->PushPendingToActive();
585 scroll_offset_map[transient_scroll_layer->id()]->PushFromMainThread(
586 transient_scroll_layer->scroll_offset());
587 scroll_offset_map[transient_scroll_layer->id()]->PushPendingToActive();
588 EXPECT_TRUE(
589 is_equal(scroll_offset_map, host_impl->active_tree()
590 ->property_trees()
591 ->scroll_tree.scroll_offset_map()));
592
593 // Set ScrollOffset active delta: gfx::ScrollOffset(10, 10)
594 LayerImpl* scroll_layer_impl =
595 host_impl->active_tree()->LayerById(scroll_layer->id());
596 ScrollTree& scroll_tree =
597 host_impl->active_tree()->property_trees()->scroll_tree;
sunxdc044b11a2016-03-16 16:23:20598 scroll_tree.SetScrollOffset(scroll_layer_impl->id(),
599 gfx::ScrollOffset(20, 30));
sunxdc36713a2016-03-03 22:31:10600
601 // Pull ScrollOffset delta for main thread, and change offset on main thread
danakj60bc3bc2016-04-09 00:24:48602 std::unique_ptr<ScrollAndScaleSet> scroll_info(new ScrollAndScaleSet());
sunxdc36713a2016-03-03 22:31:10603 scroll_tree.CollectScrollDeltas(scroll_info.get());
604 host_->proxy()->SetNeedsCommit();
605 host_->ApplyScrollAndScale(scroll_info.get());
606 EXPECT_EQ(gfx::ScrollOffset(20, 30), scroll_layer->scroll_offset());
607 scroll_layer->SetScrollOffset(gfx::ScrollOffset(100, 100));
608
609 // More update to ScrollOffset active delta: gfx::ScrollOffset(20, 20)
sunxdc044b11a2016-03-16 16:23:20610 scroll_tree.SetScrollOffset(scroll_layer_impl->id(),
611 gfx::ScrollOffset(40, 50));
sunxdc36713a2016-03-03 22:31:10612 host_impl->active_tree()->SetCurrentlyScrollingLayer(scroll_layer_impl);
613
614 // Make one layer unscrollable so that scroll tree topology changes
615 transient_scroll_layer->SetScrollClipLayerId(Layer::INVALID_ID);
616 host_->BuildPropertyTreesForTesting();
617
618 host_impl->CreatePendingTree();
619 host_->CommitAndCreatePendingTree();
620 host_impl->ActivateSyncTree();
621
622 EXPECT_EQ(scroll_layer->id(),
623 host_impl->active_tree()->CurrentlyScrollingLayer()->id());
624 scroll_offset_map.erase(transient_scroll_layer->id());
625 scroll_offset_map[scroll_layer->id()]->SetCurrent(gfx::ScrollOffset(20, 30));
626 scroll_offset_map[scroll_layer->id()]->PullDeltaForMainThread();
627 scroll_offset_map[scroll_layer->id()]->SetCurrent(gfx::ScrollOffset(40, 50));
628 scroll_offset_map[scroll_layer->id()]->PushFromMainThread(
629 gfx::ScrollOffset(100, 100));
630 scroll_offset_map[scroll_layer->id()]->PushPendingToActive();
631 EXPECT_TRUE(is_equal(scroll_offset_map, scroll_tree.scroll_offset_map()));
632}
633
[email protected]ba565742012-11-10 09:29:48634} // namespace
635} // namespace cc