| // Copyright 2016 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "cc/layers/layer_list_iterator.h" |
| |
| #include <memory> |
| |
| #include "base/containers/adapters.h" |
| #include "cc/animation/animation_host.h" |
| #include "cc/test/fake_impl_task_runner_provider.h" |
| #include "cc/test/fake_layer_tree_frame_sink.h" |
| #include "cc/test/fake_layer_tree_host.h" |
| #include "cc/test/fake_layer_tree_host_impl.h" |
| #include "cc/test/test_task_graph_runner.h" |
| #include "cc/trees/layer_tree_impl.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace cc { |
| namespace { |
| |
| // Layer version unit tests |
| |
| TEST(LayerListIteratorTest, VerifyTraversalOrder) { |
| // Unfortunate preamble. |
| FakeLayerTreeHostClient client; |
| TestTaskGraphRunner task_graph_runner; |
| auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN); |
| std::unique_ptr<FakeLayerTreeHost> host_ptr = FakeLayerTreeHost::Create( |
| &client, &task_graph_runner, animation_host.get()); |
| FakeLayerTreeHost* host = host_ptr.get(); |
| |
| // This test constructs the following tree. |
| // 1 |
| // +-2 |
| // | +-3 |
| // | +-4 |
| // + 5 |
| // +-6 |
| // +-7 |
| // We expect to visit all seven layers in that order. |
| scoped_refptr<Layer> layer1 = Layer::Create(); |
| scoped_refptr<Layer> layer2 = Layer::Create(); |
| scoped_refptr<Layer> layer3 = Layer::Create(); |
| scoped_refptr<Layer> layer4 = Layer::Create(); |
| scoped_refptr<Layer> layer5 = Layer::Create(); |
| scoped_refptr<Layer> layer6 = Layer::Create(); |
| scoped_refptr<Layer> layer7 = Layer::Create(); |
| |
| std::unordered_map<int, int> layer_id_to_order; |
| layer_id_to_order[layer1->id()] = 1; |
| layer_id_to_order[layer2->id()] = 2; |
| layer_id_to_order[layer3->id()] = 3; |
| layer_id_to_order[layer4->id()] = 4; |
| layer_id_to_order[layer5->id()] = 5; |
| layer_id_to_order[layer6->id()] = 6; |
| layer_id_to_order[layer7->id()] = 7; |
| |
| layer2->AddChild(std::move(layer3)); |
| layer2->AddChild(std::move(layer4)); |
| |
| layer5->AddChild(std::move(layer6)); |
| layer5->AddChild(std::move(layer7)); |
| |
| layer1->AddChild(std::move(layer2)); |
| layer1->AddChild(std::move(layer5)); |
| |
| host->SetRootLayer(std::move(layer1)); |
| |
| int i = 1; |
| for (auto* layer : *host) { |
| EXPECT_EQ(i++, layer_id_to_order[layer->id()]); |
| } |
| EXPECT_EQ(8, i); |
| } |
| |
| TEST(LayerListIteratorTest, VerifySingleLayer) { |
| // Unfortunate preamble. |
| FakeLayerTreeHostClient client; |
| TestTaskGraphRunner task_graph_runner; |
| auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN); |
| std::unique_ptr<FakeLayerTreeHost> host_ptr = FakeLayerTreeHost::Create( |
| &client, &task_graph_runner, animation_host.get()); |
| FakeLayerTreeHost* host = host_ptr.get(); |
| |
| // This test constructs a tree consisting of a single layer. |
| scoped_refptr<Layer> layer1 = Layer::Create(); |
| std::unordered_map<int, int> layer_id_to_order; |
| layer_id_to_order[layer1->id()] = 1; |
| host->SetRootLayer(std::move(layer1)); |
| |
| int i = 1; |
| for (auto* layer : *host) { |
| EXPECT_EQ(i++, layer_id_to_order[layer->id()]); |
| } |
| EXPECT_EQ(2, i); |
| } |
| |
| TEST(LayerListIteratorTest, VerifyNullFirstLayer) { |
| // Ensures that if an iterator is constructed with a nullptr, that it can be |
| // iterated without issue and that it remains equal to any other |
| // null-initialized iterator. |
| LayerListIterator<Layer> it(nullptr); |
| LayerListIterator<Layer> end(nullptr); |
| |
| EXPECT_EQ(it, end); |
| ++it; |
| EXPECT_EQ(it, end); |
| } |
| |
| TEST(LayerListReverseIteratorTest, VerifyTraversalOrder) { |
| // Unfortunate preamble. |
| FakeLayerTreeHostClient client; |
| TestTaskGraphRunner task_graph_runner; |
| auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN); |
| std::unique_ptr<FakeLayerTreeHost> host_ptr = FakeLayerTreeHost::Create( |
| &client, &task_graph_runner, animation_host.get()); |
| FakeLayerTreeHost* host = host_ptr.get(); |
| |
| // This test constructs the following tree. |
| // 1 |
| // +-2 |
| // | +-3 |
| // | +-4 |
| // + 5 |
| // +-6 |
| // +-7 |
| // We expect to visit all seven layers in reverse order. |
| scoped_refptr<Layer> layer1 = Layer::Create(); |
| scoped_refptr<Layer> layer2 = Layer::Create(); |
| scoped_refptr<Layer> layer3 = Layer::Create(); |
| scoped_refptr<Layer> layer4 = Layer::Create(); |
| scoped_refptr<Layer> layer5 = Layer::Create(); |
| scoped_refptr<Layer> layer6 = Layer::Create(); |
| scoped_refptr<Layer> layer7 = Layer::Create(); |
| |
| std::unordered_map<int, int> layer_id_to_order; |
| layer_id_to_order[layer1->id()] = 1; |
| layer_id_to_order[layer2->id()] = 2; |
| layer_id_to_order[layer3->id()] = 3; |
| layer_id_to_order[layer4->id()] = 4; |
| layer_id_to_order[layer5->id()] = 5; |
| layer_id_to_order[layer6->id()] = 6; |
| layer_id_to_order[layer7->id()] = 7; |
| |
| layer2->AddChild(std::move(layer3)); |
| layer2->AddChild(std::move(layer4)); |
| |
| layer5->AddChild(std::move(layer6)); |
| layer5->AddChild(std::move(layer7)); |
| |
| layer1->AddChild(std::move(layer2)); |
| layer1->AddChild(std::move(layer5)); |
| |
| host->SetRootLayer(std::move(layer1)); |
| |
| int i = 7; |
| |
| for (auto* layer : base::Reversed(*host)) { |
| EXPECT_EQ(i--, layer_id_to_order[layer->id()]); |
| } |
| |
| EXPECT_EQ(0, i); |
| } |
| |
| TEST(LayerListReverseIteratorTest, VerifySingleLayer) { |
| // Unfortunate preamble. |
| FakeLayerTreeHostClient client; |
| TestTaskGraphRunner task_graph_runner; |
| auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN); |
| std::unique_ptr<FakeLayerTreeHost> host_ptr = FakeLayerTreeHost::Create( |
| &client, &task_graph_runner, animation_host.get()); |
| FakeLayerTreeHost* host = host_ptr.get(); |
| |
| // This test constructs a tree consisting of a single layer. |
| scoped_refptr<Layer> layer1 = Layer::Create(); |
| std::unordered_map<int, int> layer_id_to_order; |
| layer_id_to_order[layer1->id()] = 1; |
| host->SetRootLayer(std::move(layer1)); |
| |
| int i = 1; |
| for (auto* layer : base::Reversed(*host)) { |
| EXPECT_EQ(i--, layer_id_to_order[layer->id()]); |
| } |
| EXPECT_EQ(0, i); |
| } |
| |
| TEST(LayerListReverseIteratorTest, VerifyNullFirstLayer) { |
| // Ensures that if an iterator is constructed with a nullptr, that it can be |
| // iterated without issue and that it remains equal to any other |
| // null-initialized iterator. |
| LayerListReverseIterator<Layer> it(nullptr); |
| LayerListReverseIterator<Layer> end(nullptr); |
| |
| EXPECT_EQ(it, end); |
| ++it; |
| EXPECT_EQ(it, end); |
| } |
| |
| // LayerImpl version unit tests |
| |
| TEST(LayerListIteratorTest, VerifyTraversalOrderImpl) { |
| // Unfortunate preamble. |
| FakeImplTaskRunnerProvider task_runner_provider; |
| TestTaskGraphRunner task_graph_runner; |
| std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink = |
| FakeLayerTreeFrameSink::Create3d(); |
| FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); |
| host_impl.SetVisible(true); |
| EXPECT_TRUE(host_impl.InitializeFrameSink(layer_tree_frame_sink.get())); |
| |
| // This test constructs the following tree. |
| // 1 |
| // +-2 |
| // | +-3 |
| // | +-4 |
| // + 5 |
| // +-6 |
| // +-7 |
| // We expect to visit all seven layers in that order. |
| std::unique_ptr<LayerImpl> layer1 = |
| LayerImpl::Create(host_impl.active_tree(), 1); |
| std::unique_ptr<LayerImpl> layer2 = |
| LayerImpl::Create(host_impl.active_tree(), 2); |
| std::unique_ptr<LayerImpl> layer3 = |
| LayerImpl::Create(host_impl.active_tree(), 3); |
| std::unique_ptr<LayerImpl> layer4 = |
| LayerImpl::Create(host_impl.active_tree(), 4); |
| std::unique_ptr<LayerImpl> layer5 = |
| LayerImpl::Create(host_impl.active_tree(), 5); |
| std::unique_ptr<LayerImpl> layer6 = |
| LayerImpl::Create(host_impl.active_tree(), 6); |
| std::unique_ptr<LayerImpl> layer7 = |
| LayerImpl::Create(host_impl.active_tree(), 7); |
| |
| layer2->test_properties()->AddChild(std::move(layer3)); |
| layer2->test_properties()->AddChild(std::move(layer4)); |
| |
| layer5->test_properties()->AddChild(std::move(layer6)); |
| layer5->test_properties()->AddChild(std::move(layer7)); |
| |
| layer1->test_properties()->AddChild(std::move(layer2)); |
| layer1->test_properties()->AddChild(std::move(layer5)); |
| |
| host_impl.active_tree()->SetRootLayerForTesting(std::move(layer1)); |
| host_impl.active_tree()->BuildLayerListForTesting(); |
| |
| int i = 1; |
| for (auto* layer : *host_impl.active_tree()) { |
| EXPECT_EQ(i++, layer->id()); |
| } |
| EXPECT_EQ(8, i); |
| } |
| |
| TEST(LayerListIteratorTest, VerifySingleLayerImpl) { |
| // Unfortunate preamble. |
| FakeImplTaskRunnerProvider task_runner_provider; |
| TestTaskGraphRunner task_graph_runner; |
| std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink = |
| FakeLayerTreeFrameSink::Create3d(); |
| FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); |
| host_impl.SetVisible(true); |
| EXPECT_TRUE(host_impl.InitializeFrameSink(layer_tree_frame_sink.get())); |
| |
| // This test constructs a tree consisting of a single layer. |
| std::unique_ptr<LayerImpl> layer1 = |
| LayerImpl::Create(host_impl.active_tree(), 1); |
| host_impl.active_tree()->SetRootLayerForTesting(std::move(layer1)); |
| host_impl.active_tree()->BuildLayerListForTesting(); |
| |
| int i = 1; |
| for (auto* layer : *host_impl.active_tree()) { |
| EXPECT_EQ(i++, layer->id()); |
| } |
| EXPECT_EQ(2, i); |
| } |
| |
| TEST(LayerListIteratorTest, VerifyNullFirstLayerImpl) { |
| // Ensures that if an iterator is constructed with a nullptr, that it can be |
| // iterated without issue and that it remains equal to any other |
| // null-initialized iterator. |
| LayerListIterator<LayerImpl> it(nullptr); |
| LayerListIterator<LayerImpl> end(nullptr); |
| |
| EXPECT_EQ(it, end); |
| ++it; |
| EXPECT_EQ(it, end); |
| } |
| |
| TEST(LayerListReverseIteratorTest, VerifyTraversalOrderImpl) { |
| // Unfortunate preamble. |
| FakeImplTaskRunnerProvider task_runner_provider; |
| TestTaskGraphRunner task_graph_runner; |
| std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink = |
| FakeLayerTreeFrameSink::Create3d(); |
| FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); |
| host_impl.SetVisible(true); |
| EXPECT_TRUE(host_impl.InitializeFrameSink(layer_tree_frame_sink.get())); |
| |
| // This test constructs the following tree. |
| // 1 |
| // +-2 |
| // | +-3 |
| // | +-4 |
| // + 5 |
| // +-6 |
| // +-7 |
| // We expect to visit all seven layers in reverse order. |
| std::unique_ptr<LayerImpl> layer1 = |
| LayerImpl::Create(host_impl.active_tree(), 1); |
| std::unique_ptr<LayerImpl> layer2 = |
| LayerImpl::Create(host_impl.active_tree(), 2); |
| std::unique_ptr<LayerImpl> layer3 = |
| LayerImpl::Create(host_impl.active_tree(), 3); |
| std::unique_ptr<LayerImpl> layer4 = |
| LayerImpl::Create(host_impl.active_tree(), 4); |
| std::unique_ptr<LayerImpl> layer5 = |
| LayerImpl::Create(host_impl.active_tree(), 5); |
| std::unique_ptr<LayerImpl> layer6 = |
| LayerImpl::Create(host_impl.active_tree(), 6); |
| std::unique_ptr<LayerImpl> layer7 = |
| LayerImpl::Create(host_impl.active_tree(), 7); |
| |
| layer2->test_properties()->AddChild(std::move(layer3)); |
| layer2->test_properties()->AddChild(std::move(layer4)); |
| |
| layer5->test_properties()->AddChild(std::move(layer6)); |
| layer5->test_properties()->AddChild(std::move(layer7)); |
| |
| layer1->test_properties()->AddChild(std::move(layer2)); |
| layer1->test_properties()->AddChild(std::move(layer5)); |
| |
| host_impl.active_tree()->SetRootLayerForTesting(std::move(layer1)); |
| host_impl.active_tree()->BuildLayerListForTesting(); |
| |
| int i = 7; |
| |
| for (auto* layer : base::Reversed(*host_impl.active_tree())) { |
| EXPECT_EQ(i--, layer->id()); |
| } |
| |
| EXPECT_EQ(0, i); |
| } |
| |
| TEST(LayerListReverseIteratorTest, VerifySingleLayerImpl) { |
| // Unfortunate preamble. |
| FakeImplTaskRunnerProvider task_runner_provider; |
| TestTaskGraphRunner task_graph_runner; |
| std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink = |
| FakeLayerTreeFrameSink::Create3d(); |
| FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); |
| host_impl.SetVisible(true); |
| EXPECT_TRUE(host_impl.InitializeFrameSink(layer_tree_frame_sink.get())); |
| |
| // This test constructs a tree consisting of a single layer. |
| std::unique_ptr<LayerImpl> layer1 = |
| LayerImpl::Create(host_impl.active_tree(), 1); |
| host_impl.active_tree()->SetRootLayerForTesting(std::move(layer1)); |
| host_impl.active_tree()->BuildLayerListForTesting(); |
| |
| int i = 1; |
| for (auto* layer : base::Reversed(*host_impl.active_tree())) { |
| EXPECT_EQ(i--, layer->id()); |
| } |
| EXPECT_EQ(0, i); |
| } |
| |
| TEST(LayerListReverseIteratorTest, VerifyNullFirstLayerImpl) { |
| // Ensures that if an iterator is constructed with a nullptr, that it can be |
| // iterated without issue and that it remains equal to any other |
| // null-initialized iterator. |
| LayerListReverseIterator<LayerImpl> it(nullptr); |
| LayerListReverseIterator<LayerImpl> end(nullptr); |
| |
| EXPECT_EQ(it, end); |
| ++it; |
| EXPECT_EQ(it, end); |
| } |
| |
| } // namespace |
| } // namespace cc |