blob: 174dd80c0b5ae2291918e875e691e95003d875dd [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"
14#include "base/strings/stringprintf.h"
[email protected]95e4e1a02013-03-18 07:09:0915#include "cc/animation/layer_animation_controller.h"
[email protected]cc3cfaa2013-03-18 09:05:5216#include "cc/layers/layer.h"
17#include "cc/layers/layer_impl.h"
jbroman49fa12e2015-11-18 23:17:1418#include "cc/layers/layer_settings.h"
[email protected]101441ce2012-10-16 01:45:0319#include "cc/test/animation_test_common.h"
khushalsagarb64b360d2015-10-21 19:25:1620#include "cc/test/fake_impl_task_runner_provider.h"
[email protected]f4e25f92013-07-13 20:54:5321#include "cc/test/fake_layer_tree_host.h"
hendrikw9b7f6d982014-11-04 22:28:3522#include "cc/test/fake_rendering_stats_instrumentation.h"
[email protected]4e2eb352014-03-20 17:25:4523#include "cc/test/test_shared_bitmap_manager.h"
danakjcf610582015-06-16 22:48:5624#include "cc/test/test_task_graph_runner.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:
34 static scoped_ptr<MockLayerImpl> Create(LayerTreeImpl* tree_impl,
35 int layer_id) {
36 return make_scoped_ptr(new MockLayerImpl(tree_impl, layer_id));
37 }
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)
49 : LayerImpl(tree_impl, layer_id),
50 layer_impl_destruction_list_(NULL) {}
[email protected]c0dd24c2012-08-30 23:25:2751
[email protected]b5651c22013-03-14 15:06:3352 std::vector<int>* layer_impl_destruction_list_;
[email protected]c0dd24c2012-08-30 23:25:2753};
54
[email protected]96baf3e2012-10-22 23:09:5555class MockLayer : public Layer {
[email protected]b5651c22013-03-14 15:06:3356 public:
57 static scoped_refptr<MockLayer> Create(
loysoa6edaaff2015-05-25 03:26:4458 const LayerSettings& settings,
[email protected]b5651c22013-03-14 15:06:3359 std::vector<int>* layer_impl_destruction_list) {
loysoa6edaaff2015-05-25 03:26:4460 return make_scoped_refptr(
61 new MockLayer(settings, layer_impl_destruction_list));
[email protected]b5651c22013-03-14 15:06:3362 }
[email protected]c0dd24c2012-08-30 23:25:2763
dcheng716bedf2014-10-21 09:51:0864 scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override {
danakjf446a072014-09-27 21:55:4865 return MockLayerImpl::Create(tree_impl, layer_id_);
[email protected]b5651c22013-03-14 15:06:3366 }
[email protected]c0dd24c2012-08-30 23:25:2767
dcheng716bedf2014-10-21 09:51:0868 void PushPropertiesTo(LayerImpl* layer_impl) override {
[email protected]b5651c22013-03-14 15:06:3369 Layer::PushPropertiesTo(layer_impl);
[email protected]c0dd24c2012-08-30 23:25:2770
[email protected]b5651c22013-03-14 15:06:3371 MockLayerImpl* mock_layer_impl = static_cast<MockLayerImpl*>(layer_impl);
72 mock_layer_impl->SetLayerImplDestructionList(layer_impl_destruction_list_);
73 }
[email protected]d58499a2012-10-09 22:27:4774
[email protected]b5651c22013-03-14 15:06:3375 private:
loysoa6edaaff2015-05-25 03:26:4476 explicit MockLayer(const LayerSettings& settings,
77 std::vector<int>* layer_impl_destruction_list)
78 : Layer(settings),
79 layer_impl_destruction_list_(layer_impl_destruction_list) {}
dcheng716bedf2014-10-21 09:51:0880 ~MockLayer() override {}
[email protected]c0dd24c2012-08-30 23:25:2781
[email protected]b5651c22013-03-14 15:06:3382 std::vector<int>* layer_impl_destruction_list_;
[email protected]c0dd24c2012-08-30 23:25:2783};
84
[email protected]b5651c22013-03-14 15:06:3385void ExpectTreesAreIdentical(Layer* layer,
86 LayerImpl* layer_impl,
87 LayerTreeImpl* tree_impl) {
88 ASSERT_TRUE(layer);
89 ASSERT_TRUE(layer_impl);
[email protected]c0dd24c2012-08-30 23:25:2790
[email protected]b5651c22013-03-14 15:06:3391 EXPECT_EQ(layer->id(), layer_impl->id());
92 EXPECT_EQ(layer_impl->layer_tree_impl(), tree_impl);
[email protected]c0dd24c2012-08-30 23:25:2793
[email protected]b5651c22013-03-14 15:06:3394 EXPECT_EQ(layer->non_fast_scrollable_region(),
95 layer_impl->non_fast_scrollable_region());
[email protected]c0dd24c2012-08-30 23:25:2796
[email protected]b5651c22013-03-14 15:06:3397 ASSERT_EQ(!!layer->mask_layer(), !!layer_impl->mask_layer());
98 if (layer->mask_layer()) {
[email protected]d097e242014-02-28 21:51:1199 SCOPED_TRACE("mask_layer");
[email protected]b5651c22013-03-14 15:06:33100 ExpectTreesAreIdentical(
101 layer->mask_layer(), layer_impl->mask_layer(), tree_impl);
102 }
[email protected]c0dd24c2012-08-30 23:25:27103
[email protected]b5651c22013-03-14 15:06:33104 ASSERT_EQ(!!layer->replica_layer(), !!layer_impl->replica_layer());
105 if (layer->replica_layer()) {
[email protected]d097e242014-02-28 21:51:11106 SCOPED_TRACE("replica_layer");
[email protected]b5651c22013-03-14 15:06:33107 ExpectTreesAreIdentical(
108 layer->replica_layer(), layer_impl->replica_layer(), tree_impl);
109 }
[email protected]c0dd24c2012-08-30 23:25:27110
[email protected]50761e92013-03-29 20:51:28111 const LayerList& layer_children = layer->children();
112 const OwnedLayerImplList& layer_impl_children = layer_impl->children();
[email protected]c0dd24c2012-08-30 23:25:27113
[email protected]b5651c22013-03-14 15:06:33114 ASSERT_EQ(layer_children.size(), layer_impl_children.size());
[email protected]c0dd24c2012-08-30 23:25:27115
[email protected]0e98cdd2013-08-23 00:44:30116 const std::set<Layer*>* layer_scroll_children = layer->scroll_children();
117 const std::set<LayerImpl*>* layer_impl_scroll_children =
118 layer_impl->scroll_children();
119
120 ASSERT_EQ(!!layer_scroll_children, !!layer_impl_scroll_children);
121
122 if (layer_scroll_children) {
123 ASSERT_EQ(
124 layer_scroll_children->size(),
125 layer_impl_scroll_children->size());
126 }
127
128 const Layer* layer_scroll_parent = layer->scroll_parent();
129 const LayerImpl* layer_impl_scroll_parent = layer_impl->scroll_parent();
130
131 ASSERT_EQ(!!layer_scroll_parent, !!layer_impl_scroll_parent);
132
133 if (layer_scroll_parent) {
134 ASSERT_EQ(layer_scroll_parent->id(), layer_impl_scroll_parent->id());
135 ASSERT_TRUE(layer_scroll_parent->scroll_children()->find(layer) !=
136 layer_scroll_parent->scroll_children()->end());
137 ASSERT_TRUE(layer_impl_scroll_parent->scroll_children()->find(layer_impl) !=
138 layer_impl_scroll_parent->scroll_children()->end());
139 }
140
141 const std::set<Layer*>* layer_clip_children = layer->clip_children();
142 const std::set<LayerImpl*>* layer_impl_clip_children =
143 layer_impl->clip_children();
144
145 ASSERT_EQ(!!layer_clip_children, !!layer_impl_clip_children);
146
147 if (layer_clip_children)
148 ASSERT_EQ(layer_clip_children->size(), layer_impl_clip_children->size());
149
150 const Layer* layer_clip_parent = layer->clip_parent();
151 const LayerImpl* layer_impl_clip_parent = layer_impl->clip_parent();
152
153 ASSERT_EQ(!!layer_clip_parent, !!layer_impl_clip_parent);
154
155 if (layer_clip_parent) {
156 const std::set<LayerImpl*>* clip_children_impl =
157 layer_impl_clip_parent->clip_children();
158 const std::set<Layer*>* clip_children =
159 layer_clip_parent->clip_children();
160 ASSERT_EQ(layer_clip_parent->id(), layer_impl_clip_parent->id());
161 ASSERT_TRUE(clip_children->find(layer) != clip_children->end());
162 ASSERT_TRUE(clip_children_impl->find(layer_impl) !=
163 clip_children_impl->end());
164 }
165
[email protected]b5651c22013-03-14 15:06:33166 for (size_t i = 0; i < layer_children.size(); ++i) {
[email protected]d097e242014-02-28 21:51:11167 SCOPED_TRACE(base::StringPrintf("child layer %" PRIuS, i).c_str());
vmpstra370ef52015-11-18 10:41:28168 ExpectTreesAreIdentical(layer_children[i].get(),
169 layer_impl_children[i].get(), tree_impl);
[email protected]b5651c22013-03-14 15:06:33170 }
[email protected]c0dd24c2012-08-30 23:25:27171}
172
loyso0b6dfdb62016-01-06 01:04:23173class LayerTreeSettingsForTreeSynchronizerTest : public LayerTreeSettings {
174 public:
175 LayerTreeSettingsForTreeSynchronizerTest() {
176 use_compositor_animation_timelines = true;
177 }
178};
179
[email protected]c2282382012-12-16 00:46:03180class TreeSynchronizerTest : public testing::Test {
[email protected]b5651c22013-03-14 15:06:33181 public:
enne2097cab2014-09-25 20:16:31182 TreeSynchronizerTest()
183 : client_(FakeLayerTreeHostClient::DIRECT_3D),
loyso0b6dfdb62016-01-06 01:04:23184 host_(FakeLayerTreeHost::Create(
185 &client_,
186 &task_graph_runner_,
187 LayerTreeSettingsForTreeSynchronizerTest())) {
188 layer_settings_.use_compositor_animation_timelines =
189 host_->settings().use_compositor_animation_timelines;
190 }
[email protected]c2282382012-12-16 00:46:03191
[email protected]b5651c22013-03-14 15:06:33192 protected:
enne2097cab2014-09-25 20:16:31193 FakeLayerTreeHostClient client_;
danakjcf610582015-06-16 22:48:56194 TestTaskGraphRunner task_graph_runner_;
[email protected]f4e25f92013-07-13 20:54:53195 scoped_ptr<FakeLayerTreeHost> host_;
loysoa6edaaff2015-05-25 03:26:44196 LayerSettings layer_settings_;
sunxdc36713a2016-03-03 22:31:10197
198 bool is_equal(ScrollTree::ScrollOffsetMap map,
199 ScrollTree::ScrollOffsetMap other) {
200 if (map.size() != other.size())
201 return false;
202 for (auto& map_entry : map) {
203 if (other.find(map_entry.first) == other.end())
204 return false;
205 SyncedScrollOffset& from_map = *map_entry.second.get();
206 SyncedScrollOffset& from_other = *other[map_entry.first].get();
207 if (from_map.PendingBase() != from_other.PendingBase() ||
208 from_map.ActiveBase() != from_other.ActiveBase() ||
209 from_map.Delta() != from_other.Delta() ||
210 from_map.PendingDelta().get() != from_other.PendingDelta().get())
211 return false;
212 }
213 return true;
214 }
[email protected]c2282382012-12-16 00:46:03215};
216
[email protected]c0dd24c2012-08-30 23:25:27217// Attempts to synchronizes a null tree. This should not crash, and should
218// return a null tree.
[email protected]b5651c22013-03-14 15:06:33219TEST_F(TreeSynchronizerTest, SyncNullTree) {
220 scoped_ptr<LayerImpl> layer_impl_tree_root =
danakj968153f32014-10-15 22:52:16221 TreeSynchronizer::SynchronizeTrees(
222 static_cast<Layer*>(NULL), nullptr, host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27223
[email protected]b5651c22013-03-14 15:06:33224 EXPECT_TRUE(!layer_impl_tree_root.get());
[email protected]c0dd24c2012-08-30 23:25:27225}
226
[email protected]b5651c22013-03-14 15:06:33227// Constructs a very simple tree and synchronizes it without trying to reuse any
228// preexisting layers.
229TEST_F(TreeSynchronizerTest, SyncSimpleTreeFromEmpty) {
loysoa6edaaff2015-05-25 03:26:44230 scoped_refptr<Layer> layer_tree_root = Layer::Create(layer_settings_);
231 layer_tree_root->AddChild(Layer::Create(layer_settings_));
232 layer_tree_root->AddChild(Layer::Create(layer_settings_));
[email protected]c0dd24c2012-08-30 23:25:27233
[email protected]f4e25f92013-07-13 20:54:53234 host_->SetRootLayer(layer_tree_root);
235
[email protected]b5651c22013-03-14 15:06:33236 scoped_ptr<LayerImpl> layer_impl_tree_root =
danakj968153f32014-10-15 22:52:16237 TreeSynchronizer::SynchronizeTrees(
238 layer_tree_root.get(), nullptr, host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27239
[email protected]b5651c22013-03-14 15:06:33240 ExpectTreesAreIdentical(layer_tree_root.get(),
241 layer_impl_tree_root.get(),
[email protected]f4e25f92013-07-13 20:54:53242 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27243}
244
[email protected]b5651c22013-03-14 15:06:33245// Constructs a very simple tree and synchronizes it attempting to reuse some
246// layers
247TEST_F(TreeSynchronizerTest, SyncSimpleTreeReusingLayers) {
248 std::vector<int> layer_impl_destruction_list;
[email protected]c0dd24c2012-08-30 23:25:27249
[email protected]b5651c22013-03-14 15:06:33250 scoped_refptr<Layer> layer_tree_root =
loysoa6edaaff2015-05-25 03:26:44251 MockLayer::Create(layer_settings_, &layer_impl_destruction_list);
252 layer_tree_root->AddChild(
253 MockLayer::Create(layer_settings_, &layer_impl_destruction_list));
254 layer_tree_root->AddChild(
255 MockLayer::Create(layer_settings_, &layer_impl_destruction_list));
[email protected]c0dd24c2012-08-30 23:25:27256
[email protected]f4e25f92013-07-13 20:54:53257 host_->SetRootLayer(layer_tree_root);
258
[email protected]b5651c22013-03-14 15:06:33259 scoped_ptr<LayerImpl> layer_impl_tree_root =
danakj968153f32014-10-15 22:52:16260 TreeSynchronizer::SynchronizeTrees(
261 layer_tree_root.get(), nullptr, host_->active_tree());
[email protected]b5651c22013-03-14 15:06:33262 ExpectTreesAreIdentical(layer_tree_root.get(),
263 layer_impl_tree_root.get(),
[email protected]f4e25f92013-07-13 20:54:53264 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27265
[email protected]b5651c22013-03-14 15:06:33266 // We have to push properties to pick up the destruction list pointer.
267 TreeSynchronizer::PushProperties(layer_tree_root.get(),
268 layer_impl_tree_root.get());
[email protected]5c4824e12013-01-12 16:34:53269
[email protected]b5651c22013-03-14 15:06:33270 // Add a new layer to the Layer side
loysoa6edaaff2015-05-25 03:26:44271 layer_tree_root->children()[0]->AddChild(
272 MockLayer::Create(layer_settings_, &layer_impl_destruction_list));
[email protected]b5651c22013-03-14 15:06:33273 // Remove one.
274 layer_tree_root->children()[1]->RemoveFromParent();
275 int second_layer_impl_id = layer_impl_tree_root->children()[1]->id();
[email protected]c0dd24c2012-08-30 23:25:27276
[email protected]b5651c22013-03-14 15:06:33277 // Synchronize again. After the sync the trees should be equivalent and we
278 // should have created and destroyed one LayerImpl.
danakja04855a2015-11-18 20:39:10279 layer_impl_tree_root = TreeSynchronizer::SynchronizeTrees(
280 layer_tree_root.get(), std::move(layer_impl_tree_root),
281 host_->active_tree());
[email protected]b5651c22013-03-14 15:06:33282 ExpectTreesAreIdentical(layer_tree_root.get(),
283 layer_impl_tree_root.get(),
[email protected]f4e25f92013-07-13 20:54:53284 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27285
[email protected]b5651c22013-03-14 15:06:33286 ASSERT_EQ(1u, layer_impl_destruction_list.size());
287 EXPECT_EQ(second_layer_impl_id, layer_impl_destruction_list[0]);
[email protected]c0dd24c2012-08-30 23:25:27288}
289
[email protected]b5651c22013-03-14 15:06:33290// Constructs a very simple tree and checks that a stacking-order change is
291// tracked properly.
292TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndTrackStackingOrderChange) {
293 std::vector<int> layer_impl_destruction_list;
[email protected]c0dd24c2012-08-30 23:25:27294
[email protected]b5651c22013-03-14 15:06:33295 // Set up the tree and sync once. child2 needs to be synced here, too, even
296 // though we remove it to set up the intended scenario.
297 scoped_refptr<Layer> layer_tree_root =
loysoa6edaaff2015-05-25 03:26:44298 MockLayer::Create(layer_settings_, &layer_impl_destruction_list);
299 scoped_refptr<Layer> child2 =
300 MockLayer::Create(layer_settings_, &layer_impl_destruction_list);
301 layer_tree_root->AddChild(
302 MockLayer::Create(layer_settings_, &layer_impl_destruction_list));
[email protected]b5651c22013-03-14 15:06:33303 layer_tree_root->AddChild(child2);
[email protected]f4e25f92013-07-13 20:54:53304
305 host_->SetRootLayer(layer_tree_root);
306
jaydasikaef64f9e42016-03-12 01:08:18307 host_->active_tree()->SetRootLayer(TreeSynchronizer::SynchronizeTrees(
308 layer_tree_root.get(), nullptr, host_->active_tree()));
309 LayerImpl* layer_impl_tree_root = host_->active_tree()->root_layer();
310 ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root,
[email protected]f4e25f92013-07-13 20:54:53311 host_->active_tree());
[email protected]5c4824e12013-01-12 16:34:53312
[email protected]b5651c22013-03-14 15:06:33313 // We have to push properties to pick up the destruction list pointer.
jaydasikaef64f9e42016-03-12 01:08:18314 TreeSynchronizer::PushProperties(layer_tree_root.get(), layer_impl_tree_root);
[email protected]5c4824e12013-01-12 16:34:53315
jaydasikaef64f9e42016-03-12 01:08:18316 host_->active_tree()->ResetAllChangeTracking(
317 PropertyTrees::ResetFlags::ALL_TREES);
[email protected]c0dd24c2012-08-30 23:25:27318
[email protected]b5651c22013-03-14 15:06:33319 // re-insert the layer and sync again.
320 child2->RemoveFromParent();
321 layer_tree_root->AddChild(child2);
jaydasikaef64f9e42016-03-12 01:08:18322 host_->active_tree()->SetRootLayer(TreeSynchronizer::SynchronizeTrees(
323 layer_tree_root.get(), host_->active_tree()->DetachLayerTree(),
324 host_->active_tree()));
325 layer_impl_tree_root = host_->active_tree()->root_layer();
326 ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root,
[email protected]f4e25f92013-07-13 20:54:53327 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27328
jaydasikaef64f9e42016-03-12 01:08:18329 TreeSynchronizer::PushProperties(layer_tree_root.get(), layer_impl_tree_root);
[email protected]5c4824e12013-01-12 16:34:53330
[email protected]b5651c22013-03-14 15:06:33331 // Check that the impl thread properly tracked the change.
332 EXPECT_FALSE(layer_impl_tree_root->LayerPropertyChanged());
333 EXPECT_FALSE(layer_impl_tree_root->children()[0]->LayerPropertyChanged());
334 EXPECT_TRUE(layer_impl_tree_root->children()[1]->LayerPropertyChanged());
jaydasikaef64f9e42016-03-12 01:08:18335 host_->active_tree()->DetachLayerTree();
[email protected]c0dd24c2012-08-30 23:25:27336}
337
[email protected]b5651c22013-03-14 15:06:33338TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndProperties) {
loysoa6edaaff2015-05-25 03:26:44339 scoped_refptr<Layer> layer_tree_root = Layer::Create(layer_settings_);
340 layer_tree_root->AddChild(Layer::Create(layer_settings_));
341 layer_tree_root->AddChild(Layer::Create(layer_settings_));
[email protected]c0dd24c2012-08-30 23:25:27342
[email protected]f4e25f92013-07-13 20:54:53343 host_->SetRootLayer(layer_tree_root);
344
[email protected]b5651c22013-03-14 15:06:33345 // Pick some random properties to set. The values are not important, we're
346 // just testing that at least some properties are making it through.
347 gfx::PointF root_position = gfx::PointF(2.3f, 7.4f);
348 layer_tree_root->SetPosition(root_position);
[email protected]c0dd24c2012-08-30 23:25:27349
[email protected]b5651c22013-03-14 15:06:33350 float first_child_opacity = 0.25f;
351 layer_tree_root->children()[0]->SetOpacity(first_child_opacity);
[email protected]c0dd24c2012-08-30 23:25:27352
[email protected]b5651c22013-03-14 15:06:33353 gfx::Size second_child_bounds = gfx::Size(25, 53);
354 layer_tree_root->children()[1]->SetBounds(second_child_bounds);
[email protected]445881f2013-04-16 01:11:59355 layer_tree_root->children()[1]->SavePaintProperties();
[email protected]c0dd24c2012-08-30 23:25:27356
[email protected]b5651c22013-03-14 15:06:33357 scoped_ptr<LayerImpl> layer_impl_tree_root =
danakj968153f32014-10-15 22:52:16358 TreeSynchronizer::SynchronizeTrees(
359 layer_tree_root.get(), nullptr, host_->active_tree());
[email protected]b5651c22013-03-14 15:06:33360 ExpectTreesAreIdentical(layer_tree_root.get(),
361 layer_impl_tree_root.get(),
[email protected]f4e25f92013-07-13 20:54:53362 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27363
[email protected]b5651c22013-03-14 15:06:33364 TreeSynchronizer::PushProperties(layer_tree_root.get(),
365 layer_impl_tree_root.get());
[email protected]5c4824e12013-01-12 16:34:53366
[email protected]b5651c22013-03-14 15:06:33367 // Check that the property values we set on the Layer tree are reflected in
368 // the LayerImpl tree.
369 gfx::PointF root_layer_impl_position = layer_impl_tree_root->position();
370 EXPECT_EQ(root_position.x(), root_layer_impl_position.x());
371 EXPECT_EQ(root_position.y(), root_layer_impl_position.y());
[email protected]c0dd24c2012-08-30 23:25:27372
[email protected]b5651c22013-03-14 15:06:33373 EXPECT_EQ(first_child_opacity,
374 layer_impl_tree_root->children()[0]->opacity());
[email protected]c0dd24c2012-08-30 23:25:27375
bokancccfde72014-10-08 15:15:22376 gfx::Size second_layer_impl_child_bounds =
[email protected]b5651c22013-03-14 15:06:33377 layer_impl_tree_root->children()[1]->bounds();
378 EXPECT_EQ(second_child_bounds.width(),
379 second_layer_impl_child_bounds.width());
380 EXPECT_EQ(second_child_bounds.height(),
381 second_layer_impl_child_bounds.height());
[email protected]c0dd24c2012-08-30 23:25:27382}
383
[email protected]b5651c22013-03-14 15:06:33384TEST_F(TreeSynchronizerTest, ReuseLayerImplsAfterStructuralChange) {
385 std::vector<int> layer_impl_destruction_list;
[email protected]c0dd24c2012-08-30 23:25:27386
[email protected]b5651c22013-03-14 15:06:33387 // Set up a tree with this sort of structure:
388 // root --- A --- B ---+--- C
389 // |
390 // +--- D
391 scoped_refptr<Layer> layer_tree_root =
loysoa6edaaff2015-05-25 03:26:44392 MockLayer::Create(layer_settings_, &layer_impl_destruction_list);
393 layer_tree_root->AddChild(
394 MockLayer::Create(layer_settings_, &layer_impl_destruction_list));
[email protected]c0dd24c2012-08-30 23:25:27395
[email protected]b5651c22013-03-14 15:06:33396 scoped_refptr<Layer> layer_a = layer_tree_root->children()[0].get();
loysoa6edaaff2015-05-25 03:26:44397 layer_a->AddChild(
398 MockLayer::Create(layer_settings_, &layer_impl_destruction_list));
[email protected]c0dd24c2012-08-30 23:25:27399
[email protected]b5651c22013-03-14 15:06:33400 scoped_refptr<Layer> layer_b = layer_a->children()[0].get();
loysoa6edaaff2015-05-25 03:26:44401 layer_b->AddChild(
402 MockLayer::Create(layer_settings_, &layer_impl_destruction_list));
[email protected]c0dd24c2012-08-30 23:25:27403
[email protected]b5651c22013-03-14 15:06:33404 scoped_refptr<Layer> layer_c = layer_b->children()[0].get();
loysoa6edaaff2015-05-25 03:26:44405 layer_b->AddChild(
406 MockLayer::Create(layer_settings_, &layer_impl_destruction_list));
[email protected]b5651c22013-03-14 15:06:33407 scoped_refptr<Layer> layer_d = layer_b->children()[1].get();
[email protected]c0dd24c2012-08-30 23:25:27408
[email protected]f4e25f92013-07-13 20:54:53409 host_->SetRootLayer(layer_tree_root);
410
[email protected]b5651c22013-03-14 15:06:33411 scoped_ptr<LayerImpl> layer_impl_tree_root =
danakj968153f32014-10-15 22:52:16412 TreeSynchronizer::SynchronizeTrees(
413 layer_tree_root.get(), nullptr, host_->active_tree());
[email protected]b5651c22013-03-14 15:06:33414 ExpectTreesAreIdentical(layer_tree_root.get(),
415 layer_impl_tree_root.get(),
[email protected]f4e25f92013-07-13 20:54:53416 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27417
[email protected]b5651c22013-03-14 15:06:33418 // We have to push properties to pick up the destruction list pointer.
419 TreeSynchronizer::PushProperties(layer_tree_root.get(),
420 layer_impl_tree_root.get());
[email protected]5c4824e12013-01-12 16:34:53421
[email protected]b5651c22013-03-14 15:06:33422 // Now restructure the tree to look like this:
423 // root --- D ---+--- A
424 // |
425 // +--- C --- B
426 layer_tree_root->RemoveAllChildren();
427 layer_d->RemoveAllChildren();
428 layer_tree_root->AddChild(layer_d);
429 layer_a->RemoveAllChildren();
430 layer_d->AddChild(layer_a);
431 layer_c->RemoveAllChildren();
432 layer_d->AddChild(layer_c);
433 layer_b->RemoveAllChildren();
434 layer_c->AddChild(layer_b);
[email protected]c0dd24c2012-08-30 23:25:27435
[email protected]b5651c22013-03-14 15:06:33436 // After another synchronize our trees should match and we should not have
437 // destroyed any LayerImpls
danakja04855a2015-11-18 20:39:10438 layer_impl_tree_root = TreeSynchronizer::SynchronizeTrees(
439 layer_tree_root.get(), std::move(layer_impl_tree_root),
440 host_->active_tree());
[email protected]b5651c22013-03-14 15:06:33441 ExpectTreesAreIdentical(layer_tree_root.get(),
442 layer_impl_tree_root.get(),
[email protected]f4e25f92013-07-13 20:54:53443 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27444
[email protected]b5651c22013-03-14 15:06:33445 EXPECT_EQ(0u, layer_impl_destruction_list.size());
[email protected]c0dd24c2012-08-30 23:25:27446}
447
[email protected]b5651c22013-03-14 15:06:33448// Constructs a very simple tree, synchronizes it, then synchronizes to a
449// totally new tree. All layers from the old tree should be deleted.
450TEST_F(TreeSynchronizerTest, SyncSimpleTreeThenDestroy) {
451 std::vector<int> layer_impl_destruction_list;
[email protected]c0dd24c2012-08-30 23:25:27452
[email protected]b5651c22013-03-14 15:06:33453 scoped_refptr<Layer> old_layer_tree_root =
loysoa6edaaff2015-05-25 03:26:44454 MockLayer::Create(layer_settings_, &layer_impl_destruction_list);
[email protected]b5651c22013-03-14 15:06:33455 old_layer_tree_root->AddChild(
loysoa6edaaff2015-05-25 03:26:44456 MockLayer::Create(layer_settings_, &layer_impl_destruction_list));
[email protected]b5651c22013-03-14 15:06:33457 old_layer_tree_root->AddChild(
loysoa6edaaff2015-05-25 03:26:44458 MockLayer::Create(layer_settings_, &layer_impl_destruction_list));
[email protected]c0dd24c2012-08-30 23:25:27459
[email protected]f4e25f92013-07-13 20:54:53460 host_->SetRootLayer(old_layer_tree_root);
461
[email protected]b5651c22013-03-14 15:06:33462 int old_tree_root_layer_id = old_layer_tree_root->id();
463 int old_tree_first_child_layer_id = old_layer_tree_root->children()[0]->id();
464 int old_tree_second_child_layer_id = old_layer_tree_root->children()[1]->id();
[email protected]c0dd24c2012-08-30 23:25:27465
[email protected]b5651c22013-03-14 15:06:33466 scoped_ptr<LayerImpl> layer_impl_tree_root =
danakj968153f32014-10-15 22:52:16467 TreeSynchronizer::SynchronizeTrees(
468 old_layer_tree_root.get(), nullptr, host_->active_tree());
[email protected]b5651c22013-03-14 15:06:33469 ExpectTreesAreIdentical(old_layer_tree_root.get(),
470 layer_impl_tree_root.get(),
[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 // We have to push properties to pick up the destruction list pointer.
474 TreeSynchronizer::PushProperties(old_layer_tree_root.get(),
475 layer_impl_tree_root.get());
[email protected]5c4824e12013-01-12 16:34:53476
[email protected]b5651c22013-03-14 15:06:33477 // Remove all children on the Layer side.
478 old_layer_tree_root->RemoveAllChildren();
[email protected]c0dd24c2012-08-30 23:25:27479
[email protected]b5651c22013-03-14 15:06:33480 // Synchronize again. After the sync all LayerImpls from the old tree should
481 // be deleted.
loysoa6edaaff2015-05-25 03:26:44482 scoped_refptr<Layer> new_layer_tree_root = Layer::Create(layer_settings_);
[email protected]f4e25f92013-07-13 20:54:53483 host_->SetRootLayer(new_layer_tree_root);
danakja04855a2015-11-18 20:39:10484 layer_impl_tree_root = TreeSynchronizer::SynchronizeTrees(
485 new_layer_tree_root.get(), std::move(layer_impl_tree_root),
486 host_->active_tree());
[email protected]b5651c22013-03-14 15:06:33487 ExpectTreesAreIdentical(new_layer_tree_root.get(),
488 layer_impl_tree_root.get(),
[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 ASSERT_EQ(3u, layer_impl_destruction_list.size());
[email protected]2cdbdba2012-10-28 13:15:05492
[email protected]b5651c22013-03-14 15:06:33493 EXPECT_TRUE(std::find(layer_impl_destruction_list.begin(),
494 layer_impl_destruction_list.end(),
495 old_tree_root_layer_id) !=
496 layer_impl_destruction_list.end());
497 EXPECT_TRUE(std::find(layer_impl_destruction_list.begin(),
498 layer_impl_destruction_list.end(),
499 old_tree_first_child_layer_id) !=
500 layer_impl_destruction_list.end());
501 EXPECT_TRUE(std::find(layer_impl_destruction_list.begin(),
502 layer_impl_destruction_list.end(),
503 old_tree_second_child_layer_id) !=
504 layer_impl_destruction_list.end());
[email protected]c0dd24c2012-08-30 23:25:27505}
506
507// Constructs+syncs a tree with mask, replica, and replica mask layers.
[email protected]b5651c22013-03-14 15:06:33508TEST_F(TreeSynchronizerTest, SyncMaskReplicaAndReplicaMaskLayers) {
loysoa6edaaff2015-05-25 03:26:44509 scoped_refptr<Layer> layer_tree_root = Layer::Create(layer_settings_);
510 layer_tree_root->AddChild(Layer::Create(layer_settings_));
511 layer_tree_root->AddChild(Layer::Create(layer_settings_));
512 layer_tree_root->AddChild(Layer::Create(layer_settings_));
[email protected]c0dd24c2012-08-30 23:25:27513
[email protected]b5651c22013-03-14 15:06:33514 // First child gets a mask layer.
loysoa6edaaff2015-05-25 03:26:44515 scoped_refptr<Layer> mask_layer = Layer::Create(layer_settings_);
[email protected]b5651c22013-03-14 15:06:33516 layer_tree_root->children()[0]->SetMaskLayer(mask_layer.get());
[email protected]c0dd24c2012-08-30 23:25:27517
[email protected]b5651c22013-03-14 15:06:33518 // Second child gets a replica layer.
loysoa6edaaff2015-05-25 03:26:44519 scoped_refptr<Layer> replica_layer = Layer::Create(layer_settings_);
[email protected]b5651c22013-03-14 15:06:33520 layer_tree_root->children()[1]->SetReplicaLayer(replica_layer.get());
[email protected]c0dd24c2012-08-30 23:25:27521
[email protected]b5651c22013-03-14 15:06:33522 // Third child gets a replica layer with a mask layer.
loysoa6edaaff2015-05-25 03:26:44523 scoped_refptr<Layer> replica_layer_with_mask = Layer::Create(layer_settings_);
524 scoped_refptr<Layer> replica_mask_layer = Layer::Create(layer_settings_);
[email protected]b5651c22013-03-14 15:06:33525 replica_layer_with_mask->SetMaskLayer(replica_mask_layer.get());
526 layer_tree_root->children()[2]->
527 SetReplicaLayer(replica_layer_with_mask.get());
[email protected]c0dd24c2012-08-30 23:25:27528
[email protected]f4e25f92013-07-13 20:54:53529 host_->SetRootLayer(layer_tree_root);
530
[email protected]b5651c22013-03-14 15:06:33531 scoped_ptr<LayerImpl> layer_impl_tree_root =
danakj968153f32014-10-15 22:52:16532 TreeSynchronizer::SynchronizeTrees(
533 layer_tree_root.get(), nullptr, host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27534
[email protected]b5651c22013-03-14 15:06:33535 ExpectTreesAreIdentical(layer_tree_root.get(),
536 layer_impl_tree_root.get(),
[email protected]f4e25f92013-07-13 20:54:53537 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27538
[email protected]b5651c22013-03-14 15:06:33539 // Remove the mask layer.
540 layer_tree_root->children()[0]->SetMaskLayer(NULL);
danakja04855a2015-11-18 20:39:10541 layer_impl_tree_root = TreeSynchronizer::SynchronizeTrees(
542 layer_tree_root.get(), std::move(layer_impl_tree_root),
543 host_->active_tree());
[email protected]b5651c22013-03-14 15:06:33544 ExpectTreesAreIdentical(layer_tree_root.get(),
545 layer_impl_tree_root.get(),
[email protected]f4e25f92013-07-13 20:54:53546 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27547
[email protected]b5651c22013-03-14 15:06:33548 // Remove the replica layer.
549 layer_tree_root->children()[1]->SetReplicaLayer(NULL);
danakja04855a2015-11-18 20:39:10550 layer_impl_tree_root = TreeSynchronizer::SynchronizeTrees(
551 layer_tree_root.get(), std::move(layer_impl_tree_root),
552 host_->active_tree());
[email protected]b5651c22013-03-14 15:06:33553 ExpectTreesAreIdentical(layer_tree_root.get(),
554 layer_impl_tree_root.get(),
[email protected]f4e25f92013-07-13 20:54:53555 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27556
[email protected]b5651c22013-03-14 15:06:33557 // Remove the replica mask.
558 replica_layer_with_mask->SetMaskLayer(NULL);
danakja04855a2015-11-18 20:39:10559 layer_impl_tree_root = TreeSynchronizer::SynchronizeTrees(
560 layer_tree_root.get(), std::move(layer_impl_tree_root),
561 host_->active_tree());
[email protected]b5651c22013-03-14 15:06:33562 ExpectTreesAreIdentical(layer_tree_root.get(),
563 layer_impl_tree_root.get(),
[email protected]f4e25f92013-07-13 20:54:53564 host_->active_tree());
[email protected]c0dd24c2012-08-30 23:25:27565}
566
[email protected]0e98cdd2013-08-23 00:44:30567TEST_F(TreeSynchronizerTest, SynchronizeScrollParent) {
568 LayerTreeSettings settings;
khushalsagarb64b360d2015-10-21 19:25:16569 FakeImplTaskRunnerProvider task_runner_provider;
[email protected]0e98cdd2013-08-23 00:44:30570 FakeRenderingStatsInstrumentation stats_instrumentation;
danakjcf610582015-06-16 22:48:56571 TestSharedBitmapManager shared_bitmap_manager;
572 TestTaskGraphRunner task_graph_runner;
573 scoped_ptr<LayerTreeHostImpl> host_impl = LayerTreeHostImpl::Create(
khushalsagarb64b360d2015-10-21 19:25:16574 settings, nullptr, &task_runner_provider, &stats_instrumentation,
575 &shared_bitmap_manager, nullptr, &task_graph_runner, 0);
[email protected]0e98cdd2013-08-23 00:44:30576
loysoa6edaaff2015-05-25 03:26:44577 scoped_refptr<Layer> layer_tree_root = Layer::Create(layer_settings_);
578 scoped_refptr<Layer> scroll_parent = Layer::Create(layer_settings_);
[email protected]0e98cdd2013-08-23 00:44:30579 layer_tree_root->AddChild(scroll_parent);
loysoa6edaaff2015-05-25 03:26:44580 layer_tree_root->AddChild(Layer::Create(layer_settings_));
581 layer_tree_root->AddChild(Layer::Create(layer_settings_));
[email protected]0e98cdd2013-08-23 00:44:30582
583 host_->SetRootLayer(layer_tree_root);
584
585 // First child is the second and third child's scroll parent.
Daniel Chengeea98042014-08-26 00:28:10586 layer_tree_root->children()[1]->SetScrollParent(scroll_parent.get());
587 layer_tree_root->children()[2]->SetScrollParent(scroll_parent.get());
[email protected]0e98cdd2013-08-23 00:44:30588
589 scoped_ptr<LayerImpl> layer_impl_tree_root =
danakj968153f32014-10-15 22:52:16590 TreeSynchronizer::SynchronizeTrees(
591 layer_tree_root.get(), nullptr, host_impl->active_tree());
[email protected]0e98cdd2013-08-23 00:44:30592 TreeSynchronizer::PushProperties(layer_tree_root.get(),
593 layer_impl_tree_root.get());
[email protected]d097e242014-02-28 21:51:11594 {
595 SCOPED_TRACE("case one");
596 ExpectTreesAreIdentical(layer_tree_root.get(),
597 layer_impl_tree_root.get(),
598 host_impl->active_tree());
599 }
[email protected]0e98cdd2013-08-23 00:44:30600
601 // Remove the first scroll child.
602 layer_tree_root->children()[1]->RemoveFromParent();
danakja04855a2015-11-18 20:39:10603 layer_impl_tree_root = TreeSynchronizer::SynchronizeTrees(
604 layer_tree_root.get(), std::move(layer_impl_tree_root),
605 host_impl->active_tree());
[email protected]0e98cdd2013-08-23 00:44:30606 TreeSynchronizer::PushProperties(layer_tree_root.get(),
607 layer_impl_tree_root.get());
[email protected]d097e242014-02-28 21:51:11608 {
609 SCOPED_TRACE("case two");
610 ExpectTreesAreIdentical(layer_tree_root.get(),
611 layer_impl_tree_root.get(),
612 host_impl->active_tree());
613 }
[email protected]0e98cdd2013-08-23 00:44:30614
615 // Add an additional scroll layer.
loysoa6edaaff2015-05-25 03:26:44616 scoped_refptr<Layer> additional_scroll_child = Layer::Create(layer_settings_);
[email protected]0e98cdd2013-08-23 00:44:30617 layer_tree_root->AddChild(additional_scroll_child);
Daniel Chengeea98042014-08-26 00:28:10618 additional_scroll_child->SetScrollParent(scroll_parent.get());
danakja04855a2015-11-18 20:39:10619 layer_impl_tree_root = TreeSynchronizer::SynchronizeTrees(
620 layer_tree_root.get(), std::move(layer_impl_tree_root),
621 host_impl->active_tree());
[email protected]0e98cdd2013-08-23 00:44:30622 TreeSynchronizer::PushProperties(layer_tree_root.get(),
623 layer_impl_tree_root.get());
[email protected]d097e242014-02-28 21:51:11624 {
625 SCOPED_TRACE("case three");
626 ExpectTreesAreIdentical(layer_tree_root.get(),
627 layer_impl_tree_root.get(),
628 host_impl->active_tree());
629 }
[email protected]0e98cdd2013-08-23 00:44:30630}
631
632TEST_F(TreeSynchronizerTest, SynchronizeClipParent) {
633 LayerTreeSettings settings;
khushalsagarb64b360d2015-10-21 19:25:16634 FakeImplTaskRunnerProvider task_runner_provider;
[email protected]0e98cdd2013-08-23 00:44:30635 FakeRenderingStatsInstrumentation stats_instrumentation;
danakjcf610582015-06-16 22:48:56636 TestSharedBitmapManager shared_bitmap_manager;
637 TestTaskGraphRunner task_graph_runner;
638 scoped_ptr<LayerTreeHostImpl> host_impl = LayerTreeHostImpl::Create(
khushalsagarb64b360d2015-10-21 19:25:16639 settings, nullptr, &task_runner_provider, &stats_instrumentation,
640 &shared_bitmap_manager, nullptr, &task_graph_runner, 0);
[email protected]0e98cdd2013-08-23 00:44:30641
loysoa6edaaff2015-05-25 03:26:44642 scoped_refptr<Layer> layer_tree_root = Layer::Create(layer_settings_);
643 scoped_refptr<Layer> clip_parent = Layer::Create(layer_settings_);
644 scoped_refptr<Layer> intervening = Layer::Create(layer_settings_);
645 scoped_refptr<Layer> clip_child1 = Layer::Create(layer_settings_);
646 scoped_refptr<Layer> clip_child2 = Layer::Create(layer_settings_);
[email protected]0e98cdd2013-08-23 00:44:30647 layer_tree_root->AddChild(clip_parent);
648 clip_parent->AddChild(intervening);
649 intervening->AddChild(clip_child1);
650 intervening->AddChild(clip_child2);
651
652 host_->SetRootLayer(layer_tree_root);
653
654 // First child is the second and third child's scroll parent.
Daniel Chengeea98042014-08-26 00:28:10655 clip_child1->SetClipParent(clip_parent.get());
656 clip_child2->SetClipParent(clip_parent.get());
[email protected]0e98cdd2013-08-23 00:44:30657
658 scoped_ptr<LayerImpl> layer_impl_tree_root =
danakj968153f32014-10-15 22:52:16659 TreeSynchronizer::SynchronizeTrees(
660 layer_tree_root.get(), nullptr, host_impl->active_tree());
[email protected]0e98cdd2013-08-23 00:44:30661 TreeSynchronizer::PushProperties(layer_tree_root.get(),
662 layer_impl_tree_root.get());
663 ExpectTreesAreIdentical(layer_tree_root.get(),
664 layer_impl_tree_root.get(),
665 host_impl->active_tree());
666
667 // Remove the first clip child.
668 clip_child1->RemoveFromParent();
669 clip_child1 = NULL;
670
danakja04855a2015-11-18 20:39:10671 layer_impl_tree_root = TreeSynchronizer::SynchronizeTrees(
672 layer_tree_root.get(), std::move(layer_impl_tree_root),
673 host_impl->active_tree());
[email protected]0e98cdd2013-08-23 00:44:30674 TreeSynchronizer::PushProperties(layer_tree_root.get(),
675 layer_impl_tree_root.get());
676 ExpectTreesAreIdentical(layer_tree_root.get(),
677 layer_impl_tree_root.get(),
678 host_impl->active_tree());
679
680 // Add an additional clip child.
loysoa6edaaff2015-05-25 03:26:44681 scoped_refptr<Layer> additional_clip_child = Layer::Create(layer_settings_);
[email protected]0e98cdd2013-08-23 00:44:30682 intervening->AddChild(additional_clip_child);
Daniel Chengeea98042014-08-26 00:28:10683 additional_clip_child->SetClipParent(clip_parent.get());
danakja04855a2015-11-18 20:39:10684 layer_impl_tree_root = TreeSynchronizer::SynchronizeTrees(
685 layer_tree_root.get(), std::move(layer_impl_tree_root),
686 host_impl->active_tree());
[email protected]0e98cdd2013-08-23 00:44:30687 TreeSynchronizer::PushProperties(layer_tree_root.get(),
688 layer_impl_tree_root.get());
689 ExpectTreesAreIdentical(layer_tree_root.get(),
690 layer_impl_tree_root.get(),
691 host_impl->active_tree());
692
693 // Remove the nearest clipping ancestor.
694 clip_parent->RemoveFromParent();
695 clip_parent = NULL;
danakja04855a2015-11-18 20:39:10696 layer_impl_tree_root = TreeSynchronizer::SynchronizeTrees(
697 layer_tree_root.get(), std::move(layer_impl_tree_root),
698 host_impl->active_tree());
[email protected]0e98cdd2013-08-23 00:44:30699 TreeSynchronizer::PushProperties(layer_tree_root.get(),
700 layer_impl_tree_root.get());
701 ExpectTreesAreIdentical(layer_tree_root.get(),
702 layer_impl_tree_root.get(),
703 host_impl->active_tree());
704
705 // The clip children should have been unhooked.
706 EXPECT_EQ(2u, intervening->children().size());
707 EXPECT_FALSE(clip_child2->clip_parent());
708 EXPECT_FALSE(additional_clip_child->clip_parent());
709}
710
sunxd54e08e9d2016-02-22 23:01:28711TEST_F(TreeSynchronizerTest, SynchronizeCurrentlyScrollingNode) {
712 LayerTreeSettings settings;
713 FakeLayerTreeHostImplClient client;
714 FakeImplTaskRunnerProvider task_runner_provider;
715 FakeRenderingStatsInstrumentation stats_instrumentation;
716 TestSharedBitmapManager shared_bitmap_manager;
717 TestTaskGraphRunner task_graph_runner;
718 FakeLayerTreeHostImpl* host_impl = host_->host_impl();
719 host_impl->CreatePendingTree();
720
721 scoped_refptr<Layer> layer_tree_root = Layer::Create(layer_settings_);
722 scoped_refptr<Layer> scroll_clip_layer = Layer::Create(layer_settings_);
723 scoped_refptr<Layer> scroll_layer = Layer::Create(layer_settings_);
724 scoped_refptr<Layer> transient_scroll_clip_layer =
725 Layer::Create(layer_settings_);
726 scoped_refptr<Layer> transient_scroll_layer = Layer::Create(layer_settings_);
727
728 layer_tree_root->AddChild(transient_scroll_clip_layer);
729 transient_scroll_clip_layer->AddChild(transient_scroll_layer);
730 transient_scroll_layer->AddChild(scroll_clip_layer);
731 scroll_clip_layer->AddChild(scroll_layer);
732
733 transient_scroll_layer->SetScrollClipLayerId(
734 transient_scroll_clip_layer->id());
735 scroll_layer->SetScrollClipLayerId(scroll_clip_layer->id());
736 host_->SetRootLayer(layer_tree_root);
737 host_->BuildPropertyTreesForTesting();
738 host_->CommitAndCreatePendingTree();
739 host_impl->ActivateSyncTree();
740
741 ExpectTreesAreIdentical(layer_tree_root.get(),
742 host_impl->active_tree()->root_layer(),
743 host_impl->active_tree());
744
745 host_impl->active_tree()->SetCurrentlyScrollingLayer(
vollickcb3f6b12016-03-01 23:44:10746 host_impl->active_tree()->LayerById(scroll_layer->id()));
sunxd54e08e9d2016-02-22 23:01:28747 transient_scroll_layer->SetScrollClipLayerId(Layer::INVALID_ID);
748 host_->BuildPropertyTreesForTesting();
749
750 host_impl->CreatePendingTree();
751 host_->CommitAndCreatePendingTree();
752 host_impl->ActivateSyncTree();
753
754 EXPECT_EQ(scroll_layer->id(),
755 host_impl->active_tree()->CurrentlyScrollingLayer()->id());
756}
757
sunxdc36713a2016-03-03 22:31:10758TEST_F(TreeSynchronizerTest, SynchronizeScrollTreeScrollOffsetMap) {
759 host_->InitializeSingleThreaded(&client_, base::ThreadTaskRunnerHandle::Get(),
760 nullptr);
761 LayerTreeSettings settings;
762 FakeLayerTreeHostImplClient client;
763 FakeImplTaskRunnerProvider task_runner_provider;
764 FakeRenderingStatsInstrumentation stats_instrumentation;
765 TestSharedBitmapManager shared_bitmap_manager;
766 TestTaskGraphRunner task_graph_runner;
767 FakeLayerTreeHostImpl* host_impl = host_->host_impl();
768 host_impl->CreatePendingTree();
769
770 scoped_refptr<Layer> layer_tree_root = Layer::Create(layer_settings_);
771 scoped_refptr<Layer> scroll_clip_layer = Layer::Create(layer_settings_);
772 scoped_refptr<Layer> scroll_layer = Layer::Create(layer_settings_);
773 scoped_refptr<Layer> transient_scroll_clip_layer =
774 Layer::Create(layer_settings_);
775 scoped_refptr<Layer> transient_scroll_layer = Layer::Create(layer_settings_);
776
777 layer_tree_root->AddChild(transient_scroll_clip_layer);
778 transient_scroll_clip_layer->AddChild(transient_scroll_layer);
779 transient_scroll_layer->AddChild(scroll_clip_layer);
780 scroll_clip_layer->AddChild(scroll_layer);
781
782 transient_scroll_layer->SetScrollClipLayerId(
783 transient_scroll_clip_layer->id());
784 scroll_layer->SetScrollClipLayerId(scroll_clip_layer->id());
785 transient_scroll_layer->SetScrollOffset(gfx::ScrollOffset(1, 2));
786 scroll_layer->SetScrollOffset(gfx::ScrollOffset(10, 20));
787
788 host_->SetRootLayer(layer_tree_root);
789 host_->BuildPropertyTreesForTesting();
790 host_->CommitAndCreatePendingTree();
791 host_impl->ActivateSyncTree();
792
793 ExpectTreesAreIdentical(layer_tree_root.get(),
794 host_impl->active_tree()->root_layer(),
795 host_impl->active_tree());
796
797 // After the initial commit, scroll_offset_map in scroll_tree is expected to
798 // have one entry for scroll_layer and one entry for transient_scroll_layer,
799 // the pending base and active base must be the same at this stage.
800 ScrollTree::ScrollOffsetMap scroll_offset_map;
801 scroll_offset_map[scroll_layer->id()] = new SyncedScrollOffset;
802 scroll_offset_map[transient_scroll_layer->id()] = new SyncedScrollOffset;
803 scroll_offset_map[scroll_layer->id()]->PushFromMainThread(
804 scroll_layer->scroll_offset());
805 scroll_offset_map[scroll_layer->id()]->PushPendingToActive();
806 scroll_offset_map[transient_scroll_layer->id()]->PushFromMainThread(
807 transient_scroll_layer->scroll_offset());
808 scroll_offset_map[transient_scroll_layer->id()]->PushPendingToActive();
809 EXPECT_TRUE(
810 is_equal(scroll_offset_map, host_impl->active_tree()
811 ->property_trees()
812 ->scroll_tree.scroll_offset_map()));
813
814 // Set ScrollOffset active delta: gfx::ScrollOffset(10, 10)
815 LayerImpl* scroll_layer_impl =
816 host_impl->active_tree()->LayerById(scroll_layer->id());
817 ScrollTree& scroll_tree =
818 host_impl->active_tree()->property_trees()->scroll_tree;
819 scroll_tree.synced_scroll_offset(scroll_layer_impl->id())
820 ->SetCurrent(gfx::ScrollOffset(20, 30));
821
822 // Pull ScrollOffset delta for main thread, and change offset on main thread
823 scoped_ptr<ScrollAndScaleSet> scroll_info(new ScrollAndScaleSet());
824 scroll_tree.CollectScrollDeltas(scroll_info.get());
825 host_->proxy()->SetNeedsCommit();
826 host_->ApplyScrollAndScale(scroll_info.get());
827 EXPECT_EQ(gfx::ScrollOffset(20, 30), scroll_layer->scroll_offset());
828 scroll_layer->SetScrollOffset(gfx::ScrollOffset(100, 100));
829
830 // More update to ScrollOffset active delta: gfx::ScrollOffset(20, 20)
831 scroll_tree.synced_scroll_offset(scroll_layer_impl->id())
832 ->SetCurrent(gfx::ScrollOffset(40, 50));
833 host_impl->active_tree()->SetCurrentlyScrollingLayer(scroll_layer_impl);
834
835 // Make one layer unscrollable so that scroll tree topology changes
836 transient_scroll_layer->SetScrollClipLayerId(Layer::INVALID_ID);
837 host_->BuildPropertyTreesForTesting();
838
839 host_impl->CreatePendingTree();
840 host_->CommitAndCreatePendingTree();
841 host_impl->ActivateSyncTree();
842
843 EXPECT_EQ(scroll_layer->id(),
844 host_impl->active_tree()->CurrentlyScrollingLayer()->id());
845 scroll_offset_map.erase(transient_scroll_layer->id());
846 scroll_offset_map[scroll_layer->id()]->SetCurrent(gfx::ScrollOffset(20, 30));
847 scroll_offset_map[scroll_layer->id()]->PullDeltaForMainThread();
848 scroll_offset_map[scroll_layer->id()]->SetCurrent(gfx::ScrollOffset(40, 50));
849 scroll_offset_map[scroll_layer->id()]->PushFromMainThread(
850 gfx::ScrollOffset(100, 100));
851 scroll_offset_map[scroll_layer->id()]->PushPendingToActive();
852 EXPECT_TRUE(is_equal(scroll_offset_map, scroll_tree.scroll_offset_map()));
853}
854
[email protected]ba565742012-11-10 09:29:48855} // namespace
856} // namespace cc