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 <algorithm> 6 #include <vector> 7 8 #include "cc/resources/managed_tile_state.h" 9 #include "cc/resources/prioritized_tile_set.h" 10 #include "cc/resources/tile.h" 11 #include "cc/test/fake_output_surface.h" 12 #include "cc/test/fake_picture_pile_impl.h" 13 #include "cc/test/fake_tile_manager.h" 14 #include "cc/test/fake_tile_manager_client.h" 15 #include "cc/test/test_tile_priorities.h" 16 #include "testing/gtest/include/gtest/gtest.h" 17 18 namespace cc { 19 20 class BinComparator { 21 public: 22 bool operator()(const scoped_refptr<Tile>& a, 23 const scoped_refptr<Tile>& b) const { 24 const ManagedTileState& ams = a->managed_state(); 25 const ManagedTileState& bms = b->managed_state(); 26 27 if (ams.bin[LOW_PRIORITY_BIN] != bms.bin[LOW_PRIORITY_BIN]) 28 return ams.bin[LOW_PRIORITY_BIN] < bms.bin[LOW_PRIORITY_BIN]; 29 30 if (ams.required_for_activation != bms.required_for_activation) 31 return ams.required_for_activation; 32 33 if (ams.resolution != bms.resolution) 34 return ams.resolution < bms.resolution; 35 36 if (ams.time_to_needed_in_seconds != bms.time_to_needed_in_seconds) 37 return ams.time_to_needed_in_seconds < bms.time_to_needed_in_seconds; 38 39 if (ams.distance_to_visible_in_pixels != 40 bms.distance_to_visible_in_pixels) { 41 return ams.distance_to_visible_in_pixels < 42 bms.distance_to_visible_in_pixels; 43 } 44 45 gfx::Rect a_rect = a->content_rect(); 46 gfx::Rect b_rect = b->content_rect(); 47 if (a_rect.y() != b_rect.y()) 48 return a_rect.y() < b_rect.y(); 49 return a_rect.x() < b_rect.x(); 50 } 51 }; 52 53 namespace { 54 55 class PrioritizedTileSetTest : public testing::Test { 56 public: 57 PrioritizedTileSetTest() 58 : output_surface_(FakeOutputSurface::Create3d()), 59 resource_provider_(ResourceProvider::Create(output_surface_.get(), 0)), 60 tile_manager_(new FakeTileManager(&tile_manager_client_, 61 resource_provider_.get())), 62 picture_pile_(FakePicturePileImpl::CreatePile()) {} 63 64 scoped_refptr<Tile> CreateTile() { 65 return make_scoped_refptr(new Tile(tile_manager_.get(), 66 picture_pile_.get(), 67 settings_.default_tile_size, 68 gfx::Rect(), 69 gfx::Rect(), 70 1.0, 71 0, 72 0, 73 true)); 74 } 75 76 private: 77 FakeTileManagerClient tile_manager_client_; 78 LayerTreeSettings settings_; 79 scoped_ptr<FakeOutputSurface> output_surface_; 80 scoped_ptr<ResourceProvider> resource_provider_; 81 scoped_ptr<FakeTileManager> tile_manager_; 82 scoped_refptr<FakePicturePileImpl> picture_pile_; 83 }; 84 85 TEST_F(PrioritizedTileSetTest, EmptyIterator) { 86 PrioritizedTileSet set; 87 set.Sort(); 88 89 PrioritizedTileSet::PriorityIterator it(&set); 90 EXPECT_FALSE(it); 91 } 92 93 TEST_F(PrioritizedTileSetTest, NonEmptyIterator) { 94 PrioritizedTileSet set; 95 scoped_refptr<Tile> tile = CreateTile(); 96 set.InsertTile(tile, NOW_BIN); 97 set.Sort(); 98 99 PrioritizedTileSet::PriorityIterator it(&set); 100 EXPECT_TRUE(it); 101 EXPECT_TRUE(*it == tile.get()); 102 ++it; 103 EXPECT_FALSE(it); 104 } 105 106 TEST_F(PrioritizedTileSetTest, NowAndReadyToDrawBin) { 107 PrioritizedTileSet set; 108 TilePriority priorities[4] = { 109 TilePriorityForEventualBin(), 110 TilePriorityForNowBin(), 111 TilePriority(), 112 TilePriorityForSoonBin()}; 113 114 std::vector<scoped_refptr<Tile> > tiles; 115 for (int priority = 0; priority < 4; ++priority) { 116 for (int i = 0; i < 5; ++i) { 117 scoped_refptr<Tile> tile = CreateTile(); 118 tile->SetPriority(ACTIVE_TREE, priorities[priority]); 119 tile->SetPriority(PENDING_TREE, priorities[priority]); 120 tiles.push_back(tile); 121 set.InsertTile(tile, NOW_AND_READY_TO_DRAW_BIN); 122 } 123 } 124 125 set.Sort(); 126 127 // Tiles should appear in the same order as inserted. 128 int i = 0; 129 for (PrioritizedTileSet::PriorityIterator it(&set); 130 it; 131 ++it) { 132 EXPECT_TRUE(*it == tiles[i].get()); 133 ++i; 134 } 135 EXPECT_EQ(20, i); 136 } 137 138 TEST_F(PrioritizedTileSetTest, NowBin) { 139 PrioritizedTileSet set; 140 TilePriority priorities[4] = { 141 TilePriorityForEventualBin(), 142 TilePriorityForNowBin(), 143 TilePriority(), 144 TilePriorityForSoonBin()}; 145 146 std::vector<scoped_refptr<Tile> > tiles; 147 for (int priority = 0; priority < 4; ++priority) { 148 for (int i = 0; i < 5; ++i) { 149 scoped_refptr<Tile> tile = CreateTile(); 150 tile->SetPriority(ACTIVE_TREE, priorities[priority]); 151 tile->SetPriority(PENDING_TREE, priorities[priority]); 152 tiles.push_back(tile); 153 set.InsertTile(tile, NOW_BIN); 154 } 155 } 156 157 set.Sort(); 158 159 // Tiles should appear in BinComparator order. 160 std::sort(tiles.begin(), tiles.end(), BinComparator()); 161 162 int i = 0; 163 for (PrioritizedTileSet::PriorityIterator it(&set); 164 it; 165 ++it) { 166 EXPECT_TRUE(*it == tiles[i].get()); 167 ++i; 168 } 169 EXPECT_EQ(20, i); 170 } 171 172 TEST_F(PrioritizedTileSetTest, SoonBin) { 173 PrioritizedTileSet set; 174 TilePriority priorities[4] = { 175 TilePriorityForEventualBin(), 176 TilePriorityForNowBin(), 177 TilePriority(), 178 TilePriorityForSoonBin()}; 179 180 std::vector<scoped_refptr<Tile> > tiles; 181 for (int priority = 0; priority < 4; ++priority) { 182 for (int i = 0; i < 5; ++i) { 183 scoped_refptr<Tile> tile = CreateTile(); 184 tile->SetPriority(ACTIVE_TREE, priorities[priority]); 185 tile->SetPriority(PENDING_TREE, priorities[priority]); 186 tiles.push_back(tile); 187 set.InsertTile(tile, SOON_BIN); 188 } 189 } 190 191 set.Sort(); 192 193 // Tiles should appear in BinComparator order. 194 std::sort(tiles.begin(), tiles.end(), BinComparator()); 195 196 int i = 0; 197 for (PrioritizedTileSet::PriorityIterator it(&set); 198 it; 199 ++it) { 200 EXPECT_TRUE(*it == tiles[i].get()); 201 ++i; 202 } 203 EXPECT_EQ(20, i); 204 } 205 206 TEST_F(PrioritizedTileSetTest, EventuallyAndActiveBin) { 207 PrioritizedTileSet set; 208 TilePriority priorities[4] = { 209 TilePriorityForEventualBin(), 210 TilePriorityForNowBin(), 211 TilePriority(), 212 TilePriorityForSoonBin()}; 213 214 std::vector<scoped_refptr<Tile> > tiles; 215 for (int priority = 0; priority < 4; ++priority) { 216 for (int i = 0; i < 5; ++i) { 217 scoped_refptr<Tile> tile = CreateTile(); 218 tile->SetPriority(ACTIVE_TREE, priorities[priority]); 219 tile->SetPriority(PENDING_TREE, priorities[priority]); 220 tiles.push_back(tile); 221 set.InsertTile(tile, EVENTUALLY_AND_ACTIVE_BIN); 222 } 223 } 224 225 set.Sort(); 226 227 // Tiles should appear in BinComparator order. 228 std::sort(tiles.begin(), tiles.end(), BinComparator()); 229 230 int i = 0; 231 for (PrioritizedTileSet::PriorityIterator it(&set); 232 it; 233 ++it) { 234 EXPECT_TRUE(*it == tiles[i].get()); 235 ++i; 236 } 237 EXPECT_EQ(20, i); 238 } 239 240 TEST_F(PrioritizedTileSetTest, EventuallyBin) { 241 PrioritizedTileSet set; 242 TilePriority priorities[4] = { 243 TilePriorityForEventualBin(), 244 TilePriorityForNowBin(), 245 TilePriority(), 246 TilePriorityForSoonBin()}; 247 248 std::vector<scoped_refptr<Tile> > tiles; 249 for (int priority = 0; priority < 4; ++priority) { 250 for (int i = 0; i < 5; ++i) { 251 scoped_refptr<Tile> tile = CreateTile(); 252 tile->SetPriority(ACTIVE_TREE, priorities[priority]); 253 tile->SetPriority(PENDING_TREE, priorities[priority]); 254 tiles.push_back(tile); 255 set.InsertTile(tile, EVENTUALLY_BIN); 256 } 257 } 258 259 set.Sort(); 260 261 // Tiles should appear in BinComparator order. 262 std::sort(tiles.begin(), tiles.end(), BinComparator()); 263 264 int i = 0; 265 for (PrioritizedTileSet::PriorityIterator it(&set); 266 it; 267 ++it) { 268 EXPECT_TRUE(*it == tiles[i].get()); 269 ++i; 270 } 271 EXPECT_EQ(20, i); 272 } 273 274 TEST_F(PrioritizedTileSetTest, NeverAndActiveBin) { 275 PrioritizedTileSet set; 276 TilePriority priorities[4] = { 277 TilePriorityForEventualBin(), 278 TilePriorityForNowBin(), 279 TilePriority(), 280 TilePriorityForSoonBin()}; 281 282 std::vector<scoped_refptr<Tile> > tiles; 283 for (int priority = 0; priority < 4; ++priority) { 284 for (int i = 0; i < 5; ++i) { 285 scoped_refptr<Tile> tile = CreateTile(); 286 tile->SetPriority(ACTIVE_TREE, priorities[priority]); 287 tile->SetPriority(PENDING_TREE, priorities[priority]); 288 tiles.push_back(tile); 289 set.InsertTile(tile, NEVER_AND_ACTIVE_BIN); 290 } 291 } 292 293 set.Sort(); 294 295 // Tiles should appear in BinComparator order. 296 std::sort(tiles.begin(), tiles.end(), BinComparator()); 297 298 int i = 0; 299 for (PrioritizedTileSet::PriorityIterator it(&set); 300 it; 301 ++it) { 302 EXPECT_TRUE(*it == tiles[i].get()); 303 ++i; 304 } 305 EXPECT_EQ(20, i); 306 } 307 308 TEST_F(PrioritizedTileSetTest, NeverBin) { 309 PrioritizedTileSet set; 310 TilePriority priorities[4] = { 311 TilePriorityForEventualBin(), 312 TilePriorityForNowBin(), 313 TilePriority(), 314 TilePriorityForSoonBin()}; 315 316 std::vector<scoped_refptr<Tile> > tiles; 317 for (int priority = 0; priority < 4; ++priority) { 318 for (int i = 0; i < 5; ++i) { 319 scoped_refptr<Tile> tile = CreateTile(); 320 tile->SetPriority(ACTIVE_TREE, priorities[priority]); 321 tile->SetPriority(PENDING_TREE, priorities[priority]); 322 tiles.push_back(tile); 323 set.InsertTile(tile, NEVER_BIN); 324 } 325 } 326 327 set.Sort(); 328 329 // Tiles should appear in BinComparator order. 330 std::sort(tiles.begin(), tiles.end(), BinComparator()); 331 332 int i = 0; 333 for (PrioritizedTileSet::PriorityIterator it(&set); 334 it; 335 ++it) { 336 EXPECT_TRUE(*it == tiles[i].get()); 337 ++i; 338 } 339 EXPECT_EQ(20, i); 340 } 341 342 TEST_F(PrioritizedTileSetTest, TilesForEachBin) { 343 scoped_refptr<Tile> now_and_ready_to_draw_bin = CreateTile(); 344 scoped_refptr<Tile> now_bin = CreateTile(); 345 scoped_refptr<Tile> soon_bin = CreateTile(); 346 scoped_refptr<Tile> eventually_and_active_bin = CreateTile(); 347 scoped_refptr<Tile> eventually_bin = CreateTile(); 348 scoped_refptr<Tile> never_bin = CreateTile(); 349 scoped_refptr<Tile> never_and_active_bin = CreateTile(); 350 351 PrioritizedTileSet set; 352 set.InsertTile(soon_bin, SOON_BIN); 353 set.InsertTile(never_and_active_bin, NEVER_AND_ACTIVE_BIN); 354 set.InsertTile(eventually_bin, EVENTUALLY_BIN); 355 set.InsertTile(now_bin, NOW_BIN); 356 set.InsertTile(eventually_and_active_bin, EVENTUALLY_AND_ACTIVE_BIN); 357 set.InsertTile(never_bin, NEVER_BIN); 358 set.InsertTile(now_and_ready_to_draw_bin, NOW_AND_READY_TO_DRAW_BIN); 359 360 set.Sort(); 361 362 // Tiles should appear in order. 363 PrioritizedTileSet::PriorityIterator it(&set); 364 EXPECT_TRUE(*it == now_and_ready_to_draw_bin.get()); 365 ++it; 366 EXPECT_TRUE(*it == now_bin.get()); 367 ++it; 368 EXPECT_TRUE(*it == soon_bin.get()); 369 ++it; 370 EXPECT_TRUE(*it == eventually_and_active_bin.get()); 371 ++it; 372 EXPECT_TRUE(*it == eventually_bin.get()); 373 ++it; 374 EXPECT_TRUE(*it == never_and_active_bin.get()); 375 ++it; 376 EXPECT_TRUE(*it == never_bin.get()); 377 ++it; 378 EXPECT_FALSE(it); 379 } 380 381 TEST_F(PrioritizedTileSetTest, TilesForFirstAndLastBins) { 382 scoped_refptr<Tile> now_and_ready_to_draw_bin = CreateTile(); 383 scoped_refptr<Tile> never_bin = CreateTile(); 384 385 PrioritizedTileSet set; 386 set.InsertTile(never_bin, NEVER_BIN); 387 set.InsertTile(now_and_ready_to_draw_bin, NOW_AND_READY_TO_DRAW_BIN); 388 389 set.Sort(); 390 391 // Only two tiles should appear and they should appear in order. 392 PrioritizedTileSet::PriorityIterator it(&set); 393 EXPECT_TRUE(*it == now_and_ready_to_draw_bin.get()); 394 ++it; 395 EXPECT_TRUE(*it == never_bin.get()); 396 ++it; 397 EXPECT_FALSE(it); 398 } 399 400 TEST_F(PrioritizedTileSetTest, MultipleIterators) { 401 scoped_refptr<Tile> now_and_ready_to_draw_bin = CreateTile(); 402 scoped_refptr<Tile> now_bin = CreateTile(); 403 scoped_refptr<Tile> soon_bin = CreateTile(); 404 scoped_refptr<Tile> eventually_bin = CreateTile(); 405 scoped_refptr<Tile> never_bin = CreateTile(); 406 407 PrioritizedTileSet set; 408 set.InsertTile(soon_bin, SOON_BIN); 409 set.InsertTile(eventually_bin, EVENTUALLY_BIN); 410 set.InsertTile(now_bin, NOW_BIN); 411 set.InsertTile(never_bin, NEVER_BIN); 412 set.InsertTile(now_and_ready_to_draw_bin, NOW_AND_READY_TO_DRAW_BIN); 413 414 set.Sort(); 415 416 // Tiles should appear in order. 417 PrioritizedTileSet::PriorityIterator it(&set); 418 EXPECT_TRUE(*it == now_and_ready_to_draw_bin.get()); 419 ++it; 420 EXPECT_TRUE(*it == now_bin.get()); 421 ++it; 422 EXPECT_TRUE(*it == soon_bin.get()); 423 ++it; 424 EXPECT_TRUE(*it == eventually_bin.get()); 425 ++it; 426 EXPECT_TRUE(*it == never_bin.get()); 427 ++it; 428 EXPECT_FALSE(it); 429 430 // Creating multiple iterators shouldn't affect old iterators. 431 PrioritizedTileSet::PriorityIterator second_it(&set); 432 EXPECT_TRUE(second_it); 433 EXPECT_FALSE(it); 434 435 ++second_it; 436 EXPECT_TRUE(second_it); 437 ++second_it; 438 EXPECT_TRUE(second_it); 439 EXPECT_FALSE(it); 440 441 PrioritizedTileSet::PriorityIterator third_it(&set); 442 EXPECT_TRUE(third_it); 443 ++second_it; 444 ++second_it; 445 EXPECT_TRUE(second_it); 446 EXPECT_TRUE(third_it); 447 EXPECT_FALSE(it); 448 449 ++third_it; 450 ++third_it; 451 EXPECT_TRUE(third_it); 452 EXPECT_TRUE(*third_it == soon_bin.get()); 453 EXPECT_TRUE(second_it); 454 EXPECT_TRUE(*second_it == never_bin.get()); 455 EXPECT_FALSE(it); 456 457 ++second_it; 458 EXPECT_TRUE(third_it); 459 EXPECT_FALSE(second_it); 460 EXPECT_FALSE(it); 461 462 set.Clear(); 463 464 PrioritizedTileSet::PriorityIterator empty_it(&set); 465 EXPECT_FALSE(empty_it); 466 } 467 468 } // namespace 469 } // namespace cc 470 471