| Index: cc/resources/tile_manager.cc
|
| diff --git a/cc/resources/tile_manager.cc b/cc/resources/tile_manager.cc
|
| index 8b6a72afc6fb4622a218cc08327cbfc082f0175d..1c7d4ca97f8ae107005724a25d0b8a754f40168c 100644
|
| --- a/cc/resources/tile_manager.cc
|
| +++ b/cc/resources/tile_manager.cc
|
| @@ -175,6 +175,20 @@ class ImageDecodeTaskImpl : public ImageDecodeTask {
|
| DISALLOW_COPY_AND_ASSIGN(ImageDecodeTaskImpl);
|
| };
|
|
|
| +const char* TaskSetName(TaskSet task_set) {
|
| + switch (task_set) {
|
| + case TileManager::ALL:
|
| + return "ALL";
|
| + case TileManager::REQUIRED_FOR_ACTIVATION:
|
| + return "REQUIRED_FOR_ACTIVATION";
|
| + case TileManager::REQUIRED_FOR_DRAW:
|
| + return "REQUIRED_FOR_DRAW";
|
| + }
|
| +
|
| + NOTREACHED();
|
| + return "Invalid TaskSet";
|
| +}
|
| +
|
| } // namespace
|
|
|
| RasterTaskCompletionStats::RasterTaskCompletionStats()
|
| @@ -225,7 +239,10 @@ TileManager::TileManager(
|
| ready_to_activate_check_notifier_(
|
| task_runner_.get(),
|
| base::Bind(&TileManager::CheckIfReadyToActivate,
|
| - base::Unretained(this))) {
|
| + base::Unretained(this))),
|
| + ready_to_draw_check_notifier_(task_runner_.get(),
|
| + base::Bind(&TileManager::CheckIfReadyToDraw,
|
| + base::Unretained(this))) {
|
| rasterizer_->SetClient(this);
|
| }
|
|
|
| @@ -295,85 +312,91 @@ void TileManager::CleanUpReleasedTiles() {
|
| }
|
|
|
| void TileManager::DidFinishRunningTasks(TaskSet task_set) {
|
| - if (task_set == ALL) {
|
| - TRACE_EVENT1("cc", "TileManager::DidFinishRunningTasks", "task_set", "ALL");
|
| -
|
| - bool memory_usage_above_limit = resource_pool_->total_memory_usage_bytes() >
|
| - global_state_.soft_memory_limit_in_bytes;
|
| -
|
| - // When OOM, keep re-assigning memory until we reach a steady state
|
| - // where top-priority tiles are initialized.
|
| - if (all_tiles_that_need_to_be_rasterized_are_scheduled_ &&
|
| - !memory_usage_above_limit)
|
| - return;
|
| + TRACE_EVENT1("cc", "TileManager::DidFinishRunningTasks", "task_set",
|
| + TaskSetName(task_set));
|
| +
|
| + switch (task_set) {
|
| + case ALL: {
|
| + bool memory_usage_above_limit =
|
| + resource_pool_->total_memory_usage_bytes() >
|
| + global_state_.soft_memory_limit_in_bytes;
|
| +
|
| + // When OOM, keep re-assigning memory until we reach a steady state
|
| + // where top-priority tiles are initialized.
|
| + if (all_tiles_that_need_to_be_rasterized_are_scheduled_ &&
|
| + !memory_usage_above_limit)
|
| + return;
|
|
|
| - rasterizer_->CheckForCompletedTasks();
|
| - did_check_for_completed_tasks_since_last_schedule_tasks_ = true;
|
| + rasterizer_->CheckForCompletedTasks();
|
| + did_check_for_completed_tasks_since_last_schedule_tasks_ = true;
|
|
|
| - TileVector tiles_that_need_to_be_rasterized;
|
| - AssignGpuMemoryToTiles(&tiles_that_need_to_be_rasterized);
|
| + TileVector tiles_that_need_to_be_rasterized;
|
| + AssignGpuMemoryToTiles(&tiles_that_need_to_be_rasterized);
|
|
|
| - // |tiles_that_need_to_be_rasterized| will be empty when we reach a
|
| - // steady memory state. Keep scheduling tasks until we reach this state.
|
| - if (!tiles_that_need_to_be_rasterized.empty()) {
|
| - ScheduleTasks(tiles_that_need_to_be_rasterized);
|
| - return;
|
| - }
|
| + // |tiles_that_need_to_be_rasterized| will be empty when we reach a
|
| + // steady memory state. Keep scheduling tasks until we reach this state.
|
| + if (!tiles_that_need_to_be_rasterized.empty()) {
|
| + ScheduleTasks(tiles_that_need_to_be_rasterized);
|
| + return;
|
| + }
|
|
|
| - FreeResourcesForReleasedTiles();
|
| -
|
| - resource_pool_->ReduceResourceUsage();
|
| -
|
| - // We don't reserve memory for required-for-activation tiles during
|
| - // accelerated gestures, so we just postpone activation when we don't
|
| - // have these tiles, and activate after the accelerated gesture.
|
| - // Likewise if we don't allow any tiles (as is the case when we're
|
| - // invisible), if we have tiles that aren't ready, then we shouldn't
|
| - // activate as activation can cause checkerboards.
|
| - bool allow_rasterize_on_demand =
|
| - global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY &&
|
| - global_state_.memory_limit_policy != ALLOW_NOTHING;
|
| -
|
| - // Use on-demand raster for any required-for-activation tiles that have not
|
| - // been been assigned memory after reaching a steady memory state. This
|
| - // ensures that we activate even when OOM. Note that we have to rebuilt the
|
| - // queue in case the last AssignGpuMemoryToTiles evicted some tiles that
|
| - // would otherwise not be picked up by the old raster queue.
|
| - client_->BuildRasterQueue(&raster_priority_queue_,
|
| - global_state_.tree_priority);
|
| - bool ready_to_activate = true;
|
| - while (!raster_priority_queue_.IsEmpty()) {
|
| - Tile* tile = raster_priority_queue_.Top();
|
| - ManagedTileState& mts = tile->managed_state();
|
| -
|
| - if (tile->required_for_activation() && !mts.draw_info.IsReadyToDraw()) {
|
| - // If we can't raster on demand, give up early (and don't activate).
|
| - if (!allow_rasterize_on_demand) {
|
| - ready_to_activate = false;
|
| - break;
|
| + FreeResourcesForReleasedTiles();
|
| +
|
| + resource_pool_->ReduceResourceUsage();
|
| +
|
| + // We don't reserve memory for required-for-activation tiles during
|
| + // accelerated gestures, so we just postpone activation when we don't
|
| + // have these tiles, and activate after the accelerated gesture.
|
| + // Likewise if we don't allow any tiles (as is the case when we're
|
| + // invisible), if we have tiles that aren't ready, then we shouldn't
|
| + // activate as activation can cause checkerboards.
|
| + bool allow_rasterize_on_demand =
|
| + global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY &&
|
| + global_state_.memory_limit_policy != ALLOW_NOTHING;
|
| +
|
| + // Use on-demand raster for any required-for-activation tiles that have
|
| + // not
|
| + // been been assigned memory after reaching a steady memory state. This
|
| + // ensures that we activate even when OOM. Note that we have to rebuilt
|
| + // the
|
| + // queue in case the last AssignGpuMemoryToTiles evicted some tiles that
|
| + // would otherwise not be picked up by the old raster queue.
|
| + client_->BuildRasterQueue(&raster_priority_queue_,
|
| + global_state_.tree_priority);
|
| + bool ready_to_activate = true;
|
| + while (!raster_priority_queue_.IsEmpty()) {
|
| + Tile* tile = raster_priority_queue_.Top();
|
| + ManagedTileState& mts = tile->managed_state();
|
| +
|
| + if (tile->required_for_activation() && !mts.draw_info.IsReadyToDraw()) {
|
| + // If we can't raster on demand, give up early (and don't activate).
|
| + if (!allow_rasterize_on_demand) {
|
| + ready_to_activate = false;
|
| + break;
|
| + }
|
| +
|
| + mts.draw_info.set_rasterize_on_demand();
|
| + client_->NotifyTileStateChanged(tile);
|
| }
|
| + raster_priority_queue_.Pop();
|
| + }
|
|
|
| - mts.draw_info.set_rasterize_on_demand();
|
| - client_->NotifyTileStateChanged(tile);
|
| + if (ready_to_activate) {
|
| + DCHECK(IsReadyToActivate());
|
| + ready_to_activate_check_notifier_.Schedule();
|
| }
|
| - raster_priority_queue_.Pop();
|
| + raster_priority_queue_.Reset();
|
| + return;
|
| }
|
| -
|
| - if (ready_to_activate) {
|
| - DCHECK(IsReadyToActivate());
|
| + case REQUIRED_FOR_ACTIVATION:
|
| ready_to_activate_check_notifier_.Schedule();
|
| - }
|
| - raster_priority_queue_.Reset();
|
| - return;
|
| + return;
|
| + case REQUIRED_FOR_DRAW:
|
| + ready_to_draw_check_notifier_.Schedule();
|
| + return;
|
| }
|
|
|
| - if (task_set == REQUIRED_FOR_ACTIVATION) {
|
| - TRACE_EVENT1("cc",
|
| - "TileManager::DidFinishRunningTasks",
|
| - "task_set",
|
| - "REQUIRED_FOR_ACTIVATION");
|
| - ready_to_activate_check_notifier_.Schedule();
|
| - }
|
| + NOTREACHED();
|
| }
|
|
|
| void TileManager::ManageTiles(const GlobalStateThatImpactsTilePriority& state) {
|
| @@ -671,6 +694,8 @@ void TileManager::ScheduleTasks(
|
| TaskSetCollection task_sets;
|
| if (tile->required_for_activation())
|
| task_sets.set(REQUIRED_FOR_ACTIVATION);
|
| + if (tile->required_for_draw())
|
| + task_sets.set(REQUIRED_FOR_DRAW);
|
| task_sets.set(ALL);
|
| raster_queue_.items.push_back(
|
| RasterTaskQueue::Item(mts.raster_task.get(), task_sets));
|
| @@ -840,10 +865,19 @@ bool TileManager::IsReadyToActivate() const {
|
| TRACE_EVENT0("cc", "TileManager::IsReadyToActivate");
|
| const std::vector<PictureLayerImpl*>& layers = client_->GetPictureLayers();
|
|
|
| - for (std::vector<PictureLayerImpl*>::const_iterator it = layers.begin();
|
| - it != layers.end();
|
| - ++it) {
|
| - if (!(*it)->AllTilesRequiredForActivationAreReadyToDraw())
|
| + for (const auto& layer : layers) {
|
| + if (!layer->AllTilesRequiredForActivationAreReadyToDraw())
|
| + return false;
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| +bool TileManager::IsReadyToDraw() const {
|
| + const std::vector<PictureLayerImpl*>& layers = client_->GetPictureLayers();
|
| +
|
| + for (const auto& layer : layers) {
|
| + if (!layer->AllTilesRequiredForDrawAreReadyToDraw())
|
| return false;
|
| }
|
|
|
| @@ -860,6 +894,16 @@ void TileManager::CheckIfReadyToActivate() {
|
| client_->NotifyReadyToActivate();
|
| }
|
|
|
| +void TileManager::CheckIfReadyToDraw() {
|
| + TRACE_EVENT0("cc", "TileManager::CheckIfReadyToDraw");
|
| +
|
| + rasterizer_->CheckForCompletedTasks();
|
| + did_check_for_completed_tasks_since_last_schedule_tasks_ = true;
|
| +
|
| + if (IsReadyToDraw())
|
| + client_->NotifyReadyToDraw();
|
| +}
|
| +
|
| TileManager::MemoryUsage::MemoryUsage() : memory_bytes_(0), resource_count_(0) {
|
| }
|
|
|
|
|