blob: 69035a1ff0643b8bb54b4700de68879c4c1f0f3d [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
jaydasika4b0fd7512016-06-09 18:12:5381void ExpectTreesAreIdentical(Layer* root_layer,
82 LayerImpl* root_layer_impl,
[email protected]b5651c22013-03-14 15:06:3383 LayerTreeImpl* tree_impl) {
jaydasika4b0fd7512016-06-09 18:12:5384 auto layer_iter = root_layer->layer_tree_host()->begin();
85 auto layer_impl_iter = tree_impl->begin();
86 for (; layer_iter != root_layer->layer_tree_host()->end();
87 ++layer_iter, ++layer_impl_iter) {
88 Layer* layer = *layer_iter;
89 LayerImpl* layer_impl = *layer_impl_iter;
90 ASSERT_TRUE(layer);
91 ASSERT_TRUE(layer_impl);
[email protected]c0dd24c2012-08-30 23:25:2792
jaydasika4b0fd7512016-06-09 18:12:5393 EXPECT_EQ(layer->id(), layer_impl->id());
94 EXPECT_EQ(layer_impl->layer_tree_impl(), tree_impl);
[email protected]c0dd24c2012-08-30 23:25:2795
jaydasika4b0fd7512016-06-09 18:12:5396 EXPECT_EQ(layer->non_fast_scrollable_region(),
97 layer_impl->non_fast_scrollable_region());
[email protected]c0dd24c2012-08-30 23:25:2798
jaydasika4b0fd7512016-06-09 18:12:5399 ASSERT_EQ(!!layer->mask_layer(), !!layer_impl->mask_layer());
100 if (layer->mask_layer()) {
101 SCOPED_TRACE("mask_layer");
102 EXPECT_EQ(layer->mask_layer()->id(), layer_impl->mask_layer()->id());
103 }
[email protected]c0dd24c2012-08-30 23:25:27104
jaydasika4b0fd7512016-06-09 18:12:53105 ASSERT_EQ(!!layer->replica_layer(), !!layer_impl->replica_layer());
106 if (layer->replica_layer()) {
107 SCOPED_TRACE("replica_layer");
108 EXPECT_EQ(layer->replica_layer()->id(),
109 layer_impl->replica_layer()->id());
110 ASSERT_EQ(!!layer->replica_layer()->mask_layer(),
111 !!layer_impl->replica_layer()->mask_layer());
112 if (layer->replica_layer()->mask_layer()) {
113 SCOPED_TRACE("mask_layer");
114 EXPECT_EQ(layer->replica_layer()->mask_layer()->id(),
115 layer_impl->replica_layer()->mask_layer()->id());
116 }
117 }
[email protected]c0dd24c2012-08-30 23:25:27118
jaydasika4b0fd7512016-06-09 18:12:53119 const Layer* layer_scroll_parent = layer->scroll_parent();
[email protected]c0dd24c2012-08-30 23:25:27120
jaydasika4b0fd7512016-06-09 18:12:53121 if (layer_scroll_parent) {
122 ASSERT_TRUE(layer_scroll_parent->scroll_children()->find(layer) !=
123 layer_scroll_parent->scroll_children()->end());
124 }
[email protected]c0dd24c2012-08-30 23:25:27125
jaydasika4b0fd7512016-06-09 18:12:53126 const Layer* layer_clip_parent = layer->clip_parent();
[email protected]0e98cdd2013-08-23 00:44:30127
jaydasika4b0fd7512016-06-09 18:12:53128 if (layer_clip_parent) {
129 const std::set<Layer*>* clip_children =
130 layer_clip_parent->clip_children();
131 ASSERT_TRUE(clip_children->find(layer) != clip_children->end());
132 }
[email protected]b5651c22013-03-14 15:06:33133 }
[email protected]c0dd24c2012-08-30 23:25:27134}
135
[email protected]c2282382012-12-16 00:46:03136class TreeSynchronizerTest : public testing::Test {
[email protected]b5651c22013-03-14 15:06:33137 public:
enne2097cab2014-09-25 20:16:31138 TreeSynchronizerTest()
139 : client_(FakeLayerTreeHostClient::DIRECT_3D),
loyso0940d412016-03-14 01:30:31140 host_(FakeLayerTreeHost::Create(&client_, &task_graph_runner_)) {}
[email protected]c2282382012-12-16 00:46:03141
[email protected]b5651c22013-03-14 15:06:33142 protected:
enne2097cab2014-09-25 20:16:31143 FakeLayerTreeHostClient client_;
danakjcf610582015-06-16 22:48:56144 TestTaskGraphRunner task_graph_runner_;
danakj60bc3bc2016-04-09 00:24:48145 std::unique_ptr<FakeLayerTreeHost> host_;
sunxdc36713a2016-03-03 22:31:10146
147 bool is_equal(ScrollTree::ScrollOffsetMap map,
148 ScrollTree::ScrollOffsetMap other) {
149 if (map.size() != other.size())
150 return false;
151 for (auto& map_entry : map) {
152 if (other.find(map_entry.first) == other.end())
153 return false;
154 SyncedScrollOffset& from_map = *map_entry.second.get();
155 SyncedScrollOffset& from_other = *other[map_entry.first].get();
156 if (from_map.PendingBase() != from_other.PendingBase() ||
157 from_map.ActiveBase() != from_other.ActiveBase() ||
158 from_map.Delta() != from_other.Delta() ||
159 from_map.PendingDelta().get() != from_other.PendingDelta().get())
160 return false;
161 }
162 return true;
163 }
[email protected]c2282382012-12-16 00:46:03164};
165
[email protected]c0dd24c2012-08-30 23:25:27166// Attempts to synchronizes a null tree. This should not crash, and should
167// return a null tree.
[email protected]b5651c22013-03-14 15:06:33168TEST_F(TreeSynchronizerTest, SyncNullTree) {
vollick83fbfc82016-03-22 18:33:27169 TreeSynchronizer::SynchronizeTrees(static_cast<Layer*>(NULL),
170 host_->active_tree());
171 EXPECT_TRUE(!host_->active_tree()->root_layer());
[email protected]c0dd24c2012-08-30 23:25:27172}
173
[email protected]b5651c22013-03-14 15:06:33174// Constructs a very simple tree and synchronizes it without trying to reuse any
175// preexisting layers.
176TEST_F(TreeSynchronizerTest, SyncSimpleTreeFromEmpty) {
loyso0940d412016-03-14 01:30:31177 scoped_refptr<Layer> layer_tree_root = Layer::Create();
178 layer_tree_root->AddChild(Layer::Create());
179 layer_tree_root->AddChild(Layer::Create());
[email protected]c0dd24c2012-08-30 23:25:27180
[email protected]f4e25f92013-07-13 20:54:53181 host_->SetRootLayer(layer_tree_root);
182
vollick83fbfc82016-03-22 18:33:27183 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
184 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27185
[email protected]b5651c22013-03-14 15:06:33186 ExpectTreesAreIdentical(layer_tree_root.get(),
vollick83fbfc82016-03-22 18:33:27187 host_->active_tree()->root_layer(),
[email protected]f4e25f92013-07-13 20:54:53188 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27189}
190
[email protected]b5651c22013-03-14 15:06:33191// Constructs a very simple tree and synchronizes it attempting to reuse some
192// layers
193TEST_F(TreeSynchronizerTest, SyncSimpleTreeReusingLayers) {
194 std::vector<int> layer_impl_destruction_list;
[email protected]c0dd24c2012-08-30 23:25:27195
[email protected]b5651c22013-03-14 15:06:33196 scoped_refptr<Layer> layer_tree_root =
loyso0940d412016-03-14 01:30:31197 MockLayer::Create(&layer_impl_destruction_list);
198 layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list));
199 layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list));
jaydasika4b0fd7512016-06-09 18:12:53200 int second_layer_impl_id = layer_tree_root->children()[1]->id();
[email protected]c0dd24c2012-08-30 23:25:27201
[email protected]f4e25f92013-07-13 20:54:53202 host_->SetRootLayer(layer_tree_root);
203
vollick83fbfc82016-03-22 18:33:27204 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
205 host_->active_tree());
206 LayerImpl* layer_impl_tree_root = host_->active_tree()->root_layer();
207 ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root,
[email protected]f4e25f92013-07-13 20:54:53208 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27209
[email protected]b5651c22013-03-14 15:06:33210 // We have to push properties to pick up the destruction list pointer.
jaydasika9234e402016-03-21 20:44:22211 TreeSynchronizer::PushLayerProperties(layer_tree_root->layer_tree_host(),
212 host_->active_tree());
[email protected]5c4824e12013-01-12 16:34:53213
[email protected]b5651c22013-03-14 15:06:33214 // Add a new layer to the Layer side
loysoa6edaaff2015-05-25 03:26:44215 layer_tree_root->children()[0]->AddChild(
loyso0940d412016-03-14 01:30:31216 MockLayer::Create(&layer_impl_destruction_list));
[email protected]b5651c22013-03-14 15:06:33217 // Remove one.
218 layer_tree_root->children()[1]->RemoveFromParent();
[email protected]c0dd24c2012-08-30 23:25:27219
[email protected]b5651c22013-03-14 15:06:33220 // Synchronize again. After the sync the trees should be equivalent and we
221 // should have created and destroyed one LayerImpl.
vollick83fbfc82016-03-22 18:33:27222 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
223 host_->active_tree());
224 layer_impl_tree_root = host_->active_tree()->root_layer();
225
226 ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root,
[email protected]f4e25f92013-07-13 20:54:53227 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27228
[email protected]b5651c22013-03-14 15:06:33229 ASSERT_EQ(1u, layer_impl_destruction_list.size());
230 EXPECT_EQ(second_layer_impl_id, layer_impl_destruction_list[0]);
vollick83fbfc82016-03-22 18:33:27231
rockot2176f922016-06-08 19:18:32232 host_->active_tree()->DetachLayers();
[email protected]c0dd24c2012-08-30 23:25:27233}
234
[email protected]b5651c22013-03-14 15:06:33235// Constructs a very simple tree and checks that a stacking-order change is
236// tracked properly.
237TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndTrackStackingOrderChange) {
238 std::vector<int> layer_impl_destruction_list;
[email protected]c0dd24c2012-08-30 23:25:27239
[email protected]b5651c22013-03-14 15:06:33240 // Set up the tree and sync once. child2 needs to be synced here, too, even
241 // though we remove it to set up the intended scenario.
242 scoped_refptr<Layer> layer_tree_root =
loyso0940d412016-03-14 01:30:31243 MockLayer::Create(&layer_impl_destruction_list);
244 scoped_refptr<Layer> child2 = MockLayer::Create(&layer_impl_destruction_list);
245 layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list));
[email protected]b5651c22013-03-14 15:06:33246 layer_tree_root->AddChild(child2);
jaydasika4b0fd7512016-06-09 18:12:53247 int child1_id = layer_tree_root->children()[0]->id();
248 int child2_id = layer_tree_root->children()[1]->id();
[email protected]f4e25f92013-07-13 20:54:53249
250 host_->SetRootLayer(layer_tree_root);
251
vollick83fbfc82016-03-22 18:33:27252 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
253 host_->active_tree());
jaydasikaef64f9e42016-03-12 01:08:18254 LayerImpl* layer_impl_tree_root = host_->active_tree()->root_layer();
255 ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root,
[email protected]f4e25f92013-07-13 20:54:53256 host_->active_tree());
[email protected]5c4824e12013-01-12 16:34:53257
[email protected]b5651c22013-03-14 15:06:33258 // We have to push properties to pick up the destruction list pointer.
jaydasika9234e402016-03-21 20:44:22259 TreeSynchronizer::PushLayerProperties(layer_tree_root->layer_tree_host(),
260 host_->active_tree());
[email protected]5c4824e12013-01-12 16:34:53261
jaydasikad6f778b2016-05-19 22:51:26262 host_->active_tree()->ResetAllChangeTracking();
[email protected]c0dd24c2012-08-30 23:25:27263
[email protected]b5651c22013-03-14 15:06:33264 // re-insert the layer and sync again.
265 child2->RemoveFromParent();
266 layer_tree_root->AddChild(child2);
vollick83fbfc82016-03-22 18:33:27267 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
268 host_->active_tree());
jaydasikaef64f9e42016-03-12 01:08:18269 layer_impl_tree_root = host_->active_tree()->root_layer();
270 ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root,
[email protected]f4e25f92013-07-13 20:54:53271 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27272
jaydasika9234e402016-03-21 20:44:22273 TreeSynchronizer::PushLayerProperties(layer_tree_root->layer_tree_host(),
274 host_->active_tree());
[email protected]5c4824e12013-01-12 16:34:53275
[email protected]b5651c22013-03-14 15:06:33276 // Check that the impl thread properly tracked the change.
277 EXPECT_FALSE(layer_impl_tree_root->LayerPropertyChanged());
jaydasika4b0fd7512016-06-09 18:12:53278 EXPECT_FALSE(
279 host_->active_tree()->LayerById(child1_id)->LayerPropertyChanged());
280 EXPECT_TRUE(
281 host_->active_tree()->LayerById(child2_id)->LayerPropertyChanged());
rockot2176f922016-06-08 19:18:32282 host_->active_tree()->DetachLayers();
[email protected]c0dd24c2012-08-30 23:25:27283}
284
[email protected]b5651c22013-03-14 15:06:33285TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndProperties) {
loyso0940d412016-03-14 01:30:31286 scoped_refptr<Layer> layer_tree_root = Layer::Create();
287 layer_tree_root->AddChild(Layer::Create());
288 layer_tree_root->AddChild(Layer::Create());
[email protected]c0dd24c2012-08-30 23:25:27289
[email protected]f4e25f92013-07-13 20:54:53290 host_->SetRootLayer(layer_tree_root);
291
[email protected]b5651c22013-03-14 15:06:33292 // Pick some random properties to set. The values are not important, we're
293 // just testing that at least some properties are making it through.
294 gfx::PointF root_position = gfx::PointF(2.3f, 7.4f);
295 layer_tree_root->SetPosition(root_position);
[email protected]c0dd24c2012-08-30 23:25:27296
[email protected]b5651c22013-03-14 15:06:33297 gfx::Size second_child_bounds = gfx::Size(25, 53);
298 layer_tree_root->children()[1]->SetBounds(second_child_bounds);
[email protected]445881f2013-04-16 01:11:59299 layer_tree_root->children()[1]->SavePaintProperties();
jaydasika4b0fd7512016-06-09 18:12:53300 int second_child_id = layer_tree_root->children()[1]->id();
[email protected]c0dd24c2012-08-30 23:25:27301
vollick83fbfc82016-03-22 18:33:27302 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
303 host_->active_tree());
304 LayerImpl* layer_impl_tree_root = host_->active_tree()->root_layer();
305 ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root,
[email protected]f4e25f92013-07-13 20:54:53306 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27307
jaydasika9234e402016-03-21 20:44:22308 TreeSynchronizer::PushLayerProperties(layer_tree_root->layer_tree_host(),
309 host_->active_tree());
[email protected]5c4824e12013-01-12 16:34:53310
[email protected]b5651c22013-03-14 15:06:33311 // Check that the property values we set on the Layer tree are reflected in
312 // the LayerImpl tree.
313 gfx::PointF root_layer_impl_position = layer_impl_tree_root->position();
314 EXPECT_EQ(root_position.x(), root_layer_impl_position.x());
315 EXPECT_EQ(root_position.y(), root_layer_impl_position.y());
[email protected]c0dd24c2012-08-30 23:25:27316
bokancccfde72014-10-08 15:15:22317 gfx::Size second_layer_impl_child_bounds =
jaydasika4b0fd7512016-06-09 18:12:53318 layer_impl_tree_root->layer_tree_impl()
319 ->LayerById(second_child_id)
320 ->bounds();
[email protected]b5651c22013-03-14 15:06:33321 EXPECT_EQ(second_child_bounds.width(),
322 second_layer_impl_child_bounds.width());
323 EXPECT_EQ(second_child_bounds.height(),
324 second_layer_impl_child_bounds.height());
[email protected]c0dd24c2012-08-30 23:25:27325}
326
[email protected]b5651c22013-03-14 15:06:33327TEST_F(TreeSynchronizerTest, ReuseLayerImplsAfterStructuralChange) {
328 std::vector<int> layer_impl_destruction_list;
[email protected]c0dd24c2012-08-30 23:25:27329
[email protected]b5651c22013-03-14 15:06:33330 // Set up a tree with this sort of structure:
331 // root --- A --- B ---+--- C
332 // |
333 // +--- D
334 scoped_refptr<Layer> layer_tree_root =
loyso0940d412016-03-14 01:30:31335 MockLayer::Create(&layer_impl_destruction_list);
336 layer_tree_root->AddChild(MockLayer::Create(&layer_impl_destruction_list));
[email protected]c0dd24c2012-08-30 23:25:27337
vollick83fbfc82016-03-22 18:33:27338 scoped_refptr<Layer> layer_a = layer_tree_root->children()[0];
loyso0940d412016-03-14 01:30:31339 layer_a->AddChild(MockLayer::Create(&layer_impl_destruction_list));
[email protected]c0dd24c2012-08-30 23:25:27340
vollick83fbfc82016-03-22 18:33:27341 scoped_refptr<Layer> layer_b = layer_a->children()[0];
loyso0940d412016-03-14 01:30:31342 layer_b->AddChild(MockLayer::Create(&layer_impl_destruction_list));
[email protected]c0dd24c2012-08-30 23:25:27343
vollick83fbfc82016-03-22 18:33:27344 scoped_refptr<Layer> layer_c = layer_b->children()[0];
loyso0940d412016-03-14 01:30:31345 layer_b->AddChild(MockLayer::Create(&layer_impl_destruction_list));
vollick83fbfc82016-03-22 18:33:27346 scoped_refptr<Layer> layer_d = layer_b->children()[1];
[email protected]c0dd24c2012-08-30 23:25:27347
[email protected]f4e25f92013-07-13 20:54:53348 host_->SetRootLayer(layer_tree_root);
349
vollick83fbfc82016-03-22 18:33:27350 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
351 host_->active_tree());
352 LayerImpl* layer_impl_tree_root = host_->active_tree()->root_layer();
353 ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root,
[email protected]f4e25f92013-07-13 20:54:53354 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27355
[email protected]b5651c22013-03-14 15:06:33356 // We have to push properties to pick up the destruction list pointer.
jaydasika9234e402016-03-21 20:44:22357 TreeSynchronizer::PushLayerProperties(layer_tree_root->layer_tree_host(),
358 host_->active_tree());
[email protected]5c4824e12013-01-12 16:34:53359
[email protected]b5651c22013-03-14 15:06:33360 // Now restructure the tree to look like this:
361 // root --- D ---+--- A
362 // |
363 // +--- C --- B
364 layer_tree_root->RemoveAllChildren();
365 layer_d->RemoveAllChildren();
366 layer_tree_root->AddChild(layer_d);
367 layer_a->RemoveAllChildren();
368 layer_d->AddChild(layer_a);
369 layer_c->RemoveAllChildren();
370 layer_d->AddChild(layer_c);
371 layer_b->RemoveAllChildren();
372 layer_c->AddChild(layer_b);
[email protected]c0dd24c2012-08-30 23:25:27373
[email protected]b5651c22013-03-14 15:06:33374 // After another synchronize our trees should match and we should not have
375 // destroyed any LayerImpls
vollick83fbfc82016-03-22 18:33:27376 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
377 host_->active_tree());
378 layer_impl_tree_root = host_->active_tree()->root_layer();
379 ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root,
[email protected]f4e25f92013-07-13 20:54:53380 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27381
[email protected]b5651c22013-03-14 15:06:33382 EXPECT_EQ(0u, layer_impl_destruction_list.size());
vollick83fbfc82016-03-22 18:33:27383
rockot2176f922016-06-08 19:18:32384 host_->active_tree()->DetachLayers();
[email protected]c0dd24c2012-08-30 23:25:27385}
386
[email protected]b5651c22013-03-14 15:06:33387// Constructs a very simple tree, synchronizes it, then synchronizes to a
388// totally new tree. All layers from the old tree should be deleted.
389TEST_F(TreeSynchronizerTest, SyncSimpleTreeThenDestroy) {
390 std::vector<int> layer_impl_destruction_list;
[email protected]c0dd24c2012-08-30 23:25:27391
[email protected]b5651c22013-03-14 15:06:33392 scoped_refptr<Layer> old_layer_tree_root =
loyso0940d412016-03-14 01:30:31393 MockLayer::Create(&layer_impl_destruction_list);
[email protected]b5651c22013-03-14 15:06:33394 old_layer_tree_root->AddChild(
loyso0940d412016-03-14 01:30:31395 MockLayer::Create(&layer_impl_destruction_list));
[email protected]b5651c22013-03-14 15:06:33396 old_layer_tree_root->AddChild(
loyso0940d412016-03-14 01:30:31397 MockLayer::Create(&layer_impl_destruction_list));
[email protected]c0dd24c2012-08-30 23:25:27398
[email protected]f4e25f92013-07-13 20:54:53399 host_->SetRootLayer(old_layer_tree_root);
400
[email protected]b5651c22013-03-14 15:06:33401 int old_tree_root_layer_id = old_layer_tree_root->id();
402 int old_tree_first_child_layer_id = old_layer_tree_root->children()[0]->id();
403 int old_tree_second_child_layer_id = old_layer_tree_root->children()[1]->id();
[email protected]c0dd24c2012-08-30 23:25:27404
vollick83fbfc82016-03-22 18:33:27405 TreeSynchronizer::SynchronizeTrees(old_layer_tree_root.get(),
406 host_->active_tree());
407 LayerImpl* layer_impl_tree_root = host_->active_tree()->root_layer();
408 ExpectTreesAreIdentical(old_layer_tree_root.get(), layer_impl_tree_root,
[email protected]f4e25f92013-07-13 20:54:53409 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27410
[email protected]b5651c22013-03-14 15:06:33411 // We have to push properties to pick up the destruction list pointer.
jaydasika9234e402016-03-21 20:44:22412 TreeSynchronizer::PushLayerProperties(old_layer_tree_root->layer_tree_host(),
413 host_->active_tree());
[email protected]5c4824e12013-01-12 16:34:53414
[email protected]b5651c22013-03-14 15:06:33415 // Remove all children on the Layer side.
416 old_layer_tree_root->RemoveAllChildren();
[email protected]c0dd24c2012-08-30 23:25:27417
[email protected]b5651c22013-03-14 15:06:33418 // Synchronize again. After the sync all LayerImpls from the old tree should
419 // be deleted.
loyso0940d412016-03-14 01:30:31420 scoped_refptr<Layer> new_layer_tree_root = Layer::Create();
[email protected]f4e25f92013-07-13 20:54:53421 host_->SetRootLayer(new_layer_tree_root);
vollick83fbfc82016-03-22 18:33:27422
423 TreeSynchronizer::SynchronizeTrees(new_layer_tree_root.get(),
424 host_->active_tree());
425 layer_impl_tree_root = host_->active_tree()->root_layer();
426 ExpectTreesAreIdentical(new_layer_tree_root.get(), layer_impl_tree_root,
[email protected]f4e25f92013-07-13 20:54:53427 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27428
[email protected]b5651c22013-03-14 15:06:33429 ASSERT_EQ(3u, layer_impl_destruction_list.size());
[email protected]2cdbdba2012-10-28 13:15:05430
[email protected]b5651c22013-03-14 15:06:33431 EXPECT_TRUE(std::find(layer_impl_destruction_list.begin(),
432 layer_impl_destruction_list.end(),
433 old_tree_root_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_first_child_layer_id) !=
438 layer_impl_destruction_list.end());
439 EXPECT_TRUE(std::find(layer_impl_destruction_list.begin(),
440 layer_impl_destruction_list.end(),
441 old_tree_second_child_layer_id) !=
442 layer_impl_destruction_list.end());
[email protected]c0dd24c2012-08-30 23:25:27443}
444
445// Constructs+syncs a tree with mask, replica, and replica mask layers.
[email protected]b5651c22013-03-14 15:06:33446TEST_F(TreeSynchronizerTest, SyncMaskReplicaAndReplicaMaskLayers) {
loyso0940d412016-03-14 01:30:31447 scoped_refptr<Layer> layer_tree_root = Layer::Create();
448 layer_tree_root->AddChild(Layer::Create());
449 layer_tree_root->AddChild(Layer::Create());
450 layer_tree_root->AddChild(Layer::Create());
[email protected]c0dd24c2012-08-30 23:25:27451
[email protected]b5651c22013-03-14 15:06:33452 // First child gets a mask layer.
loyso0940d412016-03-14 01:30:31453 scoped_refptr<Layer> mask_layer = Layer::Create();
[email protected]b5651c22013-03-14 15:06:33454 layer_tree_root->children()[0]->SetMaskLayer(mask_layer.get());
[email protected]c0dd24c2012-08-30 23:25:27455
[email protected]b5651c22013-03-14 15:06:33456 // Second child gets a replica layer.
loyso0940d412016-03-14 01:30:31457 scoped_refptr<Layer> replica_layer = Layer::Create();
[email protected]b5651c22013-03-14 15:06:33458 layer_tree_root->children()[1]->SetReplicaLayer(replica_layer.get());
[email protected]c0dd24c2012-08-30 23:25:27459
[email protected]b5651c22013-03-14 15:06:33460 // Third child gets a replica layer with a mask layer.
loyso0940d412016-03-14 01:30:31461 scoped_refptr<Layer> replica_layer_with_mask = Layer::Create();
462 scoped_refptr<Layer> replica_mask_layer = Layer::Create();
[email protected]b5651c22013-03-14 15:06:33463 replica_layer_with_mask->SetMaskLayer(replica_mask_layer.get());
vollick83fbfc82016-03-22 18:33:27464 layer_tree_root->children()[2]->SetReplicaLayer(
465 replica_layer_with_mask.get());
[email protected]c0dd24c2012-08-30 23:25:27466
[email protected]f4e25f92013-07-13 20:54:53467 host_->SetRootLayer(layer_tree_root);
468
vollick83fbfc82016-03-22 18:33:27469 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
470 host_->active_tree());
471 LayerImpl* layer_impl_tree_root = host_->active_tree()->root_layer();
472 ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root,
[email protected]f4e25f92013-07-13 20:54:53473 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27474
[email protected]b5651c22013-03-14 15:06:33475 // Remove the mask layer.
476 layer_tree_root->children()[0]->SetMaskLayer(NULL);
vollick83fbfc82016-03-22 18:33:27477 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
478 host_->active_tree());
479 layer_impl_tree_root = host_->active_tree()->root_layer();
480 ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root,
[email protected]f4e25f92013-07-13 20:54:53481 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27482
[email protected]b5651c22013-03-14 15:06:33483 // Remove the replica layer.
484 layer_tree_root->children()[1]->SetReplicaLayer(NULL);
vollick83fbfc82016-03-22 18:33:27485 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
486 host_->active_tree());
487 layer_impl_tree_root = host_->active_tree()->root_layer();
488 ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root,
[email protected]f4e25f92013-07-13 20:54:53489 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27490
[email protected]b5651c22013-03-14 15:06:33491 // Remove the replica mask.
492 replica_layer_with_mask->SetMaskLayer(NULL);
vollick83fbfc82016-03-22 18:33:27493 TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(),
494 host_->active_tree());
495 layer_impl_tree_root = host_->active_tree()->root_layer();
496 ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root,
[email protected]f4e25f92013-07-13 20:54:53497 host_->active_tree());
vollick83fbfc82016-03-22 18:33:27498
rockot2176f922016-06-08 19:18:32499 host_->active_tree()->DetachLayers();
[email protected]c0dd24c2012-08-30 23:25:27500}
501
sunxd54e08e9d2016-02-22 23:01:28502TEST_F(TreeSynchronizerTest, SynchronizeCurrentlyScrollingNode) {
503 LayerTreeSettings settings;
504 FakeLayerTreeHostImplClient client;
505 FakeImplTaskRunnerProvider task_runner_provider;
506 FakeRenderingStatsInstrumentation stats_instrumentation;
507 TestSharedBitmapManager shared_bitmap_manager;
508 TestTaskGraphRunner task_graph_runner;
509 FakeLayerTreeHostImpl* host_impl = host_->host_impl();
510 host_impl->CreatePendingTree();
511
loyso0940d412016-03-14 01:30:31512 scoped_refptr<Layer> layer_tree_root = Layer::Create();
513 scoped_refptr<Layer> scroll_clip_layer = Layer::Create();
514 scoped_refptr<Layer> scroll_layer = Layer::Create();
515 scoped_refptr<Layer> transient_scroll_clip_layer = Layer::Create();
516 scoped_refptr<Layer> transient_scroll_layer = Layer::Create();
sunxd54e08e9d2016-02-22 23:01:28517
518 layer_tree_root->AddChild(transient_scroll_clip_layer);
519 transient_scroll_clip_layer->AddChild(transient_scroll_layer);
520 transient_scroll_layer->AddChild(scroll_clip_layer);
521 scroll_clip_layer->AddChild(scroll_layer);
522
523 transient_scroll_layer->SetScrollClipLayerId(
524 transient_scroll_clip_layer->id());
525 scroll_layer->SetScrollClipLayerId(scroll_clip_layer->id());
526 host_->SetRootLayer(layer_tree_root);
527 host_->BuildPropertyTreesForTesting();
528 host_->CommitAndCreatePendingTree();
529 host_impl->ActivateSyncTree();
530
531 ExpectTreesAreIdentical(layer_tree_root.get(),
532 host_impl->active_tree()->root_layer(),
533 host_impl->active_tree());
534
535 host_impl->active_tree()->SetCurrentlyScrollingLayer(
vollickcb3f6b12016-03-01 23:44:10536 host_impl->active_tree()->LayerById(scroll_layer->id()));
sunxd54e08e9d2016-02-22 23:01:28537 transient_scroll_layer->SetScrollClipLayerId(Layer::INVALID_ID);
538 host_->BuildPropertyTreesForTesting();
539
540 host_impl->CreatePendingTree();
541 host_->CommitAndCreatePendingTree();
542 host_impl->ActivateSyncTree();
543
544 EXPECT_EQ(scroll_layer->id(),
545 host_impl->active_tree()->CurrentlyScrollingLayer()->id());
546}
547
sunxdc36713a2016-03-03 22:31:10548TEST_F(TreeSynchronizerTest, SynchronizeScrollTreeScrollOffsetMap) {
549 host_->InitializeSingleThreaded(&client_, base::ThreadTaskRunnerHandle::Get(),
550 nullptr);
551 LayerTreeSettings settings;
552 FakeLayerTreeHostImplClient client;
553 FakeImplTaskRunnerProvider task_runner_provider;
554 FakeRenderingStatsInstrumentation stats_instrumentation;
555 TestSharedBitmapManager shared_bitmap_manager;
556 TestTaskGraphRunner task_graph_runner;
557 FakeLayerTreeHostImpl* host_impl = host_->host_impl();
558 host_impl->CreatePendingTree();
559
loyso0940d412016-03-14 01:30:31560 scoped_refptr<Layer> layer_tree_root = Layer::Create();
561 scoped_refptr<Layer> scroll_clip_layer = Layer::Create();
562 scoped_refptr<Layer> scroll_layer = Layer::Create();
563 scoped_refptr<Layer> transient_scroll_clip_layer = Layer::Create();
564 scoped_refptr<Layer> transient_scroll_layer = Layer::Create();
sunxdc36713a2016-03-03 22:31:10565
566 layer_tree_root->AddChild(transient_scroll_clip_layer);
567 transient_scroll_clip_layer->AddChild(transient_scroll_layer);
568 transient_scroll_layer->AddChild(scroll_clip_layer);
569 scroll_clip_layer->AddChild(scroll_layer);
570
571 transient_scroll_layer->SetScrollClipLayerId(
572 transient_scroll_clip_layer->id());
573 scroll_layer->SetScrollClipLayerId(scroll_clip_layer->id());
574 transient_scroll_layer->SetScrollOffset(gfx::ScrollOffset(1, 2));
575 scroll_layer->SetScrollOffset(gfx::ScrollOffset(10, 20));
576
577 host_->SetRootLayer(layer_tree_root);
578 host_->BuildPropertyTreesForTesting();
579 host_->CommitAndCreatePendingTree();
580 host_impl->ActivateSyncTree();
581
582 ExpectTreesAreIdentical(layer_tree_root.get(),
583 host_impl->active_tree()->root_layer(),
584 host_impl->active_tree());
585
586 // After the initial commit, scroll_offset_map in scroll_tree is expected to
587 // have one entry for scroll_layer and one entry for transient_scroll_layer,
588 // the pending base and active base must be the same at this stage.
589 ScrollTree::ScrollOffsetMap scroll_offset_map;
590 scroll_offset_map[scroll_layer->id()] = new SyncedScrollOffset;
591 scroll_offset_map[transient_scroll_layer->id()] = new SyncedScrollOffset;
592 scroll_offset_map[scroll_layer->id()]->PushFromMainThread(
593 scroll_layer->scroll_offset());
594 scroll_offset_map[scroll_layer->id()]->PushPendingToActive();
595 scroll_offset_map[transient_scroll_layer->id()]->PushFromMainThread(
596 transient_scroll_layer->scroll_offset());
597 scroll_offset_map[transient_scroll_layer->id()]->PushPendingToActive();
598 EXPECT_TRUE(
599 is_equal(scroll_offset_map, host_impl->active_tree()
600 ->property_trees()
601 ->scroll_tree.scroll_offset_map()));
602
603 // Set ScrollOffset active delta: gfx::ScrollOffset(10, 10)
604 LayerImpl* scroll_layer_impl =
605 host_impl->active_tree()->LayerById(scroll_layer->id());
606 ScrollTree& scroll_tree =
607 host_impl->active_tree()->property_trees()->scroll_tree;
sunxdc044b11a2016-03-16 16:23:20608 scroll_tree.SetScrollOffset(scroll_layer_impl->id(),
609 gfx::ScrollOffset(20, 30));
sunxdc36713a2016-03-03 22:31:10610
611 // Pull ScrollOffset delta for main thread, and change offset on main thread
danakj60bc3bc2016-04-09 00:24:48612 std::unique_ptr<ScrollAndScaleSet> scroll_info(new ScrollAndScaleSet());
sunxdc36713a2016-03-03 22:31:10613 scroll_tree.CollectScrollDeltas(scroll_info.get());
614 host_->proxy()->SetNeedsCommit();
615 host_->ApplyScrollAndScale(scroll_info.get());
616 EXPECT_EQ(gfx::ScrollOffset(20, 30), scroll_layer->scroll_offset());
617 scroll_layer->SetScrollOffset(gfx::ScrollOffset(100, 100));
618
619 // More update to ScrollOffset active delta: gfx::ScrollOffset(20, 20)
sunxdc044b11a2016-03-16 16:23:20620 scroll_tree.SetScrollOffset(scroll_layer_impl->id(),
621 gfx::ScrollOffset(40, 50));
sunxdc36713a2016-03-03 22:31:10622 host_impl->active_tree()->SetCurrentlyScrollingLayer(scroll_layer_impl);
623
624 // Make one layer unscrollable so that scroll tree topology changes
625 transient_scroll_layer->SetScrollClipLayerId(Layer::INVALID_ID);
626 host_->BuildPropertyTreesForTesting();
627
628 host_impl->CreatePendingTree();
629 host_->CommitAndCreatePendingTree();
630 host_impl->ActivateSyncTree();
631
632 EXPECT_EQ(scroll_layer->id(),
633 host_impl->active_tree()->CurrentlyScrollingLayer()->id());
634 scroll_offset_map.erase(transient_scroll_layer->id());
635 scroll_offset_map[scroll_layer->id()]->SetCurrent(gfx::ScrollOffset(20, 30));
636 scroll_offset_map[scroll_layer->id()]->PullDeltaForMainThread();
637 scroll_offset_map[scroll_layer->id()]->SetCurrent(gfx::ScrollOffset(40, 50));
638 scroll_offset_map[scroll_layer->id()]->PushFromMainThread(
639 gfx::ScrollOffset(100, 100));
640 scroll_offset_map[scroll_layer->id()]->PushPendingToActive();
641 EXPECT_TRUE(is_equal(scroll_offset_map, scroll_tree.scroll_offset_map()));
642}
643
[email protected]ba565742012-11-10 09:29:48644} // namespace
645} // namespace cc