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