1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <stddef.h>
6 #include <stdint.h>
7
8 #include <utility>
9
10 #include "base/bind.h"
11 #include "base/callback.h"
12 #include "base/callback_helpers.h"
13 #include "base/run_loop.h"
14 #include "base/stl_util.h"
15 #include "base/test/test_simple_task_runner.h"
16 #include "base/threading/thread_task_runner_handle.h"
17 #include "cc/layers/recording_source.h"
18 #include "cc/raster/raster_buffer.h"
19 #include "cc/raster/raster_source.h"
20 #include "cc/raster/synchronous_task_graph_runner.h"
21 #include "cc/resources/resource_pool.h"
22 #include "cc/test/fake_impl_task_runner_provider.h"
23 #include "cc/test/fake_layer_tree_frame_sink.h"
24 #include "cc/test/fake_layer_tree_frame_sink_client.h"
25 #include "cc/test/fake_layer_tree_host_impl.h"
26 #include "cc/test/fake_paint_image_generator.h"
27 #include "cc/test/fake_picture_layer_impl.h"
28 #include "cc/test/fake_picture_layer_tiling_client.h"
29 #include "cc/test/fake_raster_source.h"
30 #include "cc/test/fake_recording_source.h"
31 #include "cc/test/fake_tile_manager.h"
32 #include "cc/test/fake_tile_task_manager.h"
33 #include "cc/test/layer_test_common.h"
34 #include "cc/test/skia_common.h"
35 #include "cc/test/test_layer_tree_host_base.h"
36 #include "cc/test/test_task_graph_runner.h"
37 #include "cc/test/test_tile_priorities.h"
38 #include "cc/tiles/eviction_tile_priority_queue.h"
39 #include "cc/tiles/raster_tile_priority_queue.h"
40 #include "cc/tiles/tile.h"
41 #include "cc/tiles/tile_priority.h"
42 #include "cc/tiles/tiling_set_raster_queue_all.h"
43 #include "cc/trees/layer_tree_impl.h"
44 #include "components/viz/common/resources/resource_sizes.h"
45 #include "components/viz/test/begin_frame_args_test.h"
46 #include "testing/gmock/include/gmock/gmock.h"
47 #include "testing/gtest/include/gtest/gtest.h"
48 #include "third_party/skia/include/core/SkImageGenerator.h"
49 #include "third_party/skia/include/core/SkRefCnt.h"
50 #include "third_party/skia/include/core/SkSurface.h"
51
52 using testing::_;
53 using testing::Invoke;
54 using testing::Return;
55 using testing::StrictMock;
56
57 namespace cc {
58 namespace {
59
60 // A version of simple task runner that lets the user control if all tasks
61 // posted should run synchronously.
62 class SynchronousSimpleTaskRunner : public base::TestSimpleTaskRunner {
63 public:
PostDelayedTask(const base::Location & from_here,base::OnceClosure task,base::TimeDelta delay)64 bool PostDelayedTask(const base::Location& from_here,
65 base::OnceClosure task,
66 base::TimeDelta delay) override {
67 TestSimpleTaskRunner::PostDelayedTask(from_here, std::move(task), delay);
68 if (run_tasks_synchronously_)
69 RunUntilIdle();
70 return true;
71 }
72
PostNonNestableDelayedTask(const base::Location & from_here,base::OnceClosure task,base::TimeDelta delay)73 bool PostNonNestableDelayedTask(const base::Location& from_here,
74 base::OnceClosure task,
75 base::TimeDelta delay) override {
76 return PostDelayedTask(from_here, std::move(task), delay);
77 }
78
set_run_tasks_synchronously(bool run_tasks_synchronously)79 void set_run_tasks_synchronously(bool run_tasks_synchronously) {
80 run_tasks_synchronously_ = run_tasks_synchronously;
81 }
82
83 protected:
84 ~SynchronousSimpleTaskRunner() override = default;
85
86 bool run_tasks_synchronously_ = false;
87 };
88
89 class FakeRasterBuffer : public RasterBuffer {
90 public:
Playback(const RasterSource * raster_source,const gfx::Rect & raster_full_rect,const gfx::Rect & raster_dirty_rect,uint64_t new_content_id,const gfx::AxisTransform2d & transform,const RasterSource::PlaybackSettings & playback_settings,const GURL & url)91 void Playback(const RasterSource* raster_source,
92 const gfx::Rect& raster_full_rect,
93 const gfx::Rect& raster_dirty_rect,
94 uint64_t new_content_id,
95 const gfx::AxisTransform2d& transform,
96 const RasterSource::PlaybackSettings& playback_settings,
97 const GURL& url) override {}
98
SupportsBackgroundThreadPriority() const99 bool SupportsBackgroundThreadPriority() const override { return true; }
100 };
101
102 class TileManagerTilePriorityQueueTest : public TestLayerTreeHostBase {
103 public:
CreateSettings()104 LayerTreeSettings CreateSettings() override {
105 auto settings = TestLayerTreeHostBase::CreateSettings();
106 settings.create_low_res_tiling = true;
107 return settings;
108 }
109
tile_manager()110 TileManager* tile_manager() { return host_impl()->tile_manager(); }
111 };
112
TEST_F(TileManagerTilePriorityQueueTest,RasterTilePriorityQueue)113 TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueue) {
114 const gfx::Size layer_bounds(1000, 1000);
115 host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect(layer_bounds));
116 SetupDefaultTrees(layer_bounds);
117
118 std::unique_ptr<RasterTilePriorityQueue> queue(host_impl()->BuildRasterQueue(
119 SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL));
120 EXPECT_FALSE(queue->IsEmpty());
121
122 size_t tile_count = 0;
123 std::set<Tile*> all_tiles;
124 while (!queue->IsEmpty()) {
125 EXPECT_TRUE(queue->Top().tile());
126 all_tiles.insert(queue->Top().tile());
127 ++tile_count;
128 queue->Pop();
129 }
130
131 EXPECT_EQ(tile_count, all_tiles.size());
132 EXPECT_EQ(16u, tile_count);
133
134 // Sanity check, all tiles should be visible.
135 std::set<Tile*> smoothness_tiles;
136 queue = host_impl()->BuildRasterQueue(SMOOTHNESS_TAKES_PRIORITY,
137 RasterTilePriorityQueue::Type::ALL);
138 bool had_low_res = false;
139 while (!queue->IsEmpty()) {
140 PrioritizedTile prioritized_tile = queue->Top();
141 EXPECT_TRUE(prioritized_tile.tile());
142 EXPECT_EQ(TilePriority::NOW, prioritized_tile.priority().priority_bin);
143 if (prioritized_tile.priority().resolution == LOW_RESOLUTION)
144 had_low_res = true;
145 else
146 smoothness_tiles.insert(prioritized_tile.tile());
147 queue->Pop();
148 }
149 EXPECT_EQ(all_tiles, smoothness_tiles);
150 EXPECT_TRUE(had_low_res);
151
152 // Check that everything is required for activation.
153 queue = host_impl()->BuildRasterQueue(
154 SMOOTHNESS_TAKES_PRIORITY,
155 RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION);
156 std::set<Tile*> required_for_activation_tiles;
157 while (!queue->IsEmpty()) {
158 PrioritizedTile prioritized_tile = queue->Top();
159 EXPECT_TRUE(prioritized_tile.tile()->required_for_activation());
160 required_for_activation_tiles.insert(prioritized_tile.tile());
161 queue->Pop();
162 }
163 EXPECT_EQ(all_tiles, required_for_activation_tiles);
164
165 // Check that everything is required for draw.
166 queue = host_impl()->BuildRasterQueue(
167 SMOOTHNESS_TAKES_PRIORITY,
168 RasterTilePriorityQueue::Type::REQUIRED_FOR_DRAW);
169 std::set<Tile*> required_for_draw_tiles;
170 while (!queue->IsEmpty()) {
171 PrioritizedTile prioritized_tile = queue->Top();
172 EXPECT_TRUE(prioritized_tile.tile()->required_for_draw());
173 required_for_draw_tiles.insert(prioritized_tile.tile());
174 queue->Pop();
175 }
176 EXPECT_EQ(all_tiles, required_for_draw_tiles);
177
178 Region invalidation(gfx::Rect(0, 0, 500, 500));
179
180 // Invalidate the pending tree.
181 pending_layer()->set_invalidation(invalidation);
182 pending_layer()->HighResTiling()->Invalidate(invalidation);
183
184 // Renew all of the tile priorities.
185 gfx::Rect viewport(50, 50, 100, 100);
186 pending_layer()->picture_layer_tiling_set()->UpdateTilePriorities(
187 viewport, 1.0f, 1.0, Occlusion(), true);
188 active_layer()->picture_layer_tiling_set()->UpdateTilePriorities(
189 viewport, 1.0f, 1.0, Occlusion(), true);
190
191 // Populate all tiles directly from the tilings.
192 all_tiles.clear();
193 std::set<Tile*> high_res_tiles;
194 std::vector<Tile*> pending_high_res_tiles =
195 pending_layer()->HighResTiling()->AllTilesForTesting();
196 for (size_t i = 0; i < pending_high_res_tiles.size(); ++i) {
197 all_tiles.insert(pending_high_res_tiles[i]);
198 high_res_tiles.insert(pending_high_res_tiles[i]);
199 }
200
201 std::vector<Tile*> active_high_res_tiles =
202 active_layer()->HighResTiling()->AllTilesForTesting();
203 for (size_t i = 0; i < active_high_res_tiles.size(); ++i) {
204 all_tiles.insert(active_high_res_tiles[i]);
205 high_res_tiles.insert(active_high_res_tiles[i]);
206 }
207
208 std::vector<Tile*> active_low_res_tiles =
209 active_layer()->LowResTiling()->AllTilesForTesting();
210 for (size_t i = 0; i < active_low_res_tiles.size(); ++i)
211 all_tiles.insert(active_low_res_tiles[i]);
212
213 PrioritizedTile last_tile;
214 smoothness_tiles.clear();
215 tile_count = 0;
216 size_t correct_order_tiles = 0u;
217 // Here we expect to get increasing ACTIVE_TREE priority_bin.
218 queue = host_impl()->BuildRasterQueue(SMOOTHNESS_TAKES_PRIORITY,
219 RasterTilePriorityQueue::Type::ALL);
220 std::set<Tile*> expected_required_for_draw_tiles;
221 std::set<Tile*> expected_required_for_activation_tiles;
222 while (!queue->IsEmpty()) {
223 PrioritizedTile prioritized_tile = queue->Top();
224 EXPECT_TRUE(prioritized_tile.tile());
225
226 if (!last_tile.tile())
227 last_tile = prioritized_tile;
228
229 EXPECT_LE(last_tile.priority().priority_bin,
230 prioritized_tile.priority().priority_bin);
231 bool skip_updating_last_tile = false;
232 if (last_tile.priority().priority_bin ==
233 prioritized_tile.priority().priority_bin) {
234 correct_order_tiles += last_tile.priority().distance_to_visible <=
235 prioritized_tile.priority().distance_to_visible;
236 } else if (prioritized_tile.priority().priority_bin == TilePriority::NOW) {
237 // Since we'd return pending tree now tiles before the eventually tiles on
238 // the active tree, update the value.
239 ++correct_order_tiles;
240 skip_updating_last_tile = true;
241 }
242
243 if (prioritized_tile.priority().priority_bin == TilePriority::NOW &&
244 last_tile.priority().resolution !=
245 prioritized_tile.priority().resolution) {
246 // Low resolution should come first.
247 EXPECT_EQ(LOW_RESOLUTION, last_tile.priority().resolution);
248 }
249
250 if (!skip_updating_last_tile)
251 last_tile = prioritized_tile;
252 ++tile_count;
253 smoothness_tiles.insert(prioritized_tile.tile());
254 if (prioritized_tile.tile()->required_for_draw())
255 expected_required_for_draw_tiles.insert(prioritized_tile.tile());
256 if (prioritized_tile.tile()->required_for_activation())
257 expected_required_for_activation_tiles.insert(prioritized_tile.tile());
258 queue->Pop();
259 }
260
261 EXPECT_EQ(tile_count, smoothness_tiles.size());
262 EXPECT_EQ(all_tiles, smoothness_tiles);
263 // Since we don't guarantee increasing distance due to spiral iterator, we
264 // should check that we're _mostly_ right.
265 EXPECT_GT(correct_order_tiles, 3 * tile_count / 4);
266
267 // Check that we have consistent required_for_activation tiles.
268 queue = host_impl()->BuildRasterQueue(
269 SMOOTHNESS_TAKES_PRIORITY,
270 RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION);
271 required_for_activation_tiles.clear();
272 while (!queue->IsEmpty()) {
273 PrioritizedTile prioritized_tile = queue->Top();
274 EXPECT_TRUE(prioritized_tile.tile()->required_for_activation());
275 required_for_activation_tiles.insert(prioritized_tile.tile());
276 queue->Pop();
277 }
278 EXPECT_EQ(expected_required_for_activation_tiles,
279 required_for_activation_tiles);
280 EXPECT_NE(all_tiles, required_for_activation_tiles);
281
282 // Check that we have consistent required_for_draw tiles.
283 queue = host_impl()->BuildRasterQueue(
284 SMOOTHNESS_TAKES_PRIORITY,
285 RasterTilePriorityQueue::Type::REQUIRED_FOR_DRAW);
286 required_for_draw_tiles.clear();
287 while (!queue->IsEmpty()) {
288 PrioritizedTile prioritized_tile = queue->Top();
289 EXPECT_TRUE(prioritized_tile.tile()->required_for_draw());
290 required_for_draw_tiles.insert(prioritized_tile.tile());
291 queue->Pop();
292 }
293 EXPECT_EQ(expected_required_for_draw_tiles, required_for_draw_tiles);
294 EXPECT_NE(all_tiles, required_for_draw_tiles);
295
296 std::set<Tile*> new_content_tiles;
297 last_tile = PrioritizedTile();
298 size_t increasing_distance_tiles = 0u;
299 // Here we expect to get increasing PENDING_TREE priority_bin.
300 queue = host_impl()->BuildRasterQueue(NEW_CONTENT_TAKES_PRIORITY,
301 RasterTilePriorityQueue::Type::ALL);
302 tile_count = 0;
303 while (!queue->IsEmpty()) {
304 PrioritizedTile prioritized_tile = queue->Top();
305 EXPECT_TRUE(prioritized_tile.tile());
306
307 if (!last_tile.tile())
308 last_tile = prioritized_tile;
309
310 EXPECT_LE(last_tile.priority().priority_bin,
311 prioritized_tile.priority().priority_bin);
312 if (last_tile.priority().priority_bin ==
313 prioritized_tile.priority().priority_bin) {
314 increasing_distance_tiles +=
315 last_tile.priority().distance_to_visible <=
316 prioritized_tile.priority().distance_to_visible;
317 }
318
319 if (prioritized_tile.priority().priority_bin == TilePriority::NOW &&
320 last_tile.priority().resolution !=
321 prioritized_tile.priority().resolution) {
322 // High resolution should come first.
323 EXPECT_EQ(HIGH_RESOLUTION, last_tile.priority().resolution);
324 }
325
326 last_tile = prioritized_tile;
327 new_content_tiles.insert(prioritized_tile.tile());
328 ++tile_count;
329 queue->Pop();
330 }
331
332 EXPECT_EQ(tile_count, new_content_tiles.size());
333 EXPECT_EQ(high_res_tiles, new_content_tiles);
334 // Since we don't guarantee increasing distance due to spiral iterator, we
335 // should check that we're _mostly_ right.
336 EXPECT_GE(increasing_distance_tiles, 3 * tile_count / 4);
337
338 // Check that we have consistent required_for_activation tiles.
339 queue = host_impl()->BuildRasterQueue(
340 NEW_CONTENT_TAKES_PRIORITY,
341 RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION);
342 required_for_activation_tiles.clear();
343 while (!queue->IsEmpty()) {
344 PrioritizedTile prioritized_tile = queue->Top();
345 EXPECT_TRUE(prioritized_tile.tile()->required_for_activation());
346 required_for_activation_tiles.insert(prioritized_tile.tile());
347 queue->Pop();
348 }
349 EXPECT_EQ(expected_required_for_activation_tiles,
350 required_for_activation_tiles);
351 EXPECT_NE(new_content_tiles, required_for_activation_tiles);
352
353 // Check that we have consistent required_for_draw tiles.
354 queue = host_impl()->BuildRasterQueue(
355 NEW_CONTENT_TAKES_PRIORITY,
356 RasterTilePriorityQueue::Type::REQUIRED_FOR_DRAW);
357 required_for_draw_tiles.clear();
358 while (!queue->IsEmpty()) {
359 PrioritizedTile prioritized_tile = queue->Top();
360 EXPECT_TRUE(prioritized_tile.tile()->required_for_draw());
361 required_for_draw_tiles.insert(prioritized_tile.tile());
362 queue->Pop();
363 }
364 EXPECT_EQ(expected_required_for_draw_tiles, required_for_draw_tiles);
365 EXPECT_NE(new_content_tiles, required_for_draw_tiles);
366 }
367
TEST_F(TileManagerTilePriorityQueueTest,RasterTilePriorityQueueHighNonIdealTilings)368 TEST_F(TileManagerTilePriorityQueueTest,
369 RasterTilePriorityQueueHighNonIdealTilings) {
370 const gfx::Size layer_bounds(1000, 1000);
371 const gfx::Size viewport(800, 800);
372 host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport));
373 SetupDefaultTrees(layer_bounds);
374
375 pending_layer()->tilings()->AddTiling(
376 gfx::AxisTransform2d(1.5f, gfx::Vector2dF()),
377 pending_layer()->raster_source());
378 active_layer()->tilings()->AddTiling(
379 gfx::AxisTransform2d(1.5f, gfx::Vector2dF()),
380 active_layer()->raster_source());
381 pending_layer()->tilings()->AddTiling(
382 gfx::AxisTransform2d(1.7f, gfx::Vector2dF()),
383 pending_layer()->raster_source());
384 active_layer()->tilings()->AddTiling(
385 gfx::AxisTransform2d(1.7f, gfx::Vector2dF()),
386 active_layer()->raster_source());
387
388 pending_layer()->tilings()->UpdateTilePriorities(gfx::Rect(viewport), 1.f,
389 5.0, Occlusion(), true);
390 active_layer()->tilings()->UpdateTilePriorities(gfx::Rect(viewport), 1.f, 5.0,
391 Occlusion(), true);
392
393 std::set<Tile*> all_expected_tiles;
394 for (size_t i = 0; i < pending_layer()->num_tilings(); ++i) {
395 PictureLayerTiling* tiling = pending_layer()->tilings()->tiling_at(i);
396 if (tiling->contents_scale_key() == 1.f) {
397 tiling->set_resolution(HIGH_RESOLUTION);
398 const auto& all_tiles = tiling->AllTilesForTesting();
399 all_expected_tiles.insert(all_tiles.begin(), all_tiles.end());
400 } else {
401 tiling->set_resolution(NON_IDEAL_RESOLUTION);
402 }
403 }
404
405 for (size_t i = 0; i < active_layer()->num_tilings(); ++i) {
406 PictureLayerTiling* tiling = active_layer()->tilings()->tiling_at(i);
407 if (tiling->contents_scale_key() == 1.5f) {
408 tiling->set_resolution(HIGH_RESOLUTION);
409 const auto& all_tiles = tiling->AllTilesForTesting();
410 all_expected_tiles.insert(all_tiles.begin(), all_tiles.end());
411 } else {
412 tiling->set_resolution(NON_IDEAL_RESOLUTION);
413 // Non ideal tilings with a high res pending twin have to be processed
414 // because of possible activation tiles.
415 if (tiling->contents_scale_key() == 1.f) {
416 tiling->UpdateAndGetAllPrioritizedTilesForTesting();
417 const auto& all_tiles = tiling->AllTilesForTesting();
418 for (auto* tile : all_tiles)
419 EXPECT_TRUE(tile->required_for_activation());
420 all_expected_tiles.insert(all_tiles.begin(), all_tiles.end());
421 }
422 }
423 }
424
425 std::unique_ptr<RasterTilePriorityQueue> queue(host_impl()->BuildRasterQueue(
426 SMOOTHNESS_TAKES_PRIORITY, RasterTilePriorityQueue::Type::ALL));
427 EXPECT_FALSE(queue->IsEmpty());
428
429 size_t tile_count = 0;
430 std::set<Tile*> all_actual_tiles;
431 while (!queue->IsEmpty()) {
432 EXPECT_TRUE(queue->Top().tile());
433 all_actual_tiles.insert(queue->Top().tile());
434 ++tile_count;
435 queue->Pop();
436 }
437
438 EXPECT_EQ(tile_count, all_actual_tiles.size());
439 EXPECT_EQ(all_expected_tiles.size(), all_actual_tiles.size());
440 EXPECT_EQ(all_expected_tiles, all_actual_tiles);
441 }
442
TEST_F(TileManagerTilePriorityQueueTest,RasterTilePriorityQueueHighLowTilings)443 TEST_F(TileManagerTilePriorityQueueTest,
444 RasterTilePriorityQueueHighLowTilings) {
445 const gfx::Size layer_bounds(1000, 1000);
446 const gfx::Size viewport(800, 800);
447 host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport));
448 SetupDefaultTrees(layer_bounds);
449
450 pending_layer()->tilings()->AddTiling(
451 gfx::AxisTransform2d(1.5f, gfx::Vector2dF()),
452 pending_layer()->raster_source());
453 active_layer()->tilings()->AddTiling(
454 gfx::AxisTransform2d(1.5f, gfx::Vector2dF()),
455 active_layer()->raster_source());
456 pending_layer()->tilings()->AddTiling(
457 gfx::AxisTransform2d(1.7f, gfx::Vector2dF()),
458 pending_layer()->raster_source());
459 active_layer()->tilings()->AddTiling(
460 gfx::AxisTransform2d(1.7f, gfx::Vector2dF()),
461 active_layer()->raster_source());
462
463 pending_layer()->tilings()->UpdateTilePriorities(gfx::Rect(viewport), 1.f,
464 5.0, Occlusion(), true);
465 active_layer()->tilings()->UpdateTilePriorities(gfx::Rect(viewport), 1.f, 5.0,
466 Occlusion(), true);
467
468 std::set<Tile*> all_expected_tiles;
469 for (size_t i = 0; i < pending_layer()->num_tilings(); ++i) {
470 PictureLayerTiling* tiling = pending_layer()->tilings()->tiling_at(i);
471 if (tiling->contents_scale_key() == 1.f) {
472 tiling->set_resolution(HIGH_RESOLUTION);
473 const auto& all_tiles = tiling->AllTilesForTesting();
474 all_expected_tiles.insert(all_tiles.begin(), all_tiles.end());
475 } else {
476 tiling->set_resolution(NON_IDEAL_RESOLUTION);
477 }
478 }
479
480 for (size_t i = 0; i < active_layer()->num_tilings(); ++i) {
481 PictureLayerTiling* tiling = active_layer()->tilings()->tiling_at(i);
482 if (tiling->contents_scale_key() == 1.5f) {
483 tiling->set_resolution(HIGH_RESOLUTION);
484 const auto& all_tiles = tiling->AllTilesForTesting();
485 all_expected_tiles.insert(all_tiles.begin(), all_tiles.end());
486 } else {
487 tiling->set_resolution(LOW_RESOLUTION);
488 // Low res tilings with a high res pending twin have to be processed
489 // because of possible activation tiles.
490 if (tiling->contents_scale_key() == 1.f) {
491 tiling->UpdateAndGetAllPrioritizedTilesForTesting();
492 const auto& all_tiles = tiling->AllTilesForTesting();
493 for (auto* tile : all_tiles)
494 EXPECT_TRUE(tile->required_for_activation());
495 all_expected_tiles.insert(all_tiles.begin(), all_tiles.end());
496 }
497 }
498 }
499
500 std::unique_ptr<RasterTilePriorityQueue> queue(host_impl()->BuildRasterQueue(
501 SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL));
502 EXPECT_FALSE(queue->IsEmpty());
503
504 size_t tile_count = 0;
505 std::set<Tile*> all_actual_tiles;
506 while (!queue->IsEmpty()) {
507 EXPECT_TRUE(queue->Top().tile());
508 all_actual_tiles.insert(queue->Top().tile());
509 ++tile_count;
510 queue->Pop();
511 }
512
513 EXPECT_EQ(tile_count, all_actual_tiles.size());
514 EXPECT_EQ(all_expected_tiles.size(), all_actual_tiles.size());
515 EXPECT_EQ(all_expected_tiles, all_actual_tiles);
516 }
517
TEST_F(TileManagerTilePriorityQueueTest,RasterTilePriorityQueueInvalidation)518 TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueueInvalidation) {
519 const gfx::Size layer_bounds(1000, 1000);
520 host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect(500, 500));
521 SetupDefaultTrees(layer_bounds);
522
523 // Use a tile's content rect as an invalidation. We should inset it a bit to
524 // ensure that border math doesn't invalidate neighbouring tiles.
525 gfx::Rect invalidation =
526 active_layer()->HighResTiling()->TileAt(1, 0)->content_rect();
527 invalidation.Inset(2, 2);
528
529 pending_layer()->set_invalidation(invalidation);
530 pending_layer()->HighResTiling()->Invalidate(invalidation);
531 pending_layer()->HighResTiling()->CreateMissingTilesInLiveTilesRect();
532
533 // Sanity checks: Tile at 0, 0 not exist on the pending tree (it's not
534 // invalidated). Tile 1, 0 should exist on both.
535 EXPECT_FALSE(pending_layer()->HighResTiling()->TileAt(0, 0));
536 EXPECT_TRUE(active_layer()->HighResTiling()->TileAt(0, 0));
537 EXPECT_TRUE(pending_layer()->HighResTiling()->TileAt(1, 0));
538 EXPECT_TRUE(active_layer()->HighResTiling()->TileAt(1, 0));
539 EXPECT_NE(pending_layer()->HighResTiling()->TileAt(1, 0),
540 active_layer()->HighResTiling()->TileAt(1, 0));
541
542 std::set<Tile*> expected_now_tiles;
543 std::set<Tile*> expected_required_for_draw_tiles;
544 std::set<Tile*> expected_required_for_activation_tiles;
545 for (int i = 0; i <= 1; ++i) {
546 for (int j = 0; j <= 1; ++j) {
547 bool have_pending_tile = false;
548 if (pending_layer()->HighResTiling()->TileAt(i, j)) {
549 expected_now_tiles.insert(
550 pending_layer()->HighResTiling()->TileAt(i, j));
551 expected_required_for_activation_tiles.insert(
552 pending_layer()->HighResTiling()->TileAt(i, j));
553 have_pending_tile = true;
554 }
555 Tile* active_tile = active_layer()->HighResTiling()->TileAt(i, j);
556 EXPECT_TRUE(active_tile);
557 expected_now_tiles.insert(active_tile);
558 expected_required_for_draw_tiles.insert(active_tile);
559 if (!have_pending_tile)
560 expected_required_for_activation_tiles.insert(active_tile);
561 }
562 }
563 // Expect 3 shared tiles and 1 unshared tile in total.
564 EXPECT_EQ(5u, expected_now_tiles.size());
565 // Expect 4 tiles for each draw and activation, but not all the same.
566 EXPECT_EQ(4u, expected_required_for_activation_tiles.size());
567 EXPECT_EQ(4u, expected_required_for_draw_tiles.size());
568 EXPECT_NE(expected_required_for_draw_tiles,
569 expected_required_for_activation_tiles);
570
571 std::set<Tile*> expected_all_tiles;
572 for (int i = 0; i <= 3; ++i) {
573 for (int j = 0; j <= 3; ++j) {
574 if (pending_layer()->HighResTiling()->TileAt(i, j))
575 expected_all_tiles.insert(
576 pending_layer()->HighResTiling()->TileAt(i, j));
577 EXPECT_TRUE(active_layer()->HighResTiling()->TileAt(i, j));
578 expected_all_tiles.insert(active_layer()->HighResTiling()->TileAt(i, j));
579 }
580 }
581 // Expect 15 shared tiles and 1 unshared tile.
582 EXPECT_EQ(17u, expected_all_tiles.size());
583
584 // The actual test will now build different queues and verify that the queues
585 // return the same information as computed manually above.
586 std::unique_ptr<RasterTilePriorityQueue> queue(host_impl()->BuildRasterQueue(
587 SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL));
588 std::set<Tile*> actual_now_tiles;
589 std::set<Tile*> actual_all_tiles;
590 while (!queue->IsEmpty()) {
591 PrioritizedTile prioritized_tile = queue->Top();
592 queue->Pop();
593 if (prioritized_tile.priority().priority_bin == TilePriority::NOW)
594 actual_now_tiles.insert(prioritized_tile.tile());
595 actual_all_tiles.insert(prioritized_tile.tile());
596 }
597 EXPECT_EQ(expected_now_tiles, actual_now_tiles);
598 EXPECT_EQ(expected_all_tiles, actual_all_tiles);
599
600 queue = host_impl()->BuildRasterQueue(
601 SAME_PRIORITY_FOR_BOTH_TREES,
602 RasterTilePriorityQueue::Type::REQUIRED_FOR_DRAW);
603 std::set<Tile*> actual_required_for_draw_tiles;
604 while (!queue->IsEmpty()) {
605 PrioritizedTile prioritized_tile = queue->Top();
606 queue->Pop();
607 actual_required_for_draw_tiles.insert(prioritized_tile.tile());
608 }
609 EXPECT_EQ(expected_required_for_draw_tiles, actual_required_for_draw_tiles);
610
611 queue = host_impl()->BuildRasterQueue(
612 SAME_PRIORITY_FOR_BOTH_TREES,
613 RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION);
614 std::set<Tile*> actual_required_for_activation_tiles;
615 while (!queue->IsEmpty()) {
616 Tile* tile = queue->Top().tile();
617 queue->Pop();
618 actual_required_for_activation_tiles.insert(tile);
619 }
620 EXPECT_EQ(expected_required_for_activation_tiles,
621 actual_required_for_activation_tiles);
622 }
623
TEST_F(TileManagerTilePriorityQueueTest,ActivationComesBeforeSoon)624 TEST_F(TileManagerTilePriorityQueueTest, ActivationComesBeforeSoon) {
625 host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
626
627 gfx::Size layer_bounds(1000, 1000);
628 SetupDefaultTrees(layer_bounds);
629
630 // Create a pending child layer.
631 scoped_refptr<FakeRasterSource> pending_raster_source =
632 FakeRasterSource::CreateFilled(layer_bounds);
633 auto* pending_child = AddLayer<FakePictureLayerImpl>(
634 host_impl()->pending_tree(), pending_raster_source);
635 pending_child->SetDrawsContent(true);
636 CopyProperties(pending_layer(), pending_child);
637
638 // Set a small viewport, so we have soon and eventually tiles.
639 host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect(200, 200));
640 host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
641 UpdateDrawProperties(host_impl()->pending_tree());
642
643 host_impl()->SetRequiresHighResToDraw();
644 std::unique_ptr<RasterTilePriorityQueue> queue(host_impl()->BuildRasterQueue(
645 SMOOTHNESS_TAKES_PRIORITY, RasterTilePriorityQueue::Type::ALL));
646 EXPECT_FALSE(queue->IsEmpty());
647
648 // Get all the tiles that are NOW and make sure they are ready to draw.
649 std::vector<Tile*> all_tiles;
650 while (!queue->IsEmpty()) {
651 PrioritizedTile prioritized_tile = queue->Top();
652 if (prioritized_tile.priority().priority_bin >= TilePriority::SOON)
653 break;
654
655 all_tiles.push_back(prioritized_tile.tile());
656 queue->Pop();
657 }
658
659 tile_manager()->InitializeTilesWithResourcesForTesting(
660 std::vector<Tile*>(all_tiles.begin(), all_tiles.end()));
661
662 // Ensure we can activate.
663 EXPECT_TRUE(tile_manager()->IsReadyToActivate());
664 }
665
TEST_F(TileManagerTilePriorityQueueTest,EvictionTilePriorityQueue)666 TEST_F(TileManagerTilePriorityQueueTest, EvictionTilePriorityQueue) {
667 const gfx::Size layer_bounds(1000, 1000);
668 host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect(layer_bounds));
669 SetupDefaultTrees(layer_bounds);
670 ASSERT_TRUE(active_layer()->HighResTiling());
671 ASSERT_TRUE(active_layer()->LowResTiling());
672 ASSERT_TRUE(pending_layer()->HighResTiling());
673 EXPECT_FALSE(pending_layer()->LowResTiling());
674
675 std::unique_ptr<EvictionTilePriorityQueue> empty_queue(
676 host_impl()->BuildEvictionQueue(SAME_PRIORITY_FOR_BOTH_TREES));
677 EXPECT_TRUE(empty_queue->IsEmpty());
678 std::set<Tile*> all_tiles;
679 size_t tile_count = 0;
680
681 std::unique_ptr<RasterTilePriorityQueue> raster_queue(
682 host_impl()->BuildRasterQueue(SAME_PRIORITY_FOR_BOTH_TREES,
683 RasterTilePriorityQueue::Type::ALL));
684 while (!raster_queue->IsEmpty()) {
685 ++tile_count;
686 EXPECT_TRUE(raster_queue->Top().tile());
687 all_tiles.insert(raster_queue->Top().tile());
688 raster_queue->Pop();
689 }
690
691 EXPECT_EQ(tile_count, all_tiles.size());
692 EXPECT_EQ(16u, tile_count);
693
694 tile_manager()->InitializeTilesWithResourcesForTesting(
695 std::vector<Tile*>(all_tiles.begin(), all_tiles.end()));
696
697 std::unique_ptr<EvictionTilePriorityQueue> queue(
698 host_impl()->BuildEvictionQueue(SMOOTHNESS_TAKES_PRIORITY));
699 EXPECT_FALSE(queue->IsEmpty());
700
701 // Sanity check, all tiles should be visible.
702 std::set<Tile*> smoothness_tiles;
703 while (!queue->IsEmpty()) {
704 PrioritizedTile prioritized_tile = queue->Top();
705 EXPECT_TRUE(prioritized_tile.tile());
706 EXPECT_EQ(TilePriority::NOW, prioritized_tile.priority().priority_bin);
707 EXPECT_TRUE(prioritized_tile.tile()->draw_info().has_resource());
708 smoothness_tiles.insert(prioritized_tile.tile());
709 queue->Pop();
710 }
711 EXPECT_EQ(all_tiles, smoothness_tiles);
712
713 tile_manager()->ReleaseTileResourcesForTesting(
714 std::vector<Tile*>(all_tiles.begin(), all_tiles.end()));
715
716 Region invalidation(gfx::Rect(0, 0, 500, 500));
717
718 // Invalidate the pending tree.
719 pending_layer()->set_invalidation(invalidation);
720 pending_layer()->HighResTiling()->Invalidate(invalidation);
721 pending_layer()->HighResTiling()->CreateMissingTilesInLiveTilesRect();
722 EXPECT_FALSE(pending_layer()->LowResTiling());
723
724 // Renew all of the tile priorities.
725 gfx::Rect viewport(50, 50, 100, 100);
726 pending_layer()->picture_layer_tiling_set()->UpdateTilePriorities(
727 viewport, 1.0f, 1.0, Occlusion(), true);
728 active_layer()->picture_layer_tiling_set()->UpdateTilePriorities(
729 viewport, 1.0f, 1.0, Occlusion(), true);
730
731 // Populate all tiles directly from the tilings.
732 all_tiles.clear();
733 std::vector<Tile*> pending_high_res_tiles =
734 pending_layer()->HighResTiling()->AllTilesForTesting();
735 for (size_t i = 0; i < pending_high_res_tiles.size(); ++i)
736 all_tiles.insert(pending_high_res_tiles[i]);
737
738 std::vector<Tile*> active_high_res_tiles =
739 active_layer()->HighResTiling()->AllTilesForTesting();
740 for (size_t i = 0; i < active_high_res_tiles.size(); ++i)
741 all_tiles.insert(active_high_res_tiles[i]);
742
743 std::vector<Tile*> active_low_res_tiles =
744 active_layer()->LowResTiling()->AllTilesForTesting();
745 for (size_t i = 0; i < active_low_res_tiles.size(); ++i)
746 all_tiles.insert(active_low_res_tiles[i]);
747
748 tile_manager()->InitializeTilesWithResourcesForTesting(
749 std::vector<Tile*>(all_tiles.begin(), all_tiles.end()));
750
751 PrioritizedTile last_tile;
752 smoothness_tiles.clear();
753 tile_count = 0;
754 // Here we expect to get increasing combined priority_bin.
755 queue = host_impl()->BuildEvictionQueue(SMOOTHNESS_TAKES_PRIORITY);
756 int distance_increasing = 0;
757 int distance_decreasing = 0;
758 while (!queue->IsEmpty()) {
759 PrioritizedTile prioritized_tile = queue->Top();
760 Tile* tile = prioritized_tile.tile();
761 EXPECT_TRUE(tile);
762 EXPECT_TRUE(tile->draw_info().has_resource());
763
764 if (!last_tile.tile())
765 last_tile = prioritized_tile;
766
767 const TilePriority& last_priority = last_tile.priority();
768 const TilePriority& priority = prioritized_tile.priority();
769
770 EXPECT_GE(last_priority.priority_bin, priority.priority_bin);
771 if (last_priority.priority_bin == priority.priority_bin) {
772 EXPECT_LE(last_tile.tile()->required_for_activation(),
773 tile->required_for_activation());
774 if (last_tile.tile()->required_for_activation() ==
775 tile->required_for_activation()) {
776 if (last_priority.distance_to_visible >= priority.distance_to_visible)
777 ++distance_decreasing;
778 else
779 ++distance_increasing;
780 }
781 }
782
783 last_tile = prioritized_tile;
784 ++tile_count;
785 smoothness_tiles.insert(tile);
786 queue->Pop();
787 }
788
789 // Ensure that the distance is decreasing many more times than increasing.
790 EXPECT_EQ(3, distance_increasing);
791 EXPECT_EQ(16, distance_decreasing);
792 EXPECT_EQ(tile_count, smoothness_tiles.size());
793 EXPECT_EQ(all_tiles, smoothness_tiles);
794
795 std::set<Tile*> new_content_tiles;
796 last_tile = PrioritizedTile();
797 // Again, we expect to get increasing combined priority_bin.
798 queue = host_impl()->BuildEvictionQueue(NEW_CONTENT_TAKES_PRIORITY);
799 distance_decreasing = 0;
800 distance_increasing = 0;
801 while (!queue->IsEmpty()) {
802 PrioritizedTile prioritized_tile = queue->Top();
803 Tile* tile = prioritized_tile.tile();
804 EXPECT_TRUE(tile);
805
806 if (!last_tile.tile())
807 last_tile = prioritized_tile;
808
809 const TilePriority& last_priority = last_tile.priority();
810 const TilePriority& priority = prioritized_tile.priority();
811
812 EXPECT_GE(last_priority.priority_bin, priority.priority_bin);
813 if (last_priority.priority_bin == priority.priority_bin) {
814 EXPECT_LE(last_tile.tile()->required_for_activation(),
815 tile->required_for_activation());
816 if (last_tile.tile()->required_for_activation() ==
817 tile->required_for_activation()) {
818 if (last_priority.distance_to_visible >= priority.distance_to_visible)
819 ++distance_decreasing;
820 else
821 ++distance_increasing;
822 }
823 }
824
825 last_tile = prioritized_tile;
826 new_content_tiles.insert(tile);
827 queue->Pop();
828 }
829
830 // Ensure that the distance is decreasing many more times than increasing.
831 EXPECT_EQ(3, distance_increasing);
832 EXPECT_EQ(16, distance_decreasing);
833 EXPECT_EQ(tile_count, new_content_tiles.size());
834 EXPECT_EQ(all_tiles, new_content_tiles);
835 }
836
TEST_F(TileManagerTilePriorityQueueTest,EvictionTilePriorityQueueWithOcclusion)837 TEST_F(TileManagerTilePriorityQueueTest,
838 EvictionTilePriorityQueueWithOcclusion) {
839 host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
840
841 gfx::Size layer_bounds(1000, 1000);
842
843 host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect(layer_bounds));
844
845 scoped_refptr<FakeRasterSource> pending_raster_source =
846 FakeRasterSource::CreateFilledWithText(layer_bounds);
847 SetupPendingTree(pending_raster_source);
848
849 auto* pending_child_layer = AddLayer<FakePictureLayerImpl>(
850 host_impl()->pending_tree(), pending_raster_source);
851 int child_id = pending_child_layer->id();
852 pending_child_layer->SetDrawsContent(true);
853 CopyProperties(pending_layer(), pending_child_layer);
854
855 host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
856 UpdateDrawProperties(host_impl()->pending_tree());
857
858 ActivateTree();
859 SetupPendingTree(pending_raster_source);
860
861 FakePictureLayerImpl* active_child_layer = static_cast<FakePictureLayerImpl*>(
862 host_impl()->active_tree()->LayerById(child_id));
863
864 std::set<Tile*> all_tiles;
865 size_t tile_count = 0;
866 std::unique_ptr<RasterTilePriorityQueue> raster_queue(
867 host_impl()->BuildRasterQueue(SAME_PRIORITY_FOR_BOTH_TREES,
868 RasterTilePriorityQueue::Type::ALL));
869 while (!raster_queue->IsEmpty()) {
870 ++tile_count;
871 EXPECT_TRUE(raster_queue->Top().tile());
872 all_tiles.insert(raster_queue->Top().tile());
873 raster_queue->Pop();
874 }
875 EXPECT_EQ(tile_count, all_tiles.size());
876 EXPECT_EQ(32u, tile_count);
877
878 // Renew all of the tile priorities.
879 gfx::Rect viewport(layer_bounds);
880 pending_layer()->picture_layer_tiling_set()->UpdateTilePriorities(
881 viewport, 1.0f, 1.0, Occlusion(), true);
882 pending_child_layer->picture_layer_tiling_set()->UpdateTilePriorities(
883 viewport, 1.0f, 1.0, Occlusion(), true);
884
885 active_layer()->picture_layer_tiling_set()->UpdateTilePriorities(
886 viewport, 1.0f, 1.0, Occlusion(), true);
887 active_child_layer->picture_layer_tiling_set()->UpdateTilePriorities(
888 viewport, 1.0f, 1.0, Occlusion(), true);
889
890 // Populate all tiles directly from the tilings.
891 all_tiles.clear();
892 std::vector<Tile*> pending_high_res_tiles =
893 pending_layer()->HighResTiling()->AllTilesForTesting();
894 all_tiles.insert(pending_high_res_tiles.begin(),
895 pending_high_res_tiles.end());
896
897 // Set all tiles on the pending_child_layer as occluded on the pending tree.
898 std::vector<Tile*> pending_child_high_res_tiles =
899 pending_child_layer->HighResTiling()->AllTilesForTesting();
900 pending_child_layer->HighResTiling()->SetAllTilesOccludedForTesting();
901 active_child_layer->HighResTiling()->SetAllTilesOccludedForTesting();
902 active_child_layer->LowResTiling()->SetAllTilesOccludedForTesting();
903
904 tile_manager()->InitializeTilesWithResourcesForTesting(
905 std::vector<Tile*>(all_tiles.begin(), all_tiles.end()));
906
907 // Verify occlusion is considered by EvictionTilePriorityQueue.
908 TreePriority tree_priority = NEW_CONTENT_TAKES_PRIORITY;
909 size_t occluded_count = 0u;
910 PrioritizedTile last_tile;
911 std::unique_ptr<EvictionTilePriorityQueue> queue(
912 host_impl()->BuildEvictionQueue(tree_priority));
913 while (!queue->IsEmpty()) {
914 PrioritizedTile prioritized_tile = queue->Top();
915 if (!last_tile.tile())
916 last_tile = prioritized_tile;
917
918 bool tile_is_occluded = prioritized_tile.is_occluded();
919
920 // The only way we will encounter an occluded tile after an unoccluded
921 // tile is if the priorty bin decreased, the tile is required for
922 // activation, or the scale changed.
923 if (tile_is_occluded) {
924 occluded_count++;
925
926 bool last_tile_is_occluded = last_tile.is_occluded();
927 if (!last_tile_is_occluded) {
928 TilePriority::PriorityBin tile_priority_bin =
929 prioritized_tile.priority().priority_bin;
930 TilePriority::PriorityBin last_tile_priority_bin =
931 last_tile.priority().priority_bin;
932
933 EXPECT_TRUE((tile_priority_bin < last_tile_priority_bin) ||
934 prioritized_tile.tile()->required_for_activation() ||
935 (prioritized_tile.tile()->raster_transform() !=
936 last_tile.tile()->raster_transform()));
937 }
938 }
939 last_tile = prioritized_tile;
940 queue->Pop();
941 }
942 size_t expected_occluded_count = pending_child_high_res_tiles.size();
943 EXPECT_EQ(expected_occluded_count, occluded_count);
944 }
945
TEST_F(TileManagerTilePriorityQueueTest,EvictionTilePriorityQueueWithTransparentLayer)946 TEST_F(TileManagerTilePriorityQueueTest,
947 EvictionTilePriorityQueueWithTransparentLayer) {
948 host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
949
950 gfx::Size layer_bounds(1000, 1000);
951
952 scoped_refptr<FakeRasterSource> pending_raster_source =
953 FakeRasterSource::CreateFilled(layer_bounds);
954 SetupPendingTree(pending_raster_source);
955
956 auto* pending_child_layer = AddLayer<FakePictureLayerImpl>(
957 host_impl()->pending_tree(), pending_raster_source);
958 pending_child_layer->SetElementId(
959 LayerIdToElementIdForTesting(pending_child_layer->id()));
960 CopyProperties(pending_layer(), pending_child_layer);
961
962 // Create a fully transparent child layer so that its tile priorities are not
963 // considered to be valid.
964 pending_child_layer->SetDrawsContent(true);
965 CreateEffectNode(pending_child_layer).render_surface_reason =
966 RenderSurfaceReason::kTest;
967
968 host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
969 UpdateDrawProperties(host_impl()->pending_tree());
970
971 host_impl()->pending_tree()->SetOpacityMutated(
972 pending_child_layer->element_id(), 0.0f);
973
974 host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
975 host_impl()->pending_tree()->UpdateDrawProperties();
976
977 // Renew all of the tile priorities.
978 gfx::Rect viewport(layer_bounds);
979 pending_layer()->picture_layer_tiling_set()->UpdateTilePriorities(
980 viewport, 1.0f, 1.0, Occlusion(), true);
981 pending_child_layer->picture_layer_tiling_set()->UpdateTilePriorities(
982 viewport, 1.0f, 1.0, Occlusion(), true);
983
984 // Populate all tiles directly from the tilings.
985 std::set<Tile*> all_pending_tiles;
986 std::vector<Tile*> pending_high_res_tiles =
987 pending_layer()->HighResTiling()->AllTilesForTesting();
988 all_pending_tiles.insert(pending_high_res_tiles.begin(),
989 pending_high_res_tiles.end());
990 EXPECT_EQ(16u, pending_high_res_tiles.size());
991
992 std::set<Tile*> all_pending_child_tiles;
993 std::vector<Tile*> pending_child_high_res_tiles =
994 pending_child_layer->HighResTiling()->AllTilesForTesting();
995 all_pending_child_tiles.insert(pending_child_high_res_tiles.begin(),
996 pending_child_high_res_tiles.end());
997 EXPECT_EQ(16u, pending_child_high_res_tiles.size());
998
999 std::set<Tile*> all_tiles = all_pending_tiles;
1000 all_tiles.insert(all_pending_child_tiles.begin(),
1001 all_pending_child_tiles.end());
1002
1003 tile_manager()->InitializeTilesWithResourcesForTesting(
1004 std::vector<Tile*>(all_tiles.begin(), all_tiles.end()));
1005
1006 EXPECT_TRUE(pending_layer()->HasValidTilePriorities());
1007 EXPECT_FALSE(pending_child_layer->HasValidTilePriorities());
1008
1009 // Verify that eviction queue returns tiles also from layers without valid
1010 // tile priorities and that the tile priority bin of those tiles is (at most)
1011 // EVENTUALLY.
1012 TreePriority tree_priority = NEW_CONTENT_TAKES_PRIORITY;
1013 std::set<Tile*> new_content_tiles;
1014 size_t tile_count = 0;
1015 std::unique_ptr<EvictionTilePriorityQueue> queue(
1016 host_impl()->BuildEvictionQueue(tree_priority));
1017 while (!queue->IsEmpty()) {
1018 PrioritizedTile prioritized_tile = queue->Top();
1019 Tile* tile = prioritized_tile.tile();
1020 const TilePriority& pending_priority = prioritized_tile.priority();
1021 EXPECT_NE(std::numeric_limits<float>::infinity(),
1022 pending_priority.distance_to_visible);
1023 if (all_pending_child_tiles.find(tile) != all_pending_child_tiles.end())
1024 EXPECT_EQ(TilePriority::EVENTUALLY, pending_priority.priority_bin);
1025 else
1026 EXPECT_EQ(TilePriority::NOW, pending_priority.priority_bin);
1027 new_content_tiles.insert(tile);
1028 ++tile_count;
1029 queue->Pop();
1030 }
1031 EXPECT_EQ(tile_count, new_content_tiles.size());
1032 EXPECT_EQ(all_tiles, new_content_tiles);
1033 }
1034
TEST_F(TileManagerTilePriorityQueueTest,RasterTilePriorityQueueEmptyLayers)1035 TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueueEmptyLayers) {
1036 const gfx::Size layer_bounds(1000, 1000);
1037 host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect(layer_bounds));
1038 SetupDefaultTrees(layer_bounds);
1039
1040 std::unique_ptr<RasterTilePriorityQueue> queue(host_impl()->BuildRasterQueue(
1041 SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL));
1042 EXPECT_FALSE(queue->IsEmpty());
1043
1044 size_t tile_count = 0;
1045 std::set<Tile*> all_tiles;
1046 while (!queue->IsEmpty()) {
1047 EXPECT_TRUE(queue->Top().tile());
1048 all_tiles.insert(queue->Top().tile());
1049 ++tile_count;
1050 queue->Pop();
1051 }
1052
1053 EXPECT_EQ(tile_count, all_tiles.size());
1054 EXPECT_EQ(16u, tile_count);
1055
1056 for (int i = 1; i < 10; ++i) {
1057 auto* pending_child_layer =
1058 AddLayer<FakePictureLayerImpl>(host_impl()->pending_tree());
1059 pending_child_layer->SetDrawsContent(true);
1060 pending_child_layer->set_has_valid_tile_priorities(true);
1061 CopyProperties(pending_layer(), pending_child_layer);
1062 }
1063
1064 queue = host_impl()->BuildRasterQueue(SAME_PRIORITY_FOR_BOTH_TREES,
1065 RasterTilePriorityQueue::Type::ALL);
1066 EXPECT_FALSE(queue->IsEmpty());
1067
1068 tile_count = 0;
1069 all_tiles.clear();
1070 while (!queue->IsEmpty()) {
1071 EXPECT_TRUE(queue->Top().tile());
1072 all_tiles.insert(queue->Top().tile());
1073 ++tile_count;
1074 queue->Pop();
1075 }
1076 EXPECT_EQ(tile_count, all_tiles.size());
1077 EXPECT_EQ(16u, tile_count);
1078 }
1079
TEST_F(TileManagerTilePriorityQueueTest,EvictionTilePriorityQueueEmptyLayers)1080 TEST_F(TileManagerTilePriorityQueueTest, EvictionTilePriorityQueueEmptyLayers) {
1081 const gfx::Size layer_bounds(1000, 1000);
1082 host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect(layer_bounds));
1083 SetupDefaultTrees(layer_bounds);
1084
1085 std::unique_ptr<RasterTilePriorityQueue> raster_queue(
1086 host_impl()->BuildRasterQueue(SAME_PRIORITY_FOR_BOTH_TREES,
1087 RasterTilePriorityQueue::Type::ALL));
1088 EXPECT_FALSE(raster_queue->IsEmpty());
1089
1090 size_t tile_count = 0;
1091 std::set<Tile*> all_tiles;
1092 while (!raster_queue->IsEmpty()) {
1093 EXPECT_TRUE(raster_queue->Top().tile());
1094 all_tiles.insert(raster_queue->Top().tile());
1095 ++tile_count;
1096 raster_queue->Pop();
1097 }
1098 EXPECT_EQ(tile_count, all_tiles.size());
1099 EXPECT_EQ(16u, tile_count);
1100
1101 std::vector<Tile*> tiles(all_tiles.begin(), all_tiles.end());
1102 host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting(tiles);
1103
1104 for (int i = 1; i < 10; ++i) {
1105 auto* pending_child_layer =
1106 AddLayer<FakePictureLayerImpl>(host_impl()->pending_tree());
1107 pending_child_layer->SetDrawsContent(true);
1108 pending_child_layer->set_has_valid_tile_priorities(true);
1109 CopyProperties(pending_layer(), pending_child_layer);
1110 }
1111
1112 std::unique_ptr<EvictionTilePriorityQueue> queue(
1113 host_impl()->BuildEvictionQueue(SAME_PRIORITY_FOR_BOTH_TREES));
1114 EXPECT_FALSE(queue->IsEmpty());
1115
1116 tile_count = 0;
1117 all_tiles.clear();
1118 while (!queue->IsEmpty()) {
1119 EXPECT_TRUE(queue->Top().tile());
1120 all_tiles.insert(queue->Top().tile());
1121 ++tile_count;
1122 queue->Pop();
1123 }
1124 EXPECT_EQ(tile_count, all_tiles.size());
1125 EXPECT_EQ(16u, tile_count);
1126 }
1127
TEST_F(TileManagerTilePriorityQueueTest,RasterTilePriorityQueueStaticViewport)1128 TEST_F(TileManagerTilePriorityQueueTest,
1129 RasterTilePriorityQueueStaticViewport) {
1130 FakePictureLayerTilingClient client;
1131
1132 gfx::Rect viewport(50, 50, 500, 500);
1133 gfx::Size layer_bounds(1600, 1600);
1134
1135 const int soon_border_outset = 312;
1136 gfx::Rect soon_rect = viewport;
1137 soon_rect.Inset(-soon_border_outset, -soon_border_outset);
1138
1139 client.SetTileSize(gfx::Size(30, 30));
1140 LayerTreeSettings settings;
1141
1142 std::unique_ptr<PictureLayerTilingSet> tiling_set =
1143 PictureLayerTilingSet::Create(
1144 ACTIVE_TREE, &client, settings.tiling_interest_area_padding,
1145 settings.skewport_target_time_in_seconds,
1146 settings.skewport_extrapolation_limit_in_screen_pixels,
1147 settings.max_preraster_distance_in_screen_pixels);
1148
1149 scoped_refptr<FakeRasterSource> raster_source =
1150 FakeRasterSource::CreateFilled(layer_bounds);
1151 PictureLayerTiling* tiling =
1152 tiling_set->AddTiling(gfx::AxisTransform2d(), raster_source);
1153 tiling->set_resolution(HIGH_RESOLUTION);
1154
1155 tiling_set->UpdateTilePriorities(viewport, 1.0f, 1.0, Occlusion(), true);
1156 std::vector<Tile*> all_tiles = tiling->AllTilesForTesting();
1157 // Sanity check.
1158 EXPECT_EQ(3364u, all_tiles.size());
1159
1160 // The explanation of each iteration is as follows:
1161 // 1. First iteration tests that we can get all of the tiles correctly.
1162 // 2. Second iteration ensures that we can get all of the tiles again (first
1163 // iteration didn't change any tiles), as well set all tiles to be ready to
1164 // draw.
1165 // 3. Third iteration ensures that no tiles are returned, since they were all
1166 // marked as ready to draw.
1167 for (int i = 0; i < 3; ++i) {
1168 std::unique_ptr<TilingSetRasterQueueAll> queue(
1169 new TilingSetRasterQueueAll(tiling_set.get(), false, false));
1170
1171 // There are 3 bins in TilePriority.
1172 bool have_tiles[3] = {};
1173
1174 // On the third iteration, we should get no tiles since everything was
1175 // marked as ready to draw.
1176 if (i == 2) {
1177 EXPECT_TRUE(queue->IsEmpty());
1178 continue;
1179 }
1180
1181 EXPECT_FALSE(queue->IsEmpty());
1182 std::set<Tile*> unique_tiles;
1183 unique_tiles.insert(queue->Top().tile());
1184 PrioritizedTile last_tile = queue->Top();
1185 have_tiles[last_tile.priority().priority_bin] = true;
1186
1187 // On the second iteration, mark everything as ready to draw (solid color).
1188 if (i == 1) {
1189 TileDrawInfo& draw_info = last_tile.tile()->draw_info();
1190 draw_info.SetSolidColorForTesting(SK_ColorRED);
1191 }
1192 queue->Pop();
1193 int eventually_bin_order_correct_count = 0;
1194 int eventually_bin_order_incorrect_count = 0;
1195 while (!queue->IsEmpty()) {
1196 PrioritizedTile new_tile = queue->Top();
1197 queue->Pop();
1198 unique_tiles.insert(new_tile.tile());
1199
1200 TilePriority last_priority = last_tile.priority();
1201 TilePriority new_priority = new_tile.priority();
1202 EXPECT_LE(last_priority.priority_bin, new_priority.priority_bin);
1203 if (last_priority.priority_bin == new_priority.priority_bin) {
1204 if (last_priority.priority_bin == TilePriority::EVENTUALLY) {
1205 bool order_correct = last_priority.distance_to_visible <=
1206 new_priority.distance_to_visible;
1207 eventually_bin_order_correct_count += order_correct;
1208 eventually_bin_order_incorrect_count += !order_correct;
1209 } else if (!soon_rect.Intersects(new_tile.tile()->content_rect()) &&
1210 !soon_rect.Intersects(last_tile.tile()->content_rect())) {
1211 EXPECT_LE(last_priority.distance_to_visible,
1212 new_priority.distance_to_visible);
1213 EXPECT_EQ(TilePriority::NOW, new_priority.priority_bin);
1214 } else if (new_priority.distance_to_visible > 0.f) {
1215 EXPECT_EQ(TilePriority::SOON, new_priority.priority_bin);
1216 }
1217 }
1218 have_tiles[new_priority.priority_bin] = true;
1219
1220 last_tile = new_tile;
1221
1222 // On the second iteration, mark everything as ready to draw (solid
1223 // color).
1224 if (i == 1) {
1225 TileDrawInfo& draw_info = last_tile.tile()->draw_info();
1226 draw_info.SetSolidColorForTesting(SK_ColorRED);
1227 }
1228 }
1229
1230 EXPECT_GT(eventually_bin_order_correct_count,
1231 eventually_bin_order_incorrect_count);
1232
1233 // We should have now and eventually tiles, as well as soon tiles from
1234 // the border region.
1235 EXPECT_TRUE(have_tiles[TilePriority::NOW]);
1236 EXPECT_TRUE(have_tiles[TilePriority::SOON]);
1237 EXPECT_TRUE(have_tiles[TilePriority::EVENTUALLY]);
1238
1239 EXPECT_EQ(unique_tiles.size(), all_tiles.size());
1240 }
1241 }
1242
TEST_F(TileManagerTilePriorityQueueTest,RasterTilePriorityQueueMovingViewport)1243 TEST_F(TileManagerTilePriorityQueueTest,
1244 RasterTilePriorityQueueMovingViewport) {
1245 FakePictureLayerTilingClient client;
1246
1247 gfx::Rect viewport(50, 0, 100, 100);
1248 gfx::Rect moved_viewport(50, 0, 100, 500);
1249 gfx::Size layer_bounds(1000, 1000);
1250
1251 client.SetTileSize(gfx::Size(30, 30));
1252 LayerTreeSettings settings;
1253
1254 std::unique_ptr<PictureLayerTilingSet> tiling_set =
1255 PictureLayerTilingSet::Create(
1256 ACTIVE_TREE, &client, settings.tiling_interest_area_padding,
1257 settings.skewport_target_time_in_seconds,
1258 settings.skewport_extrapolation_limit_in_screen_pixels,
1259 settings.max_preraster_distance_in_screen_pixels);
1260
1261 scoped_refptr<FakeRasterSource> raster_source =
1262 FakeRasterSource::CreateFilled(layer_bounds);
1263 PictureLayerTiling* tiling =
1264 tiling_set->AddTiling(gfx::AxisTransform2d(), raster_source);
1265 tiling->set_resolution(HIGH_RESOLUTION);
1266
1267 tiling_set->UpdateTilePriorities(viewport, 1.0f, 1.0, Occlusion(), true);
1268 tiling_set->UpdateTilePriorities(moved_viewport, 1.0f, 2.0, Occlusion(),
1269 true);
1270
1271 const int soon_border_outset = 312;
1272 gfx::Rect soon_rect = moved_viewport;
1273 soon_rect.Inset(-soon_border_outset, -soon_border_outset);
1274
1275 // There are 3 bins in TilePriority.
1276 bool have_tiles[3] = {};
1277 PrioritizedTile last_tile;
1278 int eventually_bin_order_correct_count = 0;
1279 int eventually_bin_order_incorrect_count = 0;
1280 std::unique_ptr<TilingSetRasterQueueAll> queue(
1281 new TilingSetRasterQueueAll(tiling_set.get(), false, false));
1282 for (; !queue->IsEmpty(); queue->Pop()) {
1283 if (!last_tile.tile())
1284 last_tile = queue->Top();
1285
1286 const PrioritizedTile& new_tile = queue->Top();
1287
1288 TilePriority last_priority = last_tile.priority();
1289 TilePriority new_priority = new_tile.priority();
1290
1291 have_tiles[new_priority.priority_bin] = true;
1292
1293 EXPECT_LE(last_priority.priority_bin, new_priority.priority_bin);
1294 if (last_priority.priority_bin == new_priority.priority_bin) {
1295 if (last_priority.priority_bin == TilePriority::EVENTUALLY) {
1296 bool order_correct = last_priority.distance_to_visible <=
1297 new_priority.distance_to_visible;
1298 eventually_bin_order_correct_count += order_correct;
1299 eventually_bin_order_incorrect_count += !order_correct;
1300 } else if (!soon_rect.Intersects(new_tile.tile()->content_rect()) &&
1301 !soon_rect.Intersects(last_tile.tile()->content_rect())) {
1302 EXPECT_LE(last_priority.distance_to_visible,
1303 new_priority.distance_to_visible);
1304 } else if (new_priority.distance_to_visible > 0.f) {
1305 EXPECT_EQ(TilePriority::SOON, new_priority.priority_bin);
1306 }
1307 }
1308 last_tile = new_tile;
1309 }
1310
1311 EXPECT_GT(eventually_bin_order_correct_count,
1312 eventually_bin_order_incorrect_count);
1313
1314 EXPECT_TRUE(have_tiles[TilePriority::NOW]);
1315 EXPECT_TRUE(have_tiles[TilePriority::SOON]);
1316 EXPECT_TRUE(have_tiles[TilePriority::EVENTUALLY]);
1317 }
1318
TEST_F(TileManagerTilePriorityQueueTest,SetIsLikelyToRequireADraw)1319 TEST_F(TileManagerTilePriorityQueueTest, SetIsLikelyToRequireADraw) {
1320 const gfx::Size layer_bounds(1000, 1000);
1321 host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect(layer_bounds));
1322 SetupDefaultTrees(layer_bounds);
1323
1324 // Verify that the queue has a required for draw tile at Top.
1325 std::unique_ptr<RasterTilePriorityQueue> queue(host_impl()->BuildRasterQueue(
1326 SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL));
1327 EXPECT_FALSE(queue->IsEmpty());
1328 EXPECT_TRUE(queue->Top().tile()->required_for_draw());
1329
1330 EXPECT_FALSE(host_impl()->is_likely_to_require_a_draw());
1331 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
1332 EXPECT_TRUE(host_impl()->is_likely_to_require_a_draw());
1333 }
1334
TEST_F(TileManagerTilePriorityQueueTest,SetIsLikelyToRequireADrawOnZeroMemoryBudget)1335 TEST_F(TileManagerTilePriorityQueueTest,
1336 SetIsLikelyToRequireADrawOnZeroMemoryBudget) {
1337 const gfx::Size layer_bounds(1000, 1000);
1338 host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect(layer_bounds));
1339 SetupDefaultTrees(layer_bounds);
1340
1341 // Verify that the queue has a required for draw tile at Top.
1342 std::unique_ptr<RasterTilePriorityQueue> queue(host_impl()->BuildRasterQueue(
1343 SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL));
1344 EXPECT_FALSE(queue->IsEmpty());
1345 EXPECT_TRUE(queue->Top().tile()->required_for_draw());
1346
1347 ManagedMemoryPolicy policy = host_impl()->ActualManagedMemoryPolicy();
1348 policy.bytes_limit_when_visible = 0;
1349 host_impl()->SetMemoryPolicy(policy);
1350
1351 EXPECT_FALSE(host_impl()->is_likely_to_require_a_draw());
1352 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
1353 EXPECT_FALSE(host_impl()->is_likely_to_require_a_draw());
1354 }
1355
TEST_F(TileManagerTilePriorityQueueTest,SetIsLikelyToRequireADrawOnLimitedMemoryBudget)1356 TEST_F(TileManagerTilePriorityQueueTest,
1357 SetIsLikelyToRequireADrawOnLimitedMemoryBudget) {
1358 const gfx::Size layer_bounds(1000, 1000);
1359 host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect(layer_bounds));
1360 SetupDefaultTrees(layer_bounds);
1361
1362 // Verify that the queue has a required for draw tile at Top.
1363 std::unique_ptr<RasterTilePriorityQueue> queue(host_impl()->BuildRasterQueue(
1364 SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL));
1365 EXPECT_FALSE(queue->IsEmpty());
1366 EXPECT_TRUE(queue->Top().tile()->required_for_draw());
1367 EXPECT_EQ(gfx::Size(256, 256), queue->Top().tile()->desired_texture_size());
1368
1369 ManagedMemoryPolicy policy = host_impl()->ActualManagedMemoryPolicy();
1370 policy.bytes_limit_when_visible =
1371 viz::ResourceSizes::UncheckedSizeInBytes<size_t>(gfx::Size(256, 256),
1372 viz::RGBA_8888);
1373 host_impl()->SetMemoryPolicy(policy);
1374
1375 EXPECT_FALSE(host_impl()->is_likely_to_require_a_draw());
1376 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
1377 EXPECT_TRUE(host_impl()->is_likely_to_require_a_draw());
1378
1379 ResourcePool::InUsePoolResource resource =
1380 host_impl()->resource_pool()->AcquireResource(
1381 gfx::Size(256, 256), viz::RGBA_8888, gfx::ColorSpace());
1382
1383 host_impl()->tile_manager()->CheckIfMoreTilesNeedToBePreparedForTesting();
1384 EXPECT_FALSE(host_impl()->is_likely_to_require_a_draw());
1385
1386 host_impl()->resource_pool()->ReleaseResource(std::move(resource));
1387 }
1388
TEST_F(TileManagerTilePriorityQueueTest,DefaultMemoryPolicy)1389 TEST_F(TileManagerTilePriorityQueueTest, DefaultMemoryPolicy) {
1390 const gfx::Size layer_bounds(1000, 1000);
1391 host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect(layer_bounds));
1392 SetupDefaultTrees(layer_bounds);
1393
1394 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
1395
1396 // 64MB is the default mem limit.
1397 EXPECT_EQ(67108864u,
1398 host_impl()->global_tile_state().hard_memory_limit_in_bytes);
1399 EXPECT_EQ(TileMemoryLimitPolicy::ALLOW_ANYTHING,
1400 host_impl()->global_tile_state().memory_limit_policy);
1401 EXPECT_EQ(ManagedMemoryPolicy::kDefaultNumResourcesLimit,
1402 host_impl()->global_tile_state().num_resources_limit);
1403 }
1404
TEST_F(TileManagerTilePriorityQueueTest,RasterQueueAllUsesCorrectTileBounds)1405 TEST_F(TileManagerTilePriorityQueueTest, RasterQueueAllUsesCorrectTileBounds) {
1406 // Verify that we use the real tile bounds when advancing phases during the
1407 // tile iteration.
1408 gfx::Size layer_bounds(1, 1);
1409
1410 scoped_refptr<FakeRasterSource> raster_source =
1411 FakeRasterSource::CreateFilled(layer_bounds);
1412
1413 FakePictureLayerTilingClient pending_client;
1414 pending_client.SetTileSize(gfx::Size(64, 64));
1415
1416 std::unique_ptr<PictureLayerTilingSet> tiling_set =
1417 PictureLayerTilingSet::Create(WhichTree::ACTIVE_TREE, &pending_client,
1418 1.0f, 1.0f, 1000, 1000.f);
1419 pending_client.set_twin_tiling_set(tiling_set.get());
1420
1421 auto* tiling = tiling_set->AddTiling(gfx::AxisTransform2d(), raster_source);
1422
1423 tiling->set_resolution(HIGH_RESOLUTION);
1424 tiling->CreateAllTilesForTesting();
1425
1426 // The tile is (0, 0, 1, 1), create an intersecting and non-intersecting
1427 // rectangle to test the advance phase with. The tile size is (64, 64), so
1428 // both rectangles intersect the tile content size, but only one should
1429 // intersect the actual size.
1430 gfx::Rect non_intersecting_rect(2, 2, 10, 10);
1431 gfx::Rect intersecting_rect(0, 0, 10, 10);
1432 {
1433 tiling->SetTilePriorityRectsForTesting(
1434 non_intersecting_rect, // Visible rect.
1435 intersecting_rect, // Skewport rect.
1436 intersecting_rect, // Soon rect.
1437 intersecting_rect); // Eventually rect.
1438 std::unique_ptr<TilingSetRasterQueueAll> queue(
1439 new TilingSetRasterQueueAll(tiling_set.get(), false, false));
1440 EXPECT_FALSE(queue->IsEmpty());
1441 }
1442 {
1443 tiling->SetTilePriorityRectsForTesting(
1444 non_intersecting_rect, // Visible rect.
1445 non_intersecting_rect, // Skewport rect.
1446 intersecting_rect, // Soon rect.
1447 intersecting_rect); // Eventually rect.
1448 std::unique_ptr<TilingSetRasterQueueAll> queue(
1449 new TilingSetRasterQueueAll(tiling_set.get(), false, false));
1450 EXPECT_FALSE(queue->IsEmpty());
1451 }
1452 {
1453 tiling->SetTilePriorityRectsForTesting(
1454 non_intersecting_rect, // Visible rect.
1455 non_intersecting_rect, // Skewport rect.
1456 non_intersecting_rect, // Soon rect.
1457 intersecting_rect); // Eventually rect.
1458 std::unique_ptr<TilingSetRasterQueueAll> queue(
1459 new TilingSetRasterQueueAll(tiling_set.get(), false, false));
1460 EXPECT_FALSE(queue->IsEmpty());
1461 }
1462 }
1463
TEST_F(TileManagerTilePriorityQueueTest,NoRasterTasksforSolidColorTiles)1464 TEST_F(TileManagerTilePriorityQueueTest, NoRasterTasksforSolidColorTiles) {
1465 gfx::Size size(10, 10);
1466 const gfx::Size layer_bounds(1000, 1000);
1467
1468 std::unique_ptr<FakeRecordingSource> recording_source =
1469 FakeRecordingSource::CreateFilledRecordingSource(layer_bounds);
1470
1471 PaintFlags solid_flags;
1472 SkColor solid_color = SkColorSetARGB(255, 12, 23, 34);
1473 solid_flags.setColor(solid_color);
1474 recording_source->add_draw_rect_with_flags(gfx::Rect(layer_bounds),
1475 solid_flags);
1476
1477 // Create non solid tile as well, otherwise tilings wouldnt be created.
1478 SkColor non_solid_color = SkColorSetARGB(128, 45, 56, 67);
1479 PaintFlags non_solid_flags;
1480 non_solid_flags.setColor(non_solid_color);
1481
1482 recording_source->add_draw_rect_with_flags(gfx::Rect(0, 0, 10, 10),
1483 non_solid_flags);
1484 recording_source->Rerecord();
1485
1486 scoped_refptr<RasterSource> raster_source =
1487 recording_source->CreateRasterSource();
1488
1489 FakePictureLayerTilingClient tiling_client;
1490 tiling_client.SetTileSize(size);
1491
1492 std::unique_ptr<PictureLayerImpl> layer_impl =
1493 PictureLayerImpl::Create(host_impl()->active_tree(), 1);
1494 layer_impl->set_contributes_to_drawn_render_surface(true);
1495 PictureLayerTilingSet* tiling_set = layer_impl->picture_layer_tiling_set();
1496
1497 PictureLayerTiling* tiling =
1498 tiling_set->AddTiling(gfx::AxisTransform2d(), raster_source);
1499 tiling->set_resolution(HIGH_RESOLUTION);
1500 tiling->CreateAllTilesForTesting();
1501 tiling->SetTilePriorityRectsForTesting(
1502 gfx::Rect(layer_bounds), // Visible rect.
1503 gfx::Rect(layer_bounds), // Skewport rect.
1504 gfx::Rect(layer_bounds), // Soon rect.
1505 gfx::Rect(layer_bounds)); // Eventually rect.
1506
1507 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
1508
1509 std::vector<Tile*> tiles = tiling->AllTilesForTesting();
1510 for (size_t tile_idx = 0; tile_idx < tiles.size(); ++tile_idx) {
1511 Tile* tile = tiles[tile_idx];
1512 if (tile->id() == 1) {
1513 // Non-solid tile.
1514 EXPECT_TRUE(tile->HasRasterTask());
1515 EXPECT_EQ(TileDrawInfo::RESOURCE_MODE, tile->draw_info().mode());
1516 } else {
1517 EXPECT_FALSE(tile->HasRasterTask());
1518 EXPECT_EQ(TileDrawInfo::SOLID_COLOR_MODE, tile->draw_info().mode());
1519 EXPECT_EQ(solid_color, tile->draw_info().solid_color());
1520 }
1521 }
1522 }
1523
1524 class TestSoftwareBacking : public ResourcePool::SoftwareBacking {
1525 public:
1526 // No tracing is done during these tests.
OnMemoryDump(base::trace_event::ProcessMemoryDump * pmd,const base::trace_event::MemoryAllocatorDumpGuid & buffer_dump_guid,uint64_t tracing_process_id,int importance) const1527 void OnMemoryDump(
1528 base::trace_event::ProcessMemoryDump* pmd,
1529 const base::trace_event::MemoryAllocatorDumpGuid& buffer_dump_guid,
1530 uint64_t tracing_process_id,
1531 int importance) const override {}
1532
1533 std::unique_ptr<uint32_t[]> pixels;
1534 };
1535
1536 // A RasterBufferProvider that allocates software backings with a standard
1537 // array as the backing. Overrides Playback() on the RasterBuffer to raster
1538 // into the pixels in the array.
1539 class TestSoftwareRasterBufferProvider : public FakeRasterBufferProviderImpl {
1540 public:
1541 static constexpr bool kIsGpuCompositing = true;
1542 static constexpr viz::ResourceFormat kResourceFormat = viz::RGBA_8888;
1543
AcquireBufferForRaster(const ResourcePool::InUsePoolResource & resource,uint64_t resource_content_id,uint64_t previous_content_id,bool depends_on_at_raster_decodes,bool depends_on_hardware_accelerated_jpeg_candidates,bool depends_on_hardware_accelerated_webp_candidates)1544 std::unique_ptr<RasterBuffer> AcquireBufferForRaster(
1545 const ResourcePool::InUsePoolResource& resource,
1546 uint64_t resource_content_id,
1547 uint64_t previous_content_id,
1548 bool depends_on_at_raster_decodes,
1549 bool depends_on_hardware_accelerated_jpeg_candidates,
1550 bool depends_on_hardware_accelerated_webp_candidates) override {
1551 if (!resource.software_backing()) {
1552 auto backing = std::make_unique<TestSoftwareBacking>();
1553 backing->shared_bitmap_id = viz::SharedBitmap::GenerateId();
1554 backing->pixels = std::make_unique<uint32_t[]>(
1555 viz::ResourceSizes::CheckedSizeInBytes<size_t>(resource.size(),
1556 kResourceFormat));
1557 resource.set_software_backing(std::move(backing));
1558 }
1559 auto* backing =
1560 static_cast<TestSoftwareBacking*>(resource.software_backing());
1561 return std::make_unique<TestRasterBuffer>(resource.size(),
1562 backing->pixels.get());
1563 }
1564
1565 private:
1566 class TestRasterBuffer : public RasterBuffer {
1567 public:
TestRasterBuffer(const gfx::Size & size,void * pixels)1568 TestRasterBuffer(const gfx::Size& size, void* pixels)
1569 : size_(size), pixels_(pixels) {}
1570
Playback(const RasterSource * raster_source,const gfx::Rect & raster_full_rect,const gfx::Rect & raster_dirty_rect,uint64_t new_content_id,const gfx::AxisTransform2d & transform,const RasterSource::PlaybackSettings & playback_settings,const GURL & url)1571 void Playback(const RasterSource* raster_source,
1572 const gfx::Rect& raster_full_rect,
1573 const gfx::Rect& raster_dirty_rect,
1574 uint64_t new_content_id,
1575 const gfx::AxisTransform2d& transform,
1576 const RasterSource::PlaybackSettings& playback_settings,
1577 const GURL& url) override {
1578 RasterBufferProvider::PlaybackToMemory(
1579 pixels_, kResourceFormat, size_, /*stride=*/0, raster_source,
1580 raster_full_rect, /*playback_rect=*/raster_full_rect, transform,
1581 gfx::ColorSpace(), kIsGpuCompositing, playback_settings);
1582 }
1583
SupportsBackgroundThreadPriority() const1584 bool SupportsBackgroundThreadPriority() const override { return true; }
1585
1586 private:
1587 gfx::Size size_;
1588 void* pixels_;
1589 };
1590 };
1591
1592 class TileManagerTest : public TestLayerTreeHostBase {
1593 public:
1594 // MockLayerTreeHostImpl allows us to intercept tile manager callbacks.
1595 class MockLayerTreeHostImpl : public FakeLayerTreeHostImpl {
1596 public:
MockLayerTreeHostImpl(const LayerTreeSettings & settings,TaskRunnerProvider * task_runner_provider,TaskGraphRunner * task_graph_runner)1597 MockLayerTreeHostImpl(const LayerTreeSettings& settings,
1598 TaskRunnerProvider* task_runner_provider,
1599 TaskGraphRunner* task_graph_runner)
1600 : FakeLayerTreeHostImpl(settings,
1601 task_runner_provider,
1602 task_graph_runner) {}
1603
1604 MOCK_METHOD0(NotifyReadyToActivate, void());
1605 MOCK_METHOD0(NotifyReadyToDraw, void());
1606 MOCK_METHOD0(NotifyAllTileTasksCompleted, void());
1607 };
1608
CreateHostImpl(const LayerTreeSettings & settings,TaskRunnerProvider * task_runner_provider,TaskGraphRunner * task_graph_runner)1609 std::unique_ptr<FakeLayerTreeHostImpl> CreateHostImpl(
1610 const LayerTreeSettings& settings,
1611 TaskRunnerProvider* task_runner_provider,
1612 TaskGraphRunner* task_graph_runner) override {
1613 return std::make_unique<testing::NiceMock<MockLayerTreeHostImpl>>(
1614 settings, task_runner_provider, task_graph_runner);
1615 }
1616
1617 // By default use software compositing (no context provider).
CreateLayerTreeFrameSink()1618 std::unique_ptr<LayerTreeFrameSink> CreateLayerTreeFrameSink() override {
1619 return FakeLayerTreeFrameSink::CreateSoftware();
1620 }
1621
MockHostImpl()1622 MockLayerTreeHostImpl& MockHostImpl() {
1623 return *static_cast<MockLayerTreeHostImpl*>(host_impl());
1624 }
1625 };
1626
1627 // Test to ensure that we call NotifyAllTileTasksCompleted when PrepareTiles is
1628 // called.
TEST_F(TileManagerTest,AllWorkFinished)1629 TEST_F(TileManagerTest, AllWorkFinished) {
1630 // Check with no tile work enqueued.
1631 {
1632 base::RunLoop run_loop;
1633 EXPECT_FALSE(
1634 host_impl()->tile_manager()->HasScheduledTileTasksForTesting());
1635 EXPECT_CALL(MockHostImpl(), NotifyReadyToActivate());
1636 EXPECT_CALL(MockHostImpl(), NotifyReadyToDraw());
1637 EXPECT_CALL(MockHostImpl(), NotifyAllTileTasksCompleted())
1638 .WillOnce(testing::Invoke([&run_loop]() { run_loop.Quit(); }));
1639 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
1640 EXPECT_TRUE(host_impl()->tile_manager()->HasScheduledTileTasksForTesting());
1641 run_loop.Run();
1642 }
1643
1644 // Check that the "schedule more work" path also triggers the expected
1645 // callback.
1646 {
1647 base::RunLoop run_loop;
1648 EXPECT_FALSE(
1649 host_impl()->tile_manager()->HasScheduledTileTasksForTesting());
1650 EXPECT_CALL(MockHostImpl(), NotifyReadyToActivate());
1651 EXPECT_CALL(MockHostImpl(), NotifyReadyToDraw());
1652 EXPECT_CALL(MockHostImpl(), NotifyAllTileTasksCompleted())
1653 .WillOnce(testing::Invoke([&run_loop]() { run_loop.Quit(); }));
1654 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
1655 host_impl()->tile_manager()->SetMoreTilesNeedToBeRasterizedForTesting();
1656 EXPECT_TRUE(host_impl()->tile_manager()->HasScheduledTileTasksForTesting());
1657 run_loop.Run();
1658 }
1659
1660 // Check that if callbacks are called by CheckIfMoreTilesNeedToBePrepared if
1661 // they haven't been called already.
1662 {
1663 base::RunLoop run_loop;
1664 EXPECT_FALSE(
1665 host_impl()->tile_manager()->HasScheduledTileTasksForTesting());
1666 EXPECT_CALL(MockHostImpl(), NotifyReadyToActivate());
1667 EXPECT_CALL(MockHostImpl(), NotifyReadyToDraw());
1668 EXPECT_CALL(MockHostImpl(), NotifyAllTileTasksCompleted())
1669 .WillOnce(testing::Invoke([&run_loop]() { run_loop.Quit(); }));
1670 host_impl()->tile_manager()->ResetSignalsForTesting();
1671 host_impl()->tile_manager()->SetMoreTilesNeedToBeRasterizedForTesting();
1672 host_impl()->tile_manager()->CheckIfMoreTilesNeedToBePreparedForTesting();
1673 run_loop.Run();
1674 }
1675
1676 // Same test as above but with SMOOTHNESS_TAKES_PRIORITY.
1677 {
1678 base::RunLoop run_loop;
1679 EXPECT_FALSE(
1680 host_impl()->tile_manager()->HasScheduledTileTasksForTesting());
1681 EXPECT_CALL(MockHostImpl(), NotifyReadyToActivate());
1682 EXPECT_CALL(MockHostImpl(), NotifyReadyToDraw());
1683 EXPECT_CALL(MockHostImpl(), NotifyAllTileTasksCompleted())
1684 .WillOnce(testing::Invoke([&run_loop]() { run_loop.Quit(); }));
1685 host_impl()->tile_manager()->ResetSignalsForTesting();
1686 auto global_state = host_impl()->global_tile_state();
1687 global_state.tree_priority = SMOOTHNESS_TAKES_PRIORITY;
1688 host_impl()->tile_manager()->SetGlobalStateForTesting(global_state);
1689 host_impl()->tile_manager()->SetMoreTilesNeedToBeRasterizedForTesting();
1690 host_impl()->tile_manager()->CheckIfMoreTilesNeedToBePreparedForTesting();
1691 run_loop.Run();
1692 }
1693 }
1694
TEST_F(TileManagerTest,ActivateAndDrawWhenOOM)1695 TEST_F(TileManagerTest, ActivateAndDrawWhenOOM) {
1696 SetupDefaultTrees(gfx::Size(1000, 1000));
1697
1698 auto global_state = host_impl()->global_tile_state();
1699 global_state.hard_memory_limit_in_bytes = 1u;
1700 global_state.soft_memory_limit_in_bytes = 1u;
1701
1702 {
1703 base::RunLoop run_loop;
1704 EXPECT_FALSE(
1705 host_impl()->tile_manager()->HasScheduledTileTasksForTesting());
1706 EXPECT_CALL(MockHostImpl(), NotifyReadyToActivate());
1707 EXPECT_CALL(MockHostImpl(), NotifyReadyToDraw());
1708 EXPECT_CALL(MockHostImpl(), NotifyAllTileTasksCompleted())
1709 .WillOnce(testing::Invoke([&run_loop]() { run_loop.Quit(); }));
1710 host_impl()->tile_manager()->PrepareTiles(global_state);
1711 EXPECT_TRUE(host_impl()->tile_manager()->HasScheduledTileTasksForTesting());
1712 run_loop.Run();
1713 }
1714
1715 EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToDraw());
1716 EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToActivate());
1717 EXPECT_TRUE(host_impl()->notify_tile_state_changed_called());
1718
1719 // Next PrepareTiles should skip NotifyTileStateChanged since all tiles
1720 // are marked oom already.
1721 {
1722 base::RunLoop run_loop;
1723 host_impl()->set_notify_tile_state_changed_called(false);
1724 EXPECT_CALL(MockHostImpl(), NotifyReadyToActivate());
1725 EXPECT_CALL(MockHostImpl(), NotifyReadyToDraw());
1726 EXPECT_CALL(MockHostImpl(), NotifyAllTileTasksCompleted())
1727 .WillOnce(testing::Invoke([&run_loop]() { run_loop.Quit(); }));
1728 host_impl()->tile_manager()->PrepareTiles(global_state);
1729 run_loop.Run();
1730 EXPECT_FALSE(host_impl()->notify_tile_state_changed_called());
1731 }
1732 }
1733
1734 class PixelInspectTileManagerTest : public TileManagerTest {
1735 public:
~PixelInspectTileManagerTest()1736 ~PixelInspectTileManagerTest() override {
1737 // Ensure that the host impl doesn't outlive |raster_buffer_provider_|.
1738 TakeHostImpl();
1739 }
1740
SetUp()1741 void SetUp() override {
1742 TileManagerTest::SetUp();
1743 // Use a RasterBufferProvider that will let us inspect pixels.
1744 host_impl()->tile_manager()->SetRasterBufferProviderForTesting(
1745 &raster_buffer_provider_);
1746 }
1747
1748 private:
1749 TestSoftwareRasterBufferProvider raster_buffer_provider_;
1750 };
1751
TEST_F(PixelInspectTileManagerTest,LowResHasNoImage)1752 TEST_F(PixelInspectTileManagerTest, LowResHasNoImage) {
1753 gfx::Size size(10, 12);
1754 TileResolution resolutions[] = {HIGH_RESOLUTION, LOW_RESOLUTION};
1755
1756 for (size_t i = 0; i < base::size(resolutions); ++i) {
1757 SCOPED_TRACE(resolutions[i]);
1758
1759 // Make a RasterSource that will draw a blue bitmap image.
1760 sk_sp<SkSurface> surface =
1761 SkSurface::MakeRasterN32Premul(size.width(), size.height());
1762 ASSERT_NE(surface, nullptr);
1763 surface->getCanvas()->clear(SK_ColorBLUE);
1764 sk_sp<SkImage> blue_image = surface->makeImageSnapshot();
1765
1766 std::unique_ptr<FakeRecordingSource> recording_source =
1767 FakeRecordingSource::CreateFilledRecordingSource(size);
1768 recording_source->SetBackgroundColor(SK_ColorTRANSPARENT);
1769 recording_source->SetRequiresClear(true);
1770 PaintFlags flags;
1771 flags.setColor(SK_ColorGREEN);
1772 recording_source->add_draw_rect_with_flags(gfx::Rect(size), flags);
1773 recording_source->add_draw_image(std::move(blue_image), gfx::Point());
1774 recording_source->Rerecord();
1775 scoped_refptr<RasterSource> raster = recording_source->CreateRasterSource();
1776
1777 FakePictureLayerTilingClient tiling_client;
1778 tiling_client.SetTileSize(size);
1779
1780 std::unique_ptr<PictureLayerImpl> layer =
1781 PictureLayerImpl::Create(host_impl()->active_tree(), 1);
1782 PictureLayerTilingSet* tiling_set = layer->picture_layer_tiling_set();
1783 layer->set_contributes_to_drawn_render_surface(true);
1784
1785 auto* tiling = tiling_set->AddTiling(gfx::AxisTransform2d(), raster);
1786 tiling->set_resolution(resolutions[i]);
1787 tiling->CreateAllTilesForTesting();
1788 tiling->SetTilePriorityRectsForTesting(
1789 gfx::Rect(size), // Visible rect.
1790 gfx::Rect(size), // Skewport rect.
1791 gfx::Rect(size), // Soon rect.
1792 gfx::Rect(size)); // Eventually rect.
1793
1794 // SMOOTHNESS_TAKES_PRIORITY ensures that we will actually raster
1795 // LOW_RESOLUTION tiles, otherwise they are skipped.
1796 host_impl()->SetTreePriority(SMOOTHNESS_TAKES_PRIORITY);
1797
1798 // Call PrepareTiles and wait for it to complete.
1799 auto* tile_manager = host_impl()->tile_manager();
1800 base::RunLoop run_loop;
1801 EXPECT_CALL(MockHostImpl(), NotifyAllTileTasksCompleted())
1802 .WillOnce(testing::Invoke([&run_loop]() { run_loop.Quit(); }));
1803 tile_manager->PrepareTiles(host_impl()->global_tile_state());
1804 run_loop.Run();
1805 tile_manager->CheckForCompletedTasks();
1806
1807 Tile* tile = tiling->TileAt(0, 0);
1808 // The tile in the tiling was rastered.
1809 EXPECT_EQ(TileDrawInfo::RESOURCE_MODE, tile->draw_info().mode());
1810 EXPECT_TRUE(tile->draw_info().IsReadyToDraw());
1811
1812 gfx::Size resource_size = tile->draw_info().resource_size();
1813 SkColorType ct = ResourceFormatToClosestSkColorType(
1814 TestSoftwareRasterBufferProvider::kIsGpuCompositing,
1815 TestSoftwareRasterBufferProvider::kResourceFormat);
1816 auto info = SkImageInfo::Make(resource_size.width(), resource_size.height(),
1817 ct, kPremul_SkAlphaType);
1818 // CreateLayerTreeFrameSink() sets up a software compositing, so the
1819 // tile resource will be a bitmap.
1820 auto* backing = static_cast<TestSoftwareBacking*>(
1821 tile->draw_info().GetResource().software_backing());
1822 SkBitmap bitmap;
1823 bitmap.installPixels(info, backing->pixels.get(), info.minRowBytes());
1824
1825 for (int x = 0; x < size.width(); ++x) {
1826 for (int y = 0; y < size.height(); ++y) {
1827 SCOPED_TRACE(y);
1828 SCOPED_TRACE(x);
1829 if (resolutions[i] == LOW_RESOLUTION) {
1830 // Since it's low res, the bitmap was not drawn, and the background
1831 // (green) is visible instead.
1832 ASSERT_EQ(SK_ColorGREEN, bitmap.getColor(x, y));
1833 } else {
1834 EXPECT_EQ(HIGH_RESOLUTION, resolutions[i]);
1835 // Since it's high res, the bitmap (blue) was drawn, and the
1836 // background is not visible.
1837 ASSERT_EQ(SK_ColorBLUE, bitmap.getColor(x, y));
1838 }
1839 }
1840 }
1841 }
1842 }
1843
1844 class ActivationTasksDoNotBlockReadyToDrawTest : public TileManagerTest {
1845 protected:
CreateTaskGraphRunner()1846 std::unique_ptr<TaskGraphRunner> CreateTaskGraphRunner() override {
1847 return std::make_unique<SynchronousTaskGraphRunner>();
1848 }
1849
CreateLayerTreeFrameSink()1850 std::unique_ptr<LayerTreeFrameSink> CreateLayerTreeFrameSink() override {
1851 return FakeLayerTreeFrameSink::Create3dForGpuRasterization();
1852 }
1853 };
1854
TEST_F(ActivationTasksDoNotBlockReadyToDrawTest,ActivationTasksDoNotBlockReadyToDraw)1855 TEST_F(ActivationTasksDoNotBlockReadyToDrawTest,
1856 ActivationTasksDoNotBlockReadyToDraw) {
1857 const gfx::Size layer_bounds(1000, 1000);
1858
1859 EXPECT_TRUE(host_impl()->use_gpu_rasterization());
1860
1861 // Active tree has no non-solid tiles, so it will generate no tile tasks.
1862 std::unique_ptr<FakeRecordingSource> active_tree_recording_source =
1863 FakeRecordingSource::CreateFilledRecordingSource(layer_bounds);
1864
1865 PaintFlags solid_flags;
1866 SkColor solid_color = SkColorSetARGB(255, 12, 23, 34);
1867 solid_flags.setColor(solid_color);
1868 active_tree_recording_source->add_draw_rect_with_flags(
1869 gfx::Rect(layer_bounds), solid_flags);
1870
1871 active_tree_recording_source->Rerecord();
1872
1873 // Pending tree has non-solid tiles, so it will generate tile tasks.
1874 std::unique_ptr<FakeRecordingSource> pending_tree_recording_source =
1875 FakeRecordingSource::CreateFilledRecordingSource(layer_bounds);
1876 SkColor non_solid_color = SkColorSetARGB(128, 45, 56, 67);
1877 PaintFlags non_solid_flags;
1878 non_solid_flags.setColor(non_solid_color);
1879
1880 pending_tree_recording_source->add_draw_rect_with_flags(
1881 gfx::Rect(5, 5, 10, 10), non_solid_flags);
1882 pending_tree_recording_source->Rerecord();
1883
1884 scoped_refptr<RasterSource> active_tree_raster_source =
1885 active_tree_recording_source->CreateRasterSource();
1886 scoped_refptr<RasterSource> pending_tree_raster_source =
1887 pending_tree_recording_source->CreateRasterSource();
1888
1889 SetupTrees(pending_tree_raster_source, active_tree_raster_source);
1890 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
1891
1892 // The first task to run should be ReadyToDraw (this should not be blocked by
1893 // the tasks required for activation).
1894 base::RunLoop run_loop;
1895 EXPECT_CALL(MockHostImpl(), NotifyReadyToDraw())
1896 .WillOnce(testing::Invoke([&run_loop]() { run_loop.Quit(); }));
1897 static_cast<SynchronousTaskGraphRunner*>(task_graph_runner())
1898 ->RunSingleTaskForTesting();
1899 run_loop.Run();
1900 }
1901
1902 class PartialRasterTileManagerTest : public TileManagerTest {
1903 public:
CreateSettings()1904 LayerTreeSettings CreateSettings() override {
1905 auto settings = TileManagerTest::CreateSettings();
1906 settings.use_partial_raster = true;
1907 return settings;
1908 }
1909 };
1910
1911 // Ensures that if a raster task is cancelled, it gets returned to the resource
1912 // pool with an invalid content ID, not with its invalidated content ID.
TEST_F(PartialRasterTileManagerTest,CancelledTasksHaveNoContentId)1913 TEST_F(PartialRasterTileManagerTest, CancelledTasksHaveNoContentId) {
1914 // Create a FakeTileTaskManagerImpl and set it on the tile manager so that all
1915 // scheduled work is immediately cancelled.
1916
1917 host_impl()->tile_manager()->SetTileTaskManagerForTesting(
1918 std::make_unique<FakeTileTaskManagerImpl>());
1919
1920 // Pick arbitrary IDs - they don't really matter as long as they're constant.
1921 const int kLayerId = 7;
1922 const uint64_t kInvalidatedId = 43;
1923 const gfx::Size kTileSize(128, 128);
1924
1925 scoped_refptr<FakeRasterSource> pending_raster_source =
1926 FakeRasterSource::CreateFilled(kTileSize);
1927 host_impl()->CreatePendingTree();
1928 LayerTreeImpl* pending_tree = host_impl()->pending_tree();
1929 pending_tree->SetDeviceViewportRect(
1930 host_impl()->active_tree()->GetDeviceViewport());
1931
1932 // Steal from the recycled tree.
1933 std::unique_ptr<FakePictureLayerImpl> pending_layer =
1934 FakePictureLayerImpl::Create(pending_tree, kLayerId,
1935 pending_raster_source);
1936 pending_layer->SetDrawsContent(true);
1937
1938 // The bounds() just mirror the raster source size.
1939 pending_layer->SetBounds(pending_layer->raster_source()->GetSize());
1940 SetupRootProperties(pending_layer.get());
1941 pending_tree->SetRootLayerForTesting(std::move(pending_layer));
1942
1943 // Add tilings/tiles for the layer.
1944 UpdateDrawProperties(host_impl()->pending_tree());
1945
1946 // Build the raster queue and invalidate the top tile.
1947 std::unique_ptr<RasterTilePriorityQueue> queue(host_impl()->BuildRasterQueue(
1948 SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL));
1949 EXPECT_FALSE(queue->IsEmpty());
1950 queue->Top().tile()->SetInvalidated(gfx::Rect(), kInvalidatedId);
1951
1952 // PrepareTiles to schedule tasks. Due to the FakeTileTaskManagerImpl,
1953 // these tasks will immediately be canceled.
1954 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
1955
1956 // Make sure that the tile we invalidated above was not returned to the pool
1957 // with its invalidated resource ID.
1958 gfx::Rect total_invalidated_rect;
1959 EXPECT_FALSE(host_impl()->resource_pool()->TryAcquireResourceForPartialRaster(
1960 kInvalidatedId + 1, gfx::Rect(), kInvalidatedId, &total_invalidated_rect,
1961 gfx::ColorSpace::CreateSRGB()));
1962 EXPECT_EQ(gfx::Rect(), total_invalidated_rect);
1963
1964 // Free our host_impl_ before the tile_task_manager we passed it, as it
1965 // will use that class in clean up.
1966 TakeHostImpl();
1967 }
1968
1969 // FakeRasterBufferProviderImpl that verifies the resource content ID of raster
1970 // tasks.
1971 class VerifyResourceContentIdRasterBufferProvider
1972 : public FakeRasterBufferProviderImpl {
1973 public:
VerifyResourceContentIdRasterBufferProvider(uint64_t expected_content_id)1974 explicit VerifyResourceContentIdRasterBufferProvider(
1975 uint64_t expected_content_id)
1976 : expected_content_id_(expected_content_id) {}
1977 ~VerifyResourceContentIdRasterBufferProvider() override = default;
1978
1979 // RasterBufferProvider methods.
AcquireBufferForRaster(const ResourcePool::InUsePoolResource & resource,uint64_t resource_content_id,uint64_t previous_content_id,bool depends_on_at_raster_decodes,bool depends_on_hardware_accelerated_jpeg_candidates,bool depends_on_hardware_accelerated_webp_candidates)1980 std::unique_ptr<RasterBuffer> AcquireBufferForRaster(
1981 const ResourcePool::InUsePoolResource& resource,
1982 uint64_t resource_content_id,
1983 uint64_t previous_content_id,
1984 bool depends_on_at_raster_decodes,
1985 bool depends_on_hardware_accelerated_jpeg_candidates,
1986 bool depends_on_hardware_accelerated_webp_candidates) override {
1987 EXPECT_EQ(expected_content_id_, resource_content_id);
1988 return nullptr;
1989 }
1990
1991 private:
1992 uint64_t expected_content_id_;
1993 };
1994
1995 // Runs a test to ensure that partial raster is either enabled or disabled,
1996 // depending on |partial_raster_enabled|'s value. Takes ownership of host_impl
1997 // so that cleanup order can be controlled.
RunPartialRasterCheck(std::unique_ptr<LayerTreeHostImpl> host_impl,bool partial_raster_enabled)1998 void RunPartialRasterCheck(std::unique_ptr<LayerTreeHostImpl> host_impl,
1999 bool partial_raster_enabled) {
2000 // Pick arbitrary IDs - they don't really matter as long as they're constant.
2001 const int kLayerId = 7;
2002 const uint64_t kInvalidatedId = 43;
2003 const uint64_t kExpectedId = partial_raster_enabled ? kInvalidatedId : 0u;
2004 const gfx::Size kTileSize(128, 128);
2005
2006 // Create a VerifyResourceContentIdTileTaskManager to ensure that the
2007 // raster task we see is created with |kExpectedId|.
2008 host_impl->tile_manager()->SetTileTaskManagerForTesting(
2009 std::make_unique<FakeTileTaskManagerImpl>());
2010
2011 VerifyResourceContentIdRasterBufferProvider raster_buffer_provider(
2012 kExpectedId);
2013 host_impl->tile_manager()->SetRasterBufferProviderForTesting(
2014 &raster_buffer_provider);
2015
2016 // Ensure there's a resource with our |kInvalidatedId| in the resource pool.
2017 ResourcePool::InUsePoolResource resource =
2018 host_impl->resource_pool()->AcquireResource(
2019 kTileSize, viz::RGBA_8888, gfx::ColorSpace::CreateSRGB());
2020
2021 resource.set_software_backing(std::make_unique<TestSoftwareBacking>());
2022 host_impl->resource_pool()->PrepareForExport(resource);
2023
2024 host_impl->resource_pool()->OnContentReplaced(resource, kInvalidatedId);
2025 host_impl->resource_pool()->ReleaseResource(std::move(resource));
2026
2027 scoped_refptr<FakeRasterSource> pending_raster_source =
2028 FakeRasterSource::CreateFilled(kTileSize);
2029 host_impl->CreatePendingTree();
2030 LayerTreeImpl* pending_tree = host_impl->pending_tree();
2031 pending_tree->SetDeviceViewportRect(
2032 host_impl->active_tree()->GetDeviceViewport());
2033
2034 std::unique_ptr<FakePictureLayerImpl> pending_layer =
2035 FakePictureLayerImpl::Create(pending_tree, kLayerId,
2036 pending_raster_source);
2037 pending_layer->SetDrawsContent(true);
2038
2039 // The bounds() just mirror the raster source size.
2040 pending_layer->SetBounds(pending_layer->raster_source()->GetSize());
2041 SetupRootProperties(pending_layer.get());
2042 pending_tree->SetRootLayerForTesting(std::move(pending_layer));
2043
2044 // Add tilings/tiles for the layer.
2045 UpdateDrawProperties(pending_tree);
2046
2047 // Build the raster queue and invalidate the top tile.
2048 std::unique_ptr<RasterTilePriorityQueue> queue(host_impl->BuildRasterQueue(
2049 SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL));
2050 EXPECT_FALSE(queue->IsEmpty());
2051 queue->Top().tile()->SetInvalidated(gfx::Rect(), kInvalidatedId);
2052
2053 // PrepareTiles to schedule tasks. Due to the
2054 // VerifyPreviousContentRasterBufferProvider, these tasks will verified and
2055 // cancelled.
2056 host_impl->tile_manager()->PrepareTiles(host_impl->global_tile_state());
2057
2058 // Free our host_impl before the verifying_task_manager we passed it, as it
2059 // will use that class in clean up.
2060 host_impl = nullptr;
2061 }
2062
RunPartialTileDecodeCheck(std::unique_ptr<LayerTreeHostImpl> host_impl,bool partial_raster_enabled)2063 void RunPartialTileDecodeCheck(std::unique_ptr<LayerTreeHostImpl> host_impl,
2064 bool partial_raster_enabled) {
2065 // Pick arbitrary IDs - they don't really matter as long as they're constant.
2066 const int kLayerId = 7;
2067 const uint64_t kInvalidatedId = 43;
2068 const uint64_t kExpectedId = partial_raster_enabled ? kInvalidatedId : 0u;
2069 const gfx::Size kTileSize(400, 400);
2070
2071 host_impl->tile_manager()->SetTileTaskManagerForTesting(
2072 std::make_unique<FakeTileTaskManagerImpl>());
2073
2074 // Create a VerifyResourceContentIdTileTaskManager to ensure that the
2075 // raster task we see is created with |kExpectedId|.
2076 VerifyResourceContentIdRasterBufferProvider raster_buffer_provider(
2077 kExpectedId);
2078 host_impl->tile_manager()->SetRasterBufferProviderForTesting(
2079 &raster_buffer_provider);
2080
2081 // Ensure there's a resource with our |kInvalidatedId| in the resource pool.
2082 ResourcePool::InUsePoolResource resource =
2083 host_impl->resource_pool()->AcquireResource(
2084 kTileSize, viz::RGBA_8888, gfx::ColorSpace::CreateSRGB());
2085 host_impl->resource_pool()->OnContentReplaced(resource, kInvalidatedId);
2086 host_impl->resource_pool()->ReleaseResource(std::move(resource));
2087
2088 const gfx::Size layer_bounds(500, 500);
2089
2090 std::unique_ptr<FakeRecordingSource> recording_source =
2091 FakeRecordingSource::CreateFilledRecordingSource(layer_bounds);
2092 recording_source->set_fill_with_nonsolid_color(true);
2093
2094 int dimension = 250;
2095 PaintImage image1 =
2096 CreateDiscardablePaintImage(gfx::Size(dimension, dimension));
2097 PaintImage image2 =
2098 CreateDiscardablePaintImage(gfx::Size(dimension, dimension));
2099 PaintImage image3 =
2100 CreateDiscardablePaintImage(gfx::Size(dimension, dimension));
2101 PaintImage image4 =
2102 CreateDiscardablePaintImage(gfx::Size(dimension, dimension));
2103 recording_source->add_draw_image(image1, gfx::Point(0, 0));
2104 recording_source->add_draw_image(image2, gfx::Point(300, 0));
2105 recording_source->add_draw_image(image3, gfx::Point(0, 300));
2106 recording_source->add_draw_image(image4, gfx::Point(300, 300));
2107
2108 recording_source->Rerecord();
2109
2110 scoped_refptr<FakeRasterSource> pending_raster_source =
2111 FakeRasterSource::CreateFromRecordingSource(recording_source.get());
2112
2113 host_impl->CreatePendingTree();
2114 LayerTreeImpl* pending_tree = host_impl->pending_tree();
2115 pending_tree->SetDeviceViewportRect(
2116 host_impl->active_tree()->GetDeviceViewport());
2117
2118 // Steal from the recycled tree.
2119 std::unique_ptr<FakePictureLayerImpl> pending_layer =
2120 FakePictureLayerImpl::Create(pending_tree, kLayerId,
2121 pending_raster_source);
2122 pending_layer->SetDrawsContent(true);
2123
2124 // The bounds() just mirror the raster source size.
2125 pending_layer->SetBounds(pending_layer->raster_source()->GetSize());
2126 SetupRootProperties(pending_layer.get());
2127 pending_tree->SetRootLayerForTesting(std::move(pending_layer));
2128
2129 // Add tilings/tiles for the layer.
2130 UpdateDrawProperties(pending_tree);
2131
2132 // Build the raster queue and invalidate the top tile if partial raster is
2133 // enabled.
2134 std::unique_ptr<RasterTilePriorityQueue> queue(host_impl->BuildRasterQueue(
2135 SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL));
2136 ASSERT_FALSE(queue->IsEmpty());
2137 Tile* tile = queue->Top().tile();
2138 if (partial_raster_enabled)
2139 tile->SetInvalidated(gfx::Rect(200, 200), kInvalidatedId);
2140
2141 // PrepareTiles to schedule tasks. Due to the
2142 // VerifyPreviousContentRasterBufferProvider, these tasks will verified and
2143 // cancelled.
2144 host_impl->tile_manager()->PrepareTiles(host_impl->global_tile_state());
2145
2146 // Tile will have 1 dependent decode task if we decode images only in the
2147 // invalidated rect. Otherwise it will have 4.
2148 EXPECT_EQ(
2149 host_impl->tile_manager()->decode_tasks_for_testing(tile->id()).size(),
2150 partial_raster_enabled ? 1u : 4u);
2151
2152 // Free our host_impl before the verifying_task_manager we passed it, as it
2153 // will use that class in clean up.
2154 host_impl = nullptr;
2155 }
2156
2157 // Ensures that the tile manager successfully reuses tiles when partial
2158 // raster is enabled.
TEST_F(PartialRasterTileManagerTest,PartialRasterSuccessfullyEnabled)2159 TEST_F(PartialRasterTileManagerTest, PartialRasterSuccessfullyEnabled) {
2160 RunPartialRasterCheck(TakeHostImpl(), true /* partial_raster_enabled */);
2161 }
2162
TEST_F(PartialRasterTileManagerTest,PartialTileImageDecode)2163 TEST_F(PartialRasterTileManagerTest, PartialTileImageDecode) {
2164 RunPartialTileDecodeCheck(TakeHostImpl(), true /* partial_raster_enabled */);
2165 }
2166
TEST_F(PartialRasterTileManagerTest,CompleteTileImageDecode)2167 TEST_F(PartialRasterTileManagerTest, CompleteTileImageDecode) {
2168 RunPartialTileDecodeCheck(TakeHostImpl(),
2169 false /* partial_raster_disabled */);
2170 }
2171
2172 // Ensures that the tile manager does not attempt to reuse tiles when partial
2173 // raster is disabled.
TEST_F(TileManagerTest,PartialRasterSuccessfullyDisabled)2174 TEST_F(TileManagerTest, PartialRasterSuccessfullyDisabled) {
2175 RunPartialRasterCheck(TakeHostImpl(), false /* partial_raster_enabled */);
2176 }
2177
2178 class InvalidResourceRasterBufferProvider
2179 : public FakeRasterBufferProviderImpl {
2180 public:
AcquireBufferForRaster(const ResourcePool::InUsePoolResource & resource,uint64_t resource_content_id,uint64_t previous_content_id,bool depends_on_at_raster_decodes,bool depends_on_hardware_accelerated_jpeg_candidates,bool depends_on_hardware_accelerated_webp_candidates)2181 std::unique_ptr<RasterBuffer> AcquireBufferForRaster(
2182 const ResourcePool::InUsePoolResource& resource,
2183 uint64_t resource_content_id,
2184 uint64_t previous_content_id,
2185 bool depends_on_at_raster_decodes,
2186 bool depends_on_hardware_accelerated_jpeg_candidates,
2187 bool depends_on_hardware_accelerated_webp_candidates) override {
2188 if (!resource.gpu_backing()) {
2189 auto backing = std::make_unique<StubGpuBacking>();
2190 // Don't set a mailbox to signal invalid resource.
2191 backing->texture_target = 5;
2192 resource.set_gpu_backing(std::move(backing));
2193 }
2194 return std::make_unique<FakeRasterBuffer>();
2195 }
2196
2197 private:
2198 class StubGpuBacking : public ResourcePool::GpuBacking {
2199 public:
OnMemoryDump(base::trace_event::ProcessMemoryDump * pmd,const base::trace_event::MemoryAllocatorDumpGuid & buffer_dump_guid,uint64_t tracing_process_id,int importance) const2200 void OnMemoryDump(
2201 base::trace_event::ProcessMemoryDump* pmd,
2202 const base::trace_event::MemoryAllocatorDumpGuid& buffer_dump_guid,
2203 uint64_t tracing_process_id,
2204 int importance) const override {}
2205 };
2206 };
2207
2208 class InvalidResourceTileManagerTest : public TileManagerTest {
2209 protected:
CreateLayerTreeFrameSink()2210 std::unique_ptr<LayerTreeFrameSink> CreateLayerTreeFrameSink() override {
2211 return FakeLayerTreeFrameSink::Create3d();
2212 }
2213 };
2214
TEST_F(InvalidResourceTileManagerTest,InvalidResource)2215 TEST_F(InvalidResourceTileManagerTest, InvalidResource) {
2216 auto* tile_manager = host_impl()->tile_manager();
2217 InvalidResourceRasterBufferProvider raster_buffer_provider;
2218 tile_manager->SetRasterBufferProviderForTesting(&raster_buffer_provider);
2219
2220 gfx::Size size(10, 12);
2221 FakePictureLayerTilingClient tiling_client;
2222 tiling_client.SetTileSize(size);
2223
2224 std::unique_ptr<PictureLayerImpl> layer =
2225 PictureLayerImpl::Create(host_impl()->active_tree(), 1);
2226 layer->set_contributes_to_drawn_render_surface(true);
2227
2228 auto* tiling = layer->picture_layer_tiling_set()->AddTiling(
2229 gfx::AxisTransform2d(), FakeRasterSource::CreateFilled(size));
2230 tiling->set_resolution(HIGH_RESOLUTION);
2231 tiling->CreateAllTilesForTesting();
2232 tiling->SetTilePriorityRectsForTesting(gfx::Rect(size), // Visible rect.
2233 gfx::Rect(size), // Skewport rect.
2234 gfx::Rect(size), // Soon rect.
2235 gfx::Rect(size)); // Eventually rect.
2236
2237 base::RunLoop run_loop;
2238 EXPECT_CALL(MockHostImpl(), NotifyAllTileTasksCompleted())
2239 .WillOnce(testing::Invoke([&run_loop]() { run_loop.Quit(); }));
2240 tile_manager->PrepareTiles(host_impl()->global_tile_state());
2241 run_loop.Run();
2242 tile_manager->CheckForCompletedTasks();
2243
2244 Tile* tile = tiling->TileAt(0, 0);
2245 ASSERT_TRUE(tile);
2246 // The tile in the tiling was rastered, but didn't get a resource.
2247 EXPECT_TRUE(tile->draw_info().IsReadyToDraw());
2248 EXPECT_EQ(TileDrawInfo::OOM_MODE, tile->draw_info().mode());
2249
2250 // Ensure that the host impl doesn't outlive |raster_buffer_provider|.
2251 layer = nullptr;
2252 TakeHostImpl();
2253 }
2254
2255 // FakeRasterBufferProviderImpl that allows us to mock ready to draw
2256 // functionality.
2257 class MockReadyToDrawRasterBufferProviderImpl
2258 : public FakeRasterBufferProviderImpl {
2259 public:
2260 MOCK_CONST_METHOD1(IsResourceReadyToDraw,
2261 bool(const ResourcePool::InUsePoolResource& resource));
2262 MOCK_CONST_METHOD3(
2263 SetReadyToDrawCallback,
2264 uint64_t(
2265 const std::vector<const ResourcePool::InUsePoolResource*>& resources,
2266 base::OnceClosure callback,
2267 uint64_t pending_callback_id));
2268
AcquireBufferForRaster(const ResourcePool::InUsePoolResource & resource,uint64_t resource_content_id,uint64_t previous_content_id,bool depends_on_at_raster_decodes,bool depends_on_hardware_accelerated_jpeg_candidates,bool depends_on_hardware_accelerated_webp_candidates)2269 std::unique_ptr<RasterBuffer> AcquireBufferForRaster(
2270 const ResourcePool::InUsePoolResource& resource,
2271 uint64_t resource_content_id,
2272 uint64_t previous_content_id,
2273 bool depends_on_at_raster_decodes,
2274 bool depends_on_hardware_accelerated_jpeg_candidates,
2275 bool depends_on_hardware_accelerated_webp_candidates) override {
2276 if (!resource.software_backing())
2277 resource.set_software_backing(std::make_unique<TestSoftwareBacking>());
2278 return std::make_unique<FakeRasterBuffer>();
2279 }
2280 };
2281
2282 class TileManagerReadyToDrawTest : public TileManagerTest {
2283 public:
~TileManagerReadyToDrawTest()2284 ~TileManagerReadyToDrawTest() override {
2285 // Ensure that the host impl doesn't outlive |raster_buffer_provider_|.
2286 TakeHostImpl();
2287 }
2288
SetUp()2289 void SetUp() override {
2290 TileManagerTest::SetUp();
2291 host_impl()->tile_manager()->SetRasterBufferProviderForTesting(
2292 &mock_raster_buffer_provider_);
2293
2294 const gfx::Size layer_bounds(1000, 1000);
2295
2296 solid_color_recording_source_ =
2297 FakeRecordingSource::CreateFilledRecordingSource(layer_bounds);
2298
2299 PaintFlags solid_flags;
2300 SkColor solid_color = SkColorSetARGB(255, 12, 23, 34);
2301 solid_flags.setColor(solid_color);
2302 solid_color_recording_source_->add_draw_rect_with_flags(
2303 gfx::Rect(layer_bounds), solid_flags);
2304
2305 solid_color_recording_source_->Rerecord();
2306
2307 recording_source_ =
2308 FakeRecordingSource::CreateFilledRecordingSource(layer_bounds);
2309 SkColor non_solid_color = SkColorSetARGB(128, 45, 56, 67);
2310 PaintFlags non_solid_flags;
2311 non_solid_flags.setColor(non_solid_color);
2312
2313 for (int i = 0; i < 100; ++i) {
2314 for (int j = 0; j < 100; ++j) {
2315 recording_source_->add_draw_rect_with_flags(
2316 gfx::Rect(10 * i, 10 * j, 5, 5), non_solid_flags);
2317 }
2318 }
2319 recording_source_->Rerecord();
2320 }
2321
SetupTreesWithActiveTreeTiles()2322 void SetupTreesWithActiveTreeTiles() {
2323 scoped_refptr<RasterSource> active_tree_raster_source =
2324 recording_source_->CreateRasterSource();
2325 scoped_refptr<RasterSource> pending_tree_raster_source =
2326 solid_color_recording_source_->CreateRasterSource();
2327
2328 SetupTrees(pending_tree_raster_source, active_tree_raster_source);
2329 }
2330
SetupTreesWithPendingTreeTiles()2331 void SetupTreesWithPendingTreeTiles() {
2332 scoped_refptr<RasterSource> active_tree_raster_source =
2333 solid_color_recording_source_->CreateRasterSource();
2334 scoped_refptr<RasterSource> pending_tree_raster_source =
2335 recording_source_->CreateRasterSource();
2336
2337 SetupTrees(pending_tree_raster_source, active_tree_raster_source);
2338 }
2339
tile_manager()2340 TileManager* tile_manager() { return host_impl()->tile_manager(); }
mock_raster_buffer_provider()2341 MockReadyToDrawRasterBufferProviderImpl* mock_raster_buffer_provider() {
2342 return &mock_raster_buffer_provider_;
2343 }
2344
2345 private:
2346 StrictMock<MockReadyToDrawRasterBufferProviderImpl>
2347 mock_raster_buffer_provider_;
2348 std::unique_ptr<FakeRecordingSource> recording_source_;
2349 std::unique_ptr<FakeRecordingSource> solid_color_recording_source_;
2350 };
2351
TEST_F(TileManagerReadyToDrawTest,SmoothActivationWaitsOnCallback)2352 TEST_F(TileManagerReadyToDrawTest, SmoothActivationWaitsOnCallback) {
2353 host_impl()->SetTreePriority(SMOOTHNESS_TAKES_PRIORITY);
2354 SetupTreesWithPendingTreeTiles();
2355
2356 base::OnceClosure callback;
2357 {
2358 base::RunLoop run_loop;
2359
2360 // Until we activate our ready to draw callback, treat all resources as not
2361 // ready to draw.
2362 EXPECT_CALL(*mock_raster_buffer_provider(),
2363 IsResourceReadyToDraw(testing::_))
2364 .WillRepeatedly(Return(false));
2365
2366 EXPECT_CALL(*mock_raster_buffer_provider(), SetReadyToDrawCallback(_, _, 0))
2367 .WillOnce([&run_loop, &callback](
2368 const std::vector<const ResourcePool::InUsePoolResource*>&
2369 resources,
2370 base::OnceClosure callback_in,
2371 uint64_t pending_callback_id) {
2372 callback = std::move(callback_in);
2373 run_loop.Quit();
2374 return 1;
2375 });
2376 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
2377 run_loop.Run();
2378 }
2379
2380 EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToDraw());
2381 EXPECT_FALSE(host_impl()->tile_manager()->IsReadyToActivate());
2382
2383 {
2384 base::RunLoop run_loop;
2385 EXPECT_CALL(MockHostImpl(), NotifyReadyToActivate())
2386 .WillOnce(Invoke([&run_loop]() { run_loop.Quit(); }));
2387 EXPECT_CALL(*mock_raster_buffer_provider(),
2388 IsResourceReadyToDraw(testing::_))
2389 .WillRepeatedly(Return(true));
2390 std::move(callback).Run();
2391 run_loop.Run();
2392 }
2393
2394 EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToDraw());
2395 EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToActivate());
2396 }
2397
TEST_F(TileManagerReadyToDrawTest,NonSmoothActivationDoesNotWaitOnCallback)2398 TEST_F(TileManagerReadyToDrawTest, NonSmoothActivationDoesNotWaitOnCallback) {
2399 SetupTreesWithPendingTreeTiles();
2400
2401 // We're using a StrictMock on the RasterBufferProvider, so any function call
2402 // will cause a test failure.
2403 base::RunLoop run_loop;
2404
2405 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
2406 EXPECT_CALL(MockHostImpl(), NotifyReadyToActivate())
2407 .WillOnce(Invoke([&run_loop]() { run_loop.Quit(); }));
2408 run_loop.Run();
2409
2410 EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToDraw());
2411 EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToActivate());
2412 }
2413
TEST_F(TileManagerReadyToDrawTest,SmoothDrawWaitsOnCallback)2414 TEST_F(TileManagerReadyToDrawTest, SmoothDrawWaitsOnCallback) {
2415 host_impl()->SetTreePriority(SMOOTHNESS_TAKES_PRIORITY);
2416 SetupTreesWithActiveTreeTiles();
2417
2418 base::OnceClosure callback;
2419 {
2420 base::RunLoop run_loop;
2421
2422 // Until we activate our ready to draw callback, treat all resources as not
2423 // ready to draw.
2424 EXPECT_CALL(*mock_raster_buffer_provider(),
2425 IsResourceReadyToDraw(testing::_))
2426 .WillRepeatedly(Return(false));
2427
2428 EXPECT_CALL(*mock_raster_buffer_provider(), SetReadyToDrawCallback(_, _, 0))
2429 .WillOnce([&run_loop, &callback](
2430 const std::vector<const ResourcePool::InUsePoolResource*>&
2431 resources,
2432 base::OnceClosure callback_in,
2433 uint64_t pending_callback_id) {
2434 callback = std::move(callback_in);
2435 run_loop.Quit();
2436 return 1;
2437 });
2438 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
2439 run_loop.Run();
2440 }
2441
2442 EXPECT_FALSE(host_impl()->tile_manager()->IsReadyToDraw());
2443 EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToActivate());
2444
2445 {
2446 base::RunLoop run_loop;
2447 EXPECT_CALL(MockHostImpl(), NotifyReadyToDraw())
2448 .WillOnce(testing::Invoke([&run_loop]() { run_loop.Quit(); }));
2449 EXPECT_CALL(*mock_raster_buffer_provider(),
2450 IsResourceReadyToDraw(testing::_))
2451 .WillRepeatedly(Return(true));
2452 std::move(callback).Run();
2453 run_loop.Run();
2454 }
2455
2456 EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToDraw());
2457 EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToActivate());
2458 }
2459
TEST_F(TileManagerReadyToDrawTest,NonSmoothDrawDoesNotWaitOnCallback)2460 TEST_F(TileManagerReadyToDrawTest, NonSmoothDrawDoesNotWaitOnCallback) {
2461 SetupTreesWithActiveTreeTiles();
2462
2463 // We're using a StrictMock on the RasterBufferProvider, so any function call
2464 // will cause a test failure.
2465 base::RunLoop run_loop;
2466
2467 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
2468 EXPECT_CALL(MockHostImpl(), NotifyReadyToDraw())
2469 .WillOnce(Invoke([&run_loop]() { run_loop.Quit(); }));
2470 run_loop.Run();
2471
2472 EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToDraw());
2473 EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToActivate());
2474 }
2475
TEST_F(TileManagerReadyToDrawTest,NoCallbackWhenAlreadyReadyToDraw)2476 TEST_F(TileManagerReadyToDrawTest, NoCallbackWhenAlreadyReadyToDraw) {
2477 host_impl()->SetTreePriority(SMOOTHNESS_TAKES_PRIORITY);
2478 SetupTreesWithPendingTreeTiles();
2479
2480 base::RunLoop run_loop;
2481 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
2482 EXPECT_CALL(MockHostImpl(), NotifyReadyToActivate())
2483 .WillOnce(Invoke([&run_loop]() { run_loop.Quit(); }));
2484 EXPECT_CALL(*mock_raster_buffer_provider(), IsResourceReadyToDraw(_))
2485 .WillRepeatedly(Return(true));
2486 run_loop.Run();
2487
2488 EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToDraw());
2489 EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToActivate());
2490 }
2491
TEST_F(TileManagerReadyToDrawTest,TilePrioritiesUpdated)2492 TEST_F(TileManagerReadyToDrawTest, TilePrioritiesUpdated) {
2493 // Use smoothness as that's a mode in which we wait on resources to be
2494 // ready instead of marking them ready immediately.
2495 host_impl()->SetTreePriority(SMOOTHNESS_TAKES_PRIORITY);
2496 gfx::Size very_small(1, 1);
2497 host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect(very_small));
2498
2499 gfx::Size layer_bounds(1000, 1000);
2500 SetupDefaultTrees(layer_bounds);
2501
2502 // Run until all tile tasks are complete, but don't let any draw callbacks
2503 // finish.
2504 {
2505 base::RunLoop run_loop;
2506 EXPECT_CALL(MockHostImpl(), NotifyAllTileTasksCompleted())
2507 .WillOnce(testing::Invoke([&run_loop]() { run_loop.Quit(); }));
2508
2509 // Until we activate our ready to draw callback, treat all resources as not
2510 // ready to draw.
2511 EXPECT_CALL(*mock_raster_buffer_provider(),
2512 IsResourceReadyToDraw(testing::_))
2513 .WillRepeatedly(Return(false));
2514 EXPECT_CALL(*mock_raster_buffer_provider(), SetReadyToDrawCallback(_, _, _))
2515 .WillRepeatedly(Return(1));
2516 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
2517 run_loop.Run();
2518 }
2519
2520 // Inspect the current state of tiles in this world of cpu done but gpu
2521 // not ready yet.
2522 size_t orig_num_required = 0;
2523 size_t orig_num_prepaint = 0;
2524 std::vector<Tile*> prepaint_tiles;
2525 for (auto* tile : host_impl()->tile_manager()->AllTilesForTesting()) {
2526 if (tile->draw_info().has_resource()) {
2527 if (tile->is_prepaint()) {
2528 orig_num_prepaint++;
2529 prepaint_tiles.push_back(tile);
2530 } else {
2531 orig_num_required++;
2532 }
2533 }
2534 }
2535
2536 // Verify that there exist some prepaint tiles here.
2537 EXPECT_GT(orig_num_prepaint, 0u);
2538 EXPECT_GT(orig_num_required, 0u);
2539
2540 host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect(layer_bounds));
2541 UpdateDrawProperties(host_impl()->active_tree());
2542 UpdateDrawProperties(host_impl()->pending_tree());
2543
2544 // Rerun prepare tiles.
2545 {
2546 base::RunLoop run_loop;
2547 EXPECT_CALL(MockHostImpl(), NotifyAllTileTasksCompleted())
2548 .WillOnce(testing::Invoke([&run_loop]() { run_loop.Quit(); }));
2549 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
2550 run_loop.Run();
2551 }
2552
2553 // Make sure tiles priorities are updated.
2554 size_t final_num_required = 0;
2555 size_t final_num_prepaint = 0;
2556 bool found_one_prepaint_to_required_transition = false;
2557 for (auto* tile : host_impl()->tile_manager()->AllTilesForTesting()) {
2558 if (tile->draw_info().has_resource()) {
2559 if (tile->is_prepaint()) {
2560 final_num_prepaint++;
2561 } else {
2562 final_num_required++;
2563 if (base::Contains(prepaint_tiles, tile)) {
2564 found_one_prepaint_to_required_transition = true;
2565 }
2566 }
2567 }
2568 }
2569
2570 // Tile priorities should be updated and we should have more required
2571 // and fewer prepaint now that the viewport has changed.
2572 EXPECT_GT(final_num_required, orig_num_required);
2573 EXPECT_LT(final_num_prepaint, orig_num_prepaint);
2574 EXPECT_TRUE(found_one_prepaint_to_required_transition);
2575 }
2576
UpdateVisibleRect(FakePictureLayerImpl * layer,const gfx::Rect visible_rect)2577 void UpdateVisibleRect(FakePictureLayerImpl* layer,
2578 const gfx::Rect visible_rect) {
2579 PictureLayerTilingSet* tiling_set = layer->tilings();
2580 for (size_t j = 0; j < tiling_set->num_tilings(); ++j) {
2581 PictureLayerTiling* tiling = tiling_set->tiling_at(j);
2582 tiling->SetTilePriorityRectsForTesting(
2583 visible_rect, // Visible rect.
2584 visible_rect, // Skewport rect.
2585 visible_rect, // Soon rect.
2586 gfx::Rect(0, 0, 1000, 1000)); // Eventually rect.
2587 }
2588 }
2589
TEST_F(TileManagerReadyToDrawTest,ReadyToDrawRespectsRequirementChange)2590 TEST_F(TileManagerReadyToDrawTest, ReadyToDrawRespectsRequirementChange) {
2591 host_impl()->SetTreePriority(SMOOTHNESS_TAKES_PRIORITY);
2592 SetupTreesWithPendingTreeTiles();
2593
2594 // Initially create a tiling with a visible rect of (0, 0, 100, 100) and
2595 // a soon rect of the rest of the layer.
2596 UpdateVisibleRect(pending_layer(), gfx::Rect(0, 0, 100, 100));
2597
2598 // Mark all these tiles as ready to draw.
2599 {
2600 base::RunLoop run_loop;
2601 host_impl()->tile_manager()->DidModifyTilePriorities();
2602 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
2603 EXPECT_CALL(MockHostImpl(), NotifyReadyToActivate())
2604 .WillOnce(Invoke([&run_loop]() { run_loop.Quit(); }));
2605 EXPECT_CALL(*mock_raster_buffer_provider(), IsResourceReadyToDraw(_))
2606 .WillRepeatedly(Return(true));
2607 run_loop.Run();
2608 }
2609
2610 EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToDraw());
2611 EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToActivate());
2612
2613 // Move the viewport to (900, 900, 100, 100), so that we need a different set
2614 // of tilings.
2615 UpdateVisibleRect(pending_layer(), gfx::Rect(900, 900, 100, 100));
2616
2617 EXPECT_CALL(*mock_raster_buffer_provider(), IsResourceReadyToDraw(testing::_))
2618 .WillRepeatedly(Return(false));
2619
2620 base::OnceClosure callback;
2621 {
2622 base::RunLoop run_loop;
2623
2624 EXPECT_CALL(*mock_raster_buffer_provider(), SetReadyToDrawCallback(_, _, 0))
2625 .WillOnce([&run_loop, &callback](
2626 const std::vector<const ResourcePool::InUsePoolResource*>&
2627 resources,
2628 base::OnceClosure callback_in,
2629 uint64_t pending_callback_id) {
2630 callback = std::move(callback_in);
2631 run_loop.Quit();
2632 return 1;
2633 });
2634 host_impl()->tile_manager()->DidModifyTilePriorities();
2635 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
2636 run_loop.Run();
2637 }
2638
2639 EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToDraw());
2640 EXPECT_FALSE(host_impl()->tile_manager()->IsReadyToActivate());
2641
2642 // Now switch back to our original tiling. We should be immediately able to
2643 // activate, as we still have the original tile, and no longer need the
2644 // tiles from the previous callback.
2645 UpdateVisibleRect(pending_layer(), gfx::Rect(0, 0, 100, 100));
2646
2647 {
2648 base::RunLoop run_loop;
2649 host_impl()->tile_manager()->DidModifyTilePriorities();
2650 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
2651 EXPECT_CALL(MockHostImpl(), NotifyReadyToActivate())
2652 .WillOnce(Invoke([&run_loop]() { run_loop.Quit(); }));
2653 run_loop.Run();
2654 }
2655
2656 EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToDraw());
2657 EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToActivate());
2658 }
2659
MakeCheckerablePaintImage(const gfx::Size & size)2660 PaintImage MakeCheckerablePaintImage(const gfx::Size& size) {
2661 auto image = CreateDiscardablePaintImage(size);
2662 return PaintImageBuilder::WithCopy(image)
2663 .set_decoding_mode(PaintImage::DecodingMode::kAsync)
2664 .TakePaintImage();
2665 }
2666
2667 class CheckerImagingTileManagerTest : public TestLayerTreeHostBase {
2668 public:
2669 class MockImageGenerator : public FakePaintImageGenerator {
2670 public:
MockImageGenerator(const gfx::Size & size)2671 explicit MockImageGenerator(const gfx::Size& size)
2672 : FakePaintImageGenerator(
2673 SkImageInfo::MakeN32Premul(size.width(), size.height())) {}
2674
2675 MOCK_METHOD6(GetPixels,
2676 bool(const SkImageInfo&,
2677 void*,
2678 size_t,
2679 size_t,
2680 PaintImage::GeneratorClientId,
2681 uint32_t));
2682 };
2683
TearDown()2684 void TearDown() override {
2685 // Allow all tasks on the image worker to run now. Any scheduled decodes
2686 // will be aborted.
2687 task_runner_->set_run_tasks_synchronously(true);
2688 }
2689
CreateSettings()2690 LayerTreeSettings CreateSettings() override {
2691 auto settings = TestLayerTreeHostBase::CreateSettings();
2692 settings.commit_to_active_tree = false;
2693 settings.enable_checker_imaging = true;
2694 settings.min_image_bytes_to_checker = 512 * 1024;
2695 return settings;
2696 }
2697
CreateHostImpl(const LayerTreeSettings & settings,TaskRunnerProvider * task_runner_provider,TaskGraphRunner * task_graph_runner)2698 std::unique_ptr<FakeLayerTreeHostImpl> CreateHostImpl(
2699 const LayerTreeSettings& settings,
2700 TaskRunnerProvider* task_runner_provider,
2701 TaskGraphRunner* task_graph_runner) override {
2702 task_runner_ = base::MakeRefCounted<SynchronousSimpleTaskRunner>();
2703 return std::make_unique<FakeLayerTreeHostImpl>(
2704 settings, task_runner_provider, task_graph_runner, task_runner_);
2705 }
2706
CreateTaskGraphRunner()2707 std::unique_ptr<TaskGraphRunner> CreateTaskGraphRunner() override {
2708 return std::make_unique<SynchronousTaskGraphRunner>();
2709 }
2710
FlushDecodeTasks()2711 void FlushDecodeTasks() {
2712 while (task_runner_->HasPendingTask()) {
2713 task_runner_->RunUntilIdle();
2714 base::RunLoop().RunUntilIdle();
2715 }
2716 }
2717
CleanUpTileManager()2718 void CleanUpTileManager() {
2719 task_runner_->set_run_tasks_synchronously(true);
2720 host_impl()->tile_manager()->FinishTasksAndCleanUp();
2721 task_runner_->set_run_tasks_synchronously(false);
2722 }
2723
2724 private:
2725 scoped_refptr<SynchronousSimpleTaskRunner> task_runner_;
2726 };
2727
TEST_F(CheckerImagingTileManagerTest,NoImageDecodeDependencyForCheckeredTiles)2728 TEST_F(CheckerImagingTileManagerTest,
2729 NoImageDecodeDependencyForCheckeredTiles) {
2730 const gfx::Size layer_bounds(512, 512);
2731
2732 std::unique_ptr<FakeRecordingSource> recording_source =
2733 FakeRecordingSource::CreateFilledRecordingSource(layer_bounds);
2734 recording_source->set_fill_with_nonsolid_color(true);
2735
2736 auto generator =
2737 sk_make_sp<testing::StrictMock<MockImageGenerator>>(gfx::Size(512, 512));
2738 PaintImage image = PaintImageBuilder::WithDefault()
2739 .set_id(PaintImage::GetNextId())
2740 .set_paint_image_generator(generator)
2741 .set_decoding_mode(PaintImage::DecodingMode::kAsync)
2742 .TakePaintImage();
2743 recording_source->add_draw_image(image, gfx::Point(0, 0));
2744
2745 recording_source->Rerecord();
2746 scoped_refptr<RasterSource> raster_source =
2747 recording_source->CreateRasterSource();
2748
2749 Region invalidation((gfx::Rect(layer_bounds)));
2750 SetupPendingTree(raster_source, layer_bounds, invalidation);
2751
2752 PictureLayerTilingSet* tiling_set =
2753 pending_layer()->picture_layer_tiling_set();
2754 PictureLayerTiling* tiling = tiling_set->tiling_at(0);
2755 tiling->set_resolution(HIGH_RESOLUTION);
2756 tiling->CreateAllTilesForTesting();
2757 tiling->SetTilePriorityRectsForTesting(
2758 gfx::Rect(layer_bounds), // Visible rect.
2759 gfx::Rect(layer_bounds), // Skewport rect.
2760 gfx::Rect(layer_bounds), // Soon rect.
2761 gfx::Rect(layer_bounds)); // Eventually rect.
2762 tiling->set_can_require_tiles_for_activation(true);
2763
2764 // PrepareTiles and synchronously run all tasks added to the TaskGraph. Since
2765 // we are using a strict mock for the SkImageGenerator, if the decode runs as
2766 // a part of raster tasks, the test should fail.
2767 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
2768 EXPECT_TRUE(host_impl()->tile_manager()->HasScheduledTileTasksForTesting());
2769 static_cast<SynchronousTaskGraphRunner*>(task_graph_runner())->RunUntilIdle();
2770 base::RunLoop().RunUntilIdle();
2771 EXPECT_FALSE(host_impl()->tile_manager()->HasScheduledTileTasksForTesting());
2772 }
2773
2774 class EmptyCacheTileManagerTest : public TileManagerTest {
2775 public:
CreateSettings()2776 LayerTreeSettings CreateSettings() override {
2777 auto settings = TileManagerTest::CreateSettings();
2778 settings.decoded_image_working_set_budget_bytes = 0;
2779 return settings;
2780 }
2781 };
2782
TEST_F(EmptyCacheTileManagerTest,AtRasterOnScreenTileRasterTasks)2783 TEST_F(EmptyCacheTileManagerTest, AtRasterOnScreenTileRasterTasks) {
2784 const gfx::Size layer_bounds(500, 500);
2785
2786 std::unique_ptr<FakeRecordingSource> recording_source =
2787 FakeRecordingSource::CreateFilledRecordingSource(layer_bounds);
2788 recording_source->set_fill_with_nonsolid_color(true);
2789
2790 int dimension = 500;
2791 PaintImage image = MakeCheckerablePaintImage(gfx::Size(dimension, dimension));
2792 recording_source->add_draw_image(image, gfx::Point(0, 0));
2793
2794 recording_source->Rerecord();
2795 scoped_refptr<RasterSource> raster_source =
2796 recording_source->CreateRasterSource();
2797
2798 gfx::Size tile_size(500, 500);
2799 Region invalidation((gfx::Rect(layer_bounds)));
2800 SetupPendingTree(raster_source, tile_size, invalidation);
2801
2802 PictureLayerTilingSet* tiling_set =
2803 pending_layer()->picture_layer_tiling_set();
2804 PictureLayerTiling* pending_tiling = tiling_set->tiling_at(0);
2805 pending_tiling->set_resolution(HIGH_RESOLUTION);
2806 pending_tiling->CreateAllTilesForTesting();
2807 pending_tiling->SetTilePriorityRectsForTesting(
2808 gfx::Rect(layer_bounds), // Visible rect.
2809 gfx::Rect(layer_bounds), // Skewport rect.
2810 gfx::Rect(layer_bounds), // Soon rect.
2811 gfx::Rect(layer_bounds)); // Eventually rect.
2812
2813 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
2814 // There will be a tile raster task and an image decode task.
2815 EXPECT_TRUE(pending_tiling->TileAt(0, 0)->HasRasterTask());
2816 EXPECT_TRUE(host_impl()->tile_manager()->HasScheduledTileTasksForTesting());
2817 }
2818
TEST_F(EmptyCacheTileManagerTest,AtRasterPrepaintTileRasterTasksSkipped)2819 TEST_F(EmptyCacheTileManagerTest, AtRasterPrepaintTileRasterTasksSkipped) {
2820 const gfx::Size layer_bounds(500, 500);
2821
2822 std::unique_ptr<FakeRecordingSource> recording_source =
2823 FakeRecordingSource::CreateFilledRecordingSource(layer_bounds);
2824 recording_source->set_fill_with_nonsolid_color(true);
2825
2826 int dimension = 500;
2827 PaintImage image = MakeCheckerablePaintImage(gfx::Size(dimension, dimension));
2828 recording_source->add_draw_image(image, gfx::Point(0, 0));
2829
2830 recording_source->Rerecord();
2831 scoped_refptr<RasterSource> raster_source =
2832 recording_source->CreateRasterSource();
2833
2834 gfx::Size tile_size(500, 500);
2835 Region invalidation((gfx::Rect(layer_bounds)));
2836 SetupPendingTree(raster_source, tile_size, invalidation);
2837
2838 PictureLayerTilingSet* tiling_set =
2839 pending_layer()->picture_layer_tiling_set();
2840 PictureLayerTiling* pending_tiling = tiling_set->tiling_at(0);
2841 pending_tiling->set_resolution(HIGH_RESOLUTION);
2842 pending_tiling->CreateAllTilesForTesting();
2843 pending_tiling->SetTilePriorityRectsForTesting(
2844 gfx::Rect(), // An empty visual rect leads to the tile being pre-paint.
2845 gfx::Rect(layer_bounds), // Skewport rect.
2846 gfx::Rect(layer_bounds), // Soon rect.
2847 gfx::Rect(layer_bounds)); // Eventually rect.
2848
2849 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
2850 // There will be no tile raster task, but there will be an image decode task.
2851 EXPECT_FALSE(pending_tiling->TileAt(0, 0)->HasRasterTask());
2852 EXPECT_TRUE(host_impl()->tile_manager()->HasScheduledTileTasksForTesting());
2853 }
2854
TEST_F(CheckerImagingTileManagerTest,BuildsImageDecodeQueueAsExpected)2855 TEST_F(CheckerImagingTileManagerTest, BuildsImageDecodeQueueAsExpected) {
2856 const gfx::Size layer_bounds(900, 900);
2857
2858 std::unique_ptr<FakeRecordingSource> recording_source =
2859 FakeRecordingSource::CreateFilledRecordingSource(layer_bounds);
2860 recording_source->set_fill_with_nonsolid_color(true);
2861
2862 int dimension = 450;
2863 PaintImage image1 =
2864 MakeCheckerablePaintImage(gfx::Size(dimension, dimension));
2865 PaintImage image2 =
2866 MakeCheckerablePaintImage(gfx::Size(dimension, dimension));
2867 PaintImage image3 =
2868 MakeCheckerablePaintImage(gfx::Size(dimension, dimension));
2869 recording_source->add_draw_image(image1, gfx::Point(0, 0));
2870 recording_source->add_draw_image(image2, gfx::Point(600, 0));
2871 recording_source->add_draw_image(image3, gfx::Point(0, 600));
2872
2873 recording_source->Rerecord();
2874 scoped_refptr<RasterSource> raster_source =
2875 recording_source->CreateRasterSource();
2876
2877 gfx::Size tile_size(500, 500);
2878 Region invalidation((gfx::Rect(layer_bounds)));
2879 SetupPendingTree(raster_source, tile_size, invalidation);
2880
2881 PictureLayerTilingSet* tiling_set =
2882 pending_layer()->picture_layer_tiling_set();
2883 PictureLayerTiling* pending_tiling = tiling_set->tiling_at(0);
2884 pending_tiling->set_resolution(HIGH_RESOLUTION);
2885 pending_tiling->CreateAllTilesForTesting();
2886 pending_tiling->SetTilePriorityRectsForTesting(
2887 gfx::Rect(layer_bounds), // Visible rect.
2888 gfx::Rect(layer_bounds), // Skewport rect.
2889 gfx::Rect(layer_bounds), // Soon rect.
2890 gfx::Rect(layer_bounds)); // Eventually rect.
2891
2892 // PrepareTiles and make sure we account correctly for tiles that have been
2893 // scheduled with checkered images.
2894 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
2895 EXPECT_TRUE(host_impl()->tile_manager()->HasScheduledTileTasksForTesting());
2896
2897 for (int i = 0; i < 2; i++) {
2898 for (int j = 0; j < 2; j++) {
2899 const Tile* tile = pending_tiling->TileAt(i, j);
2900 EXPECT_TRUE(tile->HasRasterTask());
2901 if (i == 1 && j == 1)
2902 EXPECT_FALSE(tile->raster_task_scheduled_with_checker_images());
2903 else
2904 EXPECT_TRUE(tile->raster_task_scheduled_with_checker_images());
2905 }
2906 }
2907 EXPECT_EQ(host_impl()->tile_manager()->num_of_tiles_with_checker_images(), 3);
2908
2909 // Now raster all the tiles and make sure these tiles are still accounted for
2910 // with checkered images.
2911 static_cast<SynchronousTaskGraphRunner*>(task_graph_runner())->RunUntilIdle();
2912 base::RunLoop().RunUntilIdle();
2913 EXPECT_FALSE(host_impl()->tile_manager()->HasScheduledTileTasksForTesting());
2914 for (int i = 0; i < 2; i++) {
2915 for (int j = 0; j < 2; j++) {
2916 const Tile* tile = pending_tiling->TileAt(i, j);
2917 EXPECT_FALSE(tile->HasRasterTask());
2918 EXPECT_FALSE(tile->raster_task_scheduled_with_checker_images());
2919 EXPECT_TRUE(tile->draw_info().has_resource());
2920 if (i == 1 && j == 1)
2921 EXPECT_FALSE(tile->draw_info().is_checker_imaged());
2922 else
2923 EXPECT_TRUE(tile->draw_info().is_checker_imaged());
2924 }
2925 }
2926 EXPECT_EQ(host_impl()->tile_manager()->num_of_tiles_with_checker_images(), 3);
2927
2928 // Activate the pending tree.
2929 ActivateTree();
2930
2931 // Set empty tile priority rects so an empty image decode queue is used.
2932 gfx::Rect empty_rect;
2933 PictureLayerTiling* active_tiling =
2934 active_layer()->picture_layer_tiling_set()->tiling_at(0);
2935 active_tiling->SetTilePriorityRectsForTesting(
2936 gfx::Rect(empty_rect), // Visible rect.
2937 gfx::Rect(empty_rect), // Skewport rect.
2938 gfx::Rect(empty_rect), // Soon rect.
2939 gfx::Rect(empty_rect)); // Eventually rect.
2940 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
2941
2942 // Run the decode tasks. Since the first decode is always scheduled, the
2943 // completion for it should be triggered.
2944 FlushDecodeTasks();
2945
2946 // Create a new pending tree to invalidate tiles for decoded images and verify
2947 // that only tiles for |image1| are invalidated.
2948 EXPECT_TRUE(host_impl()->client()->did_request_impl_side_invalidation());
2949 PerformImplSideInvalidation();
2950 for (int i = 0; i < 2; i++) {
2951 for (int j = 0; j < 2; j++) {
2952 const Tile* tile = pending_tiling->TileAt(i, j);
2953 if (i == 0 && j == 0)
2954 EXPECT_TRUE(tile);
2955 else
2956 EXPECT_FALSE(tile);
2957 }
2958 }
2959 host_impl()->client()->reset_did_request_impl_side_invalidation();
2960
2961 // Activating the tree replaces the checker-imaged tile.
2962 EXPECT_EQ(host_impl()->tile_manager()->num_of_tiles_with_checker_images(), 3);
2963 ActivateTree();
2964 EXPECT_EQ(host_impl()->tile_manager()->num_of_tiles_with_checker_images(), 2);
2965
2966 // Set the tile priority rects such that only the tile with the second image
2967 // is scheduled for decodes, since it is checker-imaged.
2968 gfx::Rect rect_to_raster(600, 0, 300, 900);
2969 active_tiling->SetTilePriorityRectsForTesting(
2970 gfx::Rect(rect_to_raster), // Visible rect.
2971 gfx::Rect(rect_to_raster), // Skewport rect.
2972 gfx::Rect(rect_to_raster), // Soon rect.
2973 gfx::Rect(rect_to_raster)); // Eventually rect.
2974 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
2975
2976 // Finish all raster and dispatch completion callback so that the decode work
2977 // for checkered images can be scheduled.
2978 static_cast<SynchronousTaskGraphRunner*>(task_graph_runner())->RunUntilIdle();
2979 base::RunLoop().RunUntilIdle();
2980
2981 // Run decode tasks to trigger completion of any pending decodes.
2982 FlushDecodeTasks();
2983
2984 // Create a new pending tree to invalidate tiles for decoded images and verify
2985 // that only tiles for |image2| are invalidated.
2986 EXPECT_TRUE(host_impl()->client()->did_request_impl_side_invalidation());
2987 PerformImplSideInvalidation();
2988 for (int i = 0; i < 2; i++) {
2989 for (int j = 0; j < 2; j++) {
2990 const Tile* tile = pending_tiling->TileAt(i, j);
2991 if (i == 1 && j == 0)
2992 EXPECT_TRUE(tile);
2993 else
2994 EXPECT_FALSE(tile);
2995 }
2996 }
2997 host_impl()->client()->reset_did_request_impl_side_invalidation();
2998
2999 // Activating the tree replaces the checker-imaged tile.
3000 EXPECT_EQ(host_impl()->tile_manager()->num_of_tiles_with_checker_images(), 2);
3001 ActivateTree();
3002 EXPECT_EQ(host_impl()->tile_manager()->num_of_tiles_with_checker_images(), 1);
3003
3004 // Set the tile priority rects to cover the complete tiling and change the
3005 // visibility. While |image3| has not yet been decoded, since we are
3006 // invisible no decodes should have been scheduled.
3007 active_tiling->SetTilePriorityRectsForTesting(
3008 gfx::Rect(layer_bounds), // Visible rect.
3009 gfx::Rect(layer_bounds), // Skewport rect.
3010 gfx::Rect(layer_bounds), // Soon rect.
3011 gfx::Rect(layer_bounds)); // Eventually rect.
3012 host_impl()->SetVisible(false);
3013 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
3014 FlushDecodeTasks();
3015 EXPECT_FALSE(host_impl()->client()->did_request_impl_side_invalidation());
3016 }
3017
TEST_F(CheckerImagingTileManagerTest,TileManagerCleanupClearsCheckerImagedDecodes)3018 TEST_F(CheckerImagingTileManagerTest,
3019 TileManagerCleanupClearsCheckerImagedDecodes) {
3020 const gfx::Size layer_bounds(512, 512);
3021
3022 std::unique_ptr<FakeRecordingSource> recording_source =
3023 FakeRecordingSource::CreateFilledRecordingSource(layer_bounds);
3024 recording_source->set_fill_with_nonsolid_color(true);
3025 PaintImage image = MakeCheckerablePaintImage(gfx::Size(512, 512));
3026 recording_source->add_draw_image(image, gfx::Point(0, 0));
3027 recording_source->Rerecord();
3028 scoped_refptr<RasterSource> raster_source =
3029 recording_source->CreateRasterSource();
3030
3031 SetupPendingTree(raster_source, gfx::Size(100, 100),
3032 Region(gfx::Rect(0, 0, 500, 500)));
3033
3034 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
3035 // Finish all raster and dispatch completion callback so that the decode work
3036 // for checkered images can be scheduled.
3037 static_cast<SynchronousTaskGraphRunner*>(task_graph_runner())->RunUntilIdle();
3038 base::RunLoop().RunUntilIdle();
3039 FlushDecodeTasks();
3040
3041 EXPECT_TRUE(host_impl()
3042 ->tile_manager()
3043 ->checker_image_tracker()
3044 .has_locked_decodes_for_testing());
3045
3046 host_impl()->pending_tree()->ReleaseTileResources();
3047 CleanUpTileManager();
3048
3049 EXPECT_FALSE(host_impl()
3050 ->tile_manager()
3051 ->checker_image_tracker()
3052 .has_locked_decodes_for_testing());
3053 EXPECT_TRUE(
3054 host_impl()->tile_manager()->TakeImagesToInvalidateOnSyncTree().empty());
3055 }
3056
TEST_F(CheckerImagingTileManagerTest,TileManagerCorrectlyPrioritizesCheckerImagedDecodes)3057 TEST_F(CheckerImagingTileManagerTest,
3058 TileManagerCorrectlyPrioritizesCheckerImagedDecodes) {
3059 gfx::Size layer_bounds(500, 500);
3060
3061 std::unique_ptr<FakeRecordingSource> recording_source =
3062 FakeRecordingSource::CreateFilledRecordingSource(layer_bounds);
3063 recording_source->set_fill_with_nonsolid_color(true);
3064 PaintImage image = MakeCheckerablePaintImage(gfx::Size(512, 512));
3065 recording_source->add_draw_image(image, gfx::Point(0, 0));
3066 recording_source->Rerecord();
3067 scoped_refptr<RasterSource> raster_source =
3068 recording_source->CreateRasterSource();
3069
3070 // Required for activation tiles block checker-imaged decodes.
3071 SetupPendingTree(raster_source, gfx::Size(100, 100),
3072 Region(gfx::Rect(0, 0, 500, 500)));
3073 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
3074 EXPECT_TRUE(host_impl()->tile_manager()->HasScheduledTileTasksForTesting());
3075 EXPECT_TRUE(host_impl()
3076 ->tile_manager()
3077 ->checker_image_tracker()
3078 .no_decodes_allowed_for_testing());
3079 while (!host_impl()->client()->ready_to_activate()) {
3080 static_cast<SynchronousTaskGraphRunner*>(task_graph_runner())
3081 ->RunSingleTaskForTesting();
3082 base::RunLoop().RunUntilIdle();
3083 }
3084 EXPECT_EQ(host_impl()
3085 ->tile_manager()
3086 ->checker_image_tracker()
3087 .decode_priority_allowed_for_testing(),
3088 CheckerImageTracker::DecodeType::kRaster);
3089
3090 // Finishing all tasks allows pre-decodes.
3091 static_cast<SynchronousTaskGraphRunner*>(task_graph_runner())->RunUntilIdle();
3092 base::RunLoop().RunUntilIdle();
3093 EXPECT_EQ(host_impl()
3094 ->tile_manager()
3095 ->checker_image_tracker()
3096 .decode_priority_allowed_for_testing(),
3097 CheckerImageTracker::DecodeType::kPreDecode);
3098
3099 // Required for draw tiles block checker-imaged decodes.
3100 // Free all tile resources and perform another PrepareTiles.
3101 ActivateTree();
3102 EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToDraw());
3103 host_impl()->tile_manager()->PrepareTiles(
3104 GlobalStateThatImpactsTilePriority());
3105 EXPECT_FALSE(host_impl()->tile_manager()->IsReadyToDraw());
3106
3107 host_impl()->client()->reset_ready_to_draw();
3108 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
3109 EXPECT_TRUE(host_impl()->tile_manager()->HasScheduledTileTasksForTesting());
3110 EXPECT_TRUE(host_impl()
3111 ->tile_manager()
3112 ->checker_image_tracker()
3113 .no_decodes_allowed_for_testing());
3114 while (!host_impl()->client()->ready_to_draw()) {
3115 static_cast<SynchronousTaskGraphRunner*>(task_graph_runner())
3116 ->RunSingleTaskForTesting();
3117 base::RunLoop().RunUntilIdle();
3118 }
3119 EXPECT_EQ(host_impl()
3120 ->tile_manager()
3121 ->checker_image_tracker()
3122 .decode_priority_allowed_for_testing(),
3123 CheckerImageTracker::DecodeType::kRaster);
3124 }
3125
3126 class CheckerImagingTileManagerMemoryTest
3127 : public CheckerImagingTileManagerTest {
3128 public:
CreateHostImpl(const LayerTreeSettings & settings,TaskRunnerProvider * task_runner_provider,TaskGraphRunner * task_graph_runner)3129 std::unique_ptr<FakeLayerTreeHostImpl> CreateHostImpl(
3130 const LayerTreeSettings& settings,
3131 TaskRunnerProvider* task_runner_provider,
3132 TaskGraphRunner* task_graph_runner) override {
3133 LayerTreeSettings new_settings = settings;
3134 new_settings.memory_policy.num_resources_limit = 4;
3135 return CheckerImagingTileManagerTest::CreateHostImpl(
3136 new_settings, task_runner_provider, task_graph_runner);
3137 }
3138 };
3139
TEST_F(CheckerImagingTileManagerMemoryTest,AddsAllNowTilesToImageDecodeQueue)3140 TEST_F(CheckerImagingTileManagerMemoryTest, AddsAllNowTilesToImageDecodeQueue) {
3141 const gfx::Size layer_bounds(900, 1400);
3142
3143 std::unique_ptr<FakeRecordingSource> recording_source =
3144 FakeRecordingSource::CreateFilledRecordingSource(layer_bounds);
3145 recording_source->set_fill_with_nonsolid_color(true);
3146
3147 int dimension = 450;
3148 PaintImage image1 =
3149 MakeCheckerablePaintImage(gfx::Size(dimension, dimension));
3150 PaintImage image2 =
3151 MakeCheckerablePaintImage(gfx::Size(dimension, dimension));
3152 recording_source->add_draw_image(image1, gfx::Point(0, 515));
3153 recording_source->add_draw_image(image2, gfx::Point(515, 515));
3154
3155 recording_source->Rerecord();
3156 scoped_refptr<RasterSource> raster_source =
3157 recording_source->CreateRasterSource();
3158
3159 gfx::Size tile_size(500, 500);
3160 Region invalidation((gfx::Rect(layer_bounds)));
3161 SetupPendingTree(raster_source, tile_size, invalidation);
3162
3163 PictureLayerTilingSet* tiling_set =
3164 pending_layer()->picture_layer_tiling_set();
3165 PictureLayerTiling* pending_tiling = tiling_set->tiling_at(0);
3166 pending_tiling->set_resolution(HIGH_RESOLUTION);
3167 pending_tiling->CreateAllTilesForTesting();
3168
3169 // Use a rect that only rasterizes the bottom 2 rows of tiles.
3170 gfx::Rect rect_to_raster(0, 500, 900, 900);
3171 pending_tiling->SetTilePriorityRectsForTesting(
3172 rect_to_raster, // Visible rect.
3173 rect_to_raster, // Skewport rect.
3174 rect_to_raster, // Soon rect.
3175 rect_to_raster); // Eventually rect.
3176
3177 // PrepareTiles, rasterize all scheduled tiles and activate while no images
3178 // have been decoded.
3179 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
3180 static_cast<SynchronousTaskGraphRunner*>(task_graph_runner())->RunUntilIdle();
3181 base::RunLoop().RunUntilIdle();
3182 ActivateTree();
3183
3184 // Expand the visible rect to include the complete tiling. The tile iteration
3185 // will not go beyond the first tile since there are no resources with a lower
3186 // priority that can be evicted. But we should still see image decodes
3187 // scheduled for all visible tiles.
3188 gfx::Rect complete_tiling_rect(layer_bounds);
3189 PictureLayerTiling* active_tiling =
3190 active_layer()->picture_layer_tiling_set()->tiling_at(0);
3191 active_tiling->SetTilePriorityRectsForTesting(
3192 complete_tiling_rect, // Visible rect.
3193 complete_tiling_rect, // Skewport rect.
3194 complete_tiling_rect, // Soon rect.
3195 complete_tiling_rect); // Eventually rect.
3196 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
3197
3198 // Finish all raster work so the decode work for checkered images can be
3199 // scheduled.
3200 static_cast<SynchronousTaskGraphRunner*>(task_graph_runner())->RunUntilIdle();
3201 base::RunLoop().RunUntilIdle();
3202
3203 // Flush all decode tasks. The tiles with checkered images should be
3204 // invalidated.
3205 FlushDecodeTasks();
3206 EXPECT_TRUE(host_impl()->client()->did_request_impl_side_invalidation());
3207 PerformImplSideInvalidation();
3208 for (int i = 0; i < 2; i++) {
3209 for (int j = 0; j < 3; j++) {
3210 const Tile* tile = pending_tiling->TileAt(i, j);
3211 if (j == 1)
3212 EXPECT_TRUE(tile);
3213 else
3214 EXPECT_FALSE(tile);
3215 }
3216 }
3217 host_impl()->client()->reset_did_request_impl_side_invalidation();
3218 }
3219
3220 class VerifyImageProviderRasterBuffer : public RasterBuffer {
3221 public:
3222 VerifyImageProviderRasterBuffer() = default;
~VerifyImageProviderRasterBuffer()3223 ~VerifyImageProviderRasterBuffer() override { EXPECT_TRUE(did_raster_); }
3224
Playback(const RasterSource * raster_source,const gfx::Rect & raster_full_rect,const gfx::Rect & raster_dirty_rect,uint64_t new_content_id,const gfx::AxisTransform2d & transform,const RasterSource::PlaybackSettings & playback_settings,const GURL & url)3225 void Playback(const RasterSource* raster_source,
3226 const gfx::Rect& raster_full_rect,
3227 const gfx::Rect& raster_dirty_rect,
3228 uint64_t new_content_id,
3229 const gfx::AxisTransform2d& transform,
3230 const RasterSource::PlaybackSettings& playback_settings,
3231 const GURL& url) override {
3232 did_raster_ = true;
3233 EXPECT_TRUE(playback_settings.image_provider);
3234 }
3235
SupportsBackgroundThreadPriority() const3236 bool SupportsBackgroundThreadPriority() const override { return true; }
3237
3238 private:
3239 bool did_raster_ = false;
3240 };
3241
3242 class VerifyImageProviderRasterBufferProvider
3243 : public FakeRasterBufferProviderImpl {
3244 public:
3245 VerifyImageProviderRasterBufferProvider() = default;
~VerifyImageProviderRasterBufferProvider()3246 ~VerifyImageProviderRasterBufferProvider() override {
3247 EXPECT_GT(buffer_count_, 0);
3248 }
3249
AcquireBufferForRaster(const ResourcePool::InUsePoolResource & resource,uint64_t resource_content_id,uint64_t previous_content_id,bool depends_on_at_raster_decodes,bool depends_on_hardware_accelerated_jpeg_candidates,bool depends_on_hardware_accelerated_webp_candidates)3250 std::unique_ptr<RasterBuffer> AcquireBufferForRaster(
3251 const ResourcePool::InUsePoolResource& resource,
3252 uint64_t resource_content_id,
3253 uint64_t previous_content_id,
3254 bool depends_on_at_raster_decodes,
3255 bool depends_on_hardware_accelerated_jpeg_candidates,
3256 bool depends_on_hardware_accelerated_webp_candidates) override {
3257 buffer_count_++;
3258 return std::make_unique<VerifyImageProviderRasterBuffer>();
3259 }
3260
3261 private:
3262 int buffer_count_ = 0;
3263 };
3264
3265 class SynchronousRasterTileManagerTest : public TileManagerTest {
3266 public:
CreateTaskGraphRunner()3267 std::unique_ptr<TaskGraphRunner> CreateTaskGraphRunner() override {
3268 return std::make_unique<SynchronousTaskGraphRunner>();
3269 }
3270 };
3271
TEST_F(SynchronousRasterTileManagerTest,AlwaysUseImageCache)3272 TEST_F(SynchronousRasterTileManagerTest, AlwaysUseImageCache) {
3273 // Tests that we always use the ImageDecodeCache during raster.
3274 VerifyImageProviderRasterBufferProvider raster_buffer_provider;
3275 host_impl()->tile_manager()->SetRasterBufferProviderForTesting(
3276 &raster_buffer_provider);
3277
3278 gfx::Size layer_bounds(500, 500);
3279 scoped_refptr<FakeRasterSource> raster_source =
3280 FakeRasterSource::CreateFilled(layer_bounds);
3281 Region invalidation((gfx::Rect(layer_bounds)));
3282 SetupPendingTree(raster_source, layer_bounds, invalidation);
3283 PictureLayerTilingSet* tiling_set =
3284 pending_layer()->picture_layer_tiling_set();
3285 PictureLayerTiling* pending_tiling = tiling_set->tiling_at(0);
3286 pending_tiling->set_resolution(HIGH_RESOLUTION);
3287 pending_tiling->CreateAllTilesForTesting();
3288 pending_tiling->SetTilePriorityRectsForTesting(
3289 gfx::Rect(layer_bounds), // Visible rect.
3290 gfx::Rect(layer_bounds), // Skewport rect.
3291 gfx::Rect(layer_bounds), // Soon rect.
3292 gfx::Rect(layer_bounds)); // Eventually rect.
3293
3294 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
3295 static_cast<SynchronousTaskGraphRunner*>(task_graph_runner())->RunUntilIdle();
3296
3297 // Destroy the LTHI since it accesses the RasterBufferProvider during cleanup.
3298 TakeHostImpl();
3299 }
3300
3301 class DecodedImageTrackerTileManagerTest : public TestLayerTreeHostBase {
3302 public:
TearDown()3303 void TearDown() override {
3304 // Allow all tasks on the image worker to run now. Any scheduled decodes
3305 // will be aborted.
3306 task_runner_->set_run_tasks_synchronously(true);
3307 }
3308
CreateSettings()3309 LayerTreeSettings CreateSettings() override {
3310 auto settings = TestLayerTreeHostBase::CreateSettings();
3311 settings.max_preraster_distance_in_screen_pixels = 100;
3312 return settings;
3313 }
3314
CreateHostImpl(const LayerTreeSettings & settings,TaskRunnerProvider * task_runner_provider,TaskGraphRunner * task_graph_runner)3315 std::unique_ptr<FakeLayerTreeHostImpl> CreateHostImpl(
3316 const LayerTreeSettings& settings,
3317 TaskRunnerProvider* task_runner_provider,
3318 TaskGraphRunner* task_graph_runner) override {
3319 task_runner_ = base::MakeRefCounted<SynchronousSimpleTaskRunner>();
3320 return std::make_unique<FakeLayerTreeHostImpl>(
3321 settings, task_runner_provider, task_graph_runner, task_runner_);
3322 }
3323
CreateTaskGraphRunner()3324 std::unique_ptr<TaskGraphRunner> CreateTaskGraphRunner() override {
3325 return std::make_unique<SynchronousTaskGraphRunner>();
3326 }
3327
FlushDecodeTasks()3328 void FlushDecodeTasks() {
3329 while (task_runner_->HasPendingTask()) {
3330 task_runner_->RunUntilIdle();
3331 base::RunLoop().RunUntilIdle();
3332 }
3333 }
3334
3335 private:
3336 scoped_refptr<SynchronousSimpleTaskRunner> task_runner_;
3337 };
3338
TEST_F(DecodedImageTrackerTileManagerTest,DecodedImageTrackerDropsLocksOnUse)3339 TEST_F(DecodedImageTrackerTileManagerTest, DecodedImageTrackerDropsLocksOnUse) {
3340 // Pick arbitrary IDs - they don't really matter as long as they're constant.
3341 const int kLayerId = 7;
3342
3343 host_impl()->tile_manager()->SetTileTaskManagerForTesting(
3344 std::make_unique<FakeTileTaskManagerImpl>());
3345
3346 // Create two test images, one will be positioned to be needed NOW, the other
3347 // will be positioned to be prepaint.
3348 int dimension = 250;
3349 PaintImage image1 =
3350 CreateDiscardablePaintImage(gfx::Size(dimension, dimension));
3351 PaintImage image2 =
3352 CreateDiscardablePaintImage(gfx::Size(dimension, dimension));
3353
3354 // Add the images to our decoded_image_tracker.
3355 host_impl()->tile_manager()->decoded_image_tracker().QueueImageDecode(
3356 image1, gfx::ColorSpace(), base::DoNothing());
3357 host_impl()->tile_manager()->decoded_image_tracker().QueueImageDecode(
3358 image2, gfx::ColorSpace(), base::DoNothing());
3359 EXPECT_EQ(0u, host_impl()
3360 ->tile_manager()
3361 ->decoded_image_tracker()
3362 .NumLockedImagesForTesting());
3363 FlushDecodeTasks();
3364 EXPECT_EQ(2u, host_impl()
3365 ->tile_manager()
3366 ->decoded_image_tracker()
3367 .NumLockedImagesForTesting());
3368
3369 // Add images to a fake recording source.
3370 const gfx::Size layer_bounds(1000, 500);
3371 std::unique_ptr<FakeRecordingSource> recording_source =
3372 FakeRecordingSource::CreateFilledRecordingSource(layer_bounds);
3373 recording_source->set_fill_with_nonsolid_color(true);
3374 recording_source->add_draw_image(image1, gfx::Point(0, 0));
3375 recording_source->add_draw_image(image2, gfx::Point(700, 0));
3376 recording_source->Rerecord();
3377
3378 scoped_refptr<FakeRasterSource> pending_raster_source =
3379 FakeRasterSource::CreateFromRecordingSource(recording_source.get());
3380
3381 host_impl()->CreatePendingTree();
3382 LayerTreeImpl* pending_tree = host_impl()->pending_tree();
3383 pending_tree->SetDeviceViewportRect(
3384 host_impl()->active_tree()->GetDeviceViewport());
3385
3386 // Steal from the recycled tree.
3387 std::unique_ptr<FakePictureLayerImpl> pending_layer =
3388 FakePictureLayerImpl::Create(pending_tree, kLayerId,
3389 pending_raster_source);
3390 pending_layer->SetDrawsContent(true);
3391
3392 // The bounds() are half the recording source size, allowing for prepaint
3393 // images.
3394 pending_layer->SetBounds(gfx::Size(500, 500));
3395 SetupRootProperties(pending_layer.get());
3396 pending_tree->SetRootLayerForTesting(std::move(pending_layer));
3397
3398 // Add tilings/tiles for the layer.
3399 UpdateDrawProperties(host_impl()->pending_tree());
3400
3401 // Build the raster queue and invalidate the top tile if partial raster is
3402 // enabled.
3403 std::unique_ptr<RasterTilePriorityQueue> queue(host_impl()->BuildRasterQueue(
3404 SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL));
3405 ASSERT_FALSE(queue->IsEmpty());
3406
3407 // PrepareTiles to schedule tasks. This should cause the decoded image tracker
3408 // to release its lock.
3409 EXPECT_EQ(2u, host_impl()
3410 ->tile_manager()
3411 ->decoded_image_tracker()
3412 .NumLockedImagesForTesting());
3413 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
3414 EXPECT_EQ(0u, host_impl()
3415 ->tile_manager()
3416 ->decoded_image_tracker()
3417 .NumLockedImagesForTesting());
3418 }
3419
3420 class HdrImageTileManagerTest : public CheckerImagingTileManagerTest {
3421 public:
DecodeHdrImage(const gfx::ColorSpace & raster_cs)3422 void DecodeHdrImage(const gfx::ColorSpace& raster_cs) {
3423 auto color_space = gfx::ColorSpace::CreateHDR10();
3424 auto size = gfx::Size(250, 250);
3425 auto info =
3426 SkImageInfo::Make(size.width(), size.height(), kRGBA_F16_SkColorType,
3427 kPremul_SkAlphaType, color_space.ToSkColorSpace());
3428 SkBitmap bitmap;
3429 bitmap.allocPixels(info);
3430 PaintImage hdr_image = PaintImageBuilder::WithDefault()
3431 .set_id(PaintImage::kInvalidId)
3432 .set_is_high_bit_depth(true)
3433 .set_image(SkImage::MakeFromBitmap(bitmap),
3434 PaintImage::GetNextContentId())
3435 .TakePaintImage();
3436
3437 // Add the image to our decoded_image_tracker.
3438 host_impl()->tile_manager()->decoded_image_tracker().QueueImageDecode(
3439 hdr_image, raster_cs, base::DoNothing());
3440 FlushDecodeTasks();
3441
3442 // Add images to a fake recording source.
3443 constexpr gfx::Size kLayerBounds(1000, 500);
3444 auto recording_source =
3445 FakeRecordingSource::CreateFilledRecordingSource(kLayerBounds);
3446 recording_source->set_fill_with_nonsolid_color(true);
3447 recording_source->add_draw_image(hdr_image, gfx::Point(0, 0));
3448 recording_source->Rerecord();
3449
3450 auto raster_source = recording_source->CreateRasterSource();
3451
3452 constexpr gfx::Size kTileSize(500, 500);
3453 Region invalidation((gfx::Rect(kLayerBounds)));
3454 SetupPendingTree(raster_source, kTileSize, invalidation);
3455
3456 constexpr float kCustomWhiteLevel = 200.f;
3457 auto display_cs = gfx::DisplayColorSpaces(raster_cs);
3458 if (raster_cs.IsHDR())
3459 display_cs.SetSDRWhiteLevel(kCustomWhiteLevel);
3460
3461 pending_layer()->layer_tree_impl()->SetDisplayColorSpaces(display_cs);
3462 PictureLayerTilingSet* tiling_set =
3463 pending_layer()->picture_layer_tiling_set();
3464 PictureLayerTiling* pending_tiling = tiling_set->tiling_at(0);
3465 pending_tiling->set_resolution(HIGH_RESOLUTION);
3466 pending_tiling->CreateAllTilesForTesting();
3467 pending_tiling->SetTilePriorityRectsForTesting(
3468 gfx::Rect(kLayerBounds), // Visible rect.
3469 gfx::Rect(kLayerBounds), // Skewport rect.
3470 gfx::Rect(kLayerBounds), // Soon rect.
3471 gfx::Rect(kLayerBounds)); // Eventually rect.
3472
3473 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
3474 ASSERT_TRUE(host_impl()->tile_manager()->HasScheduledTileTasksForTesting());
3475
3476 auto pending_tiles = pending_tiling->AllTilesForTesting();
3477 ASSERT_FALSE(pending_tiles.empty());
3478
3479 if (raster_cs.IsHDR()) {
3480 // Only the last tile will have any pending tasks.
3481 const auto& pending_tasks =
3482 host_impl()->tile_manager()->decode_tasks_for_testing(
3483 pending_tiles.back()->id());
3484 EXPECT_FALSE(pending_tasks.empty());
3485 for (const auto& draw_info : pending_tasks) {
3486 EXPECT_EQ(draw_info.target_color_space(), raster_cs);
3487 EXPECT_FLOAT_EQ(draw_info.sdr_white_level(), kCustomWhiteLevel);
3488 }
3489 }
3490
3491 // Raster all tiles.
3492 static_cast<SynchronousTaskGraphRunner*>(task_graph_runner())
3493 ->RunUntilIdle();
3494 base::RunLoop().RunUntilIdle();
3495 ASSERT_FALSE(
3496 host_impl()->tile_manager()->HasScheduledTileTasksForTesting());
3497
3498 auto expected_format = raster_cs.IsHDR() ? viz::RGBA_F16 : viz::RGBA_8888;
3499 auto all_tiles = host_impl()->tile_manager()->AllTilesForTesting();
3500 for (const auto* tile : all_tiles)
3501 EXPECT_EQ(expected_format, tile->draw_info().resource_format());
3502 }
3503 };
3504
TEST_F(HdrImageTileManagerTest,DecodeHdrImagesToHdrPq)3505 TEST_F(HdrImageTileManagerTest, DecodeHdrImagesToHdrPq) {
3506 DecodeHdrImage(gfx::ColorSpace::CreateHDR10());
3507 }
3508
TEST_F(HdrImageTileManagerTest,DecodeHdrImagesToHdrHlg)3509 TEST_F(HdrImageTileManagerTest, DecodeHdrImagesToHdrHlg) {
3510 DecodeHdrImage(gfx::ColorSpace::CreateHLG());
3511 }
3512
TEST_F(HdrImageTileManagerTest,DecodeHdrImagesToSdrSrgb)3513 TEST_F(HdrImageTileManagerTest, DecodeHdrImagesToSdrSrgb) {
3514 DecodeHdrImage(gfx::ColorSpace::CreateSRGB());
3515 }
3516
TEST_F(HdrImageTileManagerTest,DecodeHdrImagesToSdrP3)3517 TEST_F(HdrImageTileManagerTest, DecodeHdrImagesToSdrP3) {
3518 DecodeHdrImage(gfx::ColorSpace::CreateDisplayP3D65());
3519 }
3520
3521 class TileManagerCheckRasterQueriesTest : public TileManagerTest {
3522 public:
~TileManagerCheckRasterQueriesTest()3523 ~TileManagerCheckRasterQueriesTest() override {
3524 // Ensure that the host impl doesn't outlive |raster_buffer_provider_|.
3525 TakeHostImpl();
3526 }
SetUp()3527 void SetUp() override {
3528 TileManagerTest::SetUp();
3529 host_impl()->tile_manager()->SetRasterBufferProviderForTesting(
3530 &raster_buffer_provider_);
3531 }
3532
3533 protected:
3534 class MockRasterBufferProvider : public FakeRasterBufferProviderImpl {
3535 public:
3536 MOCK_METHOD0(CheckRasterFinishedQueries, bool());
3537 };
3538
3539 MockRasterBufferProvider raster_buffer_provider_;
3540 };
3541
TEST_F(TileManagerCheckRasterQueriesTest,ChecksRasterQueriesInAllTilesDoneTask)3542 TEST_F(TileManagerCheckRasterQueriesTest,
3543 ChecksRasterQueriesInAllTilesDoneTask) {
3544 base::RunLoop run_loop;
3545 EXPECT_FALSE(host_impl()->tile_manager()->HasScheduledTileTasksForTesting());
3546 EXPECT_CALL(MockHostImpl(), NotifyAllTileTasksCompleted())
3547 .WillOnce(testing::Invoke([&run_loop]() { run_loop.Quit(); }));
3548 EXPECT_CALL(raster_buffer_provider_, CheckRasterFinishedQueries()).Times(1);
3549 host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state());
3550 EXPECT_TRUE(host_impl()->tile_manager()->HasScheduledTileTasksForTesting());
3551 run_loop.Run();
3552 }
3553
3554 } // namespace
3555 } // namespace cc
3556