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

Unified Diff: cc/tiles/tile_manager.cc

Issue 2440093003: WIP GPU scheduler + delayed activation / tile draw
Patch Set: SignalSyncToken -> IsFenceSyncReleased Created 4 years 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') | content/browser/compositor/gpu_process_transport_factory.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 08796a32f949f1064dec57a5b0a9883a89e990ab..51ba8142d08472a0e5d7655a8447c200e8ca6995 100644
--- a/cc/tiles/tile_manager.cc
+++ b/cc/tiles/tile_manager.cc
@@ -366,7 +366,8 @@ TileManager::TileManager(TileManagerClient* client,
has_scheduled_tile_tasks_(false),
prepare_tiles_count_(0u),
next_tile_id_(0u),
- task_set_finished_weak_ptr_factory_(this) {}
+ task_set_finished_weak_ptr_factory_(this),
+ weak_ptr_factory_(this) {}
TileManager::~TileManager() {
FinishTasksAndCleanUp();
@@ -449,6 +450,7 @@ void TileManager::DidFinishRunningTileTasksRequiredForActivation() {
ScheduledTasksStateAsValue());
// TODO(vmpstr): Temporary check to debug crbug.com/642927.
CHECK(tile_task_manager_);
+
signals_.ready_to_activate = true;
signals_check_notifier_.Schedule();
}
@@ -459,6 +461,7 @@ void TileManager::DidFinishRunningTileTasksRequiredForDraw() {
ScheduledTasksStateAsValue());
// TODO(vmpstr): Temporary check to debug crbug.com/642927.
CHECK(tile_task_manager_);
+
signals_.ready_to_draw = true;
signals_check_notifier_.Schedule();
}
@@ -539,6 +542,9 @@ void TileManager::Flush() {
tile_task_manager_->CheckForCompletedTasks();
did_check_for_completed_tasks_since_last_schedule_tasks_ = true;
+ CheckRequiredForActivationTilesReadyToDraw();
+ CheckRequiredForDrawTilesReadyToDraw();
+
TRACE_EVENT_INSTANT1("cc", "DidFlush", TRACE_EVENT_SCOPE_THREAD, "stats",
RasterTaskCompletionStatsAsValue(flush_stats_));
flush_stats_ = RasterTaskCompletionStats();
@@ -650,6 +656,9 @@ TileManager::PrioritizedWorkToSchedule TileManager::AssignGpuMemoryToTiles() {
MemoryUsage memory_usage(resource_pool_->memory_usage_bytes(),
resource_pool_->resource_count());
+ pending_required_for_activation_tiles_.clear();
+ pending_required_for_draw_tiles_.clear();
+
std::unique_ptr<RasterTilePriorityQueue> raster_priority_queue(
client_->BuildRasterQueue(global_state_.tree_priority,
RasterTilePriorityQueue::Type::ALL));
@@ -696,6 +705,20 @@ TileManager::PrioritizedWorkToSchedule TileManager::AssignGpuMemoryToTiles() {
continue;
}
+ if (tile->required_for_activation())
+ pending_required_for_activation_tiles_.push_back(tile);
+
+ if (tile->required_for_draw())
+ pending_required_for_draw_tiles_.push_back(tile);
+
+ // If tile already has a resource then its raster task has completed but
+ // we're still waiting on raster to complete on the service side.
+ // TODO(sunnyps): Mark such tiles as ready to draw if not in smoothness
+ // takes priority mode.
+ if (tile->draw_info().has_resource()) {
+ 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_) {
@@ -712,7 +735,7 @@ TileManager::PrioritizedWorkToSchedule TileManager::AssignGpuMemoryToTiles() {
// already accounted for in memory_usage. Otherwise, we'll have to acquire
// more memory to create a raster task.
MemoryUsage memory_required_by_tile_to_be_scheduled;
- if (!tile->raster_task_.get()) {
+ if (!tile->raster_task_) {
memory_required_by_tile_to_be_scheduled = MemoryUsage::FromConfig(
tile->desired_texture_size(), DetermineResourceFormat(tile));
}
@@ -774,14 +797,16 @@ TileManager::PrioritizedWorkToSchedule 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 work_to_schedule;
}
void TileManager::FreeResourcesForTile(Tile* tile) {
TileDrawInfo& draw_info = tile->draw_info();
- if (draw_info.resource_) {
- resource_pool_->ReleaseResource(draw_info.resource_);
- draw_info.resource_ = nullptr;
+ if (draw_info.has_resource()) {
+ resource_pool_->ReleaseResource(draw_info.resource());
+ draw_info.set_resource(nullptr);
+ draw_info.set_ready_to_draw(false);
}
}
@@ -976,6 +1001,9 @@ scoped_refptr<TileTask> TileManager::CreateRasterTask(
color_space);
}
+ tile->draw_info().set_use_resource();
+ DCHECK(!tile->draw_info().IsReadyToDraw());
+
// For LOW_RESOLUTION tiles, we don't draw or predecode images.
RasterSource::PlaybackSettings playback_settings;
playback_settings.skip_images =
@@ -1016,11 +1044,14 @@ void TileManager::OnRasterTaskCompleted(
bool was_canceled) {
DCHECK(tile);
DCHECK(tiles_.find(tile->id()) != tiles_.end());
+
+ TRACE_EVENT1("cc", "TileManager::OnRasterTaskCompleted", "tile_id",
+ tile->id());
+
raster_buffer_provider_->ReleaseBufferForRaster(std::move(raster_buffer));
- TileDrawInfo& draw_info = tile->draw_info();
- DCHECK(tile->raster_task_.get());
- tile->raster_task_ = nullptr;
+ DCHECK(tile->raster_task_);
+ orphan_tasks_.push_back(std::move(tile->raster_task_));
// Unref all the images.
auto images_it = scheduled_draw_images_.find(tile->id());
@@ -1036,11 +1067,84 @@ void TileManager::OnRasterTaskCompleted(
resource_pool_->OnContentReplaced(resource->id(), tile->id());
++flush_stats_.completed_count;
- draw_info.set_use_resource();
- draw_info.resource_ = resource;
- draw_info.contents_swizzled_ = DetermineResourceRequiresSwizzle(tile);
+ TileDrawInfo& draw_info = tile->draw_info();
+ draw_info.set_resource(resource);
+ draw_info.set_contents_swizzled(DetermineResourceRequiresSwizzle(tile));
+}
+
+void TileManager::OnRequiredForActivationTilesReadyToDraw() {
+ signals_.ready_to_activate = true;
+ signals_check_notifier_.Schedule();
+}
+
+void TileManager::OnRequiredForDrawTilesReadyToDraw() {
+ signals_.ready_to_draw = true;
+ signals_check_notifier_.Schedule();
+}
+
+void TileManager::CheckRequiredForActivationTilesReadyToDraw() {
+ std::vector<Tile*> pending_tiles;
+ for (Tile* tile : pending_required_for_activation_tiles_) {
+ const Resource* resource = tile->draw_info().resource();
+ if (resource && raster_buffer_provider_->IsResourceReadyToDraw(resource)) {
+ OnTileReadyToDraw(tile);
+ } else {
+ pending_tiles.push_back(tile);
+ }
+ }
+ pending_required_for_activation_tiles_.swap(pending_tiles);
+
+ std::vector<const Resource*> resources;
+ for (Tile* tile : pending_required_for_activation_tiles_) {
+ const Resource* resource = tile->draw_info().resource();
+ if (resource)
+ resources.push_back(resource);
+ }
+
+ if (!resources.empty()) {
+ raster_buffer_provider_->SignalResourcesReadyToDraw(
+ resources,
+ base::Bind(&TileManager::OnRequiredForActivationTilesReadyToDraw,
+ weak_ptr_factory_.GetWeakPtr()));
+ }
+}
+
+void TileManager::CheckRequiredForDrawTilesReadyToDraw() {
+ std::vector<Tile*> pending_tiles;
+ for (Tile* tile : pending_required_for_draw_tiles_) {
+ const Resource* resource = tile->draw_info().resource();
+ if (resource && raster_buffer_provider_->IsResourceReadyToDraw(resource)) {
+ OnTileReadyToDraw(tile);
+ } else {
+ pending_tiles.push_back(tile);
+ }
+ }
+ pending_required_for_draw_tiles_.swap(pending_tiles);
+
+ std::vector<const Resource*> resources;
+ for (Tile* tile : pending_required_for_activation_tiles_) {
+ const Resource* resource = tile->draw_info().resource();
+ if (resource)
+ resources.push_back(resource);
+ }
+
+ if (!resources.empty()) {
+ raster_buffer_provider_->SignalResourcesReadyToDraw(
+ resources, base::Bind(&TileManager::OnRequiredForDrawTilesReadyToDraw,
+ weak_ptr_factory_.GetWeakPtr()));
+ }
+}
+
+void TileManager::OnTileReadyToDraw(Tile* tile) {
+ TRACE_EVENT1("cc", "TileManager::OnTileReadyToDraw", "tile_id", tile->id());
+
+ TileDrawInfo& draw_info = tile->draw_info();
+ if (draw_info.IsReadyToDraw())
+ return;
- DCHECK(draw_info.IsReadyToDraw());
+ DCHECK_EQ(TileDrawInfo::RESOURCE_MODE, draw_info.mode());
+ DCHECK(draw_info.has_resource());
+ draw_info.set_ready_to_draw(true);
draw_info.set_was_ever_ready_to_draw();
client_->NotifyTileStateChanged(tile);
@@ -1107,6 +1211,7 @@ void TileManager::CheckAndIssueSignals() {
// Ready to activate.
if (signals_.ready_to_activate && !signals_.did_notify_ready_to_activate) {
signals_.ready_to_activate = false;
+ CheckRequiredForActivationTilesReadyToDraw();
if (IsReadyToActivate()) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
"TileManager::CheckAndIssueSignals - ready to activate");
@@ -1118,6 +1223,7 @@ void TileManager::CheckAndIssueSignals() {
// Ready to draw.
if (signals_.ready_to_draw && !signals_.did_notify_ready_to_draw) {
signals_.ready_to_draw = false;
+ CheckRequiredForDrawTilesReadyToDraw();
if (IsReadyToDraw()) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
"TileManager::CheckAndIssueSignals - ready to draw");
« no previous file with comments | « cc/tiles/tile_manager.h ('k') | content/browser/compositor/gpu_process_transport_factory.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698