blob: 9a0beb13ee9f13f7d63b4ccbe77b8f0e742d295a [file] [log] [blame]
// Copyright 2019 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 <memory>
#include "cc/animation/animation_host.h"
#include "cc/layers/mirror_layer.h"
#include "cc/layers/mirror_layer_impl.h"
#include "cc/test/fake_impl_task_runner_provider.h"
#include "cc/test/fake_layer_tree_host.h"
#include "cc/test/fake_layer_tree_host_client.h"
#include "cc/test/fake_layer_tree_host_impl.h"
#include "cc/test/test_task_graph_runner.h"
#include "cc/trees/tree_synchronizer.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace cc {
namespace {
class MirrorLayerTest : public testing::Test {
public:
MirrorLayerTest() : host_impl_(&task_runner_provider_, &task_graph_runner_) {}
// Synchronizes |layer_tree_host_| and |host_impl_| and pushes surface ids.
void SynchronizeTrees() {
TreeSynchronizer::PushLayerProperties(layer_tree_host_.get(),
host_impl_.pending_tree());
}
protected:
void SetUp() override {
animation_host_ = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
layer_tree_host_ = FakeLayerTreeHost::Create(
&fake_client_, &task_graph_runner_, animation_host_.get());
layer_tree_host_->SetViewportRectAndScale(gfx::Rect(10, 10), 1.f,
viz::LocalSurfaceIdAllocation());
host_impl_.CreatePendingTree();
}
void TearDown() override {
layer_tree_host_->SetRootLayer(nullptr);
layer_tree_host_ = nullptr;
}
FakeLayerTreeHostClient fake_client_;
FakeImplTaskRunnerProvider task_runner_provider_;
TestTaskGraphRunner task_graph_runner_;
std::unique_ptr<AnimationHost> animation_host_;
std::unique_ptr<FakeLayerTreeHost> layer_tree_host_;
FakeLayerTreeHostImpl host_impl_;
};
// This test verifies that MirrorLayer properties are pushed across to
// MirrorLayerImpl.
TEST_F(MirrorLayerTest, PushProperties) {
auto root = Layer::Create();
layer_tree_host_->SetRootLayer(root);
auto mirrored = Layer::Create();
root->AddChild(mirrored);
auto mirror = MirrorLayer::Create(mirrored);
root->AddChild(mirror);
EXPECT_EQ(1, mirrored->mirror_count());
EXPECT_EQ(mirrored.get(), mirror->mirrored_layer());
auto root_impl = LayerImpl::Create(host_impl_.pending_tree(), root->id());
auto mirrored_impl =
LayerImpl::Create(host_impl_.pending_tree(), mirrored->id());
auto mirror_impl =
MirrorLayerImpl::Create(host_impl_.pending_tree(), mirror->id());
// Verify that impl layers have default property values.
EXPECT_EQ(0, mirror_impl->mirrored_layer_id());
SynchronizeTrees();
// Verify that property values are pushed to impl layers.
EXPECT_EQ(mirrored_impl->id(), mirror_impl->mirrored_layer_id());
}
// This test verifies adding/removing mirror layers updates mirror count
// properly and sets appropriate bits on the layer tree host.
TEST_F(MirrorLayerTest, MirrorCount) {
auto mirrored = Layer::Create();
mirrored->SetLayerTreeHost(layer_tree_host_.get());
layer_tree_host_->property_trees()->needs_rebuild = false;
layer_tree_host_->ClearLayersThatShouldPushProperties();
EXPECT_EQ(0, mirrored->mirror_count());
// Creating the first mirror layer should trigger property trees rebuild.
auto mirror1 = MirrorLayer::Create(mirrored);
EXPECT_EQ(1, mirrored->mirror_count());
EXPECT_EQ(mirrored.get(), mirror1->mirrored_layer());
EXPECT_TRUE(layer_tree_host_->property_trees()->needs_rebuild);
EXPECT_TRUE(base::Contains(layer_tree_host_->LayersThatShouldPushProperties(),
mirrored.get()));
layer_tree_host_->property_trees()->needs_rebuild = false;
layer_tree_host_->ClearLayersThatShouldPushProperties();
// Creating a second mirror layer should not trigger property trees rebuild.
auto mirror2 = MirrorLayer::Create(mirrored);
EXPECT_EQ(2, mirrored->mirror_count());
EXPECT_EQ(mirrored.get(), mirror2->mirrored_layer());
EXPECT_FALSE(layer_tree_host_->property_trees()->needs_rebuild);
EXPECT_TRUE(base::Contains(layer_tree_host_->LayersThatShouldPushProperties(),
mirrored.get()));
layer_tree_host_->property_trees()->needs_rebuild = false;
layer_tree_host_->ClearLayersThatShouldPushProperties();
// Destroying one of the mirror layers should not trigger property trees
// rebuild.
mirror1->RemoveFromParent();
mirror1 = nullptr;
EXPECT_EQ(1, mirrored->mirror_count());
EXPECT_FALSE(layer_tree_host_->property_trees()->needs_rebuild);
EXPECT_EQ(1u, layer_tree_host_->LayersThatShouldPushProperties().size());
layer_tree_host_->property_trees()->needs_rebuild = false;
layer_tree_host_->ClearLayersThatShouldPushProperties();
// Destroying the only remaining mirror layer should trigger property trees
// rebuild.
mirror2->RemoveFromParent();
mirror2 = nullptr;
EXPECT_EQ(0, mirrored->mirror_count());
EXPECT_TRUE(layer_tree_host_->property_trees()->needs_rebuild);
EXPECT_TRUE(base::Contains(layer_tree_host_->LayersThatShouldPushProperties(),
mirrored.get()));
mirrored->SetLayerTreeHost(nullptr);
}
} // namespace
} // namespace cc