blob: b9c1dce0cc464f0fe33e36b8943eecec94ac96d8 [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
229 host_->active_tree()->ClearLayers();
[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());
vollick83fbfc82016-03-22 18:33:27275 host_->active_tree()->ClearLayers();
[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 float first_child_opacity = 0.25f;
291 layer_tree_root->children()[0]->SetOpacity(first_child_opacity);
[email protected]c0dd24c2012-08-30 23:25:27292
[email protected]b5651c22013-03-14 15:06:33293 gfx::Size second_child_bounds = gfx::Size(25, 53);
294 layer_tree_root->children()[1]->SetBounds(second_child_bounds);
[email protected]445881f2013-04-16 01:11:59295 layer_tree_root->children()[1]->SavePaintProperties();
[email protected]c0dd24c2012-08-30 23:25:27296
vollick83fbfc82016-03-22 18:33:27297 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
298 host_->active_tree());
299 LayerImpl* layer_impl_tree_root = host_->active_tree()->root_layer();
300 ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root,
[email protected]f4e25f92013-07-13 20:54:53301 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27302
jaydasika9234e402016-03-21 20:44:22303 TreeSynchronizer::PushLayerProperties(layer_tree_root->layer_tree_host(),
304 host_->active_tree());
[email protected]5c4824e12013-01-12 16:34:53305
[email protected]b5651c22013-03-14 15:06:33306 // Check that the property values we set on the Layer tree are reflected in
307 // the LayerImpl tree.
308 gfx::PointF root_layer_impl_position = layer_impl_tree_root->position();
309 EXPECT_EQ(root_position.x(), root_layer_impl_position.x());
310 EXPECT_EQ(root_position.y(), root_layer_impl_position.y());
[email protected]c0dd24c2012-08-30 23:25:27311
[email protected]b5651c22013-03-14 15:06:33312 EXPECT_EQ(first_child_opacity,
313 layer_impl_tree_root->children()[0]->opacity());
[email protected]c0dd24c2012-08-30 23:25:27314
bokancccfde72014-10-08 15:15:22315 gfx::Size second_layer_impl_child_bounds =
[email protected]b5651c22013-03-14 15:06:33316 layer_impl_tree_root->children()[1]->bounds();
317 EXPECT_EQ(second_child_bounds.width(),
318 second_layer_impl_child_bounds.width());
319 EXPECT_EQ(second_child_bounds.height(),
320 second_layer_impl_child_bounds.height());
[email protected]c0dd24c2012-08-30 23:25:27321}
322
[email protected]b5651c22013-03-14 15:06:33323TEST_F(TreeSynchronizerTest, ReuseLayerImplsAfterStructuralChange) {
324 std::vector<int> layer_impl_destruction_list;
[email protected]c0dd24c2012-08-30 23:25:27325
[email protected]b5651c22013-03-14 15:06:33326 // Set up a tree with this sort of structure:
327 // root --- A --- B ---+--- C
328 // |
329 // +--- D
330 scoped_refptr<Layer> layer_tree_root =
loyso0940d412016-03-14 01:30:31331 MockLayer::Create(&layer_impl_destruction_list);
332 layer_tree_root->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_a = layer_tree_root->children()[0];
loyso0940d412016-03-14 01:30:31335 layer_a->AddChild(MockLayer::Create(&layer_impl_destruction_list));
[email protected]c0dd24c2012-08-30 23:25:27336
vollick83fbfc82016-03-22 18:33:27337 scoped_refptr<Layer> layer_b = layer_a->children()[0];
loyso0940d412016-03-14 01:30:31338 layer_b->AddChild(MockLayer::Create(&layer_impl_destruction_list));
[email protected]c0dd24c2012-08-30 23:25:27339
vollick83fbfc82016-03-22 18:33:27340 scoped_refptr<Layer> layer_c = layer_b->children()[0];
loyso0940d412016-03-14 01:30:31341 layer_b->AddChild(MockLayer::Create(&layer_impl_destruction_list));
vollick83fbfc82016-03-22 18:33:27342 scoped_refptr<Layer> layer_d = layer_b->children()[1];
[email protected]c0dd24c2012-08-30 23:25:27343
[email protected]f4e25f92013-07-13 20:54:53344 host_->SetRootLayer(layer_tree_root);
345
vollick83fbfc82016-03-22 18:33:27346 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
347 host_->active_tree());
348 LayerImpl* layer_impl_tree_root = host_->active_tree()->root_layer();
349 ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root,
[email protected]f4e25f92013-07-13 20:54:53350 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27351
[email protected]b5651c22013-03-14 15:06:33352 // We have to push properties to pick up the destruction list pointer.
jaydasika9234e402016-03-21 20:44:22353 TreeSynchronizer::PushLayerProperties(layer_tree_root->layer_tree_host(),
354 host_->active_tree());
[email protected]5c4824e12013-01-12 16:34:53355
[email protected]b5651c22013-03-14 15:06:33356 // Now restructure the tree to look like this:
357 // root --- D ---+--- A
358 // |
359 // +--- C --- B
360 layer_tree_root->RemoveAllChildren();
361 layer_d->RemoveAllChildren();
362 layer_tree_root->AddChild(layer_d);
363 layer_a->RemoveAllChildren();
364 layer_d->AddChild(layer_a);
365 layer_c->RemoveAllChildren();
366 layer_d->AddChild(layer_c);
367 layer_b->RemoveAllChildren();
368 layer_c->AddChild(layer_b);
[email protected]c0dd24c2012-08-30 23:25:27369
[email protected]b5651c22013-03-14 15:06:33370 // After another synchronize our trees should match and we should not have
371 // destroyed any LayerImpls
vollick83fbfc82016-03-22 18:33:27372 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
373 host_->active_tree());
374 layer_impl_tree_root = host_->active_tree()->root_layer();
375 ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root,
[email protected]f4e25f92013-07-13 20:54:53376 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27377
[email protected]b5651c22013-03-14 15:06:33378 EXPECT_EQ(0u, layer_impl_destruction_list.size());
vollick83fbfc82016-03-22 18:33:27379
380 host_->active_tree()->ClearLayers();
[email protected]c0dd24c2012-08-30 23:25:27381}
382
[email protected]b5651c22013-03-14 15:06:33383// Constructs a very simple tree, synchronizes it, then synchronizes to a
384// totally new tree. All layers from the old tree should be deleted.
385TEST_F(TreeSynchronizerTest, SyncSimpleTreeThenDestroy) {
386 std::vector<int> layer_impl_destruction_list;
[email protected]c0dd24c2012-08-30 23:25:27387
[email protected]b5651c22013-03-14 15:06:33388 scoped_refptr<Layer> old_layer_tree_root =
loyso0940d412016-03-14 01:30:31389 MockLayer::Create(&layer_impl_destruction_list);
[email protected]b5651c22013-03-14 15:06:33390 old_layer_tree_root->AddChild(
loyso0940d412016-03-14 01:30:31391 MockLayer::Create(&layer_impl_destruction_list));
[email protected]b5651c22013-03-14 15:06:33392 old_layer_tree_root->AddChild(
loyso0940d412016-03-14 01:30:31393 MockLayer::Create(&layer_impl_destruction_list));
[email protected]c0dd24c2012-08-30 23:25:27394
[email protected]f4e25f92013-07-13 20:54:53395 host_->SetRootLayer(old_layer_tree_root);
396
[email protected]b5651c22013-03-14 15:06:33397 int old_tree_root_layer_id = old_layer_tree_root->id();
398 int old_tree_first_child_layer_id = old_layer_tree_root->children()[0]->id();
399 int old_tree_second_child_layer_id = old_layer_tree_root->children()[1]->id();
[email protected]c0dd24c2012-08-30 23:25:27400
vollick83fbfc82016-03-22 18:33:27401 TreeSynchronizer::SynchronizeTrees(old_layer_tree_root.get(),
402 host_->active_tree());
403 LayerImpl* layer_impl_tree_root = host_->active_tree()->root_layer();
404 ExpectTreesAreIdentical(old_layer_tree_root.get(), layer_impl_tree_root,
[email protected]f4e25f92013-07-13 20:54:53405 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27406
[email protected]b5651c22013-03-14 15:06:33407 // We have to push properties to pick up the destruction list pointer.
jaydasika9234e402016-03-21 20:44:22408 TreeSynchronizer::PushLayerProperties(old_layer_tree_root->layer_tree_host(),
409 host_->active_tree());
[email protected]5c4824e12013-01-12 16:34:53410
[email protected]b5651c22013-03-14 15:06:33411 // Remove all children on the Layer side.
412 old_layer_tree_root->RemoveAllChildren();
[email protected]c0dd24c2012-08-30 23:25:27413
[email protected]b5651c22013-03-14 15:06:33414 // Synchronize again. After the sync all LayerImpls from the old tree should
415 // be deleted.
loyso0940d412016-03-14 01:30:31416 scoped_refptr<Layer> new_layer_tree_root = Layer::Create();
[email protected]f4e25f92013-07-13 20:54:53417 host_->SetRootLayer(new_layer_tree_root);
vollick83fbfc82016-03-22 18:33:27418
419 TreeSynchronizer::SynchronizeTrees(new_layer_tree_root.get(),
420 host_->active_tree());
421 layer_impl_tree_root = host_->active_tree()->root_layer();
422 ExpectTreesAreIdentical(new_layer_tree_root.get(), layer_impl_tree_root,
[email protected]f4e25f92013-07-13 20:54:53423 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27424
[email protected]b5651c22013-03-14 15:06:33425 ASSERT_EQ(3u, layer_impl_destruction_list.size());
[email protected]2cdbdba2012-10-28 13:15:05426
[email protected]b5651c22013-03-14 15:06:33427 EXPECT_TRUE(std::find(layer_impl_destruction_list.begin(),
428 layer_impl_destruction_list.end(),
429 old_tree_root_layer_id) !=
430 layer_impl_destruction_list.end());
431 EXPECT_TRUE(std::find(layer_impl_destruction_list.begin(),
432 layer_impl_destruction_list.end(),
433 old_tree_first_child_layer_id) !=
434 layer_impl_destruction_list.end());
435 EXPECT_TRUE(std::find(layer_impl_destruction_list.begin(),
436 layer_impl_destruction_list.end(),
437 old_tree_second_child_layer_id) !=
438 layer_impl_destruction_list.end());
[email protected]c0dd24c2012-08-30 23:25:27439}
440
441// Constructs+syncs a tree with mask, replica, and replica mask layers.
[email protected]b5651c22013-03-14 15:06:33442TEST_F(TreeSynchronizerTest, SyncMaskReplicaAndReplicaMaskLayers) {
loyso0940d412016-03-14 01:30:31443 scoped_refptr<Layer> layer_tree_root = Layer::Create();
444 layer_tree_root->AddChild(Layer::Create());
445 layer_tree_root->AddChild(Layer::Create());
446 layer_tree_root->AddChild(Layer::Create());
[email protected]c0dd24c2012-08-30 23:25:27447
[email protected]b5651c22013-03-14 15:06:33448 // First child gets a mask layer.
loyso0940d412016-03-14 01:30:31449 scoped_refptr<Layer> mask_layer = Layer::Create();
[email protected]b5651c22013-03-14 15:06:33450 layer_tree_root->children()[0]->SetMaskLayer(mask_layer.get());
[email protected]c0dd24c2012-08-30 23:25:27451
[email protected]b5651c22013-03-14 15:06:33452 // Second child gets a replica layer.
loyso0940d412016-03-14 01:30:31453 scoped_refptr<Layer> replica_layer = Layer::Create();
[email protected]b5651c22013-03-14 15:06:33454 layer_tree_root->children()[1]->SetReplicaLayer(replica_layer.get());
[email protected]c0dd24c2012-08-30 23:25:27455
[email protected]b5651c22013-03-14 15:06:33456 // Third child gets a replica layer with a mask layer.
loyso0940d412016-03-14 01:30:31457 scoped_refptr<Layer> replica_layer_with_mask = Layer::Create();
458 scoped_refptr<Layer> replica_mask_layer = Layer::Create();
[email protected]b5651c22013-03-14 15:06:33459 replica_layer_with_mask->SetMaskLayer(replica_mask_layer.get());
vollick83fbfc82016-03-22 18:33:27460 layer_tree_root->children()[2]->SetReplicaLayer(
461 replica_layer_with_mask.get());
[email protected]c0dd24c2012-08-30 23:25:27462
[email protected]f4e25f92013-07-13 20:54:53463 host_->SetRootLayer(layer_tree_root);
464
vollick83fbfc82016-03-22 18:33:27465 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
466 host_->active_tree());
467 LayerImpl* layer_impl_tree_root = host_->active_tree()->root_layer();
468 ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root,
[email protected]f4e25f92013-07-13 20:54:53469 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27470
[email protected]b5651c22013-03-14 15:06:33471 // Remove the mask layer.
472 layer_tree_root->children()[0]->SetMaskLayer(NULL);
vollick83fbfc82016-03-22 18:33:27473 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
474 host_->active_tree());
475 layer_impl_tree_root = host_->active_tree()->root_layer();
476 ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root,
[email protected]f4e25f92013-07-13 20:54:53477 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27478
[email protected]b5651c22013-03-14 15:06:33479 // Remove the replica layer.
480 layer_tree_root->children()[1]->SetReplicaLayer(NULL);
vollick83fbfc82016-03-22 18:33:27481 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
482 host_->active_tree());
483 layer_impl_tree_root = host_->active_tree()->root_layer();
484 ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root,
[email protected]f4e25f92013-07-13 20:54:53485 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27486
[email protected]b5651c22013-03-14 15:06:33487 // Remove the replica mask.
488 replica_layer_with_mask->SetMaskLayer(NULL);
vollick83fbfc82016-03-22 18:33:27489 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
490 host_->active_tree());
491 layer_impl_tree_root = host_->active_tree()->root_layer();
492 ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root,
[email protected]f4e25f92013-07-13 20:54:53493 host_->active_tree());
vollick83fbfc82016-03-22 18:33:27494
495 host_->active_tree()->ClearLayers();
[email protected]c0dd24c2012-08-30 23:25:27496}
497
sunxd54e08e9d2016-02-22 23:01:28498TEST_F(TreeSynchronizerTest, SynchronizeCurrentlyScrollingNode) {
499 LayerTreeSettings settings;
500 FakeLayerTreeHostImplClient client;
501 FakeImplTaskRunnerProvider task_runner_provider;
502 FakeRenderingStatsInstrumentation stats_instrumentation;
503 TestSharedBitmapManager shared_bitmap_manager;
504 TestTaskGraphRunner task_graph_runner;
505 FakeLayerTreeHostImpl* host_impl = host_->host_impl();
506 host_impl->CreatePendingTree();
507
loyso0940d412016-03-14 01:30:31508 scoped_refptr<Layer> layer_tree_root = Layer::Create();
509 scoped_refptr<Layer> scroll_clip_layer = Layer::Create();
510 scoped_refptr<Layer> scroll_layer = Layer::Create();
511 scoped_refptr<Layer> transient_scroll_clip_layer = Layer::Create();
512 scoped_refptr<Layer> transient_scroll_layer = Layer::Create();
sunxd54e08e9d2016-02-22 23:01:28513
514 layer_tree_root->AddChild(transient_scroll_clip_layer);
515 transient_scroll_clip_layer->AddChild(transient_scroll_layer);
516 transient_scroll_layer->AddChild(scroll_clip_layer);
517 scroll_clip_layer->AddChild(scroll_layer);
518
519 transient_scroll_layer->SetScrollClipLayerId(
520 transient_scroll_clip_layer->id());
521 scroll_layer->SetScrollClipLayerId(scroll_clip_layer->id());
522 host_->SetRootLayer(layer_tree_root);
523 host_->BuildPropertyTreesForTesting();
524 host_->CommitAndCreatePendingTree();
525 host_impl->ActivateSyncTree();
526
527 ExpectTreesAreIdentical(layer_tree_root.get(),
528 host_impl->active_tree()->root_layer(),
529 host_impl->active_tree());
530
531 host_impl->active_tree()->SetCurrentlyScrollingLayer(
vollickcb3f6b12016-03-01 23:44:10532 host_impl->active_tree()->LayerById(scroll_layer->id()));
sunxd54e08e9d2016-02-22 23:01:28533 transient_scroll_layer->SetScrollClipLayerId(Layer::INVALID_ID);
534 host_->BuildPropertyTreesForTesting();
535
536 host_impl->CreatePendingTree();
537 host_->CommitAndCreatePendingTree();
538 host_impl->ActivateSyncTree();
539
540 EXPECT_EQ(scroll_layer->id(),
541 host_impl->active_tree()->CurrentlyScrollingLayer()->id());
542}
543
sunxdc36713a2016-03-03 22:31:10544TEST_F(TreeSynchronizerTest, SynchronizeScrollTreeScrollOffsetMap) {
545 host_->InitializeSingleThreaded(&client_, base::ThreadTaskRunnerHandle::Get(),
546 nullptr);
547 LayerTreeSettings settings;
548 FakeLayerTreeHostImplClient client;
549 FakeImplTaskRunnerProvider task_runner_provider;
550 FakeRenderingStatsInstrumentation stats_instrumentation;
551 TestSharedBitmapManager shared_bitmap_manager;
552 TestTaskGraphRunner task_graph_runner;
553 FakeLayerTreeHostImpl* host_impl = host_->host_impl();
554 host_impl->CreatePendingTree();
555
loyso0940d412016-03-14 01:30:31556 scoped_refptr<Layer> layer_tree_root = Layer::Create();
557 scoped_refptr<Layer> scroll_clip_layer = Layer::Create();
558 scoped_refptr<Layer> scroll_layer = Layer::Create();
559 scoped_refptr<Layer> transient_scroll_clip_layer = Layer::Create();
560 scoped_refptr<Layer> transient_scroll_layer = Layer::Create();
sunxdc36713a2016-03-03 22:31:10561
562 layer_tree_root->AddChild(transient_scroll_clip_layer);
563 transient_scroll_clip_layer->AddChild(transient_scroll_layer);
564 transient_scroll_layer->AddChild(scroll_clip_layer);
565 scroll_clip_layer->AddChild(scroll_layer);
566
567 transient_scroll_layer->SetScrollClipLayerId(
568 transient_scroll_clip_layer->id());
569 scroll_layer->SetScrollClipLayerId(scroll_clip_layer->id());
570 transient_scroll_layer->SetScrollOffset(gfx::ScrollOffset(1, 2));
571 scroll_layer->SetScrollOffset(gfx::ScrollOffset(10, 20));
572
573 host_->SetRootLayer(layer_tree_root);
574 host_->BuildPropertyTreesForTesting();
575 host_->CommitAndCreatePendingTree();
576 host_impl->ActivateSyncTree();
577
578 ExpectTreesAreIdentical(layer_tree_root.get(),
579 host_impl->active_tree()->root_layer(),
580 host_impl->active_tree());
581
582 // After the initial commit, scroll_offset_map in scroll_tree is expected to
583 // have one entry for scroll_layer and one entry for transient_scroll_layer,
584 // the pending base and active base must be the same at this stage.
585 ScrollTree::ScrollOffsetMap scroll_offset_map;
586 scroll_offset_map[scroll_layer->id()] = new SyncedScrollOffset;
587 scroll_offset_map[transient_scroll_layer->id()] = new SyncedScrollOffset;
588 scroll_offset_map[scroll_layer->id()]->PushFromMainThread(
589 scroll_layer->scroll_offset());
590 scroll_offset_map[scroll_layer->id()]->PushPendingToActive();
591 scroll_offset_map[transient_scroll_layer->id()]->PushFromMainThread(
592 transient_scroll_layer->scroll_offset());
593 scroll_offset_map[transient_scroll_layer->id()]->PushPendingToActive();
594 EXPECT_TRUE(
595 is_equal(scroll_offset_map, host_impl->active_tree()
596 ->property_trees()
597 ->scroll_tree.scroll_offset_map()));
598
599 // Set ScrollOffset active delta: gfx::ScrollOffset(10, 10)
600 LayerImpl* scroll_layer_impl =
601 host_impl->active_tree()->LayerById(scroll_layer->id());
602 ScrollTree& scroll_tree =
603 host_impl->active_tree()->property_trees()->scroll_tree;
sunxdc044b11a2016-03-16 16:23:20604 scroll_tree.SetScrollOffset(scroll_layer_impl->id(),
605 gfx::ScrollOffset(20, 30));
sunxdc36713a2016-03-03 22:31:10606
607 // Pull ScrollOffset delta for main thread, and change offset on main thread
danakj60bc3bc2016-04-09 00:24:48608 std::unique_ptr<ScrollAndScaleSet> scroll_info(new ScrollAndScaleSet());
sunxdc36713a2016-03-03 22:31:10609 scroll_tree.CollectScrollDeltas(scroll_info.get());
610 host_->proxy()->SetNeedsCommit();
611 host_->ApplyScrollAndScale(scroll_info.get());
612 EXPECT_EQ(gfx::ScrollOffset(20, 30), scroll_layer->scroll_offset());
613 scroll_layer->SetScrollOffset(gfx::ScrollOffset(100, 100));
614
615 // More update to ScrollOffset active delta: gfx::ScrollOffset(20, 20)
sunxdc044b11a2016-03-16 16:23:20616 scroll_tree.SetScrollOffset(scroll_layer_impl->id(),
617 gfx::ScrollOffset(40, 50));
sunxdc36713a2016-03-03 22:31:10618 host_impl->active_tree()->SetCurrentlyScrollingLayer(scroll_layer_impl);
619
620 // Make one layer unscrollable so that scroll tree topology changes
621 transient_scroll_layer->SetScrollClipLayerId(Layer::INVALID_ID);
622 host_->BuildPropertyTreesForTesting();
623
624 host_impl->CreatePendingTree();
625 host_->CommitAndCreatePendingTree();
626 host_impl->ActivateSyncTree();
627
628 EXPECT_EQ(scroll_layer->id(),
629 host_impl->active_tree()->CurrentlyScrollingLayer()->id());
630 scroll_offset_map.erase(transient_scroll_layer->id());
631 scroll_offset_map[scroll_layer->id()]->SetCurrent(gfx::ScrollOffset(20, 30));
632 scroll_offset_map[scroll_layer->id()]->PullDeltaForMainThread();
633 scroll_offset_map[scroll_layer->id()]->SetCurrent(gfx::ScrollOffset(40, 50));
634 scroll_offset_map[scroll_layer->id()]->PushFromMainThread(
635 gfx::ScrollOffset(100, 100));
636 scroll_offset_map[scroll_layer->id()]->PushPendingToActive();
637 EXPECT_TRUE(is_equal(scroll_offset_map, scroll_tree.scroll_offset_map()));
638}
639
[email protected]ba565742012-11-10 09:29:48640} // namespace
641} // namespace cc