Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1262)

Unified Diff: cc/tiles/tile_manager.cc

Issue 2007163002: cc: Separate raster and decode prepaint regions. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « cc/tiles/tile_manager.h ('k') | cc/trees/layer_tree_host_impl.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cc/tiles/tile_manager.cc
diff --git a/cc/tiles/tile_manager.cc b/cc/tiles/tile_manager.cc
index 27a709fb9c3cf34ee30067fab94acdf61ecc1a5a..aab3047b3343be0aa2a889f2258d490f2dae0a54 100644
--- a/cc/tiles/tile_manager.cc
+++ b/cc/tiles/tile_manager.cc
@@ -307,7 +307,8 @@ RasterTaskCompletionStatsAsValue(const RasterTaskCompletionStats& stats) {
TileManager::TileManager(TileManagerClient* client,
base::SequencedTaskRunner* task_runner,
size_t scheduled_raster_task_limit,
- bool use_partial_raster)
+ bool use_partial_raster,
+ int max_preraster_distance_in_screen_pixels)
: client_(client),
task_runner_(task_runner),
resource_pool_(nullptr),
@@ -328,6 +329,8 @@ TileManager::TileManager(TileManagerClient* client,
has_scheduled_tile_tasks_(false),
prepare_tiles_count_(0u),
next_tile_id_(0u),
+ max_preraster_distance_in_screen_pixels_(
+ max_preraster_distance_in_screen_pixels),
task_set_finished_weak_ptr_factory_(this) {}
TileManager::~TileManager() {
@@ -358,6 +361,10 @@ void TileManager::FinishTasksAndCleanUp() {
more_tiles_need_prepare_check_notifier_.Cancel();
signals_check_notifier_.Cancel();
task_set_finished_weak_ptr_factory_.InvalidateWeakPtrs();
+
+ for (auto& draw_image_pair : locked_images_)
+ image_decode_controller_->UnrefImage(draw_image_pair.first);
+ locked_images_.clear();
}
void TileManager::SetResources(ResourcePool* resource_pool,
@@ -468,17 +475,16 @@ bool TileManager::PrepareTiles(
FreeResourcesForReleasedTiles();
CleanUpReleasedTiles();
- std::vector<PrioritizedTile> tiles_that_need_to_be_rasterized =
- AssignGpuMemoryToTiles();
+ PrioritizedWorkToSchedule prioritized_work = AssignGpuMemoryToTiles();
// Inform the client that will likely require a draw if the highest priority
// tile that will be rasterized is required for draw.
client_->SetIsLikelyToRequireADraw(
- !tiles_that_need_to_be_rasterized.empty() &&
- tiles_that_need_to_be_rasterized.front().tile()->required_for_draw());
+ !prioritized_work.tiles_to_raster.empty() &&
+ prioritized_work.tiles_to_raster.front().tile()->required_for_draw());
// Schedule tile tasks.
- ScheduleTasks(tiles_that_need_to_be_rasterized);
+ ScheduleTasks(prioritized_work);
TRACE_EVENT_INSTANT1("cc", "DidPrepareTiles", TRACE_EVENT_SCOPE_THREAD,
"state", BasicStateAsValue());
@@ -582,7 +588,7 @@ bool TileManager::TilePriorityViolatesMemoryPolicy(
return true;
}
-std::vector<PrioritizedTile> TileManager::AssignGpuMemoryToTiles() {
+TileManager::PrioritizedWorkToSchedule TileManager::AssignGpuMemoryToTiles() {
TRACE_EVENT_BEGIN0("cc", "TileManager::AssignGpuMemoryToTiles");
DCHECK(resource_pool_);
@@ -611,7 +617,7 @@ std::vector<PrioritizedTile> TileManager::AssignGpuMemoryToTiles() {
client_->BuildRasterQueue(global_state_.tree_priority,
RasterTilePriorityQueue::Type::ALL));
std::unique_ptr<EvictionTilePriorityQueue> eviction_priority_queue;
- std::vector<PrioritizedTile> tiles_that_need_to_be_rasterized;
+ PrioritizedWorkToSchedule work_to_schedule;
for (; !raster_priority_queue->IsEmpty(); raster_priority_queue->Pop()) {
const PrioritizedTile& prioritized_tile = raster_priority_queue->Top();
Tile* tile = prioritized_tile.tile();
@@ -644,8 +650,16 @@ std::vector<PrioritizedTile> TileManager::AssignGpuMemoryToTiles() {
}
}
+ // Prepaint tiles that are far away are only processed for images.
+ if (!tile->required_for_activation() && !tile->required_for_draw() &&
+ priority.distance_to_visible >
+ max_preraster_distance_in_screen_pixels_) {
+ work_to_schedule.tiles_to_process_for_images.push_back(prioritized_tile);
+ continue;
+ }
+
// We won't be able to schedule this tile, so break out early.
- if (tiles_that_need_to_be_rasterized.size() >=
+ if (work_to_schedule.tiles_to_raster.size() >=
scheduled_raster_task_limit_) {
all_tiles_that_need_to_be_rasterized_are_scheduled_ = false;
break;
@@ -690,7 +704,7 @@ std::vector<PrioritizedTile> TileManager::AssignGpuMemoryToTiles() {
}
memory_usage += memory_required_by_tile_to_be_scheduled;
- tiles_that_need_to_be_rasterized.push_back(prioritized_tile);
+ work_to_schedule.tiles_to_raster.push_back(prioritized_tile);
// Since we scheduled the tile, set whether it was a prepaint or not
// assuming that the tile will successfully finish running. We don't have
@@ -722,7 +736,7 @@ std::vector<PrioritizedTile> TileManager::AssignGpuMemoryToTiles() {
all_tiles_that_need_to_be_rasterized_are_scheduled_,
"had_enough_memory_to_schedule_tiles_needed_now",
had_enough_memory_to_schedule_tiles_needed_now);
- return tiles_that_need_to_be_rasterized;
+ return work_to_schedule;
}
void TileManager::FreeResourcesForTile(Tile* tile) {
@@ -742,7 +756,9 @@ void TileManager::FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(
}
void TileManager::ScheduleTasks(
- const std::vector<PrioritizedTile>& tiles_that_need_to_be_rasterized) {
+ const PrioritizedWorkToSchedule& work_to_schedule) {
+ const std::vector<PrioritizedTile>& tiles_that_need_to_be_rasterized =
+ work_to_schedule.tiles_to_raster;
TRACE_EVENT1("cc", "TileManager::ScheduleTasks", "count",
tiles_that_need_to_be_rasterized.size());
@@ -816,6 +832,52 @@ void TileManager::ScheduleTasks(
use_foreground_category);
}
+ const std::vector<PrioritizedTile>& tiles_to_process_for_images =
+ work_to_schedule.tiles_to_process_for_images;
+ std::vector<std::pair<DrawImage, scoped_refptr<TileTask>>> new_locked_images;
+ for (const PrioritizedTile& prioritized_tile : tiles_to_process_for_images) {
+ Tile* tile = prioritized_tile.tile();
+
+ std::vector<DrawImage> images;
+ prioritized_tile.raster_source()->GetDiscardableImagesInRect(
+ tile->enclosing_layer_rect(), tile->contents_scale(), &images);
+ ImageDecodeController::TracingInfo tracing_info(
+ prepare_tiles_count_, prioritized_tile.priority().priority_bin);
+ for (DrawImage& draw_image : images) {
+ scoped_refptr<TileTask> task;
+ bool need_to_unref_when_finished =
+ image_decode_controller_->GetTaskForImageAndRef(draw_image,
+ tracing_info, &task);
+ // We only care about images that need to be locked (ie they need to be
+ // unreffed later).
+ if (!need_to_unref_when_finished)
+ continue;
+ new_locked_images.emplace_back(draw_image, task);
+
+ // If there's no actual task associated with this image, then we're done.
+ if (!task)
+ continue;
+
+ auto decode_it = std::find_if(graph_.nodes.begin(), graph_.nodes.end(),
+ [&task](const TaskGraph::Node& node) {
+ return node.task == task.get();
+ });
+ // If this task is already in the graph, then we don't have to insert it.
+ if (decode_it != graph_.nodes.end())
+ continue;
+
+ InsertNodeForDecodeTask(&graph_, task.get(), false, priority++);
+ all_count++;
+ graph_.edges.push_back(TaskGraph::Edge(task.get(), all_done_task.get()));
+ }
+ }
+
+ for (auto& draw_image_pair : locked_images_)
+ image_decode_controller_->UnrefImage(draw_image_pair.first);
+ // The old locked images have to stay around until past the ScheduleTasks call
+ // below, so we do a swap instead of a move.
+ locked_images_.swap(new_locked_images);
+
// Insert nodes for our task completion tasks. We enqueue these using
// NONCONCURRENT_FOREGROUND category this is the highest prioirty category and
// we'd like to run these tasks as soon as possible.
@@ -1069,22 +1131,29 @@ void TileManager::CheckIfMoreTilesNeedToBePrepared() {
// When OOM, keep re-assigning memory until we reach a steady state
// where top-priority tiles are initialized.
- std::vector<PrioritizedTile> tiles_that_need_to_be_rasterized =
- AssignGpuMemoryToTiles();
+ PrioritizedWorkToSchedule work_to_schedule = AssignGpuMemoryToTiles();
// Inform the client that will likely require a draw if the highest priority
// tile that will be rasterized is required for draw.
client_->SetIsLikelyToRequireADraw(
- !tiles_that_need_to_be_rasterized.empty() &&
- tiles_that_need_to_be_rasterized.front().tile()->required_for_draw());
+ !work_to_schedule.tiles_to_raster.empty() &&
+ work_to_schedule.tiles_to_raster.front().tile()->required_for_draw());
// |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);
+ if (!work_to_schedule.tiles_to_raster.empty()) {
+ ScheduleTasks(work_to_schedule);
return;
}
+ // If we're not in SMOOTHNESS_TAKES_PRIORITY mode, we should unlock all
+ // images since we're technically going idle here at least for this frame.
+ if (global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY) {
+ for (auto& draw_image_pair : locked_images_)
+ image_decode_controller_->UnrefImage(draw_image_pair.first);
+ locked_images_.clear();
+ }
+
FreeResourcesForReleasedTiles();
resource_pool_->ReduceResourceUsage();
@@ -1253,4 +1322,9 @@ void TileManager::Signals::reset() {
did_notify_all_tile_tasks_completed = false;
}
+TileManager::PrioritizedWorkToSchedule::PrioritizedWorkToSchedule() = default;
+TileManager::PrioritizedWorkToSchedule::PrioritizedWorkToSchedule(
+ PrioritizedWorkToSchedule&& other) = default;
+TileManager::PrioritizedWorkToSchedule::~PrioritizedWorkToSchedule() = default;
+
} // namespace cc
« no previous file with comments | « cc/tiles/tile_manager.h ('k') | cc/trees/layer_tree_host_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698