summaryrefslogtreecommitdiffstats
path: root/cc/resources/tile_manager.cc
diff options
context:
space:
mode:
authorreveman@chromium.org <reveman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-27 21:28:12 +0000
committerreveman@chromium.org <reveman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-27 21:28:12 +0000
commit8f802b2596f69ecd68ac6496da0e4b661183a777 (patch)
tree8dff0d63a3a8dabf11bb9ceb93daab88159aa50b /cc/resources/tile_manager.cc
parentb9adabf3fd45ddbba723a7e78241df62c0cb730b (diff)
downloadchromium_src-8f802b2596f69ecd68ac6496da0e4b661183a777.zip
chromium_src-8f802b2596f69ecd68ac6496da0e4b661183a777.tar.gz
chromium_src-8f802b2596f69ecd68ac6496da0e4b661183a777.tar.bz2
Re-land: cc: Examine layers to determine if we're ready to activate.
This introduces a new mechanism for determining when we're ready to activate the pending tree. The tile priority is still used to determine when it's worth waking up the compositor thread and evaluating if we can activate. However, the actual check that determines if we're ready to activate doesn't rely on the state of scheduled raster tasks but is a synchronous call on each layer. The result is a pending tree activation mechanism that is much easier to debug and validate for correctness, while still providing the performance benefits of the old mechanism by taking the "required to activate" field of the tile priority into account when scheduling tasks. BUG=375206 TEST=cc_unittests --gtest_filter=PictureLayerImplTest.AllTilesRequiredForActivationAreReadyToDraw Review URL: https://codereview.chromium.org/287643004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@273040 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc/resources/tile_manager.cc')
-rw-r--r--cc/resources/tile_manager.cc77
1 files changed, 64 insertions, 13 deletions
diff --git a/cc/resources/tile_manager.cc b/cc/resources/tile_manager.cc
index 2b3e652..416c4e6 100644
--- a/cc/resources/tile_manager.cc
+++ b/cc/resources/tile_manager.cc
@@ -365,24 +365,25 @@ scoped_ptr<base::Value> RasterTaskCompletionStatsAsValue(
// static
scoped_ptr<TileManager> TileManager::Create(
TileManagerClient* client,
+ base::SequencedTaskRunner* task_runner,
ResourcePool* resource_pool,
Rasterizer* rasterizer,
- bool use_rasterize_on_demand,
RenderingStatsInstrumentation* rendering_stats_instrumentation) {
return make_scoped_ptr(new TileManager(client,
+ task_runner,
resource_pool,
rasterizer,
- use_rasterize_on_demand,
rendering_stats_instrumentation));
}
TileManager::TileManager(
TileManagerClient* client,
+ base::SequencedTaskRunner* task_runner,
ResourcePool* resource_pool,
Rasterizer* rasterizer,
- bool use_rasterize_on_demand,
RenderingStatsInstrumentation* rendering_stats_instrumentation)
: client_(client),
+ task_runner_(task_runner),
resource_pool_(resource_pool),
rasterizer_(rasterizer),
prioritized_tiles_dirty_(false),
@@ -396,7 +397,8 @@ TileManager::TileManager(
rendering_stats_instrumentation_(rendering_stats_instrumentation),
did_initialize_visible_tile_(false),
did_check_for_completed_tasks_since_last_schedule_tasks_(true),
- use_rasterize_on_demand_(use_rasterize_on_demand) {
+ check_if_ready_to_activate_pending_(false),
+ weak_ptr_factory_(this) {
rasterizer_->SetClient(this);
}
@@ -528,12 +530,14 @@ void TileManager::DidFinishRunningTasks() {
// If we can't raster on demand, give up early (and don't activate).
if (!allow_rasterize_on_demand)
return;
- if (use_rasterize_on_demand_)
- tile_version.set_rasterize_on_demand();
+
+ tile_version.set_rasterize_on_demand();
+ client_->NotifyTileStateChanged(tile);
}
}
- client_->NotifyReadyToActivate();
+ DCHECK(IsReadyToActivate());
+ ScheduleCheckIfReadyToActivate();
}
void TileManager::DidFinishRunningTasksRequiredForActivation() {
@@ -545,7 +549,7 @@ void TileManager::DidFinishRunningTasksRequiredForActivation() {
if (!all_tiles_required_for_activation_have_memory_)
return;
- client_->NotifyReadyToActivate();
+ ScheduleCheckIfReadyToActivate();
}
void TileManager::GetTilesWithAssignedBins(PrioritizedTileSet* tiles) {
@@ -664,7 +668,7 @@ void TileManager::GetTilesWithAssignedBins(PrioritizedTileSet* tiles) {
// can visit it.
if (mts.bin == NEVER_BIN &&
!mts.tile_versions[mts.raster_mode].raster_task_) {
- FreeResourcesForTile(tile);
+ FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile);
continue;
}
@@ -853,7 +857,7 @@ void TileManager::AssignGpuMemoryToTiles(
// If the tile is not needed, free it up.
if (mts.bin == NEVER_BIN) {
- FreeResourcesForTile(tile);
+ FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile);
continue;
}
@@ -895,14 +899,19 @@ void TileManager::AssignGpuMemoryToTiles(
// Tile is OOM.
if (tile_bytes > tile_bytes_left || tile_resources > resources_left) {
+ bool was_ready_to_draw = tile->IsReadyToDraw();
+
FreeResourcesForTile(tile);
// This tile was already on screen and now its resources have been
// released. In order to prevent checkerboarding, set this tile as
// rasterize on demand immediately.
- if (mts.visible_and_ready_to_draw && use_rasterize_on_demand_)
+ if (mts.visible_and_ready_to_draw)
tile_version.set_rasterize_on_demand();
+ if (was_ready_to_draw)
+ client_->NotifyTileStateChanged(tile);
+
oomed_soft = true;
if (tile_uses_hard_limit) {
oomed_hard = true;
@@ -997,6 +1006,14 @@ void TileManager::FreeUnusedResourcesForTile(Tile* tile) {
}
}
+void TileManager::FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(
+ Tile* tile) {
+ bool was_ready_to_draw = tile->IsReadyToDraw();
+ FreeResourcesForTile(tile);
+ if (was_ready_to_draw)
+ client_->NotifyTileStateChanged(tile);
+}
+
void TileManager::ScheduleTasks(
const TileVector& tiles_that_need_to_be_rasterized) {
TRACE_EVENT1("cc",
@@ -1189,11 +1206,11 @@ void TileManager::OnRasterTaskCompleted(
++resources_releasable_;
}
- client_->NotifyTileInitialized(tile);
-
FreeUnusedResourcesForTile(tile);
if (tile->priority(ACTIVE_TREE).distance_to_visible == 0.f)
did_initialize_visible_tile_ = true;
+
+ client_->NotifyTileStateChanged(tile);
}
scoped_refptr<Tile> TileManager::CreateTile(PicturePileImpl* picture_pile,
@@ -1627,4 +1644,38 @@ void TileManager::SetRasterizerForTesting(Rasterizer* rasterizer) {
rasterizer_->SetClient(this);
}
+bool TileManager::IsReadyToActivate() const {
+ for (std::vector<PictureLayerImpl*>::const_iterator it = layers_.begin();
+ it != layers_.end();
+ ++it) {
+ if (!(*it)->AllTilesRequiredForActivationAreReadyToDraw())
+ return false;
+ }
+
+ return true;
+}
+
+void TileManager::ScheduleCheckIfReadyToActivate() {
+ if (check_if_ready_to_activate_pending_)
+ return;
+
+ task_runner_->PostTask(FROM_HERE,
+ base::Bind(&TileManager::CheckIfReadyToActivate,
+ weak_ptr_factory_.GetWeakPtr()));
+ check_if_ready_to_activate_pending_ = true;
+}
+
+void TileManager::CheckIfReadyToActivate() {
+ TRACE_EVENT0("cc", "TileManager::CheckIfReadyToActivate");
+
+ DCHECK(check_if_ready_to_activate_pending_);
+ check_if_ready_to_activate_pending_ = false;
+
+ rasterizer_->CheckForCompletedTasks();
+ did_check_for_completed_tasks_since_last_schedule_tasks_ = true;
+
+ if (IsReadyToActivate())
+ client_->NotifyReadyToActivate();
+}
+
} // namespace cc