1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
|
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <memory>
#include <utility>
#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_->GetPendingCommitState(),
layer_tree_host_->GetThreadUnsafeCommitState(),
host_impl_.pending_tree());
}
protected:
void SetUp() override {
animation_host_ = AnimationHost::CreateForTesting(ThreadInstance::kMain);
layer_tree_host_ = FakeLayerTreeHost::Create(
&fake_client_, &task_graph_runner_, animation_host_.get());
layer_tree_host_->SetViewportRectAndScale(gfx::Rect(10, 10), 1.f,
viz::LocalSurfaceId());
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_->ClearPendingLayerCommitStates();
auto commit_state = layer_tree_host_->WillCommit(/*completion_event=*/nullptr,
/*has_updates=*/true);
layer_tree_host_->CommitComplete(commit_state->source_frame_number,
{base::TimeTicks(), base::TimeTicks::Now()});
layer_tree_host_->property_trees()->set_needs_rebuild(false);
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(
const_cast<const FakeLayerTreeHost*>(layer_tree_host_.get())
->pending_commit_state()
->layers_that_should_push_properties.contains(mirrored.get()));
layer_tree_host_->property_trees()->set_needs_rebuild(false);
// 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(
const_cast<const FakeLayerTreeHost*>(layer_tree_host_.get())
->pending_commit_state()
->layers_that_should_push_properties.contains(mirrored.get()));
layer_tree_host_->property_trees()->set_needs_rebuild(false);
// 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, const_cast<const FakeLayerTreeHost*>(layer_tree_host_.get())
->pending_commit_state()
->layers_that_should_push_properties.size());
layer_tree_host_->property_trees()->set_needs_rebuild(false);
// 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(
const_cast<const FakeLayerTreeHost*>(layer_tree_host_.get())
->pending_commit_state()
->layers_that_should_push_properties.contains(mirrored.get()));
layer_tree_host_->property_trees()->set_needs_rebuild(false);
mirrored->SetLayerTreeHost(nullptr);
}
} // namespace
} // namespace cc
|