1 // Copyright 2013 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/benchmarks/micro_benchmark_controller.h"
9 #include "base/functional/bind.h"
10 #include "base/functional/callback.h"
11 #include "base/functional/callback_helpers.h"
12 #include "base/memory/ptr_util.h"
13 #include "base/run_loop.h"
14 #include "base/task/single_thread_task_runner.h"
15 #include "cc/animation/animation_host.h"
16 #include "cc/benchmarks/micro_benchmark.h"
17 #include "cc/layers/layer.h"
18 #include "cc/test/fake_impl_task_runner_provider.h"
19 #include "cc/test/fake_layer_tree_host.h"
20 #include "cc/test/fake_layer_tree_host_impl.h"
21 #include "cc/test/fake_proxy.h"
22 #include "cc/test/test_task_graph_runner.h"
23 #include "testing/gtest/include/gtest/gtest.h"
28 class MicroBenchmarkControllerTest : public testing::Test {
30 void SetUp() override {
31 impl_task_runner_provider_ =
32 base::WrapUnique(new FakeImplTaskRunnerProvider);
33 layer_tree_host_impl_ = std::make_unique<FakeLayerTreeHostImpl>(
34 impl_task_runner_provider_.get(), &task_graph_runner_);
36 animation_host_ = AnimationHost::CreateForTesting(ThreadInstance::kMain);
37 layer_tree_host_ = FakeLayerTreeHost::Create(
38 &layer_tree_host_client_, &task_graph_runner_, animation_host_.get());
39 layer_tree_host_->SetRootLayer(Layer::Create());
40 layer_tree_host_->InitializeForTesting(
41 TaskRunnerProvider::Create(
42 base::SingleThreadTaskRunner::GetCurrentDefault(), nullptr),
43 std::unique_ptr<Proxy>(new FakeProxy));
46 void TearDown() override {
47 layer_tree_host_impl_ = nullptr;
48 layer_tree_host_ = nullptr;
49 impl_task_runner_provider_ = nullptr;
50 animation_host_ = nullptr;
53 FakeLayerTreeHostClient layer_tree_host_client_;
54 TestTaskGraphRunner task_graph_runner_;
55 std::unique_ptr<AnimationHost> animation_host_;
56 std::unique_ptr<FakeLayerTreeHost> layer_tree_host_;
57 std::unique_ptr<FakeLayerTreeHostImpl> layer_tree_host_impl_;
58 std::unique_ptr<FakeImplTaskRunnerProvider> impl_task_runner_provider_;
61 void IncrementCallCount(int* count, base::Value::Dict value) {
65 TEST_F(MicroBenchmarkControllerTest, ScheduleFail) {
66 int id = layer_tree_host_->ScheduleMicroBenchmark(
67 "non_existant_benchmark", base::Value::Dict(), base::DoNothing());
71 TEST_F(MicroBenchmarkControllerTest, CommitScheduled) {
72 layer_tree_host_->reset_needs_commit();
73 int id = layer_tree_host_->ScheduleMicroBenchmark(
74 "unittest_only_benchmark", base::Value::Dict(), base::DoNothing());
76 EXPECT_TRUE(layer_tree_host_->needs_commit());
79 TEST_F(MicroBenchmarkControllerTest, BenchmarkRan) {
81 int id = layer_tree_host_->ScheduleMicroBenchmark(
82 "unittest_only_benchmark", base::Value::Dict(),
83 base::BindOnce(&IncrementCallCount, base::Unretained(&run_count)));
86 layer_tree_host_->UpdateLayers();
88 EXPECT_EQ(1, run_count);
91 TEST_F(MicroBenchmarkControllerTest, MultipleBenchmarkRan) {
93 int id = layer_tree_host_->ScheduleMicroBenchmark(
94 "unittest_only_benchmark", base::Value::Dict(),
95 base::BindOnce(&IncrementCallCount, base::Unretained(&run_count)));
97 id = layer_tree_host_->ScheduleMicroBenchmark(
98 "unittest_only_benchmark", base::Value::Dict(),
99 base::BindOnce(&IncrementCallCount, base::Unretained(&run_count)));
102 layer_tree_host_->UpdateLayers();
104 EXPECT_EQ(2, run_count);
106 id = layer_tree_host_->ScheduleMicroBenchmark(
107 "unittest_only_benchmark", base::Value::Dict(),
108 base::BindOnce(&IncrementCallCount, base::Unretained(&run_count)));
110 id = layer_tree_host_->ScheduleMicroBenchmark(
111 "unittest_only_benchmark", base::Value::Dict(),
112 base::BindOnce(&IncrementCallCount, base::Unretained(&run_count)));
115 layer_tree_host_->UpdateLayers();
116 EXPECT_EQ(4, run_count);
118 layer_tree_host_->UpdateLayers();
119 EXPECT_EQ(4, run_count);
122 TEST_F(MicroBenchmarkControllerTest, BenchmarkImplRan) {
124 base::Value::Dict settings;
125 settings.Set("run_benchmark_impl", true);
127 // Schedule a main thread benchmark.
128 int id = layer_tree_host_->ScheduleMicroBenchmark(
129 "unittest_only_benchmark", std::move(settings),
130 base::BindOnce(&IncrementCallCount, base::Unretained(&run_count)));
133 // Scheduling benchmarks on the impl thread is usually done during
134 // LayerTreeHostImpl::FinishCommit().
135 for (auto& benchmark : layer_tree_host_->GetMicroBenchmarkController()
136 ->CreateImplBenchmarks()) {
137 layer_tree_host_impl_->ScheduleMicroBenchmark(std::move(benchmark));
139 layer_tree_host_impl_->CommitComplete();
141 // Make sure all posted messages run.
142 base::RunLoop().RunUntilIdle();
144 EXPECT_EQ(1, run_count);
147 TEST_F(MicroBenchmarkControllerTest, SendMessage) {
148 // Send valid message to invalid benchmark (id = 0)
149 base::Value::Dict message;
150 message.Set("can_handle", true);
151 bool message_handled =
152 layer_tree_host_->SendMessageToMicroBenchmark(0, std::move(message));
153 EXPECT_FALSE(message_handled);
155 // Schedule a benchmark
157 int id = layer_tree_host_->ScheduleMicroBenchmark(
158 "unittest_only_benchmark", base::Value::Dict(),
159 base::BindOnce(&IncrementCallCount, base::Unretained(&run_count)));
162 // Send valid message to valid benchmark
164 message.Set("can_handle", true);
166 layer_tree_host_->SendMessageToMicroBenchmark(id, std::move(message));
167 EXPECT_TRUE(message_handled);
169 // Send invalid message to valid benchmark
171 message.Set("can_handle", false);
173 layer_tree_host_->SendMessageToMicroBenchmark(id, std::move(message));
174 EXPECT_FALSE(message_handled);