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