| Index: cc/resources/tile_manager.cc
|
| diff --git a/cc/resources/tile_manager.cc b/cc/resources/tile_manager.cc
|
| index 824dca9ee2388f6978afe5a3b4ff7970f6f2bc89..81ae8b5c9ee656486454580dacd4e726a8c1a9c7 100644
|
| --- a/cc/resources/tile_manager.cc
|
| +++ b/cc/resources/tile_manager.cc
|
| @@ -135,10 +135,8 @@ class RasterTaskImpl : public RasterTask {
|
| class ImageDecodeTaskImpl : public ImageDecodeTask {
|
| public:
|
| ImageDecodeTaskImpl(SkPixelRef* pixel_ref,
|
| - int layer_id,
|
| const base::Callback<void(bool was_canceled)>& reply)
|
| : pixel_ref_(skia::SharePtr(pixel_ref)),
|
| - layer_id_(layer_id),
|
| reply_(reply) {}
|
|
|
| // Overridden from Task:
|
| @@ -162,7 +160,6 @@ class ImageDecodeTaskImpl : public ImageDecodeTask {
|
|
|
| private:
|
| skia::RefPtr<SkPixelRef> pixel_ref_;
|
| - int layer_id_;
|
| const base::Callback<void(bool was_canceled)> reply_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(ImageDecodeTaskImpl);
|
| @@ -363,8 +360,12 @@ void TileManager::PrepareTiles(
|
| CleanUpReleasedTiles();
|
|
|
| TileVector tiles_that_need_to_be_rasterized;
|
| - AssignGpuMemoryToTiles(&tiles_that_need_to_be_rasterized,
|
| - scheduled_raster_task_limit_, false);
|
| + RasterTilePriorityQueue raster_priority_queue;
|
| + client_->BuildRasterQueue(&raster_priority_queue,
|
| + global_state_.tree_priority,
|
| + RasterTilePriorityQueue::Type::ALL);
|
| + AssignGpuMemoryToTiles(&raster_priority_queue, scheduled_raster_task_limit_,
|
| + &tiles_that_need_to_be_rasterized);
|
|
|
| // Schedule tile tasks.
|
| ScheduleTasks(tiles_that_need_to_be_rasterized);
|
| @@ -373,10 +374,15 @@ void TileManager::PrepareTiles(
|
| did_notify_ready_to_draw_ = false;
|
| } else {
|
| if (global_state_.hard_memory_limit_in_bytes == 0) {
|
| - TileVector tiles_that_need_to_be_rasterized;
|
| - AssignGpuMemoryToTiles(&tiles_that_need_to_be_rasterized,
|
| - scheduled_raster_task_limit_, false);
|
| - DCHECK(tiles_that_need_to_be_rasterized.empty());
|
| + // TODO(vmpstr): Add a function to unconditionally create an eviction
|
| + // queue and guard the rest of the calls sites with this flag, instead of
|
| + // clearing here and building, which is a bit awkward.
|
| + eviction_priority_queue_is_up_to_date_ = false;
|
| + resource_pool_->CheckBusyResources(false);
|
| + MemoryUsage memory_limit(0, 0);
|
| + MemoryUsage memory_usage(resource_pool_->acquired_memory_usage_bytes(),
|
| + resource_pool_->acquired_resource_count());
|
| + FreeTileResourcesUntilUsageIsWithinLimit(memory_limit, &memory_usage);
|
| }
|
|
|
| did_notify_ready_to_activate_ = false;
|
| @@ -405,9 +411,14 @@ void TileManager::SynchronouslyRasterizeTiles(
|
| FreeResourcesForReleasedTiles();
|
| CleanUpReleasedTiles();
|
|
|
| + RasterTilePriorityQueue required_for_draw_queue;
|
| + client_->BuildRasterQueue(&required_for_draw_queue,
|
| + global_state_.tree_priority,
|
| + RasterTilePriorityQueue::Type::REQUIRED_FOR_DRAW);
|
| TileVector tiles_that_need_to_be_rasterized;
|
| - AssignGpuMemoryToTiles(&tiles_that_need_to_be_rasterized,
|
| - std::numeric_limits<size_t>::max(), true);
|
| + AssignGpuMemoryToTiles(&required_for_draw_queue,
|
| + std::numeric_limits<size_t>::max(),
|
| + &tiles_that_need_to_be_rasterized);
|
|
|
| // We must reduce the amount of unused resources before calling
|
| // RunTasks to prevent usage from rising above limits.
|
| @@ -418,6 +429,23 @@ void TileManager::SynchronouslyRasterizeTiles(
|
| tiles_that_need_to_be_rasterized, resource_pool_,
|
| base::Bind(&TileManager::UpdateTileDrawInfo, base::Unretained(this)));
|
|
|
| + // Use on-demand raster for any required-for-draw tiles that have not been
|
| + // assigned memory after reaching a steady memory state.
|
| + // TODO(hendrikw): Figure out why this would improve jank on some tests - See
|
| + // crbug.com/449288
|
| + required_for_draw_queue.Reset();
|
| + client_->BuildRasterQueue(&required_for_draw_queue,
|
| + global_state_.tree_priority,
|
| + RasterTilePriorityQueue::Type::REQUIRED_FOR_DRAW);
|
| +
|
| + // Use on-demand raster for any tiles that have not been been assigned
|
| + // memory. This ensures that we draw even when OOM.
|
| + for (; !required_for_draw_queue.IsEmpty(); required_for_draw_queue.Pop()) {
|
| + Tile* tile = required_for_draw_queue.Top();
|
| + tile->draw_info().set_rasterize_on_demand();
|
| + client_->NotifyTileStateChanged(tile);
|
| + }
|
| +
|
| TRACE_EVENT_INSTANT1("cc", "DidRasterize", TRACE_EVENT_SCOPE_THREAD, "state",
|
| BasicStateAsValue());
|
|
|
| @@ -532,15 +560,14 @@ bool TileManager::TilePriorityViolatesMemoryPolicy(
|
| }
|
|
|
| void TileManager::AssignGpuMemoryToTiles(
|
| - TileVector* tiles_that_need_to_be_rasterized,
|
| + RasterTilePriorityQueue* raster_priority_queue,
|
| size_t scheduled_raster_task_limit,
|
| - bool required_for_draw_only) {
|
| + TileVector* tiles_that_need_to_be_rasterized) {
|
| TRACE_EVENT_BEGIN0("cc", "TileManager::AssignGpuMemoryToTiles");
|
|
|
| // Maintain the list of released resources that can potentially be re-used
|
| - // or deleted.
|
| - // If this operation becomes expensive too, only do this after some
|
| - // resource(s) was returned. Note that in that case, one also need to
|
| + // or deleted. If this operation becomes expensive too, only do this after
|
| + // some resource(s) was returned. Note that in that case, one also need to
|
| // invalidate when releasing some resource from the pool.
|
| resource_pool_->CheckBusyResources(false);
|
|
|
| @@ -558,23 +585,8 @@ void TileManager::AssignGpuMemoryToTiles(
|
| resource_pool_->acquired_resource_count());
|
|
|
| eviction_priority_queue_is_up_to_date_ = false;
|
| - // TODO(vmpstr): Take this as a parameter and have SynchronousRaster build a
|
| - // REQUIRED_FOR_DRAW queue.
|
| - client_->BuildRasterQueue(&raster_priority_queue_,
|
| - global_state_.tree_priority,
|
| - RasterTilePriorityQueue::Type::ALL);
|
| -
|
| - while (!raster_priority_queue_.IsEmpty()) {
|
| - Tile* tile = raster_priority_queue_.Top();
|
| -
|
| - // TODO(vmpstr): Remove this when the iterator returns the correct tiles
|
| - // to draw for GPU rasterization.
|
| - if (required_for_draw_only) {
|
| - if (!tile->required_for_draw()) {
|
| - raster_priority_queue_.Pop();
|
| - continue;
|
| - }
|
| - }
|
| + for (; !raster_priority_queue->IsEmpty(); raster_priority_queue->Pop()) {
|
| + Tile* tile = raster_priority_queue->Top();
|
| TilePriority priority = tile->combined_priority();
|
|
|
| if (TilePriorityViolatesMemoryPolicy(priority)) {
|
| @@ -603,7 +615,7 @@ void TileManager::AssignGpuMemoryToTiles(
|
| MemoryUsage memory_required_by_tile_to_be_scheduled;
|
| if (!tile->raster_task_.get()) {
|
| memory_required_by_tile_to_be_scheduled = MemoryUsage::FromConfig(
|
| - tile->desired_texture_size(), resource_pool_->resource_format());
|
| + tile->desired_texture_size(), resource_pool_->default_format());
|
| }
|
|
|
| bool tile_is_needed_now = priority.priority_bin == TilePriority::NOW;
|
| @@ -630,7 +642,6 @@ void TileManager::AssignGpuMemoryToTiles(
|
|
|
| memory_usage += memory_required_by_tile_to_be_scheduled;
|
| tiles_that_need_to_be_rasterized->push_back(tile);
|
| - raster_priority_queue_.Pop();
|
| }
|
|
|
| // Note that we should try and further reduce memory in case the above loop
|
| @@ -648,8 +659,6 @@ 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",
|
| "all_tiles_that_need_to_be_rasterized_are_scheduled",
|
| all_tiles_that_need_to_be_rasterized_are_scheduled_,
|
| @@ -728,7 +737,6 @@ scoped_refptr<ImageDecodeTask> TileManager::CreateImageDecodeTask(
|
| SkPixelRef* pixel_ref) {
|
| return make_scoped_refptr(new ImageDecodeTaskImpl(
|
| pixel_ref,
|
| - tile->layer_id(),
|
| base::Bind(&TileManager::OnImageDecodeTaskCompleted,
|
| base::Unretained(this),
|
| tile->layer_id(),
|
| @@ -737,7 +745,8 @@ scoped_refptr<ImageDecodeTask> TileManager::CreateImageDecodeTask(
|
|
|
| scoped_refptr<RasterTask> TileManager::CreateRasterTask(Tile* tile) {
|
| scoped_ptr<ScopedResource> resource =
|
| - resource_pool_->AcquireResource(tile->desired_texture_size());
|
| + resource_pool_->AcquireResource(tile->desired_texture_size(),
|
| + resource_pool_->default_format());
|
| const ScopedResource* const_resource = resource.get();
|
|
|
| // Create and queue all image decode tasks that this tile depends on.
|
| @@ -862,7 +871,7 @@ bool TileManager::IsReadyToActivate() const {
|
| const std::vector<PictureLayerImpl*>& layers = client_->GetPictureLayers();
|
|
|
| // TODO(vmpstr): Replace this with building a REQUIRED_TO_ACTIVATE raster
|
| - // queue and checking if it's empty.
|
| + // queue and checking if the tiles it contains are all ready to draw.
|
| for (const auto& layer : layers) {
|
| if (!layer->AllTilesRequiredForActivationAreReadyToDraw())
|
| return false;
|
| @@ -875,7 +884,7 @@ bool TileManager::IsReadyToDraw() const {
|
| const std::vector<PictureLayerImpl*>& layers = client_->GetPictureLayers();
|
|
|
| // TODO(vmpstr): Replace this with building a REQUIRED_TO_DRAW raster queue
|
| - // and checking if it's empty.
|
| + // and checking if the tiles it contains are all ready to draw.
|
| for (const auto& layer : layers) {
|
| if (!layer->AllTilesRequiredForDrawAreReadyToDraw())
|
| return false;
|
| @@ -935,8 +944,11 @@ void TileManager::CheckIfMoreTilesNeedToBePrepared() {
|
| // When OOM, keep re-assigning memory until we reach a steady state
|
| // where top-priority tiles are initialized.
|
| TileVector tiles_that_need_to_be_rasterized;
|
| - AssignGpuMemoryToTiles(&tiles_that_need_to_be_rasterized,
|
| - scheduled_raster_task_limit_, false);
|
| + RasterTilePriorityQueue raster_priority_queue;
|
| + client_->BuildRasterQueue(&raster_priority_queue, global_state_.tree_priority,
|
| + RasterTilePriorityQueue::Type::ALL);
|
| + AssignGpuMemoryToTiles(&raster_priority_queue, scheduled_raster_task_limit_,
|
| + &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.
|
| @@ -961,36 +973,30 @@ void TileManager::CheckIfMoreTilesNeedToBePrepared() {
|
|
|
| // 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.
|
| - // TODO(vmpstr): Make this use REQUIRED_FOR_ACTIVAITON queue.
|
| - client_->BuildRasterQueue(&raster_priority_queue_,
|
| - global_state_.tree_priority,
|
| - RasterTilePriorityQueue::Type::ALL);
|
| - bool ready_to_activate = true;
|
| - while (!raster_priority_queue_.IsEmpty()) {
|
| - Tile* tile = raster_priority_queue_.Top();
|
| - TileDrawInfo& draw_info = tile->draw_info();
|
| -
|
| - if (tile->required_for_activation() && !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;
|
| - }
|
| + // ensures that we activate even when OOM. Note that we can't reuse the queue
|
| + // we used for AssignGpuMemoryToTiles, since the AssignGpuMemoryToTiles call
|
| + // could have evicted some tiles that would not be picked up by the old raster
|
| + // queue.
|
| + RasterTilePriorityQueue required_for_activation_queue;
|
| + client_->BuildRasterQueue(
|
| + &required_for_activation_queue, global_state_.tree_priority,
|
| + RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION);
|
| +
|
| + // If we have tiles to mark as rasterize on demand, but we don't allow
|
| + // rasterize on demand, then skip activation and return early.
|
| + if (!required_for_activation_queue.IsEmpty() && !allow_rasterize_on_demand)
|
| + return;
|
|
|
| - draw_info.set_rasterize_on_demand();
|
| - client_->NotifyTileStateChanged(tile);
|
| - }
|
| - raster_priority_queue_.Pop();
|
| + // Mark required tiles as rasterize on demand.
|
| + for (; !required_for_activation_queue.IsEmpty();
|
| + required_for_activation_queue.Pop()) {
|
| + Tile* tile = required_for_activation_queue.Top();
|
| + tile->draw_info().set_rasterize_on_demand();
|
| + client_->NotifyTileStateChanged(tile);
|
| }
|
|
|
| - if (ready_to_activate) {
|
| - DCHECK(IsReadyToActivate());
|
| - ready_to_activate_check_notifier_.Schedule();
|
| - }
|
| - raster_priority_queue_.Reset();
|
| + DCHECK(IsReadyToActivate());
|
| + ready_to_activate_check_notifier_.Schedule();
|
| }
|
|
|
| TileManager::MemoryUsage::MemoryUsage() : memory_bytes_(0), resource_count_(0) {
|
|
|