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_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