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.
5 #include "cc/resources/eviction_tile_priority_queue.h"
6 #include "cc/resources/raster_tile_priority_queue.h"
7 #include "cc/resources/tile.h"
8 #include "cc/resources/tile_priority.h"
9 #include "cc/test/fake_impl_proxy.h"
10 #include "cc/test/fake_layer_tree_host_impl.h"
11 #include "cc/test/fake_output_surface.h"
12 #include "cc/test/fake_output_surface_client.h"
13 #include "cc/test/fake_picture_layer_impl.h"
14 #include "cc/test/fake_picture_pile_impl.h"
15 #include "cc/test/fake_tile_manager.h"
16 #include "cc/test/impl_side_painting_settings.h"
17 #include "cc/test/test_shared_bitmap_manager.h"
18 #include "cc/test/test_tile_priorities.h"
19 #include "cc/trees/layer_tree_impl.h"
20 #include "testing/gtest/include/gtest/gtest.h"
25 class TileManagerTest : public testing::TestWithParam<bool>,
26 public TileManagerClient {
28 typedef std::vector<scoped_refptr<Tile> > TileVector;
31 : memory_limit_policy_(ALLOW_ANYTHING),
33 ready_to_activate_(false) {}
35 void Initialize(int max_tiles,
36 TileMemoryLimitPolicy memory_limit_policy,
37 TreePriority tree_priority) {
38 output_surface_ = FakeOutputSurface::Create3d();
39 CHECK(output_surface_->BindToClient(&output_surface_client_));
41 shared_bitmap_manager_.reset(new TestSharedBitmapManager());
42 resource_provider_ = ResourceProvider::Create(output_surface_.get(),
43 shared_bitmap_manager_.get(),
49 resource_pool_ = ResourcePool::Create(
50 resource_provider_.get(), GL_TEXTURE_2D, RGBA_8888);
52 make_scoped_ptr(new FakeTileManager(this, resource_pool_.get()));
54 memory_limit_policy_ = memory_limit_policy;
55 max_tiles_ = max_tiles;
56 picture_pile_ = FakePicturePileImpl::CreateInfiniteFilledPile();
58 SetTreePriority(tree_priority);
61 void SetTreePriority(TreePriority tree_priority) {
62 GlobalStateThatImpactsTilePriority state;
63 gfx::Size tile_size = settings_.default_tile_size;
65 if (UsingMemoryLimit()) {
66 state.soft_memory_limit_in_bytes =
67 max_tiles_ * 4 * tile_size.width() * tile_size.height();
68 state.num_resources_limit = 100;
70 state.soft_memory_limit_in_bytes = 100 * 1000 * 1000;
71 state.num_resources_limit = max_tiles_;
73 state.hard_memory_limit_in_bytes = state.soft_memory_limit_in_bytes * 2;
74 state.memory_limit_policy = memory_limit_policy_;
75 state.tree_priority = tree_priority;
77 global_state_ = state;
78 resource_pool_->SetResourceUsageLimits(state.soft_memory_limit_in_bytes,
79 state.soft_memory_limit_in_bytes,
80 state.num_resources_limit);
81 tile_manager_->SetGlobalStateForTesting(state);
84 virtual void TearDown() OVERRIDE {
85 tile_manager_.reset(NULL);
88 testing::Test::TearDown();
91 // TileManagerClient implementation.
92 virtual const std::vector<PictureLayerImpl*>& GetPictureLayers()
94 return picture_layers_;
96 virtual void NotifyReadyToActivate() OVERRIDE { ready_to_activate_ = true; }
97 virtual void NotifyTileStateChanged(const Tile* tile) OVERRIDE {}
98 virtual void BuildRasterQueue(RasterTilePriorityQueue* queue,
99 TreePriority priority) OVERRIDE {}
100 virtual void BuildEvictionQueue(EvictionTilePriorityQueue* queue,
101 TreePriority priority) OVERRIDE {}
103 TileVector CreateTilesWithSize(int count,
104 TilePriority active_priority,
105 TilePriority pending_priority,
106 const gfx::Size& tile_size) {
108 for (int i = 0; i < count; ++i) {
109 scoped_refptr<Tile> tile = tile_manager_->CreateTile(picture_pile_.get(),
116 tile->SetPriority(ACTIVE_TREE, active_priority);
117 tile->SetPriority(PENDING_TREE, pending_priority);
118 tiles.push_back(tile);
123 TileVector CreateTiles(int count,
124 TilePriority active_priority,
125 TilePriority pending_priority) {
126 return CreateTilesWithSize(
127 count, active_priority, pending_priority, settings_.default_tile_size);
130 void ReleaseTiles(TileVector* tiles) {
131 for (TileVector::iterator it = tiles->begin(); it != tiles->end(); it++) {
132 Tile* tile = it->get();
133 tile->SetPriority(ACTIVE_TREE, TilePriority());
134 tile->SetPriority(PENDING_TREE, TilePriority());
138 FakeTileManager* tile_manager() { return tile_manager_.get(); }
140 int AssignedMemoryCount(const TileVector& tiles) {
141 int has_memory_count = 0;
142 for (TileVector::const_iterator it = tiles.begin(); it != tiles.end();
144 if (tile_manager_->HasBeenAssignedMemory(it->get()))
147 return has_memory_count;
150 bool ready_to_activate() const { return ready_to_activate_; }
152 // The parametrization specifies whether the max tile limit should
153 // be applied to memory or resources.
154 bool UsingResourceLimit() { return !GetParam(); }
155 bool UsingMemoryLimit() { return GetParam(); }
158 GlobalStateThatImpactsTilePriority global_state_;
161 LayerTreeSettings settings_;
162 scoped_ptr<FakeTileManager> tile_manager_;
163 scoped_refptr<FakePicturePileImpl> picture_pile_;
164 FakeOutputSurfaceClient output_surface_client_;
165 scoped_ptr<FakeOutputSurface> output_surface_;
166 scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
167 scoped_ptr<ResourceProvider> resource_provider_;
168 scoped_ptr<ResourcePool> resource_pool_;
169 TileMemoryLimitPolicy memory_limit_policy_;
171 bool ready_to_activate_;
172 std::vector<PictureLayerImpl*> picture_layers_;
175 TEST_P(TileManagerTest, EnoughMemoryAllowAnything) {
176 // A few tiles of each type of priority, with enough memory for all tiles.
178 Initialize(10, ALLOW_ANYTHING, SMOOTHNESS_TAKES_PRIORITY);
179 TileVector active_now =
180 CreateTiles(3, TilePriorityForNowBin(), TilePriority());
181 TileVector pending_now =
182 CreateTiles(3, TilePriority(), TilePriorityForNowBin());
183 TileVector active_pending_soon =
184 CreateTiles(3, TilePriorityForSoonBin(), TilePriorityForSoonBin());
185 TileVector never_bin = CreateTiles(1, TilePriority(), TilePriority());
187 tile_manager()->AssignMemoryToTiles(global_state_);
189 EXPECT_EQ(3, AssignedMemoryCount(active_now));
190 EXPECT_EQ(3, AssignedMemoryCount(pending_now));
191 EXPECT_EQ(3, AssignedMemoryCount(active_pending_soon));
192 EXPECT_EQ(0, AssignedMemoryCount(never_bin));
194 ReleaseTiles(&active_now);
195 ReleaseTiles(&pending_now);
196 ReleaseTiles(&active_pending_soon);
197 ReleaseTiles(&never_bin);
200 TEST_P(TileManagerTest, EnoughMemoryAllowPrepaintOnly) {
201 // A few tiles of each type of priority, with enough memory for all tiles,
202 // with the exception of never bin.
204 Initialize(10, ALLOW_PREPAINT_ONLY, SMOOTHNESS_TAKES_PRIORITY);
205 TileVector active_now =
206 CreateTiles(3, TilePriorityForNowBin(), TilePriority());
207 TileVector pending_now =
208 CreateTiles(3, TilePriority(), TilePriorityForNowBin());
209 TileVector active_pending_soon =
210 CreateTiles(3, TilePriorityForSoonBin(), TilePriorityForSoonBin());
211 TileVector never_bin = CreateTiles(1, TilePriority(), TilePriority());
213 tile_manager()->AssignMemoryToTiles(global_state_);
215 EXPECT_EQ(3, AssignedMemoryCount(active_now));
216 EXPECT_EQ(3, AssignedMemoryCount(pending_now));
217 EXPECT_EQ(3, AssignedMemoryCount(active_pending_soon));
218 EXPECT_EQ(0, AssignedMemoryCount(never_bin));
220 ReleaseTiles(&active_now);
221 ReleaseTiles(&pending_now);
222 ReleaseTiles(&active_pending_soon);
223 ReleaseTiles(&never_bin);
226 TEST_P(TileManagerTest, EnoughMemoryPendingLowResAllowAbsoluteMinimum) {
227 // A few low-res tiles required for activation, with enough memory for all
230 Initialize(5, ALLOW_ABSOLUTE_MINIMUM, SAME_PRIORITY_FOR_BOTH_TREES);
231 TileVector pending_low_res =
232 CreateTiles(5, TilePriority(), TilePriorityLowRes());
234 tile_manager()->AssignMemoryToTiles(global_state_);
236 EXPECT_EQ(5, AssignedMemoryCount(pending_low_res));
237 ReleaseTiles(&pending_low_res);
240 TEST_P(TileManagerTest, EnoughMemoryAllowAbsoluteMinimum) {
241 // A few tiles of each type of priority, with enough memory for all tiles,
242 // with the exception of never and soon bins.
244 Initialize(10, ALLOW_ABSOLUTE_MINIMUM, SMOOTHNESS_TAKES_PRIORITY);
245 TileVector active_now =
246 CreateTiles(3, TilePriorityForNowBin(), TilePriority());
247 TileVector pending_now =
248 CreateTiles(3, TilePriority(), TilePriorityForNowBin());
249 TileVector active_pending_soon =
250 CreateTiles(3, TilePriorityForSoonBin(), TilePriorityForSoonBin());
251 TileVector never_bin = CreateTiles(1, TilePriority(), TilePriority());
253 tile_manager()->AssignMemoryToTiles(global_state_);
255 EXPECT_EQ(3, AssignedMemoryCount(active_now));
256 EXPECT_EQ(3, AssignedMemoryCount(pending_now));
257 EXPECT_EQ(0, AssignedMemoryCount(active_pending_soon));
258 EXPECT_EQ(0, AssignedMemoryCount(never_bin));
260 ReleaseTiles(&active_now);
261 ReleaseTiles(&pending_now);
262 ReleaseTiles(&active_pending_soon);
263 ReleaseTiles(&never_bin);
266 TEST_P(TileManagerTest, EnoughMemoryAllowNothing) {
267 // A few tiles of each type of priority, with enough memory for all tiles,
268 // but allow nothing should not assign any memory.
270 Initialize(10, ALLOW_NOTHING, SMOOTHNESS_TAKES_PRIORITY);
271 TileVector active_now =
272 CreateTiles(3, TilePriorityForNowBin(), TilePriority());
273 TileVector pending_now =
274 CreateTiles(3, TilePriority(), TilePriorityForNowBin());
275 TileVector active_pending_soon =
276 CreateTiles(3, TilePriorityForSoonBin(), TilePriorityForSoonBin());
277 TileVector never_bin = CreateTiles(1, TilePriority(), TilePriority());
279 tile_manager()->AssignMemoryToTiles(global_state_);
281 EXPECT_EQ(0, AssignedMemoryCount(active_now));
282 EXPECT_EQ(0, AssignedMemoryCount(pending_now));
283 EXPECT_EQ(0, AssignedMemoryCount(active_pending_soon));
284 EXPECT_EQ(0, AssignedMemoryCount(never_bin));
286 ReleaseTiles(&active_now);
287 ReleaseTiles(&pending_now);
288 ReleaseTiles(&active_pending_soon);
289 ReleaseTiles(&never_bin);
292 TEST_P(TileManagerTest, PartialOOMMemoryToPending) {
293 // 5 tiles on active tree eventually bin, 5 tiles on pending tree that are
294 // required for activation, but only enough memory for 8 tiles. The result
295 // is all pending tree tiles get memory, and 3 of the active tree tiles
296 // get memory. None of these tiles is needed to avoid calimity (flickering or
297 // raster-on-demand) so the soft memory limit is used.
299 Initialize(8, ALLOW_ANYTHING, SMOOTHNESS_TAKES_PRIORITY);
300 TileVector active_tree_tiles =
301 CreateTiles(5, TilePriorityForEventualBin(), TilePriority());
302 TileVector pending_tree_tiles =
303 CreateTiles(5, TilePriority(), TilePriorityRequiredForActivation());
304 tile_manager()->AssignMemoryToTiles(global_state_);
306 EXPECT_EQ(5, AssignedMemoryCount(active_tree_tiles));
307 EXPECT_EQ(3, AssignedMemoryCount(pending_tree_tiles));
309 SetTreePriority(SAME_PRIORITY_FOR_BOTH_TREES);
310 tile_manager()->AssignMemoryToTiles(global_state_);
312 EXPECT_EQ(3, AssignedMemoryCount(active_tree_tiles));
313 EXPECT_EQ(5, AssignedMemoryCount(pending_tree_tiles));
315 ReleaseTiles(&active_tree_tiles);
316 ReleaseTiles(&pending_tree_tiles);
319 TEST_P(TileManagerTest, PartialOOMMemoryToActive) {
320 // 5 tiles on active tree eventually bin, 5 tiles on pending tree now bin,
321 // but only enough memory for 8 tiles. The result is all active tree tiles
322 // get memory, and 3 of the pending tree tiles get memory.
323 // The pending tiles are not needed to avoid calimity (flickering or
324 // raster-on-demand) and the active tiles fit, so the soft limit is used.
326 Initialize(8, ALLOW_ANYTHING, SMOOTHNESS_TAKES_PRIORITY);
327 TileVector active_tree_tiles =
328 CreateTiles(5, TilePriorityForNowBin(), TilePriority());
329 TileVector pending_tree_tiles =
330 CreateTiles(5, TilePriority(), TilePriorityForNowBin());
332 tile_manager()->AssignMemoryToTiles(global_state_);
334 EXPECT_EQ(5, AssignedMemoryCount(active_tree_tiles));
335 EXPECT_EQ(3, AssignedMemoryCount(pending_tree_tiles));
337 ReleaseTiles(&active_tree_tiles);
338 ReleaseTiles(&pending_tree_tiles);
341 TEST_P(TileManagerTest, TotalOOMMemoryToPending) {
342 // 10 tiles on active tree eventually bin, 10 tiles on pending tree that are
343 // required for activation, but only enough tiles for 4 tiles. The result
344 // is 4 pending tree tiles get memory, and none of the active tree tiles
347 Initialize(4, ALLOW_ANYTHING, SMOOTHNESS_TAKES_PRIORITY);
348 TileVector active_tree_tiles =
349 CreateTiles(10, TilePriorityForEventualBin(), TilePriority());
350 TileVector pending_tree_tiles =
351 CreateTiles(10, TilePriority(), TilePriorityRequiredForActivation());
353 tile_manager()->AssignMemoryToTiles(global_state_);
355 EXPECT_EQ(4, AssignedMemoryCount(active_tree_tiles));
356 EXPECT_EQ(0, AssignedMemoryCount(pending_tree_tiles));
358 SetTreePriority(SAME_PRIORITY_FOR_BOTH_TREES);
359 tile_manager()->AssignMemoryToTiles(global_state_);
361 if (UsingResourceLimit()) {
362 EXPECT_EQ(0, AssignedMemoryCount(active_tree_tiles));
363 EXPECT_EQ(4, AssignedMemoryCount(pending_tree_tiles));
365 // Pending tiles are now required to avoid calimity (flickering or
366 // raster-on-demand). Hard-limit is used and double the tiles fit.
367 EXPECT_EQ(0, AssignedMemoryCount(active_tree_tiles));
368 EXPECT_EQ(8, AssignedMemoryCount(pending_tree_tiles));
371 ReleaseTiles(&active_tree_tiles);
372 ReleaseTiles(&pending_tree_tiles);
375 TEST_P(TileManagerTest, TotalOOMActiveSoonMemoryToPending) {
376 // 10 tiles on active tree soon bin, 10 tiles on pending tree that are
377 // required for activation, but only enough tiles for 4 tiles. The result
378 // is 4 pending tree tiles get memory, and none of the active tree tiles
381 Initialize(4, ALLOW_ANYTHING, SMOOTHNESS_TAKES_PRIORITY);
382 TileVector active_tree_tiles =
383 CreateTiles(10, TilePriorityForSoonBin(), TilePriority());
384 TileVector pending_tree_tiles =
385 CreateTiles(10, TilePriority(), TilePriorityRequiredForActivation());
387 tile_manager()->AssignMemoryToTiles(global_state_);
389 EXPECT_EQ(4, AssignedMemoryCount(active_tree_tiles));
390 EXPECT_EQ(0, AssignedMemoryCount(pending_tree_tiles));
392 SetTreePriority(SAME_PRIORITY_FOR_BOTH_TREES);
393 tile_manager()->AssignMemoryToTiles(global_state_);
395 if (UsingResourceLimit()) {
396 EXPECT_EQ(0, AssignedMemoryCount(active_tree_tiles));
397 EXPECT_EQ(4, AssignedMemoryCount(pending_tree_tiles));
399 // Pending tiles are now required to avoid calimity (flickering or
400 // raster-on-demand). Hard-limit is used and double the tiles fit.
401 EXPECT_EQ(0, AssignedMemoryCount(active_tree_tiles));
402 EXPECT_EQ(8, AssignedMemoryCount(pending_tree_tiles));
405 ReleaseTiles(&active_tree_tiles);
406 ReleaseTiles(&pending_tree_tiles);
409 TEST_P(TileManagerTest, TotalOOMMemoryToActive) {
410 // 10 tiles on active tree eventually bin, 10 tiles on pending tree now bin,
411 // but only enough memory for 4 tiles. The result is 4 active tree tiles
412 // get memory, and none of the pending tree tiles get memory.
414 Initialize(4, ALLOW_ANYTHING, SMOOTHNESS_TAKES_PRIORITY);
415 TileVector active_tree_tiles =
416 CreateTiles(10, TilePriorityForNowBin(), TilePriority());
417 TileVector pending_tree_tiles =
418 CreateTiles(10, TilePriority(), TilePriorityForNowBin());
420 tile_manager()->AssignMemoryToTiles(global_state_);
422 if (UsingResourceLimit()) {
423 EXPECT_EQ(4, AssignedMemoryCount(active_tree_tiles));
424 EXPECT_EQ(0, AssignedMemoryCount(pending_tree_tiles));
426 // Active tiles are required to avoid calimity (flickering or
427 // raster-on-demand). Hard-limit is used and double the tiles fit.
428 EXPECT_EQ(8, AssignedMemoryCount(active_tree_tiles));
429 EXPECT_EQ(0, AssignedMemoryCount(pending_tree_tiles));
432 ReleaseTiles(&active_tree_tiles);
433 ReleaseTiles(&pending_tree_tiles);
436 TEST_P(TileManagerTest, TotalOOMMemoryToNewContent) {
437 // 10 tiles on active tree now bin, 10 tiles on pending tree now bin,
438 // but only enough memory for 8 tiles. Any tile missing would cause
439 // a calamity (flickering or raster-on-demand). Depending on mode,
440 // we should use varying amounts of the higher hard memory limit.
441 if (UsingResourceLimit())
444 Initialize(8, ALLOW_ANYTHING, SMOOTHNESS_TAKES_PRIORITY);
445 TileVector active_tree_tiles =
446 CreateTiles(10, TilePriorityForNowBin(), TilePriority());
447 TileVector pending_tree_tiles =
448 CreateTiles(10, TilePriority(), TilePriorityForNowBin());
450 // Active tiles are required to avoid calimity. The hard-limit is used and all
451 // active-tiles fit. No pending tiles are needed to avoid calamity so only 10
452 // tiles total are used.
453 tile_manager()->AssignMemoryToTiles(global_state_);
454 EXPECT_EQ(10, AssignedMemoryCount(active_tree_tiles));
455 EXPECT_EQ(0, AssignedMemoryCount(pending_tree_tiles));
457 // Even the hard-limit won't save us now. All tiles are required to avoid
458 // a clamity but we only have 16. The tiles will be distribted randomly
459 // given they are identical, in practice depending on their screen location.
460 SetTreePriority(SAME_PRIORITY_FOR_BOTH_TREES);
461 tile_manager()->AssignMemoryToTiles(global_state_);
463 AssignedMemoryCount(active_tree_tiles) +
464 AssignedMemoryCount(pending_tree_tiles));
466 // The pending tree is now more important. Active tiles will take higher
467 // priority if they are ready-to-draw in practice. Importantly though,
468 // pending tiles also utilize the hard-limit.
469 SetTreePriority(NEW_CONTENT_TAKES_PRIORITY);
470 tile_manager()->AssignMemoryToTiles(global_state_);
471 EXPECT_EQ(0, AssignedMemoryCount(active_tree_tiles));
472 EXPECT_EQ(10, AssignedMemoryCount(pending_tree_tiles));
474 ReleaseTiles(&active_tree_tiles);
475 ReleaseTiles(&pending_tree_tiles);
478 // If true, the max tile limit should be applied as bytes; if false,
479 // as num_resources_limit.
480 INSTANTIATE_TEST_CASE_P(TileManagerTests,
482 ::testing::Values(true, false));
484 class LowResTilingsSettings : public ImplSidePaintingSettings {
486 LowResTilingsSettings() { create_low_res_tiling = true; }
489 class TileManagerTilePriorityQueueTest : public testing::Test {
491 TileManagerTilePriorityQueueTest()
492 : memory_limit_policy_(ALLOW_ANYTHING),
494 ready_to_activate_(false),
496 proxy_(base::MessageLoopProxy::current()),
497 host_impl_(LowResTilingsSettings(), &proxy_, &shared_bitmap_manager_) {}
499 void SetTreePriority(TreePriority tree_priority) {
500 GlobalStateThatImpactsTilePriority state;
501 gfx::Size tile_size(256, 256);
503 state.soft_memory_limit_in_bytes = 100 * 1000 * 1000;
504 state.num_resources_limit = max_tiles_;
505 state.hard_memory_limit_in_bytes = state.soft_memory_limit_in_bytes * 2;
506 state.memory_limit_policy = memory_limit_policy_;
507 state.tree_priority = tree_priority;
509 global_state_ = state;
510 host_impl_.resource_pool()->SetResourceUsageLimits(
511 state.soft_memory_limit_in_bytes,
512 state.soft_memory_limit_in_bytes,
513 state.num_resources_limit);
514 host_impl_.tile_manager()->SetGlobalStateForTesting(state);
517 virtual void SetUp() OVERRIDE {
518 InitializeRenderer();
519 SetTreePriority(SAME_PRIORITY_FOR_BOTH_TREES);
522 virtual void InitializeRenderer() {
523 host_impl_.InitializeRenderer(
524 FakeOutputSurface::Create3d().PassAs<OutputSurface>());
527 void SetupDefaultTrees(const gfx::Size& layer_bounds) {
528 gfx::Size tile_size(100, 100);
530 scoped_refptr<FakePicturePileImpl> pending_pile =
531 FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
532 scoped_refptr<FakePicturePileImpl> active_pile =
533 FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
535 SetupTrees(pending_pile, active_pile);
538 void ActivateTree() {
539 host_impl_.ActivateSyncTree();
540 CHECK(!host_impl_.pending_tree());
541 pending_layer_ = NULL;
542 active_layer_ = static_cast<FakePictureLayerImpl*>(
543 host_impl_.active_tree()->LayerById(id_));
546 void SetupDefaultTreesWithFixedTileSize(const gfx::Size& layer_bounds,
547 const gfx::Size& tile_size) {
548 SetupDefaultTrees(layer_bounds);
549 pending_layer_->set_fixed_tile_size(tile_size);
550 active_layer_->set_fixed_tile_size(tile_size);
553 void SetupTrees(scoped_refptr<PicturePileImpl> pending_pile,
554 scoped_refptr<PicturePileImpl> active_pile) {
555 SetupPendingTree(active_pile);
557 SetupPendingTree(pending_pile);
560 void SetupPendingTree(scoped_refptr<PicturePileImpl> pile) {
561 host_impl_.CreatePendingTree();
562 LayerTreeImpl* pending_tree = host_impl_.pending_tree();
563 // Clear recycled tree.
564 pending_tree->DetachLayerTree();
566 scoped_ptr<FakePictureLayerImpl> pending_layer =
567 FakePictureLayerImpl::CreateWithPile(pending_tree, id_, pile);
568 pending_layer->SetDrawsContent(true);
569 pending_tree->SetRootLayer(pending_layer.PassAs<LayerImpl>());
571 pending_layer_ = static_cast<FakePictureLayerImpl*>(
572 host_impl_.pending_tree()->LayerById(id_));
573 pending_layer_->DoPostCommitInitializationIfNeeded();
576 void CreateHighLowResAndSetAllTilesVisible() {
577 // Active layer must get updated first so pending layer can share from it.
578 active_layer_->CreateDefaultTilingsAndTiles();
579 active_layer_->SetAllTilesVisible();
580 pending_layer_->CreateDefaultTilingsAndTiles();
581 pending_layer_->SetAllTilesVisible();
584 TileManager* tile_manager() { return host_impl_.tile_manager(); }
587 GlobalStateThatImpactsTilePriority global_state_;
589 TestSharedBitmapManager shared_bitmap_manager_;
590 TileMemoryLimitPolicy memory_limit_policy_;
592 bool ready_to_activate_;
594 FakeImplProxy proxy_;
595 FakeLayerTreeHostImpl host_impl_;
596 FakePictureLayerImpl* pending_layer_;
597 FakePictureLayerImpl* active_layer_;
600 TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueue) {
601 SetupDefaultTrees(gfx::Size(1000, 1000));
603 active_layer_->CreateDefaultTilingsAndTiles();
604 pending_layer_->CreateDefaultTilingsAndTiles();
606 RasterTilePriorityQueue queue;
607 host_impl_.BuildRasterQueue(&queue, SAME_PRIORITY_FOR_BOTH_TREES);
608 EXPECT_FALSE(queue.IsEmpty());
610 size_t tile_count = 0;
611 std::set<Tile*> all_tiles;
612 while (!queue.IsEmpty()) {
613 EXPECT_TRUE(queue.Top());
614 all_tiles.insert(queue.Top());
619 EXPECT_EQ(tile_count, all_tiles.size());
620 EXPECT_EQ(17u, tile_count);
622 // Sanity check, all tiles should be visible.
623 std::set<Tile*> smoothness_tiles;
625 host_impl_.BuildRasterQueue(&queue, SMOOTHNESS_TAKES_PRIORITY);
626 while (!queue.IsEmpty()) {
627 Tile* tile = queue.Top();
629 EXPECT_EQ(TilePriority::NOW, tile->priority(ACTIVE_TREE).priority_bin);
630 EXPECT_EQ(TilePriority::NOW, tile->priority(PENDING_TREE).priority_bin);
631 smoothness_tiles.insert(tile);
634 EXPECT_EQ(all_tiles, smoothness_tiles);
636 Region invalidation(gfx::Rect(0, 0, 500, 500));
638 // Invalidate the pending tree.
639 pending_layer_->set_invalidation(invalidation);
640 pending_layer_->HighResTiling()->UpdateTilesToCurrentPile(
641 invalidation, gfx::Size(1000, 1000));
642 pending_layer_->LowResTiling()->UpdateTilesToCurrentPile(
643 invalidation, gfx::Size(1000, 1000));
645 active_layer_->ResetAllTilesPriorities();
646 pending_layer_->ResetAllTilesPriorities();
648 // Renew all of the tile priorities.
649 gfx::Rect viewport(50, 50, 100, 100);
650 pending_layer_->HighResTiling()->UpdateTilePriorities(
651 PENDING_TREE, viewport, 1.0f, 1.0, Occlusion());
652 pending_layer_->LowResTiling()->UpdateTilePriorities(
653 PENDING_TREE, viewport, 1.0f, 1.0, Occlusion());
654 active_layer_->HighResTiling()->UpdateTilePriorities(
655 ACTIVE_TREE, viewport, 1.0f, 1.0, Occlusion());
656 active_layer_->LowResTiling()->UpdateTilePriorities(
657 ACTIVE_TREE, viewport, 1.0f, 1.0, Occlusion());
659 // Populate all tiles directly from the tilings.
661 std::vector<Tile*> pending_high_res_tiles =
662 pending_layer_->HighResTiling()->AllTilesForTesting();
663 for (size_t i = 0; i < pending_high_res_tiles.size(); ++i)
664 all_tiles.insert(pending_high_res_tiles[i]);
666 std::vector<Tile*> pending_low_res_tiles =
667 pending_layer_->LowResTiling()->AllTilesForTesting();
668 for (size_t i = 0; i < pending_low_res_tiles.size(); ++i)
669 all_tiles.insert(pending_low_res_tiles[i]);
671 std::vector<Tile*> active_high_res_tiles =
672 active_layer_->HighResTiling()->AllTilesForTesting();
673 for (size_t i = 0; i < active_high_res_tiles.size(); ++i)
674 all_tiles.insert(active_high_res_tiles[i]);
676 std::vector<Tile*> active_low_res_tiles =
677 active_layer_->LowResTiling()->AllTilesForTesting();
678 for (size_t i = 0; i < active_low_res_tiles.size(); ++i)
679 all_tiles.insert(active_low_res_tiles[i]);
681 Tile* last_tile = NULL;
682 smoothness_tiles.clear();
684 size_t increasing_distance_tiles = 0u;
685 // Here we expect to get increasing ACTIVE_TREE priority_bin.
687 host_impl_.BuildRasterQueue(&queue, SMOOTHNESS_TAKES_PRIORITY);
688 while (!queue.IsEmpty()) {
689 Tile* tile = queue.Top();
695 EXPECT_LE(last_tile->priority(ACTIVE_TREE).priority_bin,
696 tile->priority(ACTIVE_TREE).priority_bin);
697 if (last_tile->priority(ACTIVE_TREE).priority_bin ==
698 tile->priority(ACTIVE_TREE).priority_bin) {
699 increasing_distance_tiles +=
700 last_tile->priority(ACTIVE_TREE).distance_to_visible <=
701 tile->priority(ACTIVE_TREE).distance_to_visible;
704 if (tile->priority(ACTIVE_TREE).priority_bin == TilePriority::NOW &&
705 last_tile->priority(ACTIVE_TREE).resolution !=
706 tile->priority(ACTIVE_TREE).resolution) {
707 // Low resolution should come first.
708 EXPECT_EQ(LOW_RESOLUTION, last_tile->priority(ACTIVE_TREE).resolution);
713 smoothness_tiles.insert(tile);
717 EXPECT_EQ(tile_count, smoothness_tiles.size());
718 EXPECT_EQ(all_tiles, smoothness_tiles);
719 // Since we don't guarantee increasing distance due to spiral iterator, we
720 // should check that we're _mostly_ right.
721 EXPECT_GT(increasing_distance_tiles, 3 * tile_count / 4);
723 std::set<Tile*> new_content_tiles;
725 increasing_distance_tiles = 0u;
726 // Here we expect to get increasing PENDING_TREE priority_bin.
728 host_impl_.BuildRasterQueue(&queue, NEW_CONTENT_TAKES_PRIORITY);
729 while (!queue.IsEmpty()) {
730 Tile* tile = queue.Top();
736 EXPECT_LE(last_tile->priority(PENDING_TREE).priority_bin,
737 tile->priority(PENDING_TREE).priority_bin);
738 if (last_tile->priority(PENDING_TREE).priority_bin ==
739 tile->priority(PENDING_TREE).priority_bin) {
740 increasing_distance_tiles +=
741 last_tile->priority(PENDING_TREE).distance_to_visible <=
742 tile->priority(PENDING_TREE).distance_to_visible;
745 if (tile->priority(PENDING_TREE).priority_bin == TilePriority::NOW &&
746 last_tile->priority(PENDING_TREE).resolution !=
747 tile->priority(PENDING_TREE).resolution) {
748 // High resolution should come first.
749 EXPECT_EQ(HIGH_RESOLUTION, last_tile->priority(PENDING_TREE).resolution);
753 new_content_tiles.insert(tile);
757 EXPECT_EQ(tile_count, new_content_tiles.size());
758 EXPECT_EQ(all_tiles, new_content_tiles);
759 // Since we don't guarantee increasing distance due to spiral iterator, we
760 // should check that we're _mostly_ right.
761 EXPECT_GT(increasing_distance_tiles, 3 * tile_count / 4);
764 TEST_F(TileManagerTilePriorityQueueTest, EvictionTilePriorityQueue) {
765 SetupDefaultTrees(gfx::Size(1000, 1000));
767 active_layer_->CreateDefaultTilingsAndTiles();
768 pending_layer_->CreateDefaultTilingsAndTiles();
770 EvictionTilePriorityQueue empty_queue;
771 host_impl_.BuildEvictionQueue(&empty_queue, SAME_PRIORITY_FOR_BOTH_TREES);
772 EXPECT_TRUE(empty_queue.IsEmpty());
773 std::set<Tile*> all_tiles;
774 size_t tile_count = 0;
776 RasterTilePriorityQueue raster_queue;
777 host_impl_.BuildRasterQueue(&raster_queue, SAME_PRIORITY_FOR_BOTH_TREES);
778 while (!raster_queue.IsEmpty()) {
780 EXPECT_TRUE(raster_queue.Top());
781 all_tiles.insert(raster_queue.Top());
785 EXPECT_EQ(tile_count, all_tiles.size());
786 EXPECT_EQ(17u, tile_count);
788 tile_manager()->InitializeTilesWithResourcesForTesting(
789 std::vector<Tile*>(all_tiles.begin(), all_tiles.end()));
791 EvictionTilePriorityQueue queue;
792 host_impl_.BuildEvictionQueue(&queue, SMOOTHNESS_TAKES_PRIORITY);
793 EXPECT_FALSE(queue.IsEmpty());
795 // Sanity check, all tiles should be visible.
796 std::set<Tile*> smoothness_tiles;
797 while (!queue.IsEmpty()) {
798 Tile* tile = queue.Top();
800 EXPECT_EQ(TilePriority::NOW, tile->priority(ACTIVE_TREE).priority_bin);
801 EXPECT_EQ(TilePriority::NOW, tile->priority(PENDING_TREE).priority_bin);
802 EXPECT_TRUE(tile->HasResources());
803 smoothness_tiles.insert(tile);
806 EXPECT_EQ(all_tiles, smoothness_tiles);
808 tile_manager()->ReleaseTileResourcesForTesting(
809 std::vector<Tile*>(all_tiles.begin(), all_tiles.end()));
811 Region invalidation(gfx::Rect(0, 0, 500, 500));
813 // Invalidate the pending tree.
814 pending_layer_->set_invalidation(invalidation);
815 pending_layer_->HighResTiling()->UpdateTilesToCurrentPile(
816 invalidation, gfx::Size(1000, 1000));
817 pending_layer_->LowResTiling()->UpdateTilesToCurrentPile(
818 invalidation, gfx::Size(1000, 1000));
820 active_layer_->ResetAllTilesPriorities();
821 pending_layer_->ResetAllTilesPriorities();
823 // Renew all of the tile priorities.
824 gfx::Rect viewport(50, 50, 100, 100);
825 pending_layer_->HighResTiling()->UpdateTilePriorities(
826 PENDING_TREE, viewport, 1.0f, 1.0, Occlusion());
827 pending_layer_->LowResTiling()->UpdateTilePriorities(
828 PENDING_TREE, viewport, 1.0f, 1.0, Occlusion());
829 active_layer_->HighResTiling()->UpdateTilePriorities(
830 ACTIVE_TREE, viewport, 1.0f, 1.0, Occlusion());
831 active_layer_->LowResTiling()->UpdateTilePriorities(
832 ACTIVE_TREE, viewport, 1.0f, 1.0, Occlusion());
834 // Populate all tiles directly from the tilings.
836 std::vector<Tile*> pending_high_res_tiles =
837 pending_layer_->HighResTiling()->AllTilesForTesting();
838 for (size_t i = 0; i < pending_high_res_tiles.size(); ++i)
839 all_tiles.insert(pending_high_res_tiles[i]);
841 std::vector<Tile*> pending_low_res_tiles =
842 pending_layer_->LowResTiling()->AllTilesForTesting();
843 for (size_t i = 0; i < pending_low_res_tiles.size(); ++i)
844 all_tiles.insert(pending_low_res_tiles[i]);
846 std::vector<Tile*> active_high_res_tiles =
847 active_layer_->HighResTiling()->AllTilesForTesting();
848 for (size_t i = 0; i < active_high_res_tiles.size(); ++i)
849 all_tiles.insert(active_high_res_tiles[i]);
851 std::vector<Tile*> active_low_res_tiles =
852 active_layer_->LowResTiling()->AllTilesForTesting();
853 for (size_t i = 0; i < active_low_res_tiles.size(); ++i)
854 all_tiles.insert(active_low_res_tiles[i]);
856 tile_manager()->InitializeTilesWithResourcesForTesting(
857 std::vector<Tile*>(all_tiles.begin(), all_tiles.end()));
859 pending_layer_->MarkVisibleResourcesAsRequired();
861 Tile* last_tile = NULL;
862 smoothness_tiles.clear();
864 // Here we expect to get increasing ACTIVE_TREE priority_bin.
866 host_impl_.BuildEvictionQueue(&queue, SMOOTHNESS_TAKES_PRIORITY);
867 while (!queue.IsEmpty()) {
868 Tile* tile = queue.Top();
870 EXPECT_TRUE(tile->HasResources());
875 EXPECT_GE(last_tile->priority(ACTIVE_TREE).priority_bin,
876 tile->priority(ACTIVE_TREE).priority_bin);
877 if (last_tile->priority(ACTIVE_TREE).priority_bin ==
878 tile->priority(ACTIVE_TREE).priority_bin) {
879 EXPECT_LE(last_tile->required_for_activation(),
880 tile->required_for_activation());
881 if (last_tile->required_for_activation() ==
882 tile->required_for_activation()) {
883 EXPECT_GE(last_tile->priority(ACTIVE_TREE).distance_to_visible,
884 tile->priority(ACTIVE_TREE).distance_to_visible);
890 smoothness_tiles.insert(tile);
894 EXPECT_EQ(tile_count, smoothness_tiles.size());
895 EXPECT_EQ(all_tiles, smoothness_tiles);
897 std::set<Tile*> new_content_tiles;
899 // Here we expect to get increasing PENDING_TREE priority_bin.
901 host_impl_.BuildEvictionQueue(&queue, NEW_CONTENT_TAKES_PRIORITY);
902 while (!queue.IsEmpty()) {
903 Tile* tile = queue.Top();
909 EXPECT_GE(last_tile->priority(PENDING_TREE).priority_bin,
910 tile->priority(PENDING_TREE).priority_bin);
911 if (last_tile->priority(PENDING_TREE).priority_bin ==
912 tile->priority(PENDING_TREE).priority_bin) {
913 EXPECT_LE(last_tile->required_for_activation(),
914 tile->required_for_activation());
915 if (last_tile->required_for_activation() ==
916 tile->required_for_activation()) {
917 EXPECT_GE(last_tile->priority(PENDING_TREE).distance_to_visible,
918 tile->priority(PENDING_TREE).distance_to_visible);
923 new_content_tiles.insert(tile);
927 EXPECT_EQ(tile_count, new_content_tiles.size());
928 EXPECT_EQ(all_tiles, new_content_tiles);
931 TEST_F(TileManagerTilePriorityQueueTest,
932 EvictionTilePriorityQueueWithOcclusion) {
933 gfx::Size tile_size(102, 102);
934 gfx::Size layer_bounds(1000, 1000);
936 scoped_refptr<FakePicturePileImpl> pending_pile =
937 FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
938 SetupPendingTree(pending_pile);
939 pending_layer_->CreateDefaultTilingsAndTiles();
941 scoped_ptr<FakePictureLayerImpl> pending_child =
942 FakePictureLayerImpl::CreateWithPile(
943 host_impl_.pending_tree(), 2, pending_pile);
944 pending_layer_->AddChild(pending_child.PassAs<LayerImpl>());
946 FakePictureLayerImpl* pending_child_layer =
947 static_cast<FakePictureLayerImpl*>(pending_layer_->children()[0]);
948 pending_child_layer->SetDrawsContent(true);
949 pending_child_layer->DoPostCommitInitializationIfNeeded();
950 pending_child_layer->CreateDefaultTilingsAndTiles();
952 std::set<Tile*> all_tiles;
953 size_t tile_count = 0;
954 RasterTilePriorityQueue raster_queue;
955 host_impl_.BuildRasterQueue(&raster_queue, SAME_PRIORITY_FOR_BOTH_TREES);
956 while (!raster_queue.IsEmpty()) {
958 EXPECT_TRUE(raster_queue.Top());
959 all_tiles.insert(raster_queue.Top());
962 EXPECT_EQ(tile_count, all_tiles.size());
963 EXPECT_EQ(34u, tile_count);
965 pending_layer_->ResetAllTilesPriorities();
967 // Renew all of the tile priorities.
968 gfx::Rect viewport(layer_bounds);
969 pending_layer_->HighResTiling()->UpdateTilePriorities(
970 PENDING_TREE, viewport, 1.0f, 1.0, Occlusion());
971 pending_layer_->LowResTiling()->UpdateTilePriorities(
972 PENDING_TREE, viewport, 1.0f, 1.0, Occlusion());
973 pending_child_layer->HighResTiling()->UpdateTilePriorities(
974 PENDING_TREE, viewport, 1.0f, 1.0, Occlusion());
975 pending_child_layer->LowResTiling()->UpdateTilePriorities(
976 PENDING_TREE, viewport, 1.0f, 1.0, Occlusion());
978 // Populate all tiles directly from the tilings.
980 std::vector<Tile*> pending_high_res_tiles =
981 pending_layer_->HighResTiling()->AllTilesForTesting();
982 for (size_t i = 0; i < pending_high_res_tiles.size(); ++i)
983 all_tiles.insert(pending_high_res_tiles[i]);
985 std::vector<Tile*> pending_low_res_tiles =
986 pending_layer_->LowResTiling()->AllTilesForTesting();
987 for (size_t i = 0; i < pending_low_res_tiles.size(); ++i)
988 all_tiles.insert(pending_low_res_tiles[i]);
990 // Set all tiles on the pending_child_layer as occluded on the pending tree.
991 std::vector<Tile*> pending_child_high_res_tiles =
992 pending_child_layer->HighResTiling()->AllTilesForTesting();
993 for (size_t i = 0; i < pending_child_high_res_tiles.size(); ++i) {
994 pending_child_high_res_tiles[i]->set_is_occluded(PENDING_TREE, true);
995 all_tiles.insert(pending_child_high_res_tiles[i]);
998 std::vector<Tile*> pending_child_low_res_tiles =
999 pending_child_layer->LowResTiling()->AllTilesForTesting();
1000 for (size_t i = 0; i < pending_child_low_res_tiles.size(); ++i) {
1001 pending_child_low_res_tiles[i]->set_is_occluded(PENDING_TREE, true);
1002 all_tiles.insert(pending_child_low_res_tiles[i]);
1005 tile_manager()->InitializeTilesWithResourcesForTesting(
1006 std::vector<Tile*>(all_tiles.begin(), all_tiles.end()));
1008 // Verify occlusion is considered by EvictionTilePriorityQueue.
1009 TreePriority tree_priority = NEW_CONTENT_TAKES_PRIORITY;
1010 size_t occluded_count = 0u;
1011 Tile* last_tile = NULL;
1012 EvictionTilePriorityQueue queue;
1013 host_impl_.BuildEvictionQueue(&queue, tree_priority);
1014 while (!queue.IsEmpty()) {
1015 Tile* tile = queue.Top();
1019 bool tile_is_occluded = tile->is_occluded_for_tree_priority(tree_priority);
1021 // The only way we will encounter an occluded tile after an unoccluded
1022 // tile is if the priorty bin decreased, the tile is required for
1023 // activation, or the scale changed.
1024 if (tile_is_occluded) {
1027 bool last_tile_is_occluded =
1028 last_tile->is_occluded_for_tree_priority(tree_priority);
1029 if (!last_tile_is_occluded) {
1030 TilePriority::PriorityBin tile_priority_bin =
1031 tile->priority_for_tree_priority(tree_priority).priority_bin;
1032 TilePriority::PriorityBin last_tile_priority_bin =
1033 last_tile->priority_for_tree_priority(tree_priority).priority_bin;
1035 EXPECT_TRUE((tile_priority_bin < last_tile_priority_bin) ||
1036 tile->required_for_activation() ||
1037 (tile->contents_scale() != last_tile->contents_scale()));
1043 size_t expected_occluded_count =
1044 pending_child_high_res_tiles.size() + pending_child_low_res_tiles.size();
1045 EXPECT_EQ(expected_occluded_count, occluded_count);
1048 TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueueEmptyLayers) {
1049 SetupDefaultTrees(gfx::Size(1000, 1000));
1051 active_layer_->CreateDefaultTilingsAndTiles();
1052 pending_layer_->CreateDefaultTilingsAndTiles();
1054 RasterTilePriorityQueue queue;
1055 host_impl_.BuildRasterQueue(&queue, SAME_PRIORITY_FOR_BOTH_TREES);
1056 EXPECT_FALSE(queue.IsEmpty());
1058 size_t tile_count = 0;
1059 std::set<Tile*> all_tiles;
1060 while (!queue.IsEmpty()) {
1061 EXPECT_TRUE(queue.Top());
1062 all_tiles.insert(queue.Top());
1067 EXPECT_EQ(tile_count, all_tiles.size());
1068 EXPECT_EQ(17u, tile_count);
1071 for (int i = 1; i < 10; ++i) {
1072 scoped_ptr<FakePictureLayerImpl> pending_layer =
1073 FakePictureLayerImpl::Create(host_impl_.pending_tree(), id_ + i);
1074 pending_layer->SetDrawsContent(true);
1075 pending_layer->DoPostCommitInitializationIfNeeded();
1076 pending_layer->set_has_valid_tile_priorities(true);
1077 pending_layer_->AddChild(pending_layer.PassAs<LayerImpl>());
1080 host_impl_.BuildRasterQueue(&queue, SAME_PRIORITY_FOR_BOTH_TREES);
1081 EXPECT_FALSE(queue.IsEmpty());
1085 while (!queue.IsEmpty()) {
1086 EXPECT_TRUE(queue.Top());
1087 all_tiles.insert(queue.Top());
1091 EXPECT_EQ(tile_count, all_tiles.size());
1092 EXPECT_EQ(17u, tile_count);
1095 TEST_F(TileManagerTilePriorityQueueTest, EvictionTilePriorityQueueEmptyLayers) {
1096 SetupDefaultTrees(gfx::Size(1000, 1000));
1098 active_layer_->CreateDefaultTilingsAndTiles();
1099 pending_layer_->CreateDefaultTilingsAndTiles();
1101 RasterTilePriorityQueue raster_queue;
1102 host_impl_.BuildRasterQueue(&raster_queue, SAME_PRIORITY_FOR_BOTH_TREES);
1103 EXPECT_FALSE(raster_queue.IsEmpty());
1105 size_t tile_count = 0;
1106 std::set<Tile*> all_tiles;
1107 while (!raster_queue.IsEmpty()) {
1108 EXPECT_TRUE(raster_queue.Top());
1109 all_tiles.insert(raster_queue.Top());
1113 EXPECT_EQ(tile_count, all_tiles.size());
1114 EXPECT_EQ(17u, tile_count);
1116 std::vector<Tile*> tiles(all_tiles.begin(), all_tiles.end());
1117 host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(tiles);
1119 EvictionTilePriorityQueue queue;
1120 for (int i = 1; i < 10; ++i) {
1121 scoped_ptr<FakePictureLayerImpl> pending_layer =
1122 FakePictureLayerImpl::Create(host_impl_.pending_tree(), id_ + i);
1123 pending_layer->SetDrawsContent(true);
1124 pending_layer->DoPostCommitInitializationIfNeeded();
1125 pending_layer->set_has_valid_tile_priorities(true);
1126 pending_layer_->AddChild(pending_layer.PassAs<LayerImpl>());
1129 host_impl_.BuildEvictionQueue(&queue, SAME_PRIORITY_FOR_BOTH_TREES);
1130 EXPECT_FALSE(queue.IsEmpty());
1134 while (!queue.IsEmpty()) {
1135 EXPECT_TRUE(queue.Top());
1136 all_tiles.insert(queue.Top());
1140 EXPECT_EQ(tile_count, all_tiles.size());
1141 EXPECT_EQ(17u, tile_count);