picture_layer_impl_unittest.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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/layers/picture_layer_impl.h" 6 7#include "cc/layers/picture_layer.h" 8#include "cc/test/fake_content_layer_client.h" 9#include "cc/test/fake_impl_proxy.h" 10#include "cc/test/fake_layer_tree_host_impl.h" 11#include "cc/test/fake_output_surface.h" 12#include "cc/trees/layer_tree_impl.h" 13#include "testing/gtest/include/gtest/gtest.h" 14#include "third_party/skia/include/core/SkDevice.h" 15#include "ui/gfx/rect_conversions.h" 16 17namespace cc { 18namespace { 19 20class TestablePictureLayerImpl : public PictureLayerImpl { 21 public: 22 static scoped_ptr<TestablePictureLayerImpl> Create( 23 LayerTreeImpl* tree_impl, 24 int id, 25 scoped_refptr<PicturePileImpl> pile) 26 { 27 return make_scoped_ptr(new TestablePictureLayerImpl(tree_impl, id, pile)); 28 } 29 30 PictureLayerTilingSet& tilings() { return *tilings_; } 31 Region& invalidation() { return invalidation_; } 32 33 virtual gfx::Size CalculateTileSize( 34 gfx::Size current_tile_size, 35 gfx::Size content_bounds) OVERRIDE { 36 if (current_tile_size.IsEmpty()) 37 return gfx::Size(100, 100); 38 return current_tile_size; 39 } 40 41 using PictureLayerImpl::AddTiling; 42 using PictureLayerImpl::CleanUpTilingsOnActiveLayer; 43 44 private: 45 TestablePictureLayerImpl( 46 LayerTreeImpl* tree_impl, 47 int id, 48 scoped_refptr<PicturePileImpl> pile) 49 : PictureLayerImpl(tree_impl, id) { 50 pile_ = pile; 51 SetBounds(pile_->size()); 52 CreateTilingSet(); 53 } 54}; 55 56class ImplSidePaintingSettings : public LayerTreeSettings { 57 public: 58 ImplSidePaintingSettings() { 59 impl_side_painting = true; 60 } 61}; 62 63class TestablePicturePileImpl : public PicturePileImpl { 64 public: 65 static scoped_refptr<TestablePicturePileImpl> CreateFilledPile( 66 gfx::Size tile_size, 67 gfx::Size layer_bounds) { 68 scoped_refptr<TestablePicturePileImpl> pile(new TestablePicturePileImpl()); 69 pile->tiling().SetTotalSize(layer_bounds); 70 pile->tiling().SetMaxTextureSize(tile_size); 71 pile->SetTileGridSize(ImplSidePaintingSettings().default_tile_size); 72 for (int x = 0; x < pile->tiling().num_tiles_x(); ++x) { 73 for (int y = 0; y < pile->tiling().num_tiles_y(); ++y) 74 pile->AddRecordingAt(x, y); 75 } 76 pile->UpdateRecordedRegion(); 77 return pile; 78 } 79 80 static scoped_refptr<TestablePicturePileImpl> CreateEmptyPile( 81 gfx::Size tile_size, 82 gfx::Size layer_bounds) { 83 scoped_refptr<TestablePicturePileImpl> pile(new TestablePicturePileImpl()); 84 pile->tiling().SetTotalSize(layer_bounds); 85 pile->tiling().SetMaxTextureSize(tile_size); 86 pile->SetTileGridSize(ImplSidePaintingSettings().default_tile_size); 87 pile->UpdateRecordedRegion(); 88 return pile; 89 } 90 91 TilingData& tiling() { return tiling_; } 92 93 void AddRecordingAt(int x, int y) { 94 EXPECT_GE(x, 0); 95 EXPECT_GE(y, 0); 96 EXPECT_LT(x, tiling_.num_tiles_x()); 97 EXPECT_LT(y, tiling_.num_tiles_y()); 98 99 if (HasRecordingAt(x, y)) 100 return; 101 gfx::Rect bounds(tiling().TileBounds(x, y)); 102 scoped_refptr<Picture> picture(Picture::Create(bounds)); 103 picture->Record(&client_, NULL, tile_grid_info_); 104 picture_list_map_[std::pair<int, int>(x, y)].push_back(picture); 105 EXPECT_TRUE(HasRecordingAt(x, y)); 106 107 UpdateRecordedRegion(); 108 } 109 110 void RemoveRecordingAt(int x, int y) { 111 EXPECT_GE(x, 0); 112 EXPECT_GE(y, 0); 113 EXPECT_LT(x, tiling_.num_tiles_x()); 114 EXPECT_LT(y, tiling_.num_tiles_y()); 115 116 if (!HasRecordingAt(x, y)) 117 return; 118 picture_list_map_.erase(std::pair<int, int>(x, y)); 119 EXPECT_FALSE(HasRecordingAt(x, y)); 120 121 UpdateRecordedRegion(); 122 } 123 124 void add_draw_rect(const gfx::Rect& rect) { 125 client_.add_draw_rect(rect); 126 } 127 128 protected: 129 TestablePicturePileImpl() : PicturePileImpl(false) {} 130 131 virtual ~TestablePicturePileImpl() {} 132 133 FakeContentLayerClient client_; 134}; 135 136class MockCanvas : public SkCanvas { 137 public: 138 explicit MockCanvas(SkDevice* device) : SkCanvas(device) {} 139 140 virtual void drawRect(const SkRect& rect, const SkPaint& paint) OVERRIDE { 141 // Capture calls before SkCanvas quickReject() kicks in. 142 rects_.push_back(rect); 143 } 144 145 std::vector<SkRect> rects_; 146}; 147 148class PictureLayerImplTest : public testing::Test { 149 public: 150 PictureLayerImplTest() 151 : host_impl_(ImplSidePaintingSettings(), &proxy_), 152 id_(7) { 153 host_impl_.InitializeRenderer(CreateFakeOutputSurface()); 154 } 155 156 virtual ~PictureLayerImplTest() { 157 } 158 159 void SetupTrees( 160 scoped_refptr<PicturePileImpl> pending_pile, 161 scoped_refptr<PicturePileImpl> active_pile) { 162 SetupPendingTree(active_pile); 163 host_impl_.ActivatePendingTree(); 164 165 active_layer_ = static_cast<TestablePictureLayerImpl*>( 166 host_impl_.active_tree()->LayerById(id_)); 167 168 SetupPendingTree(pending_pile); 169 pending_layer_ = static_cast<TestablePictureLayerImpl*>( 170 host_impl_.pending_tree()->LayerById(id_)); 171 } 172 173 void AddDefaultTilingsWithInvalidation(const Region& invalidation) { 174 active_layer_->AddTiling(2.3f); 175 active_layer_->AddTiling(1.0f); 176 active_layer_->AddTiling(0.5f); 177 pending_layer_->invalidation() = invalidation; 178 pending_layer_->SyncFromActiveLayer(); 179 } 180 181 void SetupPendingTree( 182 scoped_refptr<PicturePileImpl> pile) { 183 host_impl_.CreatePendingTree(); 184 LayerTreeImpl* pending_tree = host_impl_.pending_tree(); 185 // Clear recycled tree. 186 pending_tree->DetachLayerTree(); 187 188 scoped_ptr<TestablePictureLayerImpl> pending_layer = 189 TestablePictureLayerImpl::Create(pending_tree, id_, pile); 190 pending_layer->SetDrawsContent(true); 191 pending_tree->SetRootLayer(pending_layer.PassAs<LayerImpl>()); 192 } 193 194 static void VerifyAllTilesExistAndHavePile( 195 const PictureLayerTiling* tiling, 196 PicturePileImpl* pile) { 197 for (PictureLayerTiling::Iterator 198 iter(tiling, tiling->contents_scale(), tiling->ContentRect()); 199 iter; 200 ++iter) { 201 EXPECT_TRUE(*iter); 202 EXPECT_EQ(pile, iter->picture_pile()); 203 } 204 } 205 206 void SetContentsScaleOnBothLayers(float scale, bool animating_transform) { 207 float result_scale_x, result_scale_y; 208 gfx::Size result_bounds; 209 pending_layer_->CalculateContentsScale( 210 scale, animating_transform, 211 &result_scale_x, &result_scale_y, &result_bounds); 212 active_layer_->CalculateContentsScale( 213 scale, animating_transform, 214 &result_scale_x, &result_scale_y, &result_bounds); 215 } 216 217 protected: 218 void TestTileGridAlignmentCommon() { 219 // Layer to span 4 raster tiles in x and in y 220 ImplSidePaintingSettings settings; 221 gfx::Size layer_size( 222 settings.default_tile_size.width() * 7 / 2, 223 settings.default_tile_size.height() * 7 / 2); 224 225 scoped_refptr<TestablePicturePileImpl> pending_pile = 226 TestablePicturePileImpl::CreateFilledPile(layer_size, layer_size); 227 scoped_refptr<TestablePicturePileImpl> active_pile = 228 TestablePicturePileImpl::CreateFilledPile(layer_size, layer_size); 229 230 SetupTrees(pending_pile, active_pile); 231 232 host_impl_.active_tree()->SetPageScaleFactorAndLimits(1.f, 1.f, 1.f); 233 float result_scale_x, result_scale_y; 234 gfx::Size result_bounds; 235 active_layer_->CalculateContentsScale( 236 1.f, false, &result_scale_x, &result_scale_y, &result_bounds); 237 238 // Add 1x1 rects at the centers of each tile, then re-record pile contents 239 std::vector<Tile*> tiles = 240 active_layer_->tilings().tiling_at(0)->AllTilesForTesting(); 241 EXPECT_EQ(16, tiles.size()); 242 std::vector<SkRect> rects; 243 std::vector<Tile*>::const_iterator tile_iter; 244 for (tile_iter = tiles.begin(); tile_iter < tiles.end(); tile_iter++) { 245 gfx::Point tile_center = (*tile_iter)->content_rect().CenterPoint(); 246 gfx::Rect rect(tile_center.x(), tile_center.y(), 1, 1); 247 active_pile->add_draw_rect(rect); 248 rects.push_back(SkRect::MakeXYWH(rect.x(), rect.y(), 1, 1)); 249 } 250 // Force re-record with newly injected content 251 active_pile->RemoveRecordingAt(0, 0); 252 active_pile->AddRecordingAt(0, 0); 253 254 SkBitmap store; 255 store.setConfig(SkBitmap::kNo_Config, 1000, 1000); 256 SkDevice device(store); 257 int64 pixels_rasterized; 258 259 std::vector<SkRect>::const_iterator rect_iter = rects.begin(); 260 for (tile_iter = tiles.begin(); tile_iter < tiles.end(); tile_iter++) { 261 MockCanvas mock_canvas(&device); 262 active_pile->Raster(&mock_canvas, (*tile_iter)->content_rect(), 263 1.0f, &pixels_rasterized); 264 265 // This test verifies that when drawing the contents of a specific tile 266 // at content scale 1.0, the playback canvas never receives content from 267 // neighboring tiles which indicates that the tile grid embedded in 268 // SkPicture is perfectly aligned with the compositor's tiles. 269 // Note: There are two rects: the initial clear and the explicitly 270 // recorded rect. We only care about the second one. 271 EXPECT_EQ(2, mock_canvas.rects_.size()); 272 EXPECT_EQ(*rect_iter, mock_canvas.rects_[1]); 273 rect_iter++; 274 } 275 } 276 277 FakeImplProxy proxy_; 278 FakeLayerTreeHostImpl host_impl_; 279 int id_; 280 TestablePictureLayerImpl* pending_layer_; 281 TestablePictureLayerImpl* active_layer_; 282 283 DISALLOW_COPY_AND_ASSIGN(PictureLayerImplTest); 284}; 285 286TEST_F(PictureLayerImplTest, TileGridAlignment) { 287 host_impl_.SetDeviceScaleFactor(1.f); 288 TestTileGridAlignmentCommon(); 289} 290 291TEST_F(PictureLayerImplTest, TileGridAlignmentHiDPI) { 292 host_impl_.SetDeviceScaleFactor(2.f); 293 TestTileGridAlignmentCommon(); 294} 295 296TEST_F(PictureLayerImplTest, CloneNoInvalidation) { 297 gfx::Size tile_size(100, 100); 298 gfx::Size layer_bounds(400, 400); 299 300 scoped_refptr<TestablePicturePileImpl> pending_pile = 301 TestablePicturePileImpl::CreateFilledPile(tile_size, layer_bounds); 302 scoped_refptr<TestablePicturePileImpl> active_pile = 303 TestablePicturePileImpl::CreateFilledPile(tile_size, layer_bounds); 304 305 SetupTrees(pending_pile, active_pile); 306 307 Region invalidation; 308 AddDefaultTilingsWithInvalidation(invalidation); 309 310 EXPECT_EQ(pending_layer_->tilings().num_tilings(), 311 active_layer_->tilings().num_tilings()); 312 313 const PictureLayerTilingSet& tilings = pending_layer_->tilings(); 314 EXPECT_GT(tilings.num_tilings(), 0u); 315 for (size_t i = 0; i < tilings.num_tilings(); ++i) 316 VerifyAllTilesExistAndHavePile(tilings.tiling_at(i), active_pile.get()); 317} 318 319TEST_F(PictureLayerImplTest, ClonePartialInvalidation) { 320 gfx::Size tile_size(100, 100); 321 gfx::Size layer_bounds(400, 400); 322 gfx::Rect layer_invalidation(150, 200, 30, 180); 323 324 scoped_refptr<TestablePicturePileImpl> pending_pile = 325 TestablePicturePileImpl::CreateFilledPile(tile_size, layer_bounds); 326 scoped_refptr<TestablePicturePileImpl> active_pile = 327 TestablePicturePileImpl::CreateFilledPile(tile_size, layer_bounds); 328 329 SetupTrees(pending_pile, active_pile); 330 331 Region invalidation(layer_invalidation); 332 AddDefaultTilingsWithInvalidation(invalidation); 333 334 const PictureLayerTilingSet& tilings = pending_layer_->tilings(); 335 EXPECT_GT(tilings.num_tilings(), 0u); 336 for (size_t i = 0; i < tilings.num_tilings(); ++i) { 337 const PictureLayerTiling* tiling = tilings.tiling_at(i); 338 gfx::Rect content_invalidation = gfx::ToEnclosingRect(gfx::ScaleRect( 339 layer_invalidation, 340 tiling->contents_scale())); 341 for (PictureLayerTiling::Iterator 342 iter(tiling, 343 tiling->contents_scale(), 344 tiling->ContentRect()); 345 iter; 346 ++iter) { 347 EXPECT_TRUE(*iter); 348 EXPECT_FALSE(iter.geometry_rect().IsEmpty()); 349 if (iter.geometry_rect().Intersects(content_invalidation)) 350 EXPECT_EQ(pending_pile, iter->picture_pile()); 351 else 352 EXPECT_EQ(active_pile, iter->picture_pile()); 353 } 354 } 355} 356 357TEST_F(PictureLayerImplTest, CloneFullInvalidation) { 358 gfx::Size tile_size(90, 80); 359 gfx::Size layer_bounds(300, 500); 360 361 scoped_refptr<TestablePicturePileImpl> pending_pile = 362 TestablePicturePileImpl::CreateFilledPile(tile_size, layer_bounds); 363 scoped_refptr<TestablePicturePileImpl> active_pile = 364 TestablePicturePileImpl::CreateFilledPile(tile_size, layer_bounds); 365 366 SetupTrees(pending_pile, active_pile); 367 368 Region invalidation((gfx::Rect(layer_bounds))); 369 AddDefaultTilingsWithInvalidation(invalidation); 370 371 EXPECT_EQ(pending_layer_->tilings().num_tilings(), 372 active_layer_->tilings().num_tilings()); 373 374 const PictureLayerTilingSet& tilings = pending_layer_->tilings(); 375 EXPECT_GT(tilings.num_tilings(), 0u); 376 for (size_t i = 0; i < tilings.num_tilings(); ++i) 377 VerifyAllTilesExistAndHavePile(tilings.tiling_at(i), pending_pile.get()); 378} 379 380TEST_F(PictureLayerImplTest, NoInvalidationBoundsChange) { 381 gfx::Size tile_size(90, 80); 382 gfx::Size active_layer_bounds(300, 500); 383 gfx::Size pending_layer_bounds(400, 800); 384 385 scoped_refptr<TestablePicturePileImpl> pending_pile = 386 TestablePicturePileImpl::CreateFilledPile(tile_size, 387 pending_layer_bounds); 388 scoped_refptr<TestablePicturePileImpl> active_pile = 389 TestablePicturePileImpl::CreateFilledPile(tile_size, active_layer_bounds); 390 391 SetupTrees(pending_pile, active_pile); 392 393 Region invalidation; 394 AddDefaultTilingsWithInvalidation(invalidation); 395 396 const PictureLayerTilingSet& tilings = pending_layer_->tilings(); 397 EXPECT_GT(tilings.num_tilings(), 0u); 398 for (size_t i = 0; i < tilings.num_tilings(); ++i) { 399 const PictureLayerTiling* tiling = tilings.tiling_at(i); 400 gfx::Rect active_content_bounds = gfx::ToEnclosingRect(gfx::ScaleRect( 401 gfx::Rect(active_layer_bounds), 402 tiling->contents_scale())); 403 for (PictureLayerTiling::Iterator 404 iter(tiling, 405 tiling->contents_scale(), 406 tiling->ContentRect()); 407 iter; 408 ++iter) { 409 EXPECT_TRUE(*iter); 410 EXPECT_FALSE(iter.geometry_rect().IsEmpty()); 411 if (iter.geometry_rect().right() >= active_content_bounds.width() || 412 iter.geometry_rect().bottom() >= active_content_bounds.height()) { 413 EXPECT_EQ(pending_pile, iter->picture_pile()); 414 } else { 415 EXPECT_EQ(active_pile, iter->picture_pile()); 416 } 417 } 418 } 419} 420 421TEST_F(PictureLayerImplTest, AddTilesFromNewRecording) { 422 gfx::Size tile_size(400, 400); 423 gfx::Size layer_bounds(1300, 1900); 424 425 scoped_refptr<TestablePicturePileImpl> pending_pile = 426 TestablePicturePileImpl::CreateEmptyPile(tile_size, layer_bounds); 427 scoped_refptr<TestablePicturePileImpl> active_pile = 428 TestablePicturePileImpl::CreateEmptyPile(tile_size, layer_bounds); 429 430 // Fill in some of active pile, but more of pending pile. 431 int hole_count = 0; 432 for (int x = 0; x < active_pile->tiling().num_tiles_x(); ++x) { 433 for (int y = 0; y < active_pile->tiling().num_tiles_y(); ++y) { 434 if ((x + y) % 2) { 435 pending_pile->AddRecordingAt(x, y); 436 active_pile->AddRecordingAt(x, y); 437 } else { 438 hole_count++; 439 if (hole_count % 2) 440 pending_pile->AddRecordingAt(x, y); 441 } 442 } 443 } 444 445 SetupTrees(pending_pile, active_pile); 446 Region invalidation; 447 AddDefaultTilingsWithInvalidation(invalidation); 448 449 const PictureLayerTilingSet& tilings = pending_layer_->tilings(); 450 EXPECT_GT(tilings.num_tilings(), 0u); 451 for (size_t i = 0; i < tilings.num_tilings(); ++i) { 452 const PictureLayerTiling* tiling = tilings.tiling_at(i); 453 454 for (PictureLayerTiling::Iterator 455 iter(tiling, 456 tiling->contents_scale(), 457 tiling->ContentRect()); 458 iter; 459 ++iter) { 460 EXPECT_FALSE(iter.full_tile_geometry_rect().IsEmpty()); 461 // Ensure there is a recording for this tile. 462 gfx::Rect layer_rect = gfx::ToEnclosingRect(gfx::ScaleRect( 463 iter.full_tile_geometry_rect(), 1.f / tiling->contents_scale())); 464 layer_rect.Intersect(gfx::Rect(layer_bounds)); 465 466 bool in_pending = pending_pile->recorded_region().Contains(layer_rect); 467 bool in_active = active_pile->recorded_region().Contains(layer_rect); 468 469 if (in_pending && !in_active) 470 EXPECT_EQ(pending_pile, iter->picture_pile()); 471 else if (in_active) 472 EXPECT_EQ(active_pile, iter->picture_pile()); 473 else 474 EXPECT_FALSE(*iter); 475 } 476 } 477} 478 479TEST_F(PictureLayerImplTest, ManageTilingsWithNoRecording) { 480 gfx::Size tile_size(400, 400); 481 gfx::Size layer_bounds(1300, 1900); 482 483 scoped_refptr<TestablePicturePileImpl> pending_pile = 484 TestablePicturePileImpl::CreateEmptyPile(tile_size, layer_bounds); 485 scoped_refptr<TestablePicturePileImpl> active_pile = 486 TestablePicturePileImpl::CreateEmptyPile(tile_size, layer_bounds); 487 488 float result_scale_x, result_scale_y; 489 gfx::Size result_bounds; 490 491 SetupTrees(pending_pile, active_pile); 492 493 // These are included in the scale given to the layer. 494 host_impl_.SetDeviceScaleFactor(1.f); 495 host_impl_.pending_tree()->SetPageScaleFactorAndLimits(1.f, 1.f, 1.f); 496 497 pending_layer_->CalculateContentsScale( 498 1.f, false, &result_scale_x, &result_scale_y, &result_bounds); 499 500 EXPECT_EQ(0u, pending_layer_->tilings().num_tilings()); 501} 502 503TEST_F(PictureLayerImplTest, ManageTilingsCreatesTilings) { 504 gfx::Size tile_size(400, 400); 505 gfx::Size layer_bounds(1300, 1900); 506 507 scoped_refptr<TestablePicturePileImpl> pending_pile = 508 TestablePicturePileImpl::CreateFilledPile(tile_size, layer_bounds); 509 scoped_refptr<TestablePicturePileImpl> active_pile = 510 TestablePicturePileImpl::CreateFilledPile(tile_size, layer_bounds); 511 512 float result_scale_x, result_scale_y; 513 gfx::Size result_bounds; 514 515 SetupTrees(pending_pile, active_pile); 516 EXPECT_EQ(0u, pending_layer_->tilings().num_tilings()); 517 518 float low_res_factor = host_impl_.settings().low_res_contents_scale_factor; 519 EXPECT_LT(low_res_factor, 1.f); 520 521 // These are included in the scale given to the layer. 522 host_impl_.SetDeviceScaleFactor(1.7f); 523 host_impl_.pending_tree()->SetPageScaleFactorAndLimits(3.2f, 3.2f, 3.2f); 524 525 pending_layer_->CalculateContentsScale( 526 1.3f, false, &result_scale_x, &result_scale_y, &result_bounds); 527 ASSERT_EQ(2u, pending_layer_->tilings().num_tilings()); 528 EXPECT_FLOAT_EQ( 529 1.3f, 530 pending_layer_->tilings().tiling_at(0)->contents_scale()); 531 EXPECT_FLOAT_EQ( 532 1.3f * low_res_factor, 533 pending_layer_->tilings().tiling_at(1)->contents_scale()); 534 535 // If we change the layer's CSS scale factor, then we should not get new 536 // tilings. 537 pending_layer_->CalculateContentsScale( 538 1.8f, false, &result_scale_x, &result_scale_y, &result_bounds); 539 ASSERT_EQ(2u, pending_layer_->tilings().num_tilings()); 540 EXPECT_FLOAT_EQ( 541 1.3f, 542 pending_layer_->tilings().tiling_at(0)->contents_scale()); 543 EXPECT_FLOAT_EQ( 544 1.3f * low_res_factor, 545 pending_layer_->tilings().tiling_at(1)->contents_scale()); 546 547 // If we change the page scale factor, then we should get new tilings. 548 host_impl_.pending_tree()->SetPageScaleFactorAndLimits(2.2f, 2.2f, 2.2f); 549 550 pending_layer_->CalculateContentsScale( 551 1.8f, false, &result_scale_x, &result_scale_y, &result_bounds); 552 ASSERT_EQ(4u, pending_layer_->tilings().num_tilings()); 553 EXPECT_FLOAT_EQ( 554 1.8f, 555 pending_layer_->tilings().tiling_at(0)->contents_scale()); 556 EXPECT_FLOAT_EQ( 557 1.8f * low_res_factor, 558 pending_layer_->tilings().tiling_at(2)->contents_scale()); 559 560 // If we change the device scale factor, then we should get new tilings. 561 host_impl_.SetDeviceScaleFactor(1.4f); 562 563 pending_layer_->CalculateContentsScale( 564 1.9f, false, &result_scale_x, &result_scale_y, &result_bounds); 565 ASSERT_EQ(6u, pending_layer_->tilings().num_tilings()); 566 EXPECT_FLOAT_EQ( 567 1.9f, 568 pending_layer_->tilings().tiling_at(0)->contents_scale()); 569 EXPECT_FLOAT_EQ( 570 1.9f * low_res_factor, 571 pending_layer_->tilings().tiling_at(3)->contents_scale()); 572 573 // If we change the device scale factor, but end up at the same total scale 574 // factor somehow, then we don't get new tilings. 575 host_impl_.SetDeviceScaleFactor(2.2f); 576 host_impl_.pending_tree()->SetPageScaleFactorAndLimits(1.4f, 1.4f, 1.4f); 577 578 pending_layer_->CalculateContentsScale( 579 1.9f, false, &result_scale_x, &result_scale_y, &result_bounds); 580 ASSERT_EQ(6u, pending_layer_->tilings().num_tilings()); 581 EXPECT_FLOAT_EQ( 582 1.9f, 583 pending_layer_->tilings().tiling_at(0)->contents_scale()); 584 EXPECT_FLOAT_EQ( 585 1.9f * low_res_factor, 586 pending_layer_->tilings().tiling_at(3)->contents_scale()); 587} 588 589TEST_F(PictureLayerImplTest, CleanUpTilings) { 590 gfx::Size tile_size(400, 400); 591 gfx::Size layer_bounds(1300, 1900); 592 593 scoped_refptr<TestablePicturePileImpl> pending_pile = 594 TestablePicturePileImpl::CreateFilledPile(tile_size, layer_bounds); 595 scoped_refptr<TestablePicturePileImpl> active_pile = 596 TestablePicturePileImpl::CreateFilledPile(tile_size, layer_bounds); 597 598 float result_scale_x, result_scale_y; 599 gfx::Size result_bounds; 600 std::vector<PictureLayerTiling*> used_tilings; 601 602 SetupTrees(pending_pile, active_pile); 603 EXPECT_EQ(0u, pending_layer_->tilings().num_tilings()); 604 605 float low_res_factor = host_impl_.settings().low_res_contents_scale_factor; 606 EXPECT_LT(low_res_factor, 1.f); 607 608 // These are included in the scale given to the layer. 609 host_impl_.SetDeviceScaleFactor(1.7f); 610 host_impl_.pending_tree()->SetPageScaleFactorAndLimits(3.2f, 3.2f, 3.2f); 611 host_impl_.active_tree()->SetPageScaleFactorAndLimits(3.2f, 3.2f, 3.2f); 612 613 SetContentsScaleOnBothLayers(1.f, false); 614 ASSERT_EQ(2u, active_layer_->tilings().num_tilings()); 615 616 // We only have ideal tilings, so they aren't removed. 617 used_tilings.clear(); 618 active_layer_->CleanUpTilingsOnActiveLayer(used_tilings); 619 ASSERT_EQ(2u, active_layer_->tilings().num_tilings()); 620 621 // Changing the ideal but not creating new tilings. 622 SetContentsScaleOnBothLayers(1.5f, false); 623 ASSERT_EQ(2u, active_layer_->tilings().num_tilings()); 624 625 // The tilings are still our target scale, so they aren't removed. 626 used_tilings.clear(); 627 active_layer_->CleanUpTilingsOnActiveLayer(used_tilings); 628 ASSERT_EQ(2u, active_layer_->tilings().num_tilings()); 629 630 // Create a 1.2 scale tiling. Now we have 1.0 and 1.2 tilings. Ideal = 1.2. 631 host_impl_.pending_tree()->SetPageScaleFactorAndLimits(1.2f, 1.2f, 1.2f); 632 host_impl_.active_tree()->SetPageScaleFactorAndLimits(1.2f, 1.2f, 1.2f); 633 SetContentsScaleOnBothLayers(1.2f, false); 634 ASSERT_EQ(4u, active_layer_->tilings().num_tilings()); 635 EXPECT_FLOAT_EQ( 636 1.f, 637 active_layer_->tilings().tiling_at(1)->contents_scale()); 638 EXPECT_FLOAT_EQ( 639 1.f * low_res_factor, 640 active_layer_->tilings().tiling_at(3)->contents_scale()); 641 642 // Mark the non-ideal tilings as used. They won't be removed. 643 used_tilings.clear(); 644 used_tilings.push_back(active_layer_->tilings().tiling_at(1)); 645 used_tilings.push_back(active_layer_->tilings().tiling_at(3)); 646 active_layer_->CleanUpTilingsOnActiveLayer(used_tilings); 647 ASSERT_EQ(4u, active_layer_->tilings().num_tilings()); 648 649 // Now move the ideal scale to 0.5. Our target stays 1.2. 650 SetContentsScaleOnBothLayers(0.5f, false); 651 652 // All the tilings are between are target and the ideal, so they are not 653 // removed. 654 used_tilings.clear(); 655 active_layer_->CleanUpTilingsOnActiveLayer(used_tilings); 656 ASSERT_EQ(4u, active_layer_->tilings().num_tilings()); 657 658 // Now move the ideal scale to 1.0. Our target stays 1.2. 659 SetContentsScaleOnBothLayers(1.f, false); 660 661 // All the tilings are between are target and the ideal, so they are not 662 // removed. 663 used_tilings.clear(); 664 active_layer_->CleanUpTilingsOnActiveLayer(used_tilings); 665 ASSERT_EQ(4u, active_layer_->tilings().num_tilings()); 666 667 // Now move the ideal scale to 1.1 on the active layer. Our target stays 1.2. 668 active_layer_->CalculateContentsScale( 669 1.1f, false, &result_scale_x, &result_scale_y, &result_bounds); 670 671 // Because the pending layer's ideal scale is still 1.0, our tilings fall 672 // in the range [1.0,1.2] and are kept. 673 used_tilings.clear(); 674 active_layer_->CleanUpTilingsOnActiveLayer(used_tilings); 675 ASSERT_EQ(4u, active_layer_->tilings().num_tilings()); 676 677 // Move the ideal scale on the pending layer to 1.1 as well. Our target stays 678 // 1.2 still. 679 pending_layer_->CalculateContentsScale( 680 1.1f, false, &result_scale_x, &result_scale_y, &result_bounds); 681 682 // Our 1.0 tiling now falls outside the range between our ideal scale and our 683 // target raster scale. But it is in our used tilings set, so nothing is 684 // deleted. 685 used_tilings.clear(); 686 used_tilings.push_back(active_layer_->tilings().tiling_at(1)); 687 used_tilings.push_back(active_layer_->tilings().tiling_at(3)); 688 active_layer_->CleanUpTilingsOnActiveLayer(used_tilings); 689 ASSERT_EQ(4u, active_layer_->tilings().num_tilings()); 690 691 // If we remove it from our used tilings set, it is outside the range to keep 692 // so it is deleted. Try one tiling at a time. 693 used_tilings.clear(); 694 used_tilings.push_back(active_layer_->tilings().tiling_at(1)); 695 active_layer_->CleanUpTilingsOnActiveLayer(used_tilings); 696 ASSERT_EQ(3u, active_layer_->tilings().num_tilings()); 697 used_tilings.clear(); 698 active_layer_->CleanUpTilingsOnActiveLayer(used_tilings); 699 ASSERT_EQ(2u, active_layer_->tilings().num_tilings()); 700} 701 702} // namespace 703} // namespace cc 704