Home | History | Annotate | Download | only in resources
      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 "cc/resources/tile.h"
      6 #include "cc/resources/tile_priority.h"
      7 #include "cc/test/fake_output_surface.h"
      8 #include "cc/test/fake_picture_pile_impl.h"
      9 #include "cc/test/fake_tile_manager.h"
     10 #include "cc/test/fake_tile_manager_client.h"
     11 #include "cc/test/test_tile_priorities.h"
     12 #include "testing/gtest/include/gtest/gtest.h"
     13 
     14 namespace cc {
     15 namespace {
     16 
     17 class TileManagerTest : public testing::TestWithParam<bool> {
     18  public:
     19   typedef std::vector<scoped_refptr<Tile> > TileVector;
     20 
     21   void Initialize(int max_tiles,
     22                   TileMemoryLimitPolicy memory_limit_policy,
     23                   TreePriority tree_priority) {
     24     output_surface_ = FakeOutputSurface::Create3d();
     25     resource_provider_ = ResourceProvider::Create(output_surface_.get(), 0);
     26     tile_manager_ = make_scoped_ptr(
     27         new FakeTileManager(&tile_manager_client_, resource_provider_.get()));
     28 
     29     memory_limit_policy_ = memory_limit_policy;
     30     max_memory_tiles_ = max_tiles;
     31     GlobalStateThatImpactsTilePriority state;
     32     gfx::Size tile_size = settings_.default_tile_size;
     33 
     34     // The parametrization specifies whether the max tile limit should
     35     // be applied to RAM or to tile limit.
     36     if (GetParam()) {
     37       state.memory_limit_in_bytes =
     38           max_tiles * 4 * tile_size.width() * tile_size.height();
     39       state.num_resources_limit = 100;
     40     } else {
     41       state.memory_limit_in_bytes = 100 * 1000 * 1000;
     42       state.num_resources_limit = max_tiles;
     43     }
     44     state.memory_limit_policy = memory_limit_policy;
     45     state.tree_priority = tree_priority;
     46 
     47     tile_manager_->SetGlobalState(state);
     48     picture_pile_ = FakePicturePileImpl::CreatePile();
     49   }
     50 
     51   void SetTreePriority(TreePriority tree_priority) {
     52     GlobalStateThatImpactsTilePriority state;
     53     gfx::Size tile_size = settings_.default_tile_size;
     54     state.memory_limit_in_bytes =
     55         max_memory_tiles_ * 4 * tile_size.width() * tile_size.height();
     56     state.memory_limit_policy = memory_limit_policy_;
     57     state.num_resources_limit = 100;
     58     state.tree_priority = tree_priority;
     59     tile_manager_->SetGlobalState(state);
     60   }
     61 
     62   virtual void TearDown() OVERRIDE {
     63     tile_manager_.reset(NULL);
     64     picture_pile_ = NULL;
     65 
     66     testing::Test::TearDown();
     67   }
     68 
     69   TileVector CreateTiles(int count,
     70                          TilePriority active_priority,
     71                          TilePriority pending_priority) {
     72     TileVector tiles;
     73     for (int i = 0; i < count; ++i) {
     74       scoped_refptr<Tile> tile =
     75           make_scoped_refptr(new Tile(tile_manager_.get(),
     76                                       picture_pile_.get(),
     77                                       settings_.default_tile_size,
     78                                       gfx::Rect(),
     79                                       gfx::Rect(),
     80                                       1.0,
     81                                       0,
     82                                       0,
     83                                       true));
     84       tile->SetPriority(ACTIVE_TREE, active_priority);
     85       tile->SetPriority(PENDING_TREE, pending_priority);
     86       tiles.push_back(tile);
     87     }
     88     return tiles;
     89   }
     90 
     91   FakeTileManager* tile_manager() {
     92     return tile_manager_.get();
     93   }
     94 
     95   int AssignedMemoryCount(const TileVector& tiles) {
     96     int has_memory_count = 0;
     97     for (TileVector::const_iterator it = tiles.begin();
     98          it != tiles.end();
     99          ++it) {
    100       if (tile_manager_->HasBeenAssignedMemory(*it))
    101         ++has_memory_count;
    102     }
    103     return has_memory_count;
    104   }
    105 
    106   int TilesWithLCDCount(const TileVector& tiles) {
    107     int has_lcd_count = 0;
    108     for (TileVector::const_iterator it = tiles.begin();
    109          it != tiles.end();
    110          ++it) {
    111       if ((*it)->GetRasterModeForTesting() == HIGH_QUALITY_RASTER_MODE)
    112         ++has_lcd_count;
    113     }
    114     return has_lcd_count;
    115   }
    116 
    117  private:
    118   FakeTileManagerClient tile_manager_client_;
    119   LayerTreeSettings settings_;
    120   scoped_ptr<FakeTileManager> tile_manager_;
    121   scoped_refptr<FakePicturePileImpl> picture_pile_;
    122   scoped_ptr<FakeOutputSurface> output_surface_;
    123   scoped_ptr<ResourceProvider> resource_provider_;
    124   TileMemoryLimitPolicy memory_limit_policy_;
    125   int max_memory_tiles_;
    126 };
    127 
    128 TEST_P(TileManagerTest, EnoughMemoryAllowAnything) {
    129   // A few tiles of each type of priority, with enough memory for all tiles.
    130 
    131   Initialize(10, ALLOW_ANYTHING, SMOOTHNESS_TAKES_PRIORITY);
    132   TileVector active_now =
    133       CreateTiles(3, TilePriorityForNowBin(), TilePriority());
    134   TileVector pending_now =
    135       CreateTiles(3, TilePriority(), TilePriorityForNowBin());
    136   TileVector active_pending_soon = CreateTiles(
    137       3, TilePriorityForSoonBin(), TilePriorityForSoonBin());
    138   TileVector never_bin = CreateTiles(1, TilePriority(), TilePriority());
    139 
    140   tile_manager()->AssignMemoryToTiles();
    141 
    142   EXPECT_EQ(3, AssignedMemoryCount(active_now));
    143   EXPECT_EQ(3, AssignedMemoryCount(pending_now));
    144   EXPECT_EQ(3, AssignedMemoryCount(active_pending_soon));
    145   EXPECT_EQ(0, AssignedMemoryCount(never_bin));
    146 }
    147 
    148 TEST_P(TileManagerTest, EnoughMemoryAllowPrepaintOnly) {
    149   // A few tiles of each type of priority, with enough memory for all tiles,
    150   // with the exception of never bin.
    151 
    152   Initialize(10, ALLOW_PREPAINT_ONLY, SMOOTHNESS_TAKES_PRIORITY);
    153   TileVector active_now =
    154       CreateTiles(3, TilePriorityForNowBin(), TilePriority());
    155   TileVector pending_now =
    156       CreateTiles(3, TilePriority(), TilePriorityForNowBin());
    157   TileVector active_pending_soon = CreateTiles(
    158       3, TilePriorityForSoonBin(), TilePriorityForSoonBin());
    159   TileVector never_bin = CreateTiles(1, TilePriority(), TilePriority());
    160 
    161   tile_manager()->AssignMemoryToTiles();
    162 
    163   EXPECT_EQ(3, AssignedMemoryCount(active_now));
    164   EXPECT_EQ(3, AssignedMemoryCount(pending_now));
    165   EXPECT_EQ(3, AssignedMemoryCount(active_pending_soon));
    166   EXPECT_EQ(0, AssignedMemoryCount(never_bin));
    167 }
    168 
    169 TEST_P(TileManagerTest, EnoughMemoryAllowAbsoluteMinimum) {
    170   // A few tiles of each type of priority, with enough memory for all tiles,
    171   // with the exception of never and soon bins.
    172 
    173   Initialize(10, ALLOW_ABSOLUTE_MINIMUM, SMOOTHNESS_TAKES_PRIORITY);
    174   TileVector active_now =
    175       CreateTiles(3, TilePriorityForNowBin(), TilePriority());
    176   TileVector pending_now =
    177       CreateTiles(3, TilePriority(), TilePriorityForNowBin());
    178   TileVector active_pending_soon = CreateTiles(
    179       3, TilePriorityForSoonBin(), TilePriorityForSoonBin());
    180   TileVector never_bin = CreateTiles(1, TilePriority(), TilePriority());
    181 
    182   tile_manager()->AssignMemoryToTiles();
    183 
    184   EXPECT_EQ(3, AssignedMemoryCount(active_now));
    185   EXPECT_EQ(3, AssignedMemoryCount(pending_now));
    186   EXPECT_EQ(0, AssignedMemoryCount(active_pending_soon));
    187   EXPECT_EQ(0, AssignedMemoryCount(never_bin));
    188 }
    189 
    190 TEST_P(TileManagerTest, EnoughMemoryAllowNothing) {
    191   // A few tiles of each type of priority, with enough memory for all tiles,
    192   // but allow nothing should not assign any memory.
    193 
    194   Initialize(10, ALLOW_NOTHING, SMOOTHNESS_TAKES_PRIORITY);
    195   TileVector active_now =
    196       CreateTiles(3, TilePriorityForNowBin(), TilePriority());
    197   TileVector pending_now =
    198       CreateTiles(3, TilePriority(), TilePriorityForNowBin());
    199   TileVector active_pending_soon = CreateTiles(
    200       3, TilePriorityForSoonBin(), TilePriorityForSoonBin());
    201   TileVector never_bin = CreateTiles(1, TilePriority(), TilePriority());
    202 
    203   tile_manager()->AssignMemoryToTiles();
    204 
    205   EXPECT_EQ(0, AssignedMemoryCount(active_now));
    206   EXPECT_EQ(0, AssignedMemoryCount(pending_now));
    207   EXPECT_EQ(0, AssignedMemoryCount(active_pending_soon));
    208   EXPECT_EQ(0, AssignedMemoryCount(never_bin));
    209 }
    210 
    211 TEST_P(TileManagerTest, PartialOOMMemoryToPending) {
    212   // 5 tiles on active tree eventually bin, 5 tiles on pending tree that are
    213   // required for activation, but only enough memory for 8 tiles. The result
    214   // is all pending tree tiles get memory, and 3 of the active tree tiles
    215   // get memory.
    216 
    217   Initialize(8, ALLOW_ANYTHING, SMOOTHNESS_TAKES_PRIORITY);
    218   TileVector active_tree_tiles =
    219       CreateTiles(5, TilePriorityForEventualBin(), TilePriority());
    220   TileVector pending_tree_tiles =
    221       CreateTiles(5, TilePriority(), TilePriorityRequiredForActivation());
    222 
    223   tile_manager()->AssignMemoryToTiles();
    224 
    225   EXPECT_EQ(5, AssignedMemoryCount(active_tree_tiles));
    226   EXPECT_EQ(3, AssignedMemoryCount(pending_tree_tiles));
    227 
    228   SetTreePriority(SAME_PRIORITY_FOR_BOTH_TREES);
    229   tile_manager()->AssignMemoryToTiles();
    230 
    231   EXPECT_EQ(3, AssignedMemoryCount(active_tree_tiles));
    232   EXPECT_EQ(5, AssignedMemoryCount(pending_tree_tiles));
    233 }
    234 
    235 TEST_P(TileManagerTest, PartialOOMMemoryToActive) {
    236   // 5 tiles on active tree eventually bin, 5 tiles on pending tree now bin,
    237   // but only enough memory for 8 tiles. The result is all active tree tiles
    238   // get memory, and 3 of the pending tree tiles get memory.
    239 
    240   Initialize(8, ALLOW_ANYTHING, SMOOTHNESS_TAKES_PRIORITY);
    241   TileVector active_tree_tiles =
    242       CreateTiles(5, TilePriorityForNowBin(), TilePriority());
    243   TileVector pending_tree_tiles =
    244       CreateTiles(5, TilePriority(), TilePriorityForNowBin());
    245 
    246   tile_manager()->AssignMemoryToTiles();
    247 
    248   EXPECT_EQ(5, AssignedMemoryCount(active_tree_tiles));
    249   EXPECT_EQ(3, AssignedMemoryCount(pending_tree_tiles));
    250 }
    251 
    252 TEST_P(TileManagerTest, TotalOOMMemoryToPending) {
    253   // 5 tiles on active tree eventually bin, 5 tiles on pending tree that are
    254   // required for activation, but only enough memory for 4 tiles. The result
    255   // is 4 pending tree tiles get memory, and none of the active tree tiles
    256   // get memory.
    257 
    258   Initialize(4, ALLOW_ANYTHING, SMOOTHNESS_TAKES_PRIORITY);
    259   TileVector active_tree_tiles =
    260       CreateTiles(5, TilePriorityForEventualBin(), TilePriority());
    261   TileVector pending_tree_tiles =
    262       CreateTiles(5, TilePriority(), TilePriorityRequiredForActivation());
    263 
    264   tile_manager()->AssignMemoryToTiles();
    265 
    266   EXPECT_EQ(4, AssignedMemoryCount(active_tree_tiles));
    267   EXPECT_EQ(0, AssignedMemoryCount(pending_tree_tiles));
    268 
    269   SetTreePriority(SAME_PRIORITY_FOR_BOTH_TREES);
    270   tile_manager()->AssignMemoryToTiles();
    271 
    272   EXPECT_EQ(0, AssignedMemoryCount(active_tree_tiles));
    273   EXPECT_EQ(4, AssignedMemoryCount(pending_tree_tiles));
    274 }
    275 
    276 TEST_P(TileManagerTest, TotalOOMActiveSoonMemoryToPending) {
    277   // 5 tiles on active tree soon bin, 5 tiles on pending tree that are
    278   // required for activation, but only enough memory for 4 tiles. The result
    279   // is 4 pending tree tiles get memory, and none of the active tree tiles
    280   // get memory.
    281 
    282   Initialize(4, ALLOW_ANYTHING, SMOOTHNESS_TAKES_PRIORITY);
    283   TileVector active_tree_tiles =
    284       CreateTiles(5, TilePriorityForSoonBin(), TilePriority());
    285   TileVector pending_tree_tiles =
    286       CreateTiles(5, TilePriority(), TilePriorityRequiredForActivation());
    287 
    288   tile_manager()->AssignMemoryToTiles();
    289 
    290   EXPECT_EQ(4, AssignedMemoryCount(active_tree_tiles));
    291   EXPECT_EQ(0, AssignedMemoryCount(pending_tree_tiles));
    292 
    293   SetTreePriority(SAME_PRIORITY_FOR_BOTH_TREES);
    294   tile_manager()->AssignMemoryToTiles();
    295 
    296   EXPECT_EQ(0, AssignedMemoryCount(active_tree_tiles));
    297   EXPECT_EQ(4, AssignedMemoryCount(pending_tree_tiles));
    298 }
    299 
    300 TEST_P(TileManagerTest, TotalOOMMemoryToActive) {
    301   // 5 tiles on active tree eventually bin, 5 tiles on pending tree now bin,
    302   // but only enough memory for 4 tiles. The result is 5 active tree tiles
    303   // get memory, and none of the pending tree tiles get memory.
    304 
    305   Initialize(4, ALLOW_ANYTHING, SMOOTHNESS_TAKES_PRIORITY);
    306   TileVector active_tree_tiles =
    307       CreateTiles(5, TilePriorityForNowBin(), TilePriority());
    308   TileVector pending_tree_tiles =
    309       CreateTiles(5, TilePriority(), TilePriorityForNowBin());
    310 
    311   tile_manager()->AssignMemoryToTiles();
    312 
    313   EXPECT_EQ(4, AssignedMemoryCount(active_tree_tiles));
    314   EXPECT_EQ(0, AssignedMemoryCount(pending_tree_tiles));
    315 }
    316 
    317 
    318 
    319 TEST_P(TileManagerTest, RasterAsLCD) {
    320   Initialize(20, ALLOW_ANYTHING, SMOOTHNESS_TAKES_PRIORITY);
    321   TileVector active_tree_tiles =
    322       CreateTiles(5, TilePriorityForNowBin(), TilePriority());
    323   TileVector pending_tree_tiles =
    324       CreateTiles(5, TilePriority(), TilePriorityForNowBin());
    325 
    326   tile_manager()->ManageTiles();
    327 
    328   EXPECT_EQ(5, TilesWithLCDCount(active_tree_tiles));
    329   EXPECT_EQ(5, TilesWithLCDCount(pending_tree_tiles));
    330 }
    331 
    332 TEST_P(TileManagerTest, RasterAsNoLCD) {
    333   Initialize(20, ALLOW_ANYTHING, SMOOTHNESS_TAKES_PRIORITY);
    334   TileVector active_tree_tiles =
    335       CreateTiles(5, TilePriorityForNowBin(), TilePriority());
    336   TileVector pending_tree_tiles =
    337       CreateTiles(5, TilePriority(), TilePriorityForNowBin());
    338 
    339   for (TileVector::iterator it = active_tree_tiles.begin();
    340        it != active_tree_tiles.end();
    341        ++it) {
    342     (*it)->set_can_use_lcd_text(false);
    343   }
    344   for (TileVector::iterator it = pending_tree_tiles.begin();
    345        it != pending_tree_tiles.end();
    346        ++it) {
    347     (*it)->set_can_use_lcd_text(false);
    348   }
    349 
    350   tile_manager()->ManageTiles();
    351 
    352   EXPECT_EQ(0, TilesWithLCDCount(active_tree_tiles));
    353   EXPECT_EQ(0, TilesWithLCDCount(pending_tree_tiles));
    354 }
    355 
    356 TEST_P(TileManagerTest, ReRasterAsNoLCD) {
    357   Initialize(20, ALLOW_ANYTHING, SMOOTHNESS_TAKES_PRIORITY);
    358   TileVector active_tree_tiles =
    359       CreateTiles(5, TilePriorityForNowBin(), TilePriority());
    360   TileVector pending_tree_tiles =
    361       CreateTiles(5, TilePriority(), TilePriorityForNowBin());
    362 
    363   tile_manager()->ManageTiles();
    364 
    365   EXPECT_EQ(5, TilesWithLCDCount(active_tree_tiles));
    366   EXPECT_EQ(5, TilesWithLCDCount(pending_tree_tiles));
    367 
    368   for (TileVector::iterator it = active_tree_tiles.begin();
    369        it != active_tree_tiles.end();
    370        ++it) {
    371     (*it)->set_can_use_lcd_text(false);
    372   }
    373   for (TileVector::iterator it = pending_tree_tiles.begin();
    374        it != pending_tree_tiles.end();
    375        ++it) {
    376     (*it)->set_can_use_lcd_text(false);
    377   }
    378 
    379   tile_manager()->ManageTiles();
    380 
    381   EXPECT_EQ(0, TilesWithLCDCount(active_tree_tiles));
    382   EXPECT_EQ(0, TilesWithLCDCount(pending_tree_tiles));
    383 }
    384 
    385 TEST_P(TileManagerTest, NoTextDontReRasterAsNoLCD) {
    386   Initialize(20, ALLOW_ANYTHING, SMOOTHNESS_TAKES_PRIORITY);
    387   TileVector active_tree_tiles =
    388       CreateTiles(5, TilePriorityForNowBin(), TilePriority());
    389   TileVector pending_tree_tiles =
    390       CreateTiles(5, TilePriority(), TilePriorityForNowBin());
    391 
    392   tile_manager()->ManageTiles();
    393 
    394   EXPECT_EQ(5, TilesWithLCDCount(active_tree_tiles));
    395   EXPECT_EQ(5, TilesWithLCDCount(pending_tree_tiles));
    396 
    397   for (TileVector::iterator it = active_tree_tiles.begin();
    398        it != active_tree_tiles.end();
    399        ++it) {
    400     ManagedTileState::TileVersion& tile_version =
    401         (*it)->GetTileVersionForTesting(HIGH_QUALITY_RASTER_MODE);
    402     tile_version.SetSolidColorForTesting(SkColorSetARGB(0, 0, 0, 0));
    403     (*it)->set_can_use_lcd_text(false);
    404     EXPECT_TRUE((*it)->IsReadyToDraw());
    405   }
    406   for (TileVector::iterator it = pending_tree_tiles.begin();
    407        it != pending_tree_tiles.end();
    408        ++it) {
    409     ManagedTileState::TileVersion& tile_version =
    410         (*it)->GetTileVersionForTesting(HIGH_QUALITY_RASTER_MODE);
    411     tile_version.SetSolidColorForTesting(SkColorSetARGB(0, 0, 0, 0));
    412     (*it)->set_can_use_lcd_text(false);
    413     EXPECT_TRUE((*it)->IsReadyToDraw());
    414   }
    415 
    416   tile_manager()->ManageTiles();
    417 
    418   EXPECT_EQ(5, TilesWithLCDCount(active_tree_tiles));
    419   EXPECT_EQ(5, TilesWithLCDCount(pending_tree_tiles));
    420 }
    421 
    422 TEST_P(TileManagerTest, TextReRasterAsNoLCD) {
    423   Initialize(20, ALLOW_ANYTHING, SMOOTHNESS_TAKES_PRIORITY);
    424   TileVector active_tree_tiles =
    425       CreateTiles(5, TilePriorityForNowBin(), TilePriority());
    426   TileVector pending_tree_tiles =
    427       CreateTiles(5, TilePriority(), TilePriorityForNowBin());
    428 
    429   tile_manager()->ManageTiles();
    430 
    431   EXPECT_EQ(5, TilesWithLCDCount(active_tree_tiles));
    432   EXPECT_EQ(5, TilesWithLCDCount(pending_tree_tiles));
    433 
    434   for (TileVector::iterator it = active_tree_tiles.begin();
    435        it != active_tree_tiles.end();
    436        ++it) {
    437     ManagedTileState::TileVersion& tile_version =
    438         (*it)->GetTileVersionForTesting(HIGH_QUALITY_RASTER_MODE);
    439     tile_version.SetSolidColorForTesting(SkColorSetARGB(0, 0, 0, 0));
    440     tile_version.SetHasTextForTesting(true);
    441     (*it)->set_can_use_lcd_text(false);
    442 
    443     EXPECT_TRUE((*it)->IsReadyToDraw());
    444   }
    445   for (TileVector::iterator it = pending_tree_tiles.begin();
    446        it != pending_tree_tiles.end();
    447        ++it) {
    448     ManagedTileState::TileVersion& tile_version =
    449         (*it)->GetTileVersionForTesting(HIGH_QUALITY_RASTER_MODE);
    450     tile_version.SetSolidColorForTesting(
    451         SkColorSetARGB(0, 0, 0, 0));
    452     tile_version.SetHasTextForTesting(true);
    453     (*it)->set_can_use_lcd_text(false);
    454 
    455     EXPECT_TRUE((*it)->IsReadyToDraw());
    456   }
    457 
    458   tile_manager()->ManageTiles();
    459 
    460   EXPECT_EQ(0, TilesWithLCDCount(active_tree_tiles));
    461   EXPECT_EQ(0, TilesWithLCDCount(pending_tree_tiles));
    462 }
    463 
    464 // If true, the max tile limit should be applied as bytes; if false,
    465 // as num_resources_limit.
    466 INSTANTIATE_TEST_CASE_P(TileManagerTests,
    467                         TileManagerTest,
    468                         ::testing::Values(true, false));
    469 
    470 }  // namespace
    471 }  // namespace cc
    472