Chromium Code Reviews| Index: cc/resources/tile_manager.cc |
| diff --git a/cc/resources/tile_manager.cc b/cc/resources/tile_manager.cc |
| index ab53cfd5f3984375ae05393a16b20a326ab66ea8..a8128f52a922b709930d4e50d292feaa6833058c 100644 |
| --- a/cc/resources/tile_manager.cc |
| +++ b/cc/resources/tile_manager.cc |
| @@ -165,6 +165,7 @@ void TileManager::UnregisterTile(Tile* tile) { |
| tiles_that_need_to_be_rasterized_.erase(raster_iter); |
| tiles_that_need_to_be_initialized_for_activation_.erase(tile); |
| + oom_tiles_that_need_to_be_initialized_for_activation_.erase(tile); |
| DCHECK(std::find(tiles_.begin(), tiles_.end(), tile) != tiles_.end()); |
| FreeResourcesForTile(tile); |
| @@ -175,6 +176,44 @@ bool TileManager::ShouldForceTasksRequiredForActivationToComplete() const { |
| return client_->ShouldForceTileUploadsRequiredForActivationToComplete(); |
| } |
| +void TileManager::DidFinishedRunningTasks() { |
| + if (oom_tiles_that_need_to_be_initialized_for_activation_.empty()) |
| + return; |
| + |
| + raster_worker_pool_->CheckForCompletedTasks(); |
| + |
| + AssignGpuMemoryToTiles(); |
|
vmpstr
2013/06/21 18:38:33
Can we make this return true if reassign oom is re
reveman
2013/06/24 16:04:03
I'd rather call reassign unconditionally to keep t
|
| + ReassignGpuMemoryToOOMTiles(); |
| + |
| + if (!tiles_that_need_to_be_rasterized_.empty()) { |
| + ScheduleTasks(); |
| + return; |
| + } |
| + |
| + for (TileSet::iterator it = |
| + oom_tiles_that_need_to_be_initialized_for_activation_.begin(); |
| + it != oom_tiles_that_need_to_be_initialized_for_activation_.end(); |
| + ++it) { |
| + Tile* tile = *it; |
| + ManagedTileState& mts = tile->managed_state(); |
| + mts.tile_versions[mts.raster_mode].set_rasterize_on_demand(); |
| + } |
| + oom_tiles_that_need_to_be_initialized_for_activation_.clear(); |
| + |
| + client_->NotifyReadyToActivate(); |
| +} |
| + |
| +void TileManager::DidFinishedRunningTasksRequiredForActivation() { |
| + if (!oom_tiles_that_need_to_be_initialized_for_activation_.empty()) |
|
vmpstr
2013/06/21 18:38:33
Can you make a comment that explains why this is n
reveman
2013/06/24 16:04:03
Added a comment that explains why we might need to
|
| + return; |
| + |
| + // TODO(reveman): Push the responsibility of calling CheckForCompletedTasks() |
| + // to the LTHI where it can be delayed until it's time to draw. |
| + raster_worker_pool_->CheckForCompletedTasks(); |
| + |
| + client_->NotifyReadyToActivate(); |
| +} |
| + |
| class BinComparator { |
| public: |
| bool operator() (const Tile* a, const Tile* b) const { |
| @@ -301,10 +340,6 @@ void TileManager::ManageTiles() { |
| AssignGpuMemoryToTiles(); |
| CleanUpUnusedImageDecodeTasks(); |
| - // This could have changed after AssignGpuMemoryToTiles. |
| - if (AreTilesRequiredForActivationReady()) |
| - client_->NotifyReadyToActivate(); |
| - |
| TRACE_EVENT_INSTANT1( |
| "cc", "DidManage", TRACE_EVENT_SCOPE_THREAD, |
| "state", TracedValue::FromValue(BasicStateAsValue().release())); |
| @@ -409,6 +444,7 @@ void TileManager::AssignGpuMemoryToTiles() { |
| // the needs-to-be-rasterized queue. |
| tiles_that_need_to_be_rasterized_.clear(); |
| tiles_that_need_to_be_initialized_for_activation_.clear(); |
| + oom_tiles_that_need_to_be_initialized_for_activation_.clear(); |
| size_t bytes_releasable = 0; |
| for (TileVector::const_iterator it = tiles_.begin(); |
| @@ -433,8 +469,6 @@ void TileManager::AssignGpuMemoryToTiles() { |
| size_t bytes_that_exceeded_memory_budget_in_now_bin = 0; |
| size_t bytes_left = bytes_allocatable; |
| - size_t bytes_oom_in_now_bin_on_pending_tree = 0; |
| - TileVector tiles_requiring_memory_but_oomed; |
| bool higher_priority_tile_oomed = false; |
| for (TileVector::iterator it = tiles_.begin(); |
| it != tiles_.end(); |
| @@ -474,11 +508,8 @@ void TileManager::AssignGpuMemoryToTiles() { |
| // Tile is OOM. |
| if (tile_bytes > bytes_left) { |
| - mts.tile_versions[mts.raster_mode].set_rasterize_on_demand(); |
| - if (mts.tree_bin[PENDING_TREE] == NOW_BIN) { |
| - tiles_requiring_memory_but_oomed.push_back(tile); |
| - bytes_oom_in_now_bin_on_pending_tree += tile_bytes; |
| - } |
| + if (tile->required_for_activation()) |
| + oom_tiles_that_need_to_be_initialized_for_activation_.insert(tile); |
| FreeResourcesForTile(tile); |
| higher_priority_tile_oomed = true; |
| continue; |
| @@ -505,58 +536,6 @@ void TileManager::AssignGpuMemoryToTiles() { |
| } |
| } |
| - // In OOM situation, we iterate tiles_, remove the memory for active tree |
| - // and not the now bin. And give them to bytes_oom_in_now_bin_on_pending_tree |
| - if (!tiles_requiring_memory_but_oomed.empty()) { |
| - size_t bytes_freed = 0; |
| - for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
| - Tile* tile = *it; |
| - ManagedTileState& mts = tile->managed_state(); |
| - if (mts.tree_bin[PENDING_TREE] == NEVER_BIN && |
| - mts.tree_bin[ACTIVE_TREE] != NOW_BIN) { |
| - size_t bytes_that_can_be_freed = 0; |
| - for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { |
| - ManagedTileState::TileVersion& tile_version = |
| - mts.tile_versions[mode]; |
| - if (tile_version.resource_) { |
| - DCHECK(!tile->required_for_activation()); |
| - bytes_that_can_be_freed += tile->bytes_consumed_if_allocated(); |
| - } |
| - } |
| - |
| - if (bytes_that_can_be_freed > 0) { |
| - FreeResourcesForTile(tile); |
| - bytes_freed += bytes_that_can_be_freed; |
| - mts.tile_versions[mts.raster_mode].set_rasterize_on_demand(); |
| - TileVector::iterator it = std::find( |
| - tiles_that_need_to_be_rasterized_.begin(), |
| - tiles_that_need_to_be_rasterized_.end(), |
| - tile); |
| - if (it != tiles_that_need_to_be_rasterized_.end()) |
| - tiles_that_need_to_be_rasterized_.erase(it); |
| - } |
| - } |
| - |
| - if (bytes_oom_in_now_bin_on_pending_tree <= bytes_freed) |
| - break; |
| - } |
| - |
| - for (TileVector::iterator it = tiles_requiring_memory_but_oomed.begin(); |
| - it != tiles_requiring_memory_but_oomed.end() && bytes_freed > 0; |
| - ++it) { |
| - Tile* tile = *it; |
| - ManagedTileState& mts = tile->managed_state(); |
| - size_t bytes_needed = tile->bytes_consumed_if_allocated(); |
| - if (bytes_needed > bytes_freed) |
| - continue; |
| - mts.tile_versions[mts.raster_mode].set_use_resource(); |
| - bytes_freed -= bytes_needed; |
| - tiles_that_need_to_be_rasterized_.push_back(tile); |
| - if (tile->required_for_activation()) |
| - AddRequiredTileForActivation(tile); |
| - } |
| - } |
| - |
| ever_exceeded_memory_budget_ |= |
| bytes_that_exceeded_memory_budget_in_now_bin > 0; |
| if (ever_exceeded_memory_budget_) { |
| @@ -574,6 +553,70 @@ void TileManager::AssignGpuMemoryToTiles() { |
| bytes_that_exceeded_memory_budget_in_now_bin; |
| } |
| +void TileManager::ReassignGpuMemoryToOOMTiles() { |
| + TRACE_EVENT0("cc", "TileManager::ReassignGpuMemoryToOOMTiles"); |
| + |
| + size_t bytes_oom_for_required_tiles = 0; |
| + TileVector tiles_requiring_memory_but_oomed; |
| + for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
|
vmpstr
2013/06/21 18:38:33
Isn't this just a loop over oom_tiles_that_need_to
reveman
2013/06/24 16:04:03
Yes, but it adds tiles to |tiles_requiring_memory_
vmpstr
2013/06/24 16:34:03
Oh I didn't realize that it was a set, my bad.
|
| + Tile* tile = *it; |
| + if (oom_tiles_that_need_to_be_initialized_for_activation_.find(tile) == |
| + oom_tiles_that_need_to_be_initialized_for_activation_.end()) |
| + continue; |
| + |
| + tiles_requiring_memory_but_oomed.push_back(tile); |
| + bytes_oom_for_required_tiles += tile->bytes_consumed_if_allocated(); |
| + } |
| + |
| + // In OOM situation, we iterate tiles_, remove the memory for active tree |
| + // and not the now bin. And give them to bytes_oom_for_required_tiles |
| + size_t bytes_freed = 0; |
| + for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
|
vmpstr
2013/06/21 18:38:33
You should early out before this if nothing is OOM
reveman
2013/06/24 16:04:03
Done.
|
| + Tile* tile = *it; |
| + ManagedTileState& mts = tile->managed_state(); |
| + if (mts.tree_bin[PENDING_TREE] == NEVER_BIN && |
| + mts.tree_bin[ACTIVE_TREE] != NOW_BIN) { |
| + size_t bytes_that_can_be_freed = 0; |
| + for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { |
| + ManagedTileState::TileVersion& tile_version = mts.tile_versions[mode]; |
| + if (tile_version.resource_) { |
| + DCHECK(!tile->required_for_activation()); |
| + bytes_that_can_be_freed += tile->bytes_consumed_if_allocated(); |
| + } |
| + } |
| + |
| + if (bytes_that_can_be_freed > 0) { |
| + FreeResourcesForTile(tile); |
| + bytes_freed += bytes_that_can_be_freed; |
| + TileVector::iterator it = std::find( |
| + tiles_that_need_to_be_rasterized_.begin(), |
| + tiles_that_need_to_be_rasterized_.end(), |
| + tile); |
| + if (it != tiles_that_need_to_be_rasterized_.end()) |
| + tiles_that_need_to_be_rasterized_.erase(it); |
| + } |
| + } |
| + |
| + if (bytes_oom_for_required_tiles <= bytes_freed) |
| + break; |
| + } |
| + |
| + for (TileVector::iterator it = tiles_requiring_memory_but_oomed.begin(); |
| + it != tiles_requiring_memory_but_oomed.end() && bytes_freed > 0; |
| + ++it) { |
| + Tile* tile = *it; |
| + ManagedTileState& mts = tile->managed_state(); |
| + size_t bytes_needed = tile->bytes_consumed_if_allocated(); |
| + if (bytes_needed > bytes_freed) |
| + continue; |
| + mts.tile_versions[mts.raster_mode].set_use_resource(); |
| + bytes_freed -= bytes_needed; |
| + tiles_that_need_to_be_rasterized_.push_back(tile); |
| + AddRequiredTileForActivation(tile); |
| + oom_tiles_that_need_to_be_initialized_for_activation_.erase(tile); |
| + } |
| +} |
| + |
| void TileManager::CleanUpUnusedImageDecodeTasks() { |
| // Calculate a set of layers that are used by at least one tile. |
| base::hash_set<int> used_layers; |