1 // Copyright 2012 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/picture_layer_tiling_set.h" 6 7 #include <map> 8 #include <vector> 9 10 #include "cc/resources/resource_pool.h" 11 #include "cc/resources/resource_provider.h" 12 #include "cc/test/fake_output_surface.h" 13 #include "cc/test/fake_picture_layer_tiling_client.h" 14 #include "cc/test/fake_tile_manager_client.h" 15 #include "testing/gtest/include/gtest/gtest.h" 16 #include "ui/gfx/size_conversions.h" 17 18 namespace cc { 19 namespace { 20 21 TEST(PictureLayerTilingSetTest, NoResources) { 22 FakePictureLayerTilingClient client; 23 gfx::Size layer_bounds(1000, 800); 24 PictureLayerTilingSet set(&client, layer_bounds); 25 client.SetTileSize(gfx::Size(256, 256)); 26 27 set.AddTiling(1.0); 28 set.AddTiling(1.5); 29 set.AddTiling(2.0); 30 31 float contents_scale = 2.0; 32 gfx::Size content_bounds( 33 gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds, contents_scale))); 34 gfx::Rect content_rect(content_bounds); 35 36 Region remaining(content_rect); 37 PictureLayerTilingSet::CoverageIterator iter( 38 &set, 39 contents_scale, 40 content_rect, 41 contents_scale); 42 for (; iter; ++iter) { 43 gfx::Rect geometry_rect = iter.geometry_rect(); 44 EXPECT_TRUE(content_rect.Contains(geometry_rect)); 45 ASSERT_TRUE(remaining.Contains(geometry_rect)); 46 remaining.Subtract(geometry_rect); 47 48 // No tiles have resources, so no iter represents a real tile. 49 EXPECT_FALSE(*iter); 50 } 51 EXPECT_TRUE(remaining.IsEmpty()); 52 } 53 54 class PictureLayerTilingSetTestWithResources : public testing::Test { 55 public: 56 void runTest( 57 int num_tilings, 58 float min_scale, 59 float scale_increment, 60 float ideal_contents_scale, 61 float expected_scale) { 62 scoped_ptr<FakeOutputSurface> output_surface = 63 FakeOutputSurface::Create3d(); 64 scoped_ptr<ResourceProvider> resource_provider = 65 ResourceProvider::Create(output_surface.get(), 0); 66 67 FakePictureLayerTilingClient client; 68 client.SetTileSize(gfx::Size(256, 256)); 69 gfx::Size layer_bounds(1000, 800); 70 PictureLayerTilingSet set(&client, layer_bounds); 71 72 float scale = min_scale; 73 for (int i = 0; i < num_tilings; ++i, scale += scale_increment) { 74 PictureLayerTiling* tiling = set.AddTiling(scale); 75 tiling->CreateAllTilesForTesting(); 76 std::vector<Tile*> tiles = tiling->AllTilesForTesting(); 77 for (size_t i = 0; i < tiles.size(); ++i) { 78 ManagedTileState::TileVersion& tile_version = 79 tiles[i]->GetTileVersionForTesting(HIGH_QUALITY_NO_LCD_RASTER_MODE); 80 EXPECT_FALSE(tile_version.GetResourceForTesting()); 81 82 tile_version.SetResourceForTesting( 83 make_scoped_ptr(new ResourcePool::Resource( 84 resource_provider.get(), 85 gfx::Size(1, 1), 86 resource_provider->best_texture_format()))); 87 } 88 } 89 90 float max_contents_scale = scale; 91 gfx::Size content_bounds( 92 gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds, max_contents_scale))); 93 gfx::Rect content_rect(content_bounds); 94 95 Region remaining(content_rect); 96 PictureLayerTilingSet::CoverageIterator iter( 97 &set, 98 max_contents_scale, 99 content_rect, 100 ideal_contents_scale); 101 for (; iter; ++iter) { 102 gfx::Rect geometry_rect = iter.geometry_rect(); 103 EXPECT_TRUE(content_rect.Contains(geometry_rect)); 104 ASSERT_TRUE(remaining.Contains(geometry_rect)); 105 remaining.Subtract(geometry_rect); 106 107 float scale = iter.CurrentTiling()->contents_scale(); 108 EXPECT_EQ(expected_scale, scale); 109 110 if (num_tilings) 111 EXPECT_TRUE(*iter); 112 else 113 EXPECT_FALSE(*iter); 114 } 115 EXPECT_TRUE(remaining.IsEmpty()); 116 } 117 }; 118 119 TEST_F(PictureLayerTilingSetTestWithResources, NoTilings) { 120 runTest(0, 0.f, 0.f, 2.f, 0.f); 121 } 122 TEST_F(PictureLayerTilingSetTestWithResources, OneTiling_Smaller) { 123 runTest(1, 1.f, 0.f, 2.f, 1.f); 124 } 125 TEST_F(PictureLayerTilingSetTestWithResources, OneTiling_Larger) { 126 runTest(1, 3.f, 0.f, 2.f, 3.f); 127 } 128 TEST_F(PictureLayerTilingSetTestWithResources, TwoTilings_Smaller) { 129 runTest(2, 1.f, 1.f, 3.f, 2.f); 130 } 131 132 TEST_F(PictureLayerTilingSetTestWithResources, TwoTilings_SmallerEqual) { 133 runTest(2, 1.f, 1.f, 2.f, 2.f); 134 } 135 136 TEST_F(PictureLayerTilingSetTestWithResources, TwoTilings_LargerEqual) { 137 runTest(2, 1.f, 1.f, 1.f, 1.f); 138 } 139 140 TEST_F(PictureLayerTilingSetTestWithResources, TwoTilings_Larger) { 141 runTest(2, 2.f, 8.f, 1.f, 2.f); 142 } 143 144 TEST_F(PictureLayerTilingSetTestWithResources, ManyTilings_Equal) { 145 runTest(10, 1.f, 1.f, 5.f, 5.f); 146 } 147 148 TEST_F(PictureLayerTilingSetTestWithResources, ManyTilings_NotEqual) { 149 runTest(10, 1.f, 1.f, 4.5f, 5.f); 150 } 151 152 class PictureLayerTilingSetSyncTest : public testing::Test { 153 public: 154 PictureLayerTilingSetSyncTest() 155 : tile_size_(gfx::Size(10, 10)), 156 source_bounds_(gfx::Size(30, 20)), 157 target_bounds_(gfx::Size(30, 30)) { 158 source_client_.SetTileSize(tile_size_); 159 target_client_.SetTileSize(tile_size_); 160 source_.reset(new PictureLayerTilingSet(&source_client_, source_bounds_)); 161 target_.reset(new PictureLayerTilingSet(&target_client_, target_bounds_)); 162 } 163 164 // Sync from source to target. 165 void SyncTilings(gfx::Size new_bounds, 166 const Region& invalidation, 167 float minimum_scale) { 168 for (size_t i = 0; i < source_->num_tilings(); ++i) 169 source_->tiling_at(i)->CreateAllTilesForTesting(); 170 for (size_t i = 0; i < target_->num_tilings(); ++i) 171 target_->tiling_at(i)->CreateAllTilesForTesting(); 172 173 target_->SyncTilings( 174 *source_.get(), new_bounds, invalidation, minimum_scale); 175 } 176 void SyncTilings(gfx::Size new_bounds) { 177 Region invalidation; 178 SyncTilings(new_bounds, invalidation, 0.f); 179 } 180 void SyncTilings(gfx::Size new_bounds, const Region& invalidation) { 181 SyncTilings(new_bounds, invalidation, 0.f); 182 } 183 void SyncTilings(gfx::Size new_bounds, float minimum_scale) { 184 Region invalidation; 185 SyncTilings(new_bounds, invalidation, minimum_scale); 186 } 187 188 void VerifyTargetEqualsSource(gfx::Size new_bounds) const { 189 ASSERT_FALSE(new_bounds.IsEmpty()); 190 EXPECT_EQ(target_->num_tilings(), source_->num_tilings()); 191 EXPECT_EQ(target_->layer_bounds().ToString(), new_bounds.ToString()); 192 193 for (size_t i = 0; i < target_->num_tilings(); ++i) { 194 ASSERT_GT(source_->num_tilings(), i); 195 const PictureLayerTiling* source_tiling = source_->tiling_at(i); 196 const PictureLayerTiling* target_tiling = target_->tiling_at(i); 197 EXPECT_EQ(target_tiling->layer_bounds().ToString(), 198 new_bounds.ToString()); 199 EXPECT_EQ(source_tiling->contents_scale(), 200 target_tiling->contents_scale()); 201 } 202 203 EXPECT_EQ(source_->client(), &source_client_); 204 EXPECT_EQ(target_->client(), &target_client_); 205 ValidateTargetTilingSet(); 206 } 207 208 void ValidateTargetTilingSet() const { 209 // Tilings should be sorted largest to smallest. 210 if (target_->num_tilings() > 0) { 211 float last_scale = target_->tiling_at(0)->contents_scale(); 212 for (size_t i = 1; i < target_->num_tilings(); ++i) { 213 const PictureLayerTiling* target_tiling = target_->tiling_at(i); 214 EXPECT_LT(target_tiling->contents_scale(), last_scale); 215 last_scale = target_tiling->contents_scale(); 216 } 217 } 218 219 for (size_t i = 0; i < target_->num_tilings(); ++i) 220 ValidateTiling(target_->tiling_at(i), target_client_.pile()); 221 } 222 223 void ValidateTiling(const PictureLayerTiling* tiling, 224 const PicturePileImpl* pile) const { 225 if (tiling->ContentRect().IsEmpty()) 226 EXPECT_TRUE(tiling->live_tiles_rect().IsEmpty()); 227 else if (!tiling->live_tiles_rect().IsEmpty()) 228 EXPECT_TRUE(tiling->ContentRect().Contains(tiling->live_tiles_rect())); 229 230 std::vector<Tile*> tiles = tiling->AllTilesForTesting(); 231 for (size_t i = 0; i < tiles.size(); ++i) { 232 const Tile* tile = tiles[i]; 233 ASSERT_TRUE(!!tile); 234 EXPECT_EQ(tile->picture_pile(), pile); 235 EXPECT_TRUE(tile->content_rect().Intersects(tiling->live_tiles_rect())) 236 << "All tiles must be inside the live tiles rect."; 237 } 238 239 for (PictureLayerTiling::CoverageIterator iter( 240 tiling, tiling->contents_scale(), tiling->live_tiles_rect()); 241 iter; 242 ++iter) { 243 EXPECT_TRUE(*iter) << "The live tiles rect must be full."; 244 } 245 } 246 247 gfx::Size tile_size_; 248 249 FakePictureLayerTilingClient source_client_; 250 gfx::Size source_bounds_; 251 scoped_ptr<PictureLayerTilingSet> source_; 252 253 FakePictureLayerTilingClient target_client_; 254 gfx::Size target_bounds_; 255 scoped_ptr<PictureLayerTilingSet> target_; 256 }; 257 258 TEST_F(PictureLayerTilingSetSyncTest, EmptyBounds) { 259 float source_scales[] = {1.f, 1.2f}; 260 for (size_t i = 0; i < arraysize(source_scales); ++i) 261 source_->AddTiling(source_scales[i]); 262 263 gfx::Size new_bounds; 264 SyncTilings(new_bounds); 265 EXPECT_EQ(target_->num_tilings(), 0u); 266 EXPECT_EQ(target_->layer_bounds().ToString(), new_bounds.ToString()); 267 } 268 269 TEST_F(PictureLayerTilingSetSyncTest, AllNew) { 270 float source_scales[] = {0.5f, 1.f, 1.2f}; 271 for (size_t i = 0; i < arraysize(source_scales); ++i) 272 source_->AddTiling(source_scales[i]); 273 float target_scales[] = {0.75f, 1.4f, 3.f}; 274 for (size_t i = 0; i < arraysize(target_scales); ++i) 275 target_->AddTiling(target_scales[i]); 276 277 gfx::Size new_bounds(15, 40); 278 SyncTilings(new_bounds); 279 VerifyTargetEqualsSource(new_bounds); 280 } 281 282 Tile* FindTileAtOrigin(PictureLayerTiling* tiling) { 283 std::vector<Tile*> tiles = tiling->AllTilesForTesting(); 284 for (size_t i = 0; i < tiles.size(); ++i) { 285 if (tiles[i]->content_rect().origin() == gfx::Point()) 286 return tiles[i]; 287 } 288 return NULL; 289 } 290 291 TEST_F(PictureLayerTilingSetSyncTest, KeepExisting) { 292 float source_scales[] = {0.7f, 1.f, 1.1f, 2.f}; 293 for (size_t i = 0; i < arraysize(source_scales); ++i) 294 source_->AddTiling(source_scales[i]); 295 float target_scales[] = {0.5f, 1.f, 2.f}; 296 for (size_t i = 0; i < arraysize(target_scales); ++i) 297 target_->AddTiling(target_scales[i]); 298 299 PictureLayerTiling* tiling1 = source_->TilingAtScale(1.f); 300 ASSERT_TRUE(tiling1); 301 tiling1->CreateAllTilesForTesting(); 302 EXPECT_EQ(tiling1->contents_scale(), 1.f); 303 Tile* tile1 = FindTileAtOrigin(tiling1); 304 ASSERT_TRUE(tile1); 305 306 PictureLayerTiling* tiling2 = source_->TilingAtScale(2.f); 307 tiling2->CreateAllTilesForTesting(); 308 ASSERT_TRUE(tiling2); 309 EXPECT_EQ(tiling2->contents_scale(), 2.f); 310 Tile* tile2 = FindTileAtOrigin(tiling2); 311 ASSERT_TRUE(tile2); 312 313 gfx::Size new_bounds(15, 40); 314 SyncTilings(new_bounds); 315 VerifyTargetEqualsSource(new_bounds); 316 317 EXPECT_EQ(tiling1, source_->TilingAtScale(1.f)); 318 EXPECT_EQ(tile1, FindTileAtOrigin(tiling1)); 319 EXPECT_FALSE(tiling1->live_tiles_rect().IsEmpty()); 320 321 EXPECT_EQ(tiling2, source_->TilingAtScale(2.f)); 322 EXPECT_EQ(tile2, FindTileAtOrigin(tiling2)); 323 EXPECT_FALSE(tiling2->live_tiles_rect().IsEmpty()); 324 } 325 326 TEST_F(PictureLayerTilingSetSyncTest, EmptySet) { 327 float target_scales[] = {0.2f, 1.f}; 328 for (size_t i = 0; i < arraysize(target_scales); ++i) 329 target_->AddTiling(target_scales[i]); 330 331 gfx::Size new_bounds(15, 40); 332 SyncTilings(new_bounds); 333 VerifyTargetEqualsSource(new_bounds); 334 } 335 336 TEST_F(PictureLayerTilingSetSyncTest, MinimumScale) { 337 float source_scales[] = {0.7f, 1.f, 1.1f, 2.f}; 338 for (size_t i = 0; i < arraysize(source_scales); ++i) 339 source_->AddTiling(source_scales[i]); 340 float target_scales[] = {0.5f, 0.7f, 1.f, 1.1f, 2.f}; 341 for (size_t i = 0; i < arraysize(target_scales); ++i) 342 target_->AddTiling(target_scales[i]); 343 344 gfx::Size new_bounds(15, 40); 345 float minimum_scale = 1.5f; 346 SyncTilings(new_bounds, minimum_scale); 347 348 EXPECT_EQ(target_->num_tilings(), 1u); 349 EXPECT_EQ(target_->tiling_at(0)->contents_scale(), 2.f); 350 ValidateTargetTilingSet(); 351 } 352 353 TEST_F(PictureLayerTilingSetSyncTest, Invalidation) { 354 source_->AddTiling(2.f); 355 target_->AddTiling(2.f); 356 target_->tiling_at(0)->CreateAllTilesForTesting(); 357 358 Region layer_invalidation; 359 layer_invalidation.Union(gfx::Rect(0, 0, 1, 1)); 360 layer_invalidation.Union(gfx::Rect(0, 15, 1, 1)); 361 // Out of bounds layer_invalidation. 362 layer_invalidation.Union(gfx::Rect(100, 100, 1, 1)); 363 364 Region content_invalidation; 365 for (Region::Iterator iter(layer_invalidation); iter.has_rect(); 366 iter.next()) { 367 gfx::Rect content_rect = gfx::ScaleToEnclosingRect(iter.rect(), 2.f); 368 content_invalidation.Union(content_rect); 369 } 370 371 std::vector<Tile*> old_tiles = target_->tiling_at(0)->AllTilesForTesting(); 372 std::map<gfx::Point, scoped_refptr<Tile> > old_tile_map; 373 for (size_t i = 0; i < old_tiles.size(); ++i) 374 old_tile_map[old_tiles[i]->content_rect().origin()] = old_tiles[i]; 375 376 SyncTilings(target_bounds_, layer_invalidation); 377 VerifyTargetEqualsSource(target_bounds_); 378 379 std::vector<Tile*> new_tiles = target_->tiling_at(0)->AllTilesForTesting(); 380 for (size_t i = 0; i < new_tiles.size(); ++i) { 381 const Tile* tile = new_tiles[i]; 382 std::map<gfx::Point, scoped_refptr<Tile> >::iterator find = 383 old_tile_map.find(tile->content_rect().origin()); 384 if (content_invalidation.Intersects(tile->content_rect())) 385 EXPECT_NE(tile, find->second.get()); 386 else 387 EXPECT_EQ(tile, find->second.get()); 388 } 389 } 390 391 TEST_F(PictureLayerTilingSetSyncTest, TileSizeChange) { 392 source_->AddTiling(1.f); 393 target_->AddTiling(1.f); 394 395 target_->tiling_at(0)->CreateAllTilesForTesting(); 396 std::vector<Tile*> original_tiles = 397 target_->tiling_at(0)->AllTilesForTesting(); 398 EXPECT_GT(original_tiles.size(), 0u); 399 gfx::Size new_tile_size(100, 100); 400 target_client_.SetTileSize(new_tile_size); 401 EXPECT_NE(target_->tiling_at(0)->tile_size().ToString(), 402 new_tile_size.ToString()); 403 404 gfx::Size new_bounds(15, 40); 405 SyncTilings(new_bounds); 406 VerifyTargetEqualsSource(new_bounds); 407 408 EXPECT_EQ(target_->tiling_at(0)->tile_size().ToString(), 409 new_tile_size.ToString()); 410 411 // All old tiles should not be present in new tiles. 412 std::vector<Tile*> new_tiles = target_->tiling_at(0)->AllTilesForTesting(); 413 for (size_t i = 0; i < original_tiles.size(); ++i) { 414 std::vector<Tile*>::iterator find = 415 std::find(new_tiles.begin(), new_tiles.end(), original_tiles[i]); 416 EXPECT_TRUE(find == new_tiles.end()); 417 } 418 } 419 420 } // namespace 421 } // namespace cc 422