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.
8 #include "base/lazy_instance.h"
9 #include "base/location.h"
10 #include "base/threading/thread_task_runner_handle.h"
11 #include "base/time/time.h"
12 #include "base/timer/lap_timer.h"
13 #include "cc/raster/raster_buffer.h"
14 #include "cc/test/fake_impl_task_runner_provider.h"
15 #include "cc/test/fake_layer_tree_frame_sink.h"
16 #include "cc/test/fake_layer_tree_frame_sink_client.h"
17 #include "cc/test/fake_layer_tree_host_impl.h"
18 #include "cc/test/fake_picture_layer_impl.h"
19 #include "cc/test/fake_raster_source.h"
20 #include "cc/test/fake_tile_manager.h"
21 #include "cc/test/fake_tile_manager_client.h"
22 #include "cc/test/fake_tile_task_manager.h"
23 #include "cc/test/layer_test_common.h"
24 #include "cc/test/test_layer_tree_host_base.h"
25 #include "cc/test/test_task_graph_runner.h"
26 #include "cc/test/test_tile_priorities.h"
27 #include "cc/tiles/tile.h"
28 #include "cc/tiles/tile_priority.h"
29 #include "cc/trees/layer_tree_impl.h"
30 #include "components/viz/test/begin_frame_args_test.h"
31 #include "testing/gtest/include/gtest/gtest.h"
32 #include "testing/perf/perf_result_reporter.h"
37 static const int kTimeLimitMillis = 2000;
38 static const int kWarmupRuns = 5;
39 static const int kTimeCheckInterval = 10;
41 class TileManagerPerfTest : public TestLayerTreeHostBase {
45 base::Milliseconds(kTimeLimitMillis),
46 kTimeCheckInterval) {}
48 void InitializeFrameSink() override {
49 host_impl()->SetVisible(true);
50 host_impl()->InitializeFrameSink(layer_tree_frame_sink());
51 tile_manager()->SetTileTaskManagerForTesting(
52 std::make_unique<FakeTileTaskManagerImpl>());
55 void SetupDefaultTreesWithFixedTileSize(const gfx::Size& layer_bounds,
56 const gfx::Size& tile_size) {
57 scoped_refptr<FakeRasterSource> pending_raster_source =
58 FakeRasterSource::CreateFilledWithImages(layer_bounds);
59 scoped_refptr<FakeRasterSource> active_raster_source =
60 FakeRasterSource::CreateFilledWithImages(layer_bounds);
62 SetupPendingTree(std::move(active_raster_source), tile_size, Region());
64 SetupPendingTree(std::move(pending_raster_source), tile_size, Region());
67 perf_test::PerfResultReporter SetUpReporter(const std::string& story_name) {
68 perf_test::PerfResultReporter reporter("tile_manager", story_name);
69 reporter.RegisterImportantMetric("_raster_tile_queue_construct", "runs/s");
70 reporter.RegisterImportantMetric("_raster_tile_queue_construct_and_iterate",
72 reporter.RegisterImportantMetric("_eviction_tile_queue_construct",
74 reporter.RegisterImportantMetric(
75 "_eviction_tile_queue_construct_and_iterate", "runs/s");
79 void RunRasterQueueConstructTest(const std::string& test_name,
81 TreePriority priorities[] = {SAME_PRIORITY_FOR_BOTH_TREES,
82 SMOOTHNESS_TAKES_PRIORITY,
83 NEW_CONTENT_TAKES_PRIORITY};
84 int priority_count = 0;
86 std::vector<FakePictureLayerImpl*> layers = CreateLayers(layer_count, 10);
87 for (auto* layer : layers)
92 std::unique_ptr<RasterTilePriorityQueue> queue(
93 host_impl()->BuildRasterQueue(priorities[priority_count],
94 RasterTilePriorityQueue::Type::ALL));
95 priority_count = (priority_count + 1) % std::size(priorities);
97 } while (!timer_.HasTimeLimitExpired());
99 perf_test::PerfResultReporter reporter = SetUpReporter(test_name);
100 reporter.AddResult("_raster_tile_queue_construct", timer_.LapsPerSecond());
103 void RunRasterQueueConstructAndIterateTest(const std::string& test_name,
106 TreePriority priorities[] = {SAME_PRIORITY_FOR_BOTH_TREES,
107 SMOOTHNESS_TAKES_PRIORITY,
108 NEW_CONTENT_TAKES_PRIORITY};
110 std::vector<FakePictureLayerImpl*> layers = CreateLayers(layer_count, 100);
111 for (auto* layer : layers)
112 layer->UpdateTiles();
114 int priority_count = 0;
117 int count = tile_count;
118 std::unique_ptr<RasterTilePriorityQueue> queue(
119 host_impl()->BuildRasterQueue(priorities[priority_count],
120 RasterTilePriorityQueue::Type::ALL));
122 ASSERT_FALSE(queue->IsEmpty());
123 ASSERT_TRUE(queue->Top().tile());
126 priority_count = (priority_count + 1) % std::size(priorities);
128 } while (!timer_.HasTimeLimitExpired());
130 perf_test::PerfResultReporter reporter = SetUpReporter(test_name);
131 reporter.AddResult("_raster_tile_queue_construct_and_iterate",
132 timer_.LapsPerSecond());
135 void RunEvictionQueueConstructTest(const std::string& test_name,
137 TreePriority priorities[] = {SAME_PRIORITY_FOR_BOTH_TREES,
138 SMOOTHNESS_TAKES_PRIORITY,
139 NEW_CONTENT_TAKES_PRIORITY};
140 int priority_count = 0;
142 std::vector<FakePictureLayerImpl*> layers = CreateLayers(layer_count, 10);
143 for (auto* layer : layers) {
144 layer->UpdateTiles();
145 for (size_t i = 0; i < layer->num_tilings(); ++i) {
146 tile_manager()->InitializeTilesWithResourcesForTesting(
147 layer->tilings()->tiling_at(i)->AllTilesForTesting());
153 std::unique_ptr<EvictionTilePriorityQueue> queue(
154 host_impl()->BuildEvictionQueue(priorities[priority_count]));
155 priority_count = (priority_count + 1) % std::size(priorities);
157 } while (!timer_.HasTimeLimitExpired());
159 perf_test::PerfResultReporter reporter = SetUpReporter(test_name);
160 reporter.AddResult("_eviction_tile_queue_construct",
161 timer_.LapsPerSecond());
164 void RunEvictionQueueConstructAndIterateTest(const std::string& test_name,
167 TreePriority priorities[] = {SAME_PRIORITY_FOR_BOTH_TREES,
168 SMOOTHNESS_TAKES_PRIORITY,
169 NEW_CONTENT_TAKES_PRIORITY};
170 int priority_count = 0;
172 std::vector<FakePictureLayerImpl*> layers =
173 CreateLayers(layer_count, tile_count);
174 for (auto* layer : layers) {
175 layer->UpdateTiles();
176 for (size_t i = 0; i < layer->num_tilings(); ++i) {
177 tile_manager()->InitializeTilesWithResourcesForTesting(
178 layer->tilings()->tiling_at(i)->AllTilesForTesting());
184 int count = tile_count;
185 std::unique_ptr<EvictionTilePriorityQueue> queue(
186 host_impl()->BuildEvictionQueue(priorities[priority_count]));
188 ASSERT_FALSE(queue->IsEmpty());
189 ASSERT_TRUE(queue->Top().tile());
192 priority_count = (priority_count + 1) % std::size(priorities);
194 } while (!timer_.HasTimeLimitExpired());
196 perf_test::PerfResultReporter reporter = SetUpReporter(test_name);
197 reporter.AddResult("_eviction_tile_queue_construct_and_iterate",
198 timer_.LapsPerSecond());
201 std::vector<FakePictureLayerImpl*> CreateLayers(int layer_count,
202 int num_tiles_in_high_res) {
203 // Compute the width/height required for high res to get
204 // num_tiles_in_high_res tiles.
205 float width = std::sqrt(static_cast<float>(num_tiles_in_high_res));
206 float height = num_tiles_in_high_res / width;
208 // Adjust the width and height to account for the fact that tiles
209 // are bigger than 1x1.
210 LayerListSettings settings;
211 width *= settings.default_tile_size.width();
212 height *= settings.default_tile_size.height();
214 // Ensure that we start with blank trees and no tiles.
217 gfx::Size layer_bounds(width, height);
218 gfx::Rect viewport(width / 5, height / 5);
219 host_impl()->active_tree()->SetDeviceViewportRect(viewport);
220 SetupDefaultTreesWithFixedTileSize(layer_bounds,
221 settings.default_tile_size);
223 std::vector<FakePictureLayerImpl*> layers;
225 // Pending layer counts as one layer.
226 layers.push_back(pending_layer());
228 // Create the rest of the layers as children of the root layer.
229 scoped_refptr<FakeRasterSource> raster_source =
230 FakeRasterSource::CreateFilledWithImages(layer_bounds);
231 while (static_cast<int>(layers.size()) < layer_count) {
232 auto* child_layer = AddLayer<FakePictureLayerImpl>(
233 host_impl()->pending_tree(), raster_source);
234 child_layer->SetBounds(layer_bounds);
235 child_layer->SetDrawsContent(true);
236 layers.push_back(child_layer);
237 CopyProperties(pending_layer(), child_layer);
240 // Property trees need to be rebuilt because layers were added above.
241 host_impl()->pending_tree()->set_needs_update_draw_properties();
242 UpdateDrawProperties(host_impl()->pending_tree());
243 for (FakePictureLayerImpl* layer : layers)
244 layer->CreateAllTiles();
249 GlobalStateThatImpactsTilePriority GlobalStateForTest() {
250 GlobalStateThatImpactsTilePriority state;
251 gfx::Size tile_size = LayerTreeSettings().default_tile_size;
252 state.soft_memory_limit_in_bytes =
254 static_cast<size_t>(tile_size.width() * tile_size.height());
255 state.hard_memory_limit_in_bytes = state.soft_memory_limit_in_bytes;
256 state.num_resources_limit = 10000;
257 state.memory_limit_policy = ALLOW_ANYTHING;
258 state.tree_priority = SMOOTHNESS_TAKES_PRIORITY;
262 void RunPrepareTilesTest(const std::string& test_name,
264 int approximate_tile_count_per_layer) {
265 std::vector<FakePictureLayerImpl*> layers =
266 CreateLayers(layer_count, approximate_tile_count_per_layer);
270 host_impl()->AdvanceToNextFrame(base::Milliseconds(1));
271 for (auto* layer : layers)
272 layer->UpdateTiles();
274 GlobalStateThatImpactsTilePriority global_state(GlobalStateForTest());
275 tile_manager()->PrepareTiles(global_state);
276 tile_manager()->CheckForCompletedTasks();
278 } while (!timer_.HasTimeLimitExpired());
280 perf_test::PerfResultReporter reporter("prepare_tiles", test_name);
281 reporter.RegisterImportantMetric("", "runs/s");
282 reporter.AddResult("", timer_.LapsPerSecond());
285 TileManager* tile_manager() { return host_impl()->tile_manager(); }
288 base::LapTimer timer_;
291 // Failing. https://crbug.com/792995
292 TEST_F(TileManagerPerfTest, DISABLED_PrepareTiles) {
293 RunPrepareTilesTest("2_100", 2, 100);
294 RunPrepareTilesTest("2_500", 2, 500);
295 RunPrepareTilesTest("2_1000", 2, 1000);
296 RunPrepareTilesTest("10_100", 10, 100);
297 RunPrepareTilesTest("10_500", 10, 500);
298 RunPrepareTilesTest("10_1000", 10, 1000);
299 RunPrepareTilesTest("50_100", 100, 100);
300 RunPrepareTilesTest("50_500", 100, 500);
301 RunPrepareTilesTest("50_1000", 100, 1000);
304 TEST_F(TileManagerPerfTest, RasterTileQueueConstruct) {
305 RunRasterQueueConstructTest("2", 2);
306 RunRasterQueueConstructTest("10", 10);
307 RunRasterQueueConstructTest("50", 50);
310 TEST_F(TileManagerPerfTest, RasterTileQueueConstructAndIterate) {
311 RunRasterQueueConstructAndIterateTest("2_16", 2, 16);
312 RunRasterQueueConstructAndIterateTest("2_32", 2, 32);
313 RunRasterQueueConstructAndIterateTest("2_64", 2, 64);
314 RunRasterQueueConstructAndIterateTest("2_128", 2, 128);
315 RunRasterQueueConstructAndIterateTest("10_16", 10, 16);
316 RunRasterQueueConstructAndIterateTest("10_32", 10, 32);
317 RunRasterQueueConstructAndIterateTest("10_64", 10, 64);
318 RunRasterQueueConstructAndIterateTest("10_128", 10, 128);
319 RunRasterQueueConstructAndIterateTest("50_16", 50, 16);
320 RunRasterQueueConstructAndIterateTest("50_32", 50, 32);
321 RunRasterQueueConstructAndIterateTest("50_64", 50, 64);
322 RunRasterQueueConstructAndIterateTest("50_128", 50, 128);
325 TEST_F(TileManagerPerfTest, EvictionTileQueueConstruct) {
326 RunEvictionQueueConstructTest("2", 2);
327 RunEvictionQueueConstructTest("10", 10);
328 RunEvictionQueueConstructTest("50", 50);
331 TEST_F(TileManagerPerfTest, EvictionTileQueueConstructAndIterate) {
332 RunEvictionQueueConstructAndIterateTest("2_16", 2, 16);
333 RunEvictionQueueConstructAndIterateTest("2_32", 2, 32);
334 RunEvictionQueueConstructAndIterateTest("2_64", 2, 64);
335 RunEvictionQueueConstructAndIterateTest("2_128", 2, 128);
336 RunEvictionQueueConstructAndIterateTest("10_16", 10, 16);
337 RunEvictionQueueConstructAndIterateTest("10_32", 10, 32);
338 RunEvictionQueueConstructAndIterateTest("10_64", 10, 64);
339 RunEvictionQueueConstructAndIterateTest("10_128", 10, 128);
340 RunEvictionQueueConstructAndIterateTest("50_16", 50, 16);
341 RunEvictionQueueConstructAndIterateTest("50_32", 50, 32);
342 RunEvictionQueueConstructAndIterateTest("50_64", 50, 64);
343 RunEvictionQueueConstructAndIterateTest("50_128", 50, 128);