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