| Index: cc/resources/tile_manager.cc
|
| diff --git a/cc/resources/tile_manager.cc b/cc/resources/tile_manager.cc
|
| index 309c2b3519d63e417843d01e72a9505d4bbbcee7..400a9e934241a2092960eae59f5966dffb08e4d6 100644
|
| --- a/cc/resources/tile_manager.cc
|
| +++ b/cc/resources/tile_manager.cc
|
| @@ -203,9 +203,10 @@ scoped_ptr<TileManager> TileManager::Create(
|
| base::SequencedTaskRunner* task_runner,
|
| ResourcePool* resource_pool,
|
| TileTaskRunner* tile_task_runner,
|
| + Rasterizer* rasterizer,
|
| size_t scheduled_raster_task_limit) {
|
| return make_scoped_ptr(new TileManager(client, task_runner, resource_pool,
|
| - tile_task_runner,
|
| + tile_task_runner, rasterizer,
|
| scheduled_raster_task_limit));
|
| }
|
|
|
| @@ -214,15 +215,24 @@ TileManager::TileManager(
|
| const scoped_refptr<base::SequencedTaskRunner>& task_runner,
|
| ResourcePool* resource_pool,
|
| TileTaskRunner* tile_task_runner,
|
| + Rasterizer* rasterizer,
|
| size_t scheduled_raster_task_limit)
|
| : client_(client),
|
| task_runner_(task_runner),
|
| resource_pool_(resource_pool),
|
| tile_task_runner_(tile_task_runner),
|
| + rasterizer_(rasterizer),
|
| scheduled_raster_task_limit_(scheduled_raster_task_limit),
|
| all_tiles_that_need_to_be_rasterized_are_scheduled_(true),
|
| did_check_for_completed_tasks_since_last_schedule_tasks_(true),
|
| did_oom_on_last_assign_(false),
|
| + ready_to_activate_notifier_(
|
| + task_runner_.get(),
|
| + base::Bind(&TileManager::NotifyReadyToActivate,
|
| + base::Unretained(this))),
|
| + ready_to_draw_notifier_(
|
| + task_runner_.get(),
|
| + base::Bind(&TileManager::NotifyReadyToDraw, base::Unretained(this))),
|
| ready_to_activate_check_notifier_(
|
| task_runner_.get(),
|
| base::Bind(&TileManager::CheckIfReadyToActivate,
|
| @@ -319,8 +329,12 @@ void TileManager::DidFinishRunningTileTasks(TaskSet task_set) {
|
| tile_task_runner_->CheckForCompletedTasks();
|
| did_check_for_completed_tasks_since_last_schedule_tasks_ = true;
|
|
|
| + client_->BuildRasterQueue(&raster_priority_queue_,
|
| + global_state_.tree_priority);
|
| TileVector tiles_that_need_to_be_rasterized;
|
| - AssignGpuMemoryToTiles(&tiles_that_need_to_be_rasterized);
|
| + AssignGpuMemoryToTiles(&tiles_that_need_to_be_rasterized,
|
| + scheduled_raster_task_limit_, false);
|
| + raster_priority_queue_.Reset();
|
|
|
| // |tiles_that_need_to_be_rasterized| will be empty when we reach a
|
| // steady memory state. Keep scheduling tasks until we reach this state.
|
| @@ -394,31 +408,100 @@ void TileManager::PrepareTiles(
|
|
|
| global_state_ = state;
|
|
|
| - // We need to call CheckForCompletedTasks() once in-between each call
|
| - // to ScheduleTasks() to prevent canceled tasks from being scheduled.
|
| - if (!did_check_for_completed_tasks_since_last_schedule_tasks_) {
|
| - tile_task_runner_->CheckForCompletedTasks();
|
| - did_check_for_completed_tasks_since_last_schedule_tasks_ = true;
|
| + enum Rasterizer::PrepareTilesMode prepare_tiles_mode =
|
| + rasterizer_->PrepareTilesMode();
|
| +
|
| + if (prepare_tiles_mode != GpuRasterizer::PREPARE_NONE) {
|
| + // We need to call CheckForCompletedTasks() once in-between each call
|
| + // to ScheduleTasks() to prevent canceled tasks from being scheduled.
|
| + if (!did_check_for_completed_tasks_since_last_schedule_tasks_) {
|
| + tile_task_runner_->CheckForCompletedTasks();
|
| + did_check_for_completed_tasks_since_last_schedule_tasks_ = true;
|
| + }
|
| +
|
| + FreeResourcesForReleasedTiles();
|
| + CleanUpReleasedTiles();
|
| +
|
| + client_->BuildRasterQueue(&raster_priority_queue_,
|
| + global_state_.tree_priority);
|
| + TileVector tiles_that_need_to_be_rasterized;
|
| +
|
| + AssignGpuMemoryToTiles(&tiles_that_need_to_be_rasterized,
|
| + scheduled_raster_task_limit_, false);
|
| +
|
| + raster_priority_queue_.Reset();
|
| +
|
| + // Schedule tile tasks.
|
| + ScheduleTasks(tiles_that_need_to_be_rasterized);
|
| +
|
| + did_notify_ready_to_activate_ = false;
|
| + did_notify_ready_to_draw_ = false;
|
| + } else {
|
| + did_notify_ready_to_activate_ = false;
|
| + did_notify_ready_to_draw_ = false;
|
| + ready_to_activate_notifier_.Schedule();
|
| + ready_to_draw_notifier_.Schedule();
|
| }
|
|
|
| + TRACE_EVENT_INSTANT1("cc", "DidPrepareTiles", TRACE_EVENT_SCOPE_THREAD,
|
| + "state", BasicStateAsValue());
|
| +
|
| + TRACE_COUNTER_ID1("cc", "unused_memory_bytes", this,
|
| + resource_pool_->total_memory_usage_bytes() -
|
| + resource_pool_->acquired_memory_usage_bytes());
|
| +}
|
| +
|
| +void TileManager::PrepareTilesBeforeDraw(
|
| + const GlobalStateThatImpactsTilePriority& state) {
|
| + DCHECK(rasterizer_);
|
| + TRACE_EVENT0("cc", "TileManager::PrepareTilesBeforeDraw");
|
| +
|
| + enum Rasterizer::PrepareTilesMode prepare_tiles_mode =
|
| + rasterizer_->PrepareTilesMode();
|
| +
|
| + if (prepare_tiles_mode == GpuRasterizer::RASTERIZE_PRIORITIZED_TILES)
|
| + return;
|
| +
|
| + global_state_ = state;
|
| +
|
| FreeResourcesForReleasedTiles();
|
| CleanUpReleasedTiles();
|
|
|
| + client_->BuildRasterQueue(&raster_priority_queue_,
|
| + global_state_.tree_priority);
|
| TileVector tiles_that_need_to_be_rasterized;
|
| - AssignGpuMemoryToTiles(&tiles_that_need_to_be_rasterized);
|
| + AssignGpuMemoryToTiles(&tiles_that_need_to_be_rasterized,
|
| + std::numeric_limits<size_t>::max(), true);
|
| +
|
| + // We must reduce the amount of unused resoruces before calling
|
| + // RunTasks to prevent usage from rising above limits.
|
| + resource_pool_->ReduceResourceUsage();
|
| +
|
| + // Run and complete all raster task synchronously.
|
| + rasterizer_->RasterizeTiles(tiles_that_need_to_be_rasterized, resource_pool_,
|
| + this);
|
| +
|
| + // Use on-demand raster for any tiles that have not been been assigned
|
| + // memory. This ensures that we draw even when OOM.
|
| + while (!raster_priority_queue_.IsEmpty()) {
|
| + Tile* tile = raster_priority_queue_.Top();
|
| + ManagedTileState& mts = tile->managed_state();
|
|
|
| - // Schedule tile tasks.
|
| - ScheduleTasks(tiles_that_need_to_be_rasterized);
|
| + if (tile->required_for_draw() && !mts.draw_info.IsReadyToDraw()) {
|
| + mts.draw_info.set_rasterize_on_demand();
|
| + client_->NotifyTileStateChanged(tile);
|
| + }
|
| + raster_priority_queue_.Pop();
|
| + }
|
| + raster_priority_queue_.Reset();
|
|
|
| - did_notify_ready_to_activate_ = false;
|
| - did_notify_ready_to_draw_ = false;
|
| + if (IsReadyToDraw())
|
| + client_->NotifyReadyToDraw();
|
|
|
| - TRACE_EVENT_INSTANT1("cc", "DidPrepare", TRACE_EVENT_SCOPE_THREAD, "state",
|
| + TRACE_EVENT_INSTANT1("cc", "DidRasterize", TRACE_EVENT_SCOPE_THREAD, "state",
|
| BasicStateAsValue());
|
|
|
| - TRACE_COUNTER_ID1("cc",
|
| - "unused_memory_bytes",
|
| - this,
|
| + TRACE_COUNTER_ID1("cc", "unused_memory_bytes", this,
|
| resource_pool_->total_memory_usage_bytes() -
|
| resource_pool_->acquired_memory_usage_bytes());
|
| }
|
| @@ -522,7 +605,9 @@ bool TileManager::TilePriorityViolatesMemoryPolicy(
|
| }
|
|
|
| void TileManager::AssignGpuMemoryToTiles(
|
| - TileVector* tiles_that_need_to_be_rasterized) {
|
| + TileVector* tiles_that_need_to_be_rasterized,
|
| + size_t scheduled_raster_task_limit,
|
| + bool required_for_draw_only) {
|
| TRACE_EVENT_BEGIN0("cc", "TileManager::AssignGpuMemoryToTiles");
|
|
|
| // Maintain the list of released resources that can potentially be re-used
|
| @@ -546,24 +631,29 @@ void TileManager::AssignGpuMemoryToTiles(
|
| resource_pool_->acquired_resource_count());
|
|
|
| eviction_priority_queue_is_up_to_date_ = false;
|
| - client_->BuildRasterQueue(&raster_priority_queue_,
|
| - global_state_.tree_priority);
|
|
|
| while (!raster_priority_queue_.IsEmpty()) {
|
| Tile* tile = raster_priority_queue_.Top();
|
| +
|
| + if (required_for_draw_only) {
|
| + if (!tile->required_for_draw()) {
|
| + raster_priority_queue_.Pop();
|
| + continue;
|
| + }
|
| + }
|
| +
|
| TilePriority priority = tile->combined_priority();
|
|
|
| if (TilePriorityViolatesMemoryPolicy(priority)) {
|
| TRACE_EVENT_INSTANT0(
|
| - "cc",
|
| - "TileManager::AssignGpuMemory tile violates memory policy",
|
| + "cc", "TileManager::AssignGpuMemory tile violates memory policy",
|
| TRACE_EVENT_SCOPE_THREAD);
|
| break;
|
| }
|
|
|
| // We won't be able to schedule this tile, so break out early.
|
| if (tiles_that_need_to_be_rasterized->size() >=
|
| - scheduled_raster_task_limit_) {
|
| + scheduled_raster_task_limit) {
|
| all_tiles_that_need_to_be_rasterized_are_scheduled_ = false;
|
| break;
|
| }
|
| @@ -596,8 +686,7 @@ void TileManager::AssignGpuMemoryToTiles(
|
| bool memory_usage_is_within_limit =
|
| FreeTileResourcesWithLowerPriorityUntilUsageIsWithinLimit(
|
| tile_memory_limit - memory_required_by_tile_to_be_scheduled,
|
| - priority,
|
| - &memory_usage);
|
| + priority, &memory_usage);
|
|
|
| // If we couldn't fit the tile into our current memory limit, then we're
|
| // done.
|
| @@ -628,10 +717,7 @@ void TileManager::AssignGpuMemoryToTiles(
|
| memory_stats_from_last_assign_.had_enough_memory =
|
| had_enough_memory_to_schedule_tiles_needed_now;
|
|
|
| - raster_priority_queue_.Reset();
|
| -
|
| - TRACE_EVENT_END2("cc",
|
| - "TileManager::AssignGpuMemoryToTiles",
|
| + TRACE_EVENT_END2("cc", "TileManager::AssignGpuMemoryToTiles",
|
| "all_tiles_that_need_to_be_rasterized_are_scheduled",
|
| all_tiles_that_need_to_be_rasterized_are_scheduled_,
|
| "had_enough_memory_to_schedule_tiles_needed_now",
|
| @@ -783,6 +869,13 @@ void TileManager::OnImageDecodeTaskCompleted(int layer_id,
|
| pixel_ref_tasks.erase(task_it);
|
| }
|
|
|
| +void TileManager::CompleteRasterTask(
|
| + Tile::Id tile_id,
|
| + scoped_ptr<ScopedResource> resource,
|
| + const RasterSource::SolidColorAnalysis& analysis) {
|
| + OnRasterTaskCompleted(tile_id, resource.Pass(), analysis, false);
|
| +}
|
| +
|
| void TileManager::OnRasterTaskCompleted(
|
| Tile::Id tile_id,
|
| scoped_ptr<ScopedResource> resource,
|
| @@ -792,9 +885,10 @@ void TileManager::OnRasterTaskCompleted(
|
|
|
| Tile* tile = tiles_[tile_id];
|
| ManagedTileState& mts = tile->managed_state();
|
| - DCHECK(mts.raster_task.get());
|
| - orphan_raster_tasks_.push_back(mts.raster_task);
|
| - mts.raster_task = NULL;
|
| + if (mts.raster_task.get()) {
|
| + orphan_raster_tasks_.push_back(mts.raster_task);
|
| + mts.raster_task = NULL;
|
| + }
|
|
|
| if (was_canceled) {
|
| ++update_visible_tiles_stats_.canceled_count;
|
| @@ -866,6 +960,22 @@ bool TileManager::IsReadyToDraw() const {
|
| return true;
|
| }
|
|
|
| +void TileManager::NotifyReadyToActivate() {
|
| + TRACE_EVENT0("cc", "TileManager::NotifyReadyToActivate");
|
| + if (did_notify_ready_to_activate_)
|
| + return;
|
| + client_->NotifyReadyToActivate();
|
| + did_notify_ready_to_activate_ = true;
|
| +}
|
| +
|
| +void TileManager::NotifyReadyToDraw() {
|
| + TRACE_EVENT0("cc", "TileManager::NotifyReadyToDraw");
|
| + if (did_notify_ready_to_draw_)
|
| + return;
|
| + client_->NotifyReadyToDraw();
|
| + did_notify_ready_to_draw_ = true;
|
| +}
|
| +
|
| void TileManager::CheckIfReadyToActivate() {
|
| TRACE_EVENT0("cc", "TileManager::CheckIfReadyToActivate");
|
|
|
| @@ -877,8 +987,7 @@ void TileManager::CheckIfReadyToActivate() {
|
| if (!IsReadyToActivate())
|
| return;
|
|
|
| - client_->NotifyReadyToActivate();
|
| - did_notify_ready_to_activate_ = true;
|
| + NotifyReadyToActivate();
|
| }
|
|
|
| void TileManager::CheckIfReadyToDraw() {
|
| @@ -892,8 +1001,7 @@ void TileManager::CheckIfReadyToDraw() {
|
| if (!IsReadyToDraw())
|
| return;
|
|
|
| - client_->NotifyReadyToDraw();
|
| - did_notify_ready_to_draw_ = true;
|
| + NotifyReadyToDraw();
|
| }
|
|
|
| TileManager::MemoryUsage::MemoryUsage() : memory_bytes_(0), resource_count_(0) {
|
|
|