Chromium Code Reviews| Index: cc/tiles/tile_manager.cc |
| diff --git a/cc/tiles/tile_manager.cc b/cc/tiles/tile_manager.cc |
| index 9916918d96ce14d636b40f0b846acd4fa3b8f952..cf430fc5a44aced0fdd071708f6ff05980ef9a10 100644 |
| --- a/cc/tiles/tile_manager.cc |
| +++ b/cc/tiles/tile_manager.cc |
| @@ -643,6 +643,7 @@ TileManager::PrioritizedWorkToSchedule TileManager::AssignGpuMemoryToTiles() { |
| RasterTilePriorityQueue::Type::ALL)); |
| std::unique_ptr<EvictionTilePriorityQueue> eviction_priority_queue; |
| PrioritizedWorkToSchedule work_to_schedule; |
| + CheckerImageTracker::ImageDecodeQueue checker_image_decode_queue; |
| for (; !raster_priority_queue->IsEmpty(); raster_priority_queue->Pop()) { |
| const PrioritizedTile& prioritized_tile = raster_priority_queue->Top(); |
| Tile* tile = prioritized_tile.tile(); |
| @@ -681,6 +682,20 @@ TileManager::PrioritizedWorkToSchedule TileManager::AssignGpuMemoryToTiles() { |
| continue; |
| } |
| + // Tiles in the raster queue should either require raster or decode for |
| + // checker-images. If this tile does not need raster, process it only to |
| + // build the decode queue for checkered images. |
|
vmpstr
2017/03/29 19:11:45
Add a comment saying that this block must come aft
Khushal
2017/03/31 04:31:00
Done.
|
| + if (!tile->draw_info().NeedsRaster()) { |
| + DCHECK(tile->draw_info().is_checker_imaged()); |
| + std::vector<DrawImage> images_in_tile; |
| + prioritized_tile.raster_source()->GetDiscardableImagesInRect( |
| + tile->enclosing_layer_rect(), tile->contents_scale(), |
| + &images_in_tile); |
| + FilterImagesForCheckering(tile->tiling()->tree(), images_in_tile, nullptr, |
| + nullptr, &checker_image_decode_queue); |
| + continue; |
| + } |
| + |
| // We won't be able to schedule this tile, so break out early. |
| if (work_to_schedule.tiles_to_raster.size() >= |
| scheduled_raster_task_limit_) { |
| @@ -727,6 +742,26 @@ TileManager::PrioritizedWorkToSchedule TileManager::AssignGpuMemoryToTiles() { |
| } |
| memory_usage += memory_required_by_tile_to_be_scheduled; |
| + |
| + // If the tile has a scheduled task that will rasterize a resource with |
| + // checker-imaged content, add those images to the decode queue. Note that |
| + // we add all images as we process the raster priority queue to ensure that |
| + // images are added to the decode queue in raster priority order. |
| + if (tile->raster_task_scheduled_with_checker_images()) { |
|
vmpstr
2017/03/29 19:11:45
Maybe flip the if and the dcheck? If, if tile has
Khushal
2017/03/29 22:10:20
Not sure I followed, at this point the tile should
|
| + DCHECK(tile->HasRasterTask()); |
| + std::vector<DrawImage> images_in_tile; |
| + prioritized_tile.raster_source()->GetDiscardableImagesInRect( |
|
vmpstr
2017/03/29 19:11:46
This isn't really a trivial operation, is there an
Khushal
2017/03/29 22:10:20
I was thinking about it. Is there a reason for not
Khushal
2017/03/31 04:31:00
Cached this on Tile. I didn't realize that |schedu
|
| + tile->enclosing_layer_rect(), tile->contents_scale(), |
| + &images_in_tile); |
| + FilterImagesForCheckering(tile->tiling()->tree(), images_in_tile, nullptr, |
| + nullptr, &checker_image_decode_queue); |
| + } else if (!tile->HasRasterTask()) { |
| + // Creating the raster task here will acquire resources, but |
| + // this resource usage has already been accounted for above. |
| + tile->raster_task_ = |
| + CreateRasterTask(prioritized_tile, client_->GetRasterColorSpace(), |
|
vmpstr
2017/03/29 19:11:46
It's a bit unfortunate that we're doing this here
Khushal
2017/03/31 04:31:01
Done.
|
| + &checker_image_decode_queue); |
| + } |
| work_to_schedule.tiles_to_raster.push_back(prioritized_tile); |
| } |
| @@ -736,6 +771,30 @@ TileManager::PrioritizedWorkToSchedule TileManager::AssignGpuMemoryToTiles() { |
| eviction_priority_queue = FreeTileResourcesUntilUsageIsWithinLimit( |
|
vmpstr
2017/03/29 19:11:46
What happens if eviction evicts tiles that are bei
Khushal
2017/03/29 22:10:20
The eviction here shouldn't remove resources from
|
| std::move(eviction_priority_queue), hard_memory_limit, &memory_usage); |
| + // At this point if we still have a tile that is holding onto a resource with |
| + // checker-imaged content, add it to the decode queue to ensure that the |
| + // resource is eventually invalidated. |
| + while (!raster_priority_queue->IsEmpty()) { |
|
vmpstr
2017/03/29 19:11:46
You can't do this here. This part defeats the poin
Khushal
2017/03/29 22:10:20
Sorry, I had missed looking at the implementation
|
| + const PrioritizedTile& prioritized_tile = raster_priority_queue->Top(); |
| + Tile* tile = prioritized_tile.tile(); |
| + if (tile->draw_info().is_checker_imaged() || |
| + tile->raster_task_scheduled_with_checker_images()) { |
| + std::vector<DrawImage> images_in_tile; |
| + prioritized_tile.raster_source()->GetDiscardableImagesInRect( |
| + tile->enclosing_layer_rect(), tile->contents_scale(), |
| + &images_in_tile); |
| + FilterImagesForCheckering(tile->tiling()->tree(), images_in_tile, nullptr, |
| + nullptr, &checker_image_decode_queue); |
| + } |
| + raster_priority_queue->Pop(); |
| + } |
| + |
| + // Schedule running of the checker-image decode queue. This replaces the |
| + // previously scheduled queue and effectively cancels image decodes from the |
| + // previously scheduled queue, if not already started. |
| + checker_image_tracker_.ScheduleImageDecodeQueue( |
|
vmpstr
2017/03/29 19:11:46
Can you move this call out of this function and do
Khushal
2017/03/31 04:31:00
Moved it to ScheduleTasks.
|
| + std::move(checker_image_decode_queue)); |
| + |
| UMA_HISTOGRAM_BOOLEAN("TileManager.ExceededMemoryBudget", |
| !had_enough_memory_to_schedule_tiles_needed_now); |
| did_oom_on_last_assign_ = !had_enough_memory_to_schedule_tiles_needed_now; |
| @@ -772,6 +831,28 @@ void TileManager::FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw( |
| client_->NotifyTileStateChanged(tile); |
| } |
| +void TileManager::FilterImagesForCheckering( |
| + WhichTree tree, |
| + const std::vector<DrawImage>& images_in_tile, |
| + std::vector<DrawImage>* images_to_decode_for_raster, |
| + ImageIdFlatSet* checkered_images, |
| + CheckerImageTracker::ImageDecodeQueue* image_decode_queue) { |
| + DCHECK(!images_to_decode_for_raster || images_to_decode_for_raster->empty()); |
|
vmpstr
2017/03/29 19:11:46
It's not clear to me why some of the output parame
Khushal
2017/03/29 22:10:20
I think computing it once and storing it on tile s
Khushal
2017/03/31 04:31:00
Done.
|
| + DCHECK(!checkered_images || checkered_images->empty()); |
| + |
| + for (const auto& draw_image : images_in_tile) { |
| + const sk_sp<const SkImage>& image = draw_image.image(); |
| + DCHECK(image->isLazyGenerated()); |
| + if (checker_image_tracker_.ShouldCheckerImage(image, tree)) { |
| + if (checkered_images) |
| + checkered_images->insert(image->uniqueID()); |
|
vmpstr
2017/03/29 19:11:46
Here you're adding the image to both the vector an
Khushal
2017/03/31 04:31:00
Function died.
|
| + image_decode_queue->push_back(std::move(image)); |
| + } else if (images_to_decode_for_raster) { |
| + images_to_decode_for_raster->push_back(draw_image); |
|
vmpstr
2017/03/29 19:11:45
image to decode for raster is not a clear name. I
Khushal
2017/03/31 04:31:00
Function died.
|
| + } |
| + } |
| +} |
| + |
| void TileManager::ScheduleTasks( |
| const PrioritizedWorkToSchedule& work_to_schedule) { |
| const std::vector<PrioritizedTile>& tiles_that_need_to_be_rasterized = |
| @@ -820,11 +901,7 @@ void TileManager::ScheduleTasks( |
| DCHECK(tile->draw_info().requires_resource()); |
| DCHECK(!tile->draw_info().resource()); |
| - |
| - if (!tile->raster_task_) { |
| - tile->raster_task_ = |
| - CreateRasterTask(prioritized_tile, raster_color_space); |
| - } |
| + DCHECK(tile->HasRasterTask()); |
|
vmpstr
2017/03/29 19:11:46
comment why this is true now.
Khushal
2017/03/31 04:31:00
Done.
|
| TileTask* task = tile->raster_task_.get(); |
| @@ -933,7 +1010,8 @@ void TileManager::ScheduleTasks( |
| scoped_refptr<TileTask> TileManager::CreateRasterTask( |
| const PrioritizedTile& prioritized_tile, |
| - const gfx::ColorSpace& color_space) { |
| + const gfx::ColorSpace& color_space, |
| + CheckerImageTracker::ImageDecodeQueue* checker_image_decode_queue) { |
| Tile* tile = prioritized_tile.tile(); |
| // Get the resource. |
| @@ -962,27 +1040,31 @@ scoped_refptr<TileTask> TileManager::CreateRasterTask( |
| // Create and queue all image decode tasks that this tile depends on. |
| TileTask::Vector decode_tasks; |
| - std::vector<DrawImage>& images = scheduled_draw_images_[tile->id()]; |
| - ImageIdFlatSet images_to_skip; |
| - images.clear(); |
| + std::vector<DrawImage>& images_to_decode_for_raster = |
| + scheduled_draw_images_[tile->id()]; |
| + images_to_decode_for_raster.clear(); |
| if (!playback_settings.skip_images) { |
| + std::vector<DrawImage> images_in_tile; |
| prioritized_tile.raster_source()->GetDiscardableImagesInRect( |
|
vmpstr
2017/03/29 19:11:46
The pattern of these two calls appears throughout.
Khushal
2017/03/31 04:31:00
Happens only once now. Moved to EnsureImageAnalysi
|
| - tile->enclosing_layer_rect(), tile->contents_scale(), &images); |
| - checker_image_tracker_.FilterImagesForCheckeringForTile( |
| - &images, &images_to_skip, prioritized_tile.tile()->tiling()->tree()); |
| + tile->enclosing_layer_rect(), tile->contents_scale(), &images_in_tile); |
| + FilterImagesForCheckering( |
| + tile->tiling()->tree(), images_in_tile, &images_to_decode_for_raster, |
| + &playback_settings.images_to_skip, checker_image_decode_queue); |
| } |
| // We can skip the image hijack canvas if we have no images, or no images to |
| // skip during raster. |
| playback_settings.use_image_hijack_canvas = |
| - !images.empty() || !images_to_skip.empty(); |
| - playback_settings.images_to_skip = std::move(images_to_skip); |
| + !images_to_decode_for_raster.empty() || |
| + !playback_settings.images_to_skip.empty(); |
| + tile->raster_task_scheduled_with_checker_images_ = |
| + !playback_settings.images_to_skip.empty(); |
| // Get the tasks for the required images. |
| ImageDecodeCache::TracingInfo tracing_info( |
| prepare_tiles_count_, prioritized_tile.priority().priority_bin); |
| - image_controller_.GetTasksForImagesAndRef(&images, &decode_tasks, |
| - tracing_info); |
| + image_controller_.GetTasksForImagesAndRef(&images_to_decode_for_raster, |
| + &decode_tasks, tracing_info); |
| std::unique_ptr<RasterBuffer> raster_buffer = |
| raster_buffer_provider_->AcquireBufferForRaster( |
| @@ -1007,10 +1089,14 @@ void TileManager::OnRasterTaskCompleted( |
| auto found = tiles_.find(tile_id); |
| Tile* tile = nullptr; |
| + bool raster_task_scheduled_with_checker_images = false; |
| if (found != tiles_.end()) { |
| tile = found->second; |
| DCHECK(tile->raster_task_.get()); |
| + raster_task_scheduled_with_checker_images = |
|
vmpstr
2017/03/29 19:11:46
just make the setter return the old value
Khushal
2017/03/31 04:31:00
Done.
|
| + tile->raster_task_scheduled_with_checker_images_; |
| tile->raster_task_ = nullptr; |
| + tile->raster_task_scheduled_with_checker_images_ = false; |
| } |
| // Unref all the images. |
| @@ -1034,6 +1120,8 @@ void TileManager::OnRasterTaskCompleted( |
| TileDrawInfo& draw_info = tile->draw_info(); |
| draw_info.set_resource(resource); |
| + draw_info.resource_is_checker_imaged_ = |
| + raster_task_scheduled_with_checker_images; |
| draw_info.contents_swizzled_ = DetermineResourceRequiresSwizzle(tile); |
| // In SMOOTHNESS_TAKES_PRIORITY mode, we wait for GPU work to complete for a |