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