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 "base/time/time.h"
      6 #include "cc/resources/tile.h"
      7 #include "cc/resources/tile_priority.h"
      8 #include "cc/test/fake_output_surface.h"
      9 #include "cc/test/fake_output_surface_client.h"
     10 #include "cc/test/fake_picture_pile_impl.h"
     11 #include "cc/test/fake_tile_manager.h"
     12 #include "cc/test/fake_tile_manager_client.h"
     13 #include "cc/test/lap_timer.h"
     14 #include "cc/test/test_tile_priorities.h"
     15 
     16 #include "testing/gtest/include/gtest/gtest.h"
     17 #include "testing/perf/perf_test.h"
     18 
     19 namespace cc {
     20 
     21 namespace {
     22 
     23 static const int kTimeLimitMillis = 2000;
     24 static const int kWarmupRuns = 5;
     25 static const int kTimeCheckInterval = 10;
     26 
     27 class TileManagerPerfTest : public testing::Test {
     28  public:
     29   typedef std::vector<std::pair<scoped_refptr<Tile>, ManagedTileBin> >
     30       TileBinVector;
     31 
     32   TileManagerPerfTest()
     33       : timer_(kWarmupRuns,
     34                base::TimeDelta::FromMilliseconds(kTimeLimitMillis),
     35                kTimeCheckInterval) {}
     36 
     37   // Overridden from testing::Test:
     38   virtual void SetUp() OVERRIDE {
     39     output_surface_ = FakeOutputSurface::Create3d();
     40     CHECK(output_surface_->BindToClient(&output_surface_client_));
     41 
     42     resource_provider_ =
     43         ResourceProvider::Create(output_surface_.get(), NULL, 0, false, 1);
     44     size_t raster_task_limit_bytes = 32 * 1024 * 1024;  // 16-64MB in practice.
     45     tile_manager_ = make_scoped_ptr(
     46         new FakeTileManager(&tile_manager_client_,
     47                             resource_provider_.get(),
     48                             raster_task_limit_bytes));
     49     picture_pile_ = FakePicturePileImpl::CreatePile();
     50   }
     51 
     52   GlobalStateThatImpactsTilePriority GlobalStateForTest() {
     53     GlobalStateThatImpactsTilePriority state;
     54     gfx::Size tile_size = settings_.default_tile_size;
     55     state.memory_limit_in_bytes =
     56         10000u * 4u *
     57         static_cast<size_t>(tile_size.width() * tile_size.height());
     58     state.num_resources_limit = 10000;
     59     state.memory_limit_policy = ALLOW_ANYTHING;
     60     state.tree_priority = SMOOTHNESS_TAKES_PRIORITY;
     61     return state;
     62   }
     63 
     64   virtual void TearDown() OVERRIDE {
     65     tile_manager_.reset(NULL);
     66     picture_pile_ = NULL;
     67   }
     68 
     69   TilePriority GetTilePriorityFromBin(ManagedTileBin bin) {
     70     switch (bin) {
     71       case NOW_AND_READY_TO_DRAW_BIN:
     72       case NOW_BIN:
     73         return TilePriorityForNowBin();
     74       case SOON_BIN:
     75         return TilePriorityForSoonBin();
     76       case EVENTUALLY_AND_ACTIVE_BIN:
     77       case EVENTUALLY_BIN:
     78         return TilePriorityForEventualBin();
     79       case AT_LAST_BIN:
     80       case AT_LAST_AND_ACTIVE_BIN:
     81       case NEVER_BIN:
     82         return TilePriority();
     83       default:
     84         NOTREACHED();
     85         return TilePriority();
     86     }
     87   }
     88 
     89   ManagedTileBin GetNextBin(ManagedTileBin bin) {
     90     switch (bin) {
     91       case NOW_AND_READY_TO_DRAW_BIN:
     92       case NOW_BIN:
     93         return SOON_BIN;
     94       case SOON_BIN:
     95         return EVENTUALLY_BIN;
     96       case EVENTUALLY_AND_ACTIVE_BIN:
     97       case EVENTUALLY_BIN:
     98         return NEVER_BIN;
     99       case AT_LAST_BIN:
    100       case AT_LAST_AND_ACTIVE_BIN:
    101       case NEVER_BIN:
    102         return NOW_BIN;
    103       default:
    104         NOTREACHED();
    105         return NEVER_BIN;
    106     }
    107   }
    108 
    109   void CreateBinTiles(int count, ManagedTileBin bin, TileBinVector* tiles) {
    110     for (int i = 0; i < count; ++i) {
    111       scoped_refptr<Tile> tile =
    112           tile_manager_->CreateTile(picture_pile_.get(),
    113                                     settings_.default_tile_size,
    114                                     gfx::Rect(),
    115                                     gfx::Rect(),
    116                                     1.0,
    117                                     0,
    118                                     0,
    119                                     Tile::USE_LCD_TEXT);
    120       tile->SetPriority(ACTIVE_TREE, GetTilePriorityFromBin(bin));
    121       tile->SetPriority(PENDING_TREE, GetTilePriorityFromBin(bin));
    122       tiles->push_back(std::make_pair(tile, bin));
    123     }
    124   }
    125 
    126   void CreateTiles(int count, TileBinVector* tiles) {
    127     // Roughly an equal amount of all bins.
    128     int count_per_bin = count / NUM_BINS;
    129     CreateBinTiles(count_per_bin, NOW_BIN, tiles);
    130     CreateBinTiles(count_per_bin, SOON_BIN, tiles);
    131     CreateBinTiles(count_per_bin, EVENTUALLY_BIN, tiles);
    132     CreateBinTiles(count - 3 * count_per_bin, NEVER_BIN, tiles);
    133   }
    134 
    135   void RunManageTilesTest(const std::string& test_name,
    136                           unsigned tile_count,
    137                           int priority_change_percent) {
    138     DCHECK_GE(tile_count, 100u);
    139     DCHECK_GE(priority_change_percent, 0);
    140     DCHECK_LE(priority_change_percent, 100);
    141     TileBinVector tiles;
    142     CreateTiles(tile_count, &tiles);
    143     timer_.Reset();
    144     do {
    145       if (priority_change_percent > 0) {
    146         for (unsigned i = 0;
    147              i < tile_count;
    148              i += 100 / priority_change_percent) {
    149           Tile* tile = tiles[i].first.get();
    150           ManagedTileBin bin = GetNextBin(tiles[i].second);
    151           tile->SetPriority(ACTIVE_TREE, GetTilePriorityFromBin(bin));
    152           tile->SetPriority(PENDING_TREE, GetTilePriorityFromBin(bin));
    153           tiles[i].second = bin;
    154         }
    155       }
    156 
    157       tile_manager_->ManageTiles(GlobalStateForTest());
    158       tile_manager_->CheckForCompletedTasks();
    159       timer_.NextLap();
    160     } while (!timer_.HasTimeLimitExpired());
    161 
    162     perf_test::PrintResult("manage_tiles", "", test_name,
    163                            timer_.LapsPerSecond(), "runs/s", true);
    164   }
    165 
    166  private:
    167   FakeTileManagerClient tile_manager_client_;
    168   LayerTreeSettings settings_;
    169   scoped_ptr<FakeTileManager> tile_manager_;
    170   scoped_refptr<FakePicturePileImpl> picture_pile_;
    171   FakeOutputSurfaceClient output_surface_client_;
    172   scoped_ptr<FakeOutputSurface> output_surface_;
    173   scoped_ptr<ResourceProvider> resource_provider_;
    174   LapTimer timer_;
    175 };
    176 
    177 TEST_F(TileManagerPerfTest, ManageTiles) {
    178   RunManageTilesTest("100_0", 100, 0);
    179   RunManageTilesTest("1000_0", 1000, 0);
    180   RunManageTilesTest("10000_0", 10000, 0);
    181   RunManageTilesTest("100_10", 100, 10);
    182   RunManageTilesTest("1000_10", 1000, 10);
    183   RunManageTilesTest("10000_10", 10000, 10);
    184   RunManageTilesTest("100_100", 100, 100);
    185   RunManageTilesTest("1000_100", 1000, 100);
    186   RunManageTilesTest("10000_100", 10000, 100);
    187 }
    188 
    189 }  // namespace
    190 
    191 }  // namespace cc
    192