Home | History | Annotate | Download | only in resources
      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