Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "cc/tile_manager.h" | 5 #include "cc/tile_manager.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <set> | 8 #include <set> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 24 | 24 |
| 25 const char* kRasterThreadNamePrefix = "CompositorRaster"; | 25 const char* kRasterThreadNamePrefix = "CompositorRaster"; |
| 26 | 26 |
| 27 const int kMaxRasterThreads = 64; | 27 const int kMaxRasterThreads = 64; |
| 28 const int kDefaultNumberOfRasterThreads = 1; | 28 const int kDefaultNumberOfRasterThreads = 1; |
| 29 | 29 |
| 30 // Allow two pending raster tasks per thread. This keeps resource usage | 30 // Allow two pending raster tasks per thread. This keeps resource usage |
| 31 // low while making sure raster threads aren't unnecessarily idle. | 31 // low while making sure raster threads aren't unnecessarily idle. |
| 32 const int kNumPendingRasterTasksPerThread = 2; | 32 const int kNumPendingRasterTasksPerThread = 2; |
| 33 | 33 |
| 34 // Determine bin based on three categories of tiles: things we need now, | |
| 35 // things we need soon, and eventually. | |
| 36 cc::TileManagerBin BinFromTilePriority(const cc::TilePriority& prio) { | |
|
enne (OOO)
2012/12/16 01:26:44
This is a nice refactoring.
| |
| 37 | |
| 38 // The amount of time for which we want to have prepainting coverage. | |
| 39 const double prepainting_window_time_seconds = 1.0; | |
| 40 const double backfling_guard_distance_pixels = 314.0; | |
| 41 | |
| 42 if (prio.time_to_needed_in_seconds() == std::numeric_limits<float>::max()) | |
| 43 return cc::NEVER_BIN; | |
| 44 | |
| 45 if (prio.resolution == cc::NON_IDEAL_RESOLUTION) | |
| 46 return cc::EVENTUALLY_BIN; | |
| 47 | |
| 48 if (prio.time_to_needed_in_seconds() == 0 || | |
| 49 prio.distance_to_visible_in_pixels < backfling_guard_distance_pixels) | |
| 50 return cc::NOW_BIN; | |
| 51 | |
| 52 if (prio.time_to_needed_in_seconds() < prepainting_window_time_seconds) | |
| 53 return cc::SOON_BIN; | |
| 54 | |
| 55 return cc::EVENTUALLY_BIN; | |
| 56 } | |
| 57 | |
| 34 } // namespace | 58 } // namespace |
| 35 | 59 |
| 36 namespace cc { | 60 namespace cc { |
| 37 | 61 |
| 38 class RasterThread : public base::Thread { | 62 class RasterThread : public base::Thread { |
| 39 public: | 63 public: |
| 40 RasterThread(const std::string name) | 64 RasterThread(const std::string name) |
| 41 : base::Thread(name.c_str()), | 65 : base::Thread(name.c_str()), |
| 42 num_pending_tasks_(0) { | 66 num_pending_tasks_(0) { |
| 43 Start(); | 67 Start(); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 137 check_for_completed_set_pixels_pending_(false) { | 161 check_for_completed_set_pixels_pending_(false) { |
| 138 // Initialize all threads. | 162 // Initialize all threads. |
| 139 const std::string thread_name_prefix = kRasterThreadNamePrefix; | 163 const std::string thread_name_prefix = kRasterThreadNamePrefix; |
| 140 while (raster_threads_.size() < num_raster_threads) { | 164 while (raster_threads_.size() < num_raster_threads) { |
| 141 int thread_number = raster_threads_.size() + 1; | 165 int thread_number = raster_threads_.size() + 1; |
| 142 scoped_ptr<RasterThread> thread = make_scoped_ptr( | 166 scoped_ptr<RasterThread> thread = make_scoped_ptr( |
| 143 new RasterThread(thread_name_prefix + | 167 new RasterThread(thread_name_prefix + |
| 144 StringPrintf("Worker%d", thread_number).c_str())); | 168 StringPrintf("Worker%d", thread_number).c_str())); |
| 145 raster_threads_.append(thread.Pass()); | 169 raster_threads_.append(thread.Pass()); |
| 146 } | 170 } |
| 171 | |
| 172 ResetBinCounts(); | |
| 147 } | 173 } |
| 148 | 174 |
| 149 TileManager::~TileManager() { | 175 TileManager::~TileManager() { |
| 150 // Reset global state and manage. This should cause | 176 // Reset global state and manage. This should cause |
| 151 // our memory usage to drop to zero. | 177 // our memory usage to drop to zero. |
| 152 global_state_ = GlobalStateThatImpactsTilePriority(); | 178 global_state_ = GlobalStateThatImpactsTilePriority(); |
| 153 AssignGpuMemoryToTiles(); | 179 AssignGpuMemoryToTiles(); |
| 154 // This should finish all pending raster tasks and release any | 180 // This should finish all pending raster tasks and release any |
| 155 // uninitialized resources. | 181 // uninitialized resources. |
| 156 raster_threads_.clear(); | 182 raster_threads_.clear(); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 212 return; | 238 return; |
| 213 client_->ScheduleCheckForCompletedSetPixels(); | 239 client_->ScheduleCheckForCompletedSetPixels(); |
| 214 check_for_completed_set_pixels_pending_ = true; | 240 check_for_completed_set_pixels_pending_ = true; |
| 215 } | 241 } |
| 216 | 242 |
| 217 class BinComparator { | 243 class BinComparator { |
| 218 public: | 244 public: |
| 219 bool operator() (const Tile* a, const Tile* b) const { | 245 bool operator() (const Tile* a, const Tile* b) const { |
| 220 const ManagedTileState& ams = a->managed_state(); | 246 const ManagedTileState& ams = a->managed_state(); |
| 221 const ManagedTileState& bms = b->managed_state(); | 247 const ManagedTileState& bms = b->managed_state(); |
| 222 if (ams.bin != bms.bin) | 248 if (ams.raster_bin != bms.raster_bin) |
| 223 return ams.bin < bms.bin; | 249 return ams.raster_bin < bms.raster_bin; |
| 224 | 250 |
| 225 if (ams.resolution != bms.resolution) | 251 if (ams.resolution != bms.resolution) |
| 226 return ams.resolution < ams.resolution; | 252 return ams.resolution < ams.resolution; |
| 227 | 253 |
| 228 return | 254 return |
| 229 ams.time_to_needed_in_seconds < | 255 ams.time_to_needed_in_seconds < |
| 230 bms.time_to_needed_in_seconds; | 256 bms.time_to_needed_in_seconds; |
| 231 } | 257 } |
| 232 }; | 258 }; |
| 233 | 259 |
| 234 void TileManager::ManageTiles() { | 260 void TileManager::ManageTiles() { |
| 235 TRACE_EVENT0("cc", "TileManager::ManageTiles"); | 261 TRACE_EVENT0("cc", "TileManager::ManageTiles"); |
| 236 manage_tiles_pending_ = false; | 262 manage_tiles_pending_ = false; |
| 237 | 263 |
| 238 // The amount of time for which we want to have prepainting coverage. | 264 const bool smoothness_takes_priority = |
| 239 const double prepainting_window_time_seconds = 1.0; | 265 global_state_.smoothness_takes_priority; |
| 240 const double backfling_guard_distance_pixels = 314.0; | |
| 241 | 266 |
| 242 const bool smoothness_takes_priority = global_state_.smoothness_takes_priority ; | 267 // For each tree, bin into different categories of tiles. |
| 243 | |
| 244 // Bin into three categories of tiles: things we need now, things we need soon , and eventually | |
| 245 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 268 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
| 246 Tile* tile = *it; | 269 Tile* tile = *it; |
| 247 ManagedTileState& mts = tile->managed_state(); | 270 ManagedTileState& mts = tile->managed_state(); |
| 271 mts.bin[ACTIVE_TREE] = BinFromTilePriority(tile->priority(ACTIVE_TREE)); | |
| 272 mts.bin[PENDING_TREE] = BinFromTilePriority(tile->priority(PENDING_TREE)); | |
| 273 | |
| 248 TilePriority prio; | 274 TilePriority prio; |
| 249 if (smoothness_takes_priority) | 275 if (smoothness_takes_priority) |
| 250 prio = tile->priority(ACTIVE_TREE); | 276 prio = tile->priority(ACTIVE_TREE); |
| 251 else | 277 else |
| 252 prio = tile->combined_priority(); | 278 prio = tile->combined_priority(); |
| 253 | 279 |
| 254 mts.resolution = prio.resolution; | 280 mts.resolution = prio.resolution; |
| 255 mts.time_to_needed_in_seconds = prio.time_to_needed_in_seconds(); | 281 mts.time_to_needed_in_seconds = prio.time_to_needed_in_seconds(); |
| 256 | 282 mts.raster_bin = BinFromTilePriority(prio); |
| 257 if (mts.time_to_needed_in_seconds == | |
| 258 std::numeric_limits<float>::max()) { | |
| 259 mts.bin = NEVER_BIN; | |
| 260 continue; | |
| 261 } | |
| 262 | |
| 263 if (mts.resolution == NON_IDEAL_RESOLUTION) { | |
| 264 mts.bin = EVENTUALLY_BIN; | |
| 265 continue; | |
| 266 } | |
| 267 | |
| 268 if (mts.time_to_needed_in_seconds == 0 || | |
| 269 prio.distance_to_visible_in_pixels < backfling_guard_distance_pixels) { | |
| 270 mts.bin = NOW_BIN; | |
| 271 continue; | |
| 272 } | |
| 273 | |
| 274 if (prio.time_to_needed_in_seconds() < prepainting_window_time_seconds) { | |
| 275 mts.bin = SOON_BIN; | |
| 276 continue; | |
| 277 } | |
| 278 | |
| 279 mts.bin = EVENTUALLY_BIN; | |
| 280 } | 283 } |
| 281 | 284 |
| 282 // Memory limit policy works by mapping some bin states to the NEVER bin. | 285 // Memory limit policy works by mapping some bin states to the NEVER bin. |
| 283 TileManagerBin bin_map[NUM_BINS]; | 286 TileManagerBin bin_map[NUM_BINS]; |
| 284 if (global_state_.memory_limit_policy == ALLOW_NOTHING) { | 287 if (global_state_.memory_limit_policy == ALLOW_NOTHING) { |
| 285 bin_map[NOW_BIN] = NEVER_BIN; | 288 bin_map[NOW_BIN] = NEVER_BIN; |
| 286 bin_map[SOON_BIN] = NEVER_BIN; | 289 bin_map[SOON_BIN] = NEVER_BIN; |
| 287 bin_map[EVENTUALLY_BIN] = NEVER_BIN; | 290 bin_map[EVENTUALLY_BIN] = NEVER_BIN; |
| 288 bin_map[NEVER_BIN] = NEVER_BIN; | 291 bin_map[NEVER_BIN] = NEVER_BIN; |
| 289 } else if (global_state_.memory_limit_policy == ALLOW_ABSOLUTE_MINIMUM) { | 292 } else if (global_state_.memory_limit_policy == ALLOW_ABSOLUTE_MINIMUM) { |
| 290 bin_map[NOW_BIN] = NOW_BIN; | 293 bin_map[NOW_BIN] = NOW_BIN; |
| 291 bin_map[SOON_BIN] = NEVER_BIN; | 294 bin_map[SOON_BIN] = NEVER_BIN; |
| 292 bin_map[EVENTUALLY_BIN] = NEVER_BIN; | 295 bin_map[EVENTUALLY_BIN] = NEVER_BIN; |
| 293 bin_map[NEVER_BIN] = NEVER_BIN; | 296 bin_map[NEVER_BIN] = NEVER_BIN; |
| 294 } else if (global_state_.memory_limit_policy == ALLOW_PREPAINT_ONLY) { | 297 } else if (global_state_.memory_limit_policy == ALLOW_PREPAINT_ONLY) { |
| 295 bin_map[NOW_BIN] = NOW_BIN; | 298 bin_map[NOW_BIN] = NOW_BIN; |
| 296 bin_map[SOON_BIN] = SOON_BIN; | 299 bin_map[SOON_BIN] = SOON_BIN; |
| 297 bin_map[EVENTUALLY_BIN] = NEVER_BIN; | 300 bin_map[EVENTUALLY_BIN] = NEVER_BIN; |
| 298 bin_map[NEVER_BIN] = NEVER_BIN; | 301 bin_map[NEVER_BIN] = NEVER_BIN; |
| 299 } else { | 302 } else { |
| 300 bin_map[NOW_BIN] = NOW_BIN; | 303 bin_map[NOW_BIN] = NOW_BIN; |
| 301 bin_map[SOON_BIN] = SOON_BIN; | 304 bin_map[SOON_BIN] = SOON_BIN; |
| 302 bin_map[EVENTUALLY_BIN] = EVENTUALLY_BIN; | 305 bin_map[EVENTUALLY_BIN] = EVENTUALLY_BIN; |
| 303 bin_map[NEVER_BIN] = NEVER_BIN; | 306 bin_map[NEVER_BIN] = NEVER_BIN; |
| 304 } | 307 } |
| 305 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 308 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
| 306 Tile* tile = *it; | 309 Tile* tile = *it; |
| 307 TileManagerBin bin = bin_map[tile->managed_state().bin]; | 310 ManagedTileState& mts = tile->managed_state(); |
| 308 tile->managed_state().bin = bin; | 311 mts.bin[ACTIVE_TREE] = bin_map[mts.bin[ACTIVE_TREE]]; |
| 312 mts.bin[PENDING_TREE] = bin_map[mts.bin[PENDING_TREE]]; | |
| 313 mts.raster_bin = bin_map[mts.raster_bin]; | |
| 314 } | |
| 315 | |
| 316 // Update bin counts. | |
| 317 ResetBinCounts(); | |
| 318 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | |
| 319 Tile* tile = *it; | |
| 320 ManagedTileState& mts = tile->managed_state(); | |
| 321 for (int i = 0; i < NUM_TREES; ++i) | |
| 322 tiles_in_bin_count_[mts.bin[i]][i]++; | |
| 323 | |
| 324 // Increment drawable count if GetResourceId() doesn't return 0. | |
| 325 if (tile->GetResourceId()) { | |
| 326 for (int i = 0; i < NUM_TREES; ++i) | |
| 327 drawable_tiles_in_bin_count_[mts.bin[i]][i]++; | |
| 328 } | |
| 309 } | 329 } |
| 310 | 330 |
| 311 // Sort by bin. | 331 // Sort by bin. |
| 312 std::sort(tiles_.begin(), tiles_.end(), BinComparator()); | 332 std::sort(tiles_.begin(), tiles_.end(), BinComparator()); |
| 313 | 333 |
| 314 // Assign gpu memory and determine what tiles need to be rasterized. | 334 // Assign gpu memory and determine what tiles need to be rasterized. |
| 315 AssignGpuMemoryToTiles(); | 335 AssignGpuMemoryToTiles(); |
| 316 | 336 |
| 317 // Finally, kick the rasterizer. | 337 // Finally, kick the rasterizer. |
| 318 DispatchMoreTasks(); | 338 DispatchMoreTasks(); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 334 | 354 |
| 335 // It's now safe to release the pixel buffer. | 355 // It's now safe to release the pixel buffer. |
| 336 resource_pool_->resource_provider()->releasePixelBuffer( | 356 resource_pool_->resource_provider()->releasePixelBuffer( |
| 337 tile->managed_state().resource->id()); | 357 tile->managed_state().resource->id()); |
| 338 | 358 |
| 339 DidFinishTileInitialization(tile); | 359 DidFinishTileInitialization(tile); |
| 340 tiles_with_pending_set_pixels_.pop(); | 360 tiles_with_pending_set_pixels_.pop(); |
| 341 } | 361 } |
| 342 } | 362 } |
| 343 | 363 |
| 344 void TileManager::renderingStats(RenderingStats* stats) { | 364 void TileManager::GetRenderingStats(RenderingStats* stats) { |
| 345 stats->totalRasterizeTimeInSeconds = | 365 stats->totalRasterizeTimeInSeconds = |
| 346 rendering_stats_.totalRasterizeTimeInSeconds; | 366 rendering_stats_.totalRasterizeTimeInSeconds; |
| 347 stats->totalPixelsRasterized = rendering_stats_.totalPixelsRasterized; | 367 stats->totalPixelsRasterized = rendering_stats_.totalPixelsRasterized; |
| 348 } | 368 } |
| 349 | 369 |
| 370 int TileManager::GetTilesInBinCount(TileManagerBin bin, WhichTree tree) { | |
| 371 DCHECK(bin >= 0); | |
| 372 DCHECK(bin < NUM_BINS); | |
| 373 DCHECK(tree >= 0); | |
| 374 DCHECK(tree < NUM_TREES); | |
| 375 return tiles_in_bin_count_[bin][tree]; | |
| 376 } | |
| 377 | |
| 378 int TileManager::GetDrawableTilesInBinCount( | |
| 379 TileManagerBin bin, WhichTree tree) { | |
| 380 DCHECK(bin >= 0); | |
| 381 DCHECK(bin < NUM_BINS); | |
| 382 DCHECK(tree >= 0); | |
| 383 DCHECK(tree < NUM_TREES); | |
| 384 return drawable_tiles_in_bin_count_[bin][tree]; | |
| 385 } | |
| 386 | |
| 387 void TileManager::ResetBinCounts() { | |
| 388 for (int i = 0; i < NUM_BINS; ++i) | |
| 389 for (int j = 0; j < NUM_TREES; ++j) | |
| 390 tiles_in_bin_count_[i][j] = drawable_tiles_in_bin_count_[i][j] = 0; | |
| 391 } | |
| 392 | |
| 350 void TileManager::AssignGpuMemoryToTiles() { | 393 void TileManager::AssignGpuMemoryToTiles() { |
| 351 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles"); | 394 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles"); |
| 352 // Some memory cannot be released. Figure out which. | 395 // Some memory cannot be released. Figure out which. |
| 353 size_t unreleasable_bytes = 0; | 396 size_t unreleasable_bytes = 0; |
| 354 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 397 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
| 355 Tile* tile = *it; | 398 Tile* tile = *it; |
| 356 if (!tile->managed_state().can_be_freed) | 399 if (!tile->managed_state().can_be_freed) |
| 357 unreleasable_bytes += tile->bytes_consumed_if_allocated(); | 400 unreleasable_bytes += tile->bytes_consumed_if_allocated(); |
| 358 } | 401 } |
| 359 | 402 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 372 } | 415 } |
| 373 tiles_with_image_decoding_tasks_.clear(); | 416 tiles_with_image_decoding_tasks_.clear(); |
| 374 | 417 |
| 375 size_t bytes_left = global_state_.memory_limit_in_bytes - unreleasable_bytes; | 418 size_t bytes_left = global_state_.memory_limit_in_bytes - unreleasable_bytes; |
| 376 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 419 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
| 377 Tile* tile = *it; | 420 Tile* tile = *it; |
| 378 size_t tile_bytes = tile->bytes_consumed_if_allocated(); | 421 size_t tile_bytes = tile->bytes_consumed_if_allocated(); |
| 379 ManagedTileState& managed_tile_state = tile->managed_state(); | 422 ManagedTileState& managed_tile_state = tile->managed_state(); |
| 380 if (!managed_tile_state.can_be_freed) | 423 if (!managed_tile_state.can_be_freed) |
| 381 continue; | 424 continue; |
| 382 if (managed_tile_state.bin == NEVER_BIN) { | 425 if (managed_tile_state.raster_bin == NEVER_BIN) { |
| 383 managed_tile_state.can_use_gpu_memory = false; | 426 managed_tile_state.can_use_gpu_memory = false; |
| 384 FreeResourcesForTile(tile); | 427 FreeResourcesForTile(tile); |
| 385 continue; | 428 continue; |
| 386 } | 429 } |
| 387 if (tile_bytes > bytes_left) { | 430 if (tile_bytes > bytes_left) { |
| 388 managed_tile_state.can_use_gpu_memory = false; | 431 managed_tile_state.can_use_gpu_memory = false; |
| 389 FreeResourcesForTile(tile); | 432 FreeResourcesForTile(tile); |
| 390 continue; | 433 continue; |
| 391 } | 434 } |
| 392 bytes_left -= tile_bytes; | 435 bytes_left -= tile_bytes; |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 612 managed_tile_state.resource_is_being_initialized = false; | 655 managed_tile_state.resource_is_being_initialized = false; |
| 613 } | 656 } |
| 614 DispatchMoreTasks(); | 657 DispatchMoreTasks(); |
| 615 } | 658 } |
| 616 | 659 |
| 617 void TileManager::DidFinishTileInitialization(Tile* tile) { | 660 void TileManager::DidFinishTileInitialization(Tile* tile) { |
| 618 ManagedTileState& managed_tile_state = tile->managed_state(); | 661 ManagedTileState& managed_tile_state = tile->managed_state(); |
| 619 DCHECK(managed_tile_state.resource); | 662 DCHECK(managed_tile_state.resource); |
| 620 managed_tile_state.resource_is_being_initialized = false; | 663 managed_tile_state.resource_is_being_initialized = false; |
| 621 managed_tile_state.can_be_freed = true; | 664 managed_tile_state.can_be_freed = true; |
| 665 for (int i = 0; i < NUM_TREES; ++i) | |
| 666 drawable_tiles_in_bin_count_[managed_tile_state.bin[i]][i]++; | |
| 622 } | 667 } |
| 623 | 668 |
| 624 } | 669 } |
| OLD | NEW |