Home | History | Annotate | Download | only in resources
      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/debug/lap_timer.h"
      6 #include "cc/resources/picture_layer_tiling.h"
      7 #include "cc/resources/resource_provider.h"
      8 #include "cc/resources/scoped_resource.h"
      9 #include "cc/test/fake_output_surface.h"
     10 #include "cc/test/fake_output_surface_client.h"
     11 #include "cc/test/fake_picture_layer_tiling_client.h"
     12 #include "cc/test/test_context_provider.h"
     13 #include "cc/test/test_shared_bitmap_manager.h"
     14 
     15 #include "testing/gtest/include/gtest/gtest.h"
     16 #include "testing/perf/perf_test.h"
     17 
     18 namespace cc {
     19 
     20 namespace {
     21 
     22 static const int kTimeLimitMillis = 2000;
     23 static const int kWarmupRuns = 5;
     24 static const int kTimeCheckInterval = 10;
     25 
     26 class PictureLayerTilingPerfTest : public testing::Test {
     27  public:
     28   PictureLayerTilingPerfTest()
     29       : timer_(kWarmupRuns,
     30                base::TimeDelta::FromMilliseconds(kTimeLimitMillis),
     31                kTimeCheckInterval),
     32         context_provider_(TestContextProvider::Create()) {
     33     output_surface_ = FakeOutputSurface::Create3d(context_provider_).Pass();
     34     CHECK(output_surface_->BindToClient(&output_surface_client_));
     35 
     36     shared_bitmap_manager_.reset(new TestSharedBitmapManager());
     37     resource_provider_ = ResourceProvider::Create(output_surface_.get(),
     38                                                   shared_bitmap_manager_.get(),
     39                                                   NULL,
     40                                                   0,
     41                                                   false,
     42                                                   1,
     43                                                   false).Pass();
     44   }
     45 
     46   virtual void SetUp() OVERRIDE {
     47     picture_layer_tiling_client_.SetTileSize(gfx::Size(256, 256));
     48     picture_layer_tiling_client_.set_max_tiles_for_interest_area(250);
     49     picture_layer_tiling_client_.set_tree(PENDING_TREE);
     50     picture_layer_tiling_ = PictureLayerTiling::Create(
     51         1, gfx::Size(256 * 50, 256 * 50), &picture_layer_tiling_client_);
     52     picture_layer_tiling_->CreateAllTilesForTesting();
     53   }
     54 
     55   virtual void TearDown() OVERRIDE {
     56     picture_layer_tiling_.reset(NULL);
     57   }
     58 
     59   void RunInvalidateTest(const std::string& test_name, const Region& region) {
     60     timer_.Reset();
     61     do {
     62       picture_layer_tiling_->UpdateTilesToCurrentPile(
     63           region, picture_layer_tiling_->tiling_size());
     64       timer_.NextLap();
     65     } while (!timer_.HasTimeLimitExpired());
     66 
     67     perf_test::PrintResult(
     68         "invalidation", "", test_name, timer_.LapsPerSecond(), "runs/s", true);
     69   }
     70 
     71   void RunUpdateTilePrioritiesStationaryTest(const std::string& test_name,
     72                                              const gfx::Transform& transform) {
     73     gfx::Rect viewport_rect(0, 0, 1024, 768);
     74 
     75     timer_.Reset();
     76     do {
     77       picture_layer_tiling_->UpdateTilePriorities(
     78           PENDING_TREE, viewport_rect, 1.f, timer_.NumLaps() + 1, Occlusion());
     79       timer_.NextLap();
     80     } while (!timer_.HasTimeLimitExpired());
     81 
     82     perf_test::PrintResult("update_tile_priorities_stationary",
     83                            "",
     84                            test_name,
     85                            timer_.LapsPerSecond(),
     86                            "runs/s",
     87                            true);
     88   }
     89 
     90   void RunUpdateTilePrioritiesScrollingTest(const std::string& test_name,
     91                                             const gfx::Transform& transform) {
     92     gfx::Size viewport_size(1024, 768);
     93     gfx::Rect viewport_rect(viewport_size);
     94     int xoffsets[] = {10, 0, -10, 0};
     95     int yoffsets[] = {0, 10, 0, -10};
     96     int offsetIndex = 0;
     97     int offsetCount = 0;
     98     const int maxOffsetCount = 1000;
     99 
    100     timer_.Reset();
    101     do {
    102       picture_layer_tiling_->UpdateTilePriorities(
    103           PENDING_TREE, viewport_rect, 1.f, timer_.NumLaps() + 1, Occlusion());
    104 
    105       viewport_rect = gfx::Rect(viewport_rect.x() + xoffsets[offsetIndex],
    106                                 viewport_rect.y() + yoffsets[offsetIndex],
    107                                 viewport_rect.width(),
    108                                 viewport_rect.height());
    109 
    110       if (++offsetCount > maxOffsetCount) {
    111         offsetCount = 0;
    112         offsetIndex = (offsetIndex + 1) % 4;
    113       }
    114       timer_.NextLap();
    115     } while (!timer_.HasTimeLimitExpired());
    116 
    117     perf_test::PrintResult("update_tile_priorities_scrolling",
    118                            "",
    119                            test_name,
    120                            timer_.LapsPerSecond(),
    121                            "runs/s",
    122                            true);
    123   }
    124 
    125   void RunRasterIteratorConstructTest(const std::string& test_name,
    126                                       const gfx::Rect& viewport) {
    127     gfx::Size bounds(viewport.size());
    128     picture_layer_tiling_ =
    129         PictureLayerTiling::Create(1, bounds, &picture_layer_tiling_client_);
    130     picture_layer_tiling_client_.set_tree(ACTIVE_TREE);
    131     picture_layer_tiling_->UpdateTilePriorities(
    132         ACTIVE_TREE, viewport, 1.0f, 1.0, Occlusion());
    133 
    134     timer_.Reset();
    135     do {
    136       PictureLayerTiling::TilingRasterTileIterator it(
    137           picture_layer_tiling_.get(), ACTIVE_TREE);
    138       timer_.NextLap();
    139     } while (!timer_.HasTimeLimitExpired());
    140 
    141     perf_test::PrintResult("tiling_raster_tile_iterator_construct",
    142                            "",
    143                            test_name,
    144                            timer_.LapsPerSecond(),
    145                            "runs/s",
    146                            true);
    147   }
    148 
    149   void RunRasterIteratorConstructAndIterateTest(const std::string& test_name,
    150                                                 int num_tiles,
    151                                                 const gfx::Rect& viewport) {
    152     gfx::Size bounds(10000, 10000);
    153     picture_layer_tiling_ =
    154         PictureLayerTiling::Create(1, bounds, &picture_layer_tiling_client_);
    155     picture_layer_tiling_client_.set_tree(ACTIVE_TREE);
    156     picture_layer_tiling_->UpdateTilePriorities(
    157         ACTIVE_TREE, viewport, 1.0f, 1.0, Occlusion());
    158 
    159     timer_.Reset();
    160     do {
    161       int count = num_tiles;
    162       PictureLayerTiling::TilingRasterTileIterator it(
    163           picture_layer_tiling_.get(), ACTIVE_TREE);
    164       while (count--) {
    165         ASSERT_TRUE(it) << "count: " << count;
    166         ASSERT_TRUE(*it != NULL) << "count: " << count;
    167         ++it;
    168       }
    169       timer_.NextLap();
    170     } while (!timer_.HasTimeLimitExpired());
    171 
    172     perf_test::PrintResult("tiling_raster_tile_iterator_construct_and_iterate",
    173                            "",
    174                            test_name,
    175                            timer_.LapsPerSecond(),
    176                            "runs/s",
    177                            true);
    178   }
    179 
    180   void RunEvictionIteratorConstructTest(const std::string& test_name,
    181                                         const gfx::Rect& viewport) {
    182     gfx::Size bounds(viewport.size());
    183     picture_layer_tiling_ =
    184         PictureLayerTiling::Create(1, bounds, &picture_layer_tiling_client_);
    185     picture_layer_tiling_client_.set_tree(ACTIVE_TREE);
    186     picture_layer_tiling_->UpdateTilePriorities(
    187         ACTIVE_TREE, viewport, 1.0f, 1.0, Occlusion());
    188 
    189     timer_.Reset();
    190     TreePriority priorities[] = {SAME_PRIORITY_FOR_BOTH_TREES,
    191                                  SMOOTHNESS_TAKES_PRIORITY,
    192                                  NEW_CONTENT_TAKES_PRIORITY};
    193     int priority_count = 0;
    194     do {
    195       PictureLayerTiling::TilingEvictionTileIterator it(
    196           picture_layer_tiling_.get(),
    197           priorities[priority_count],
    198           PictureLayerTiling::NOW);
    199       priority_count = (priority_count + 1) % arraysize(priorities);
    200       timer_.NextLap();
    201     } while (!timer_.HasTimeLimitExpired());
    202 
    203     perf_test::PrintResult("tiling_eviction_tile_iterator_construct",
    204                            "",
    205                            test_name,
    206                            timer_.LapsPerSecond(),
    207                            "runs/s",
    208                            true);
    209   }
    210 
    211   void RunEvictionIteratorConstructAndIterateTest(const std::string& test_name,
    212                                                   int num_tiles,
    213                                                   const gfx::Rect& viewport) {
    214     gfx::Size bounds(10000, 10000);
    215     picture_layer_tiling_ =
    216         PictureLayerTiling::Create(1, bounds, &picture_layer_tiling_client_);
    217     picture_layer_tiling_client_.set_tree(ACTIVE_TREE);
    218     picture_layer_tiling_->UpdateTilePriorities(
    219         ACTIVE_TREE, viewport, 1.0f, 1.0, Occlusion());
    220 
    221     TreePriority priorities[] = {SAME_PRIORITY_FOR_BOTH_TREES,
    222                                  SMOOTHNESS_TAKES_PRIORITY,
    223                                  NEW_CONTENT_TAKES_PRIORITY};
    224 
    225     // Ensure all tiles have resources.
    226     std::vector<Tile*> all_tiles = picture_layer_tiling_->AllTilesForTesting();
    227     for (std::vector<Tile*>::iterator tile_it = all_tiles.begin();
    228          tile_it != all_tiles.end();
    229          ++tile_it) {
    230       Tile* tile = *tile_it;
    231       ManagedTileState::TileVersion& tile_version =
    232           tile->GetTileVersionForTesting(tile->GetRasterModeForTesting());
    233       tile_version.SetResourceForTesting(
    234           ScopedResource::Create(resource_provider_.get()).Pass());
    235     }
    236 
    237     int priority_count = 0;
    238     timer_.Reset();
    239     do {
    240       int count = num_tiles;
    241       PictureLayerTiling::TilingEvictionTileIterator it(
    242           picture_layer_tiling_.get(),
    243           priorities[priority_count],
    244           PictureLayerTiling::EVENTUALLY);
    245       while (count--) {
    246         ASSERT_TRUE(it) << "count: " << count;
    247         ASSERT_TRUE(*it != NULL) << "count: " << count;
    248         ++it;
    249       }
    250       priority_count = (priority_count + 1) % arraysize(priorities);
    251       timer_.NextLap();
    252     } while (!timer_.HasTimeLimitExpired());
    253 
    254     // Remove all resources from tiles to make sure the tile version destructor
    255     // doesn't complain.
    256     for (std::vector<Tile*>::iterator tile_it = all_tiles.begin();
    257          tile_it != all_tiles.end();
    258          ++tile_it) {
    259       Tile* tile = *tile_it;
    260       ManagedTileState::TileVersion& tile_version =
    261           tile->GetTileVersionForTesting(tile->GetRasterModeForTesting());
    262       tile_version.SetResourceForTesting(scoped_ptr<ScopedResource>());
    263     }
    264 
    265     perf_test::PrintResult(
    266         "tiling_eviction_tile_iterator_construct_and_iterate",
    267         "",
    268         test_name,
    269         timer_.LapsPerSecond(),
    270         "runs/s",
    271         true);
    272   }
    273 
    274  private:
    275   FakePictureLayerTilingClient picture_layer_tiling_client_;
    276   scoped_ptr<PictureLayerTiling> picture_layer_tiling_;
    277 
    278   LapTimer timer_;
    279 
    280   scoped_refptr<ContextProvider> context_provider_;
    281   FakeOutputSurfaceClient output_surface_client_;
    282   scoped_ptr<FakeOutputSurface> output_surface_;
    283   scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
    284   scoped_ptr<ResourceProvider> resource_provider_;
    285 };
    286 
    287 TEST_F(PictureLayerTilingPerfTest, Invalidate) {
    288   Region one_tile(gfx::Rect(256, 256));
    289   RunInvalidateTest("1x1", one_tile);
    290 
    291   Region half_region(gfx::Rect(25 * 256, 50 * 256));
    292   RunInvalidateTest("25x50", half_region);
    293 
    294   Region full_region(gfx::Rect(50 * 256, 50 * 256));
    295   RunInvalidateTest("50x50", full_region);
    296 }
    297 
    298 #if defined(OS_ANDROID)
    299 // TODO(vmpstr): Investigate why this is noisy (crbug.com/310220).
    300 TEST_F(PictureLayerTilingPerfTest, DISABLED_UpdateTilePriorities) {
    301 #else
    302 TEST_F(PictureLayerTilingPerfTest, UpdateTilePriorities) {
    303 #endif  // defined(OS_ANDROID)
    304   gfx::Transform transform;
    305 
    306   RunUpdateTilePrioritiesStationaryTest("no_transform", transform);
    307   RunUpdateTilePrioritiesScrollingTest("no_transform", transform);
    308 
    309   transform.Rotate(10);
    310   RunUpdateTilePrioritiesStationaryTest("rotation", transform);
    311   RunUpdateTilePrioritiesScrollingTest("rotation", transform);
    312 
    313   transform.ApplyPerspectiveDepth(10);
    314   RunUpdateTilePrioritiesStationaryTest("perspective", transform);
    315   RunUpdateTilePrioritiesScrollingTest("perspective", transform);
    316 }
    317 
    318 TEST_F(PictureLayerTilingPerfTest, TilingRasterTileIteratorConstruct) {
    319   RunRasterIteratorConstructTest("0_0_100x100", gfx::Rect(0, 0, 100, 100));
    320   RunRasterIteratorConstructTest("50_0_100x100", gfx::Rect(50, 0, 100, 100));
    321   RunRasterIteratorConstructTest("100_0_100x100", gfx::Rect(100, 0, 100, 100));
    322   RunRasterIteratorConstructTest("150_0_100x100", gfx::Rect(150, 0, 100, 100));
    323 }
    324 
    325 TEST_F(PictureLayerTilingPerfTest,
    326        TilingRasterTileIteratorConstructAndIterate) {
    327   RunRasterIteratorConstructAndIterateTest(
    328       "32_100x100", 32, gfx::Rect(0, 0, 100, 100));
    329   RunRasterIteratorConstructAndIterateTest(
    330       "32_500x500", 32, gfx::Rect(0, 0, 500, 500));
    331   RunRasterIteratorConstructAndIterateTest(
    332       "64_100x100", 64, gfx::Rect(0, 0, 100, 100));
    333   RunRasterIteratorConstructAndIterateTest(
    334       "64_500x500", 64, gfx::Rect(0, 0, 500, 500));
    335 }
    336 
    337 TEST_F(PictureLayerTilingPerfTest, TilingEvictionTileIteratorConstruct) {
    338   RunEvictionIteratorConstructTest("0_0_100x100", gfx::Rect(0, 0, 100, 100));
    339   RunEvictionIteratorConstructTest("50_0_100x100", gfx::Rect(50, 0, 100, 100));
    340   RunEvictionIteratorConstructTest("100_0_100x100",
    341                                    gfx::Rect(100, 0, 100, 100));
    342   RunEvictionIteratorConstructTest("150_0_100x100",
    343                                    gfx::Rect(150, 0, 100, 100));
    344 }
    345 
    346 TEST_F(PictureLayerTilingPerfTest,
    347        TilingEvictionTileIteratorConstructAndIterate) {
    348   RunEvictionIteratorConstructAndIterateTest(
    349       "32_100x100", 32, gfx::Rect(0, 0, 100, 100));
    350   RunEvictionIteratorConstructAndIterateTest(
    351       "32_500x500", 32, gfx::Rect(0, 0, 500, 500));
    352   RunEvictionIteratorConstructAndIterateTest(
    353       "64_100x100", 64, gfx::Rect(0, 0, 100, 100));
    354   RunEvictionIteratorConstructAndIterateTest(
    355       "64_500x500", 64, gfx::Rect(0, 0, 500, 500));
    356 }
    357 
    358 }  // namespace
    359 
    360 }  // namespace cc
    361