| 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/resources/tile_manager.h" | 5 #include "cc/resources/tile_manager.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <limits> | 8 #include <limits> |
| 9 #include <string> | 9 #include <string> |
| 10 | 10 |
| (...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 414 DCHECK(TilePriority() == tile->combined_priority()); | 414 DCHECK(TilePriority() == tile->combined_priority()); |
| 415 | 415 |
| 416 prioritized_tiles_dirty_ = true; | 416 prioritized_tiles_dirty_ = true; |
| 417 released_tiles_.push_back(tile); | 417 released_tiles_.push_back(tile); |
| 418 } | 418 } |
| 419 | 419 |
| 420 void TileManager::DidChangeTilePriority(Tile* tile) { | 420 void TileManager::DidChangeTilePriority(Tile* tile) { |
| 421 prioritized_tiles_dirty_ = true; | 421 prioritized_tiles_dirty_ = true; |
| 422 } | 422 } |
| 423 | 423 |
| 424 bool TileManager::ShouldForceTasksRequiredForActivationToComplete() const { | 424 TaskSetCollection TileManager::TasksThatShouldBeForcedToComplete() const { |
| 425 return global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY; | 425 TaskSetCollection tasks_that_should_be_forced_to_complete; |
| 426 if (global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY) |
| 427 tasks_that_should_be_forced_to_complete[REQUIRED_FOR_ACTIVATION] = true; |
| 428 return tasks_that_should_be_forced_to_complete; |
| 426 } | 429 } |
| 427 | 430 |
| 428 void TileManager::FreeResourcesForReleasedTiles() { | 431 void TileManager::FreeResourcesForReleasedTiles() { |
| 429 for (std::vector<Tile*>::iterator it = released_tiles_.begin(); | 432 for (std::vector<Tile*>::iterator it = released_tiles_.begin(); |
| 430 it != released_tiles_.end(); | 433 it != released_tiles_.end(); |
| 431 ++it) { | 434 ++it) { |
| 432 Tile* tile = *it; | 435 Tile* tile = *it; |
| 433 FreeResourcesForTile(tile); | 436 FreeResourcesForTile(tile); |
| 434 } | 437 } |
| 435 } | 438 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 471 | 474 |
| 472 prioritized_tiles_.Clear(); | 475 prioritized_tiles_.Clear(); |
| 473 | 476 |
| 474 FreeResourcesForReleasedTiles(); | 477 FreeResourcesForReleasedTiles(); |
| 475 CleanUpReleasedTiles(); | 478 CleanUpReleasedTiles(); |
| 476 | 479 |
| 477 GetTilesWithAssignedBins(&prioritized_tiles_); | 480 GetTilesWithAssignedBins(&prioritized_tiles_); |
| 478 prioritized_tiles_dirty_ = false; | 481 prioritized_tiles_dirty_ = false; |
| 479 } | 482 } |
| 480 | 483 |
| 481 void TileManager::DidFinishRunningTasks() { | 484 void TileManager::DidFinishRunningTasks(TaskSet task_set) { |
| 482 TRACE_EVENT0("cc", "TileManager::DidFinishRunningTasks"); | 485 TRACE_EVENT1( |
| 486 "cc", "TileManager::DidFinishRunningTasks", "task_set", task_set); |
| 483 | 487 |
| 484 bool memory_usage_above_limit = resource_pool_->total_memory_usage_bytes() > | 488 if (task_set == ALL) { |
| 485 global_state_.soft_memory_limit_in_bytes; | 489 bool memory_usage_above_limit = resource_pool_->total_memory_usage_bytes() > |
| 490 global_state_.soft_memory_limit_in_bytes; |
| 486 | 491 |
| 487 // When OOM, keep re-assigning memory until we reach a steady state | 492 // When OOM, keep re-assigning memory until we reach a steady state |
| 488 // where top-priority tiles are initialized. | 493 // where top-priority tiles are initialized. |
| 489 if (all_tiles_that_need_to_be_rasterized_have_memory_ && | 494 if (all_tiles_that_need_to_be_rasterized_have_memory_ && |
| 490 !memory_usage_above_limit) | 495 !memory_usage_above_limit) |
| 491 return; | 496 return; |
| 492 | 497 |
| 493 rasterizer_->CheckForCompletedTasks(); | 498 rasterizer_->CheckForCompletedTasks(); |
| 494 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; | 499 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; |
| 495 | 500 |
| 496 TileVector tiles_that_need_to_be_rasterized; | 501 TileVector tiles_that_need_to_be_rasterized; |
| 497 AssignGpuMemoryToTiles(&prioritized_tiles_, | 502 AssignGpuMemoryToTiles(&prioritized_tiles_, |
| 498 &tiles_that_need_to_be_rasterized); | 503 &tiles_that_need_to_be_rasterized); |
| 499 | 504 |
| 500 // |tiles_that_need_to_be_rasterized| will be empty when we reach a | 505 // |tiles_that_need_to_be_rasterized| will be empty when we reach a |
| 501 // steady memory state. Keep scheduling tasks until we reach this state. | 506 // steady memory state. Keep scheduling tasks until we reach this state. |
| 502 if (!tiles_that_need_to_be_rasterized.empty()) { | 507 if (!tiles_that_need_to_be_rasterized.empty()) { |
| 503 ScheduleTasks(tiles_that_need_to_be_rasterized); | 508 ScheduleTasks(tiles_that_need_to_be_rasterized); |
| 509 return; |
| 510 } |
| 511 |
| 512 FreeResourcesForReleasedTiles(); |
| 513 |
| 514 resource_pool_->ReduceResourceUsage(); |
| 515 |
| 516 // We don't reserve memory for required-for-activation tiles during |
| 517 // accelerated gestures, so we just postpone activation when we don't |
| 518 // have these tiles, and activate after the accelerated gesture. |
| 519 bool allow_rasterize_on_demand = |
| 520 global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY; |
| 521 |
| 522 // Use on-demand raster for any required-for-activation tiles that have not |
| 523 // been been assigned memory after reaching a steady memory state. This |
| 524 // ensures that we activate even when OOM. |
| 525 for (TileMap::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
| 526 Tile* tile = it->second; |
| 527 ManagedTileState& mts = tile->managed_state(); |
| 528 ManagedTileState::TileVersion& tile_version = |
| 529 mts.tile_versions[mts.raster_mode]; |
| 530 |
| 531 if (tile->required_for_activation() && !tile_version.IsReadyToDraw()) { |
| 532 // If we can't raster on demand, give up early (and don't activate). |
| 533 if (!allow_rasterize_on_demand) |
| 534 return; |
| 535 |
| 536 tile_version.set_rasterize_on_demand(); |
| 537 client_->NotifyTileStateChanged(tile); |
| 538 } |
| 539 } |
| 540 |
| 541 DCHECK(IsReadyToActivate()); |
| 542 ready_to_activate_check_notifier_.Schedule(); |
| 504 return; | 543 return; |
| 505 } | 544 } |
| 506 | 545 |
| 507 FreeResourcesForReleasedTiles(); | 546 if (task_set == REQUIRED_FOR_ACTIVATION) { |
| 547 // This is only a true indication that all tiles required for |
| 548 // activation are initialized when no tiles are OOM. We need to |
| 549 // wait for DidFinishRunningTasks() to be called, try to re-assign |
| 550 // memory and in worst case use on-demand raster when tiles |
| 551 // required for activation are OOM. |
| 552 if (!all_tiles_required_for_activation_have_memory_) |
| 553 return; |
| 508 | 554 |
| 509 resource_pool_->ReduceResourceUsage(); | 555 ready_to_activate_check_notifier_.Schedule(); |
| 510 | |
| 511 // We don't reserve memory for required-for-activation tiles during | |
| 512 // accelerated gestures, so we just postpone activation when we don't | |
| 513 // have these tiles, and activate after the accelerated gesture. | |
| 514 bool allow_rasterize_on_demand = | |
| 515 global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY; | |
| 516 | |
| 517 // Use on-demand raster for any required-for-activation tiles that have not | |
| 518 // been been assigned memory after reaching a steady memory state. This | |
| 519 // ensures that we activate even when OOM. | |
| 520 for (TileMap::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | |
| 521 Tile* tile = it->second; | |
| 522 ManagedTileState& mts = tile->managed_state(); | |
| 523 ManagedTileState::TileVersion& tile_version = | |
| 524 mts.tile_versions[mts.raster_mode]; | |
| 525 | |
| 526 if (tile->required_for_activation() && !tile_version.IsReadyToDraw()) { | |
| 527 // If we can't raster on demand, give up early (and don't activate). | |
| 528 if (!allow_rasterize_on_demand) | |
| 529 return; | |
| 530 | |
| 531 tile_version.set_rasterize_on_demand(); | |
| 532 client_->NotifyTileStateChanged(tile); | |
| 533 } | |
| 534 } | 556 } |
| 535 | |
| 536 DCHECK(IsReadyToActivate()); | |
| 537 ready_to_activate_check_notifier_.Schedule(); | |
| 538 } | |
| 539 | |
| 540 void TileManager::DidFinishRunningTasksRequiredForActivation() { | |
| 541 // This is only a true indication that all tiles required for | |
| 542 // activation are initialized when no tiles are OOM. We need to | |
| 543 // wait for DidFinishRunningTasks() to be called, try to re-assign | |
| 544 // memory and in worst case use on-demand raster when tiles | |
| 545 // required for activation are OOM. | |
| 546 if (!all_tiles_required_for_activation_have_memory_) | |
| 547 return; | |
| 548 | |
| 549 ready_to_activate_check_notifier_.Schedule(); | |
| 550 } | 557 } |
| 551 | 558 |
| 552 void TileManager::GetTilesWithAssignedBins(PrioritizedTileSet* tiles) { | 559 void TileManager::GetTilesWithAssignedBins(PrioritizedTileSet* tiles) { |
| 553 TRACE_EVENT0("cc", "TileManager::GetTilesWithAssignedBins"); | 560 TRACE_EVENT0("cc", "TileManager::GetTilesWithAssignedBins"); |
| 554 | 561 |
| 555 const TileMemoryLimitPolicy memory_policy = global_state_.memory_limit_policy; | 562 const TileMemoryLimitPolicy memory_policy = global_state_.memory_limit_policy; |
| 556 const TreePriority tree_priority = global_state_.tree_priority; | 563 const TreePriority tree_priority = global_state_.tree_priority; |
| 557 | 564 |
| 558 // For each tree, bin into different categories of tiles. | 565 // For each tree, bin into different categories of tiles. |
| 559 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 566 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
| (...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 969 ManagedTileState& mts = tile->managed_state(); | 976 ManagedTileState& mts = tile->managed_state(); |
| 970 ManagedTileState::TileVersion& tile_version = | 977 ManagedTileState::TileVersion& tile_version = |
| 971 mts.tile_versions[mts.raster_mode]; | 978 mts.tile_versions[mts.raster_mode]; |
| 972 | 979 |
| 973 DCHECK(tile_version.requires_resource()); | 980 DCHECK(tile_version.requires_resource()); |
| 974 DCHECK(!tile_version.resource_); | 981 DCHECK(!tile_version.resource_); |
| 975 | 982 |
| 976 if (!tile_version.raster_task_.get()) | 983 if (!tile_version.raster_task_.get()) |
| 977 tile_version.raster_task_ = CreateRasterTask(tile); | 984 tile_version.raster_task_ = CreateRasterTask(tile); |
| 978 | 985 |
| 979 raster_queue_.items.push_back(RasterTaskQueue::Item( | 986 TaskSetCollection task_sets; |
| 980 tile_version.raster_task_.get(), tile->required_for_activation())); | 987 if (tile->required_for_activation()) |
| 988 task_sets.set(REQUIRED_FOR_ACTIVATION); |
| 989 task_sets.set(ALL); |
| 990 raster_queue_.items.push_back( |
| 991 RasterTaskQueue::Item(tile_version.raster_task_.get(), task_sets)); |
| 981 } | 992 } |
| 982 | 993 |
| 983 // We must reduce the amount of unused resoruces before calling | 994 // We must reduce the amount of unused resoruces before calling |
| 984 // ScheduleTasks to prevent usage from rising above limits. | 995 // ScheduleTasks to prevent usage from rising above limits. |
| 985 resource_pool_->ReduceResourceUsage(); | 996 resource_pool_->ReduceResourceUsage(); |
| 986 | 997 |
| 987 // Schedule running of |raster_tasks_|. This replaces any previously | 998 // Schedule running of |raster_tasks_|. This replaces any previously |
| 988 // scheduled tasks and effectively cancels all tasks not present | 999 // scheduled tasks and effectively cancels all tasks not present |
| 989 // in |raster_tasks_|. | 1000 // in |raster_tasks_|. |
| 990 rasterizer_->ScheduleTasks(&raster_queue_); | 1001 rasterizer_->ScheduleTasks(&raster_queue_); |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1169 TRACE_EVENT0("cc", "TileManager::CheckIfReadyToActivate"); | 1180 TRACE_EVENT0("cc", "TileManager::CheckIfReadyToActivate"); |
| 1170 | 1181 |
| 1171 rasterizer_->CheckForCompletedTasks(); | 1182 rasterizer_->CheckForCompletedTasks(); |
| 1172 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; | 1183 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; |
| 1173 | 1184 |
| 1174 if (IsReadyToActivate()) | 1185 if (IsReadyToActivate()) |
| 1175 client_->NotifyReadyToActivate(); | 1186 client_->NotifyReadyToActivate(); |
| 1176 } | 1187 } |
| 1177 | 1188 |
| 1178 } // namespace cc | 1189 } // namespace cc |
| OLD | NEW |