Index: cc/tile_manager.cc |
diff --git a/cc/tile_manager.cc b/cc/tile_manager.cc |
index 3bbcbe351f47e207842897d1983594808438c970..888a0f71dba3b0dcfe84d2c25ca66ac98cea464d 100644 |
--- a/cc/tile_manager.cc |
+++ b/cc/tile_manager.cc |
@@ -196,8 +196,9 @@ TileManager::~TileManager() { |
// resources. |
raster_worker_pool_.reset(); |
AbortPendingTileUploads(); |
- DCHECK(tiles_with_pending_set_pixels_.size() == 0); |
- DCHECK(tiles_.size() == 0); |
+ DCHECK_EQ(tiles_with_pending_set_pixels_.size(), 0); |
+ DCHECK_EQ(all_tiles_.size(), 0); |
+ DCHECK_EQ(live_or_allocated_tiles_.size(), 0); |
} |
void TileManager::SetGlobalState( |
@@ -208,7 +209,7 @@ void TileManager::SetGlobalState( |
} |
void TileManager::RegisterTile(Tile* tile) { |
- tiles_.push_back(tile); |
+ all_tiles_.push_back(tile); |
const ManagedTileState& mts = tile->managed_state(); |
for (int i = 0; i < NUM_TREES; ++i) |
@@ -232,13 +233,21 @@ void TileManager::UnregisterTile(Tile* tile) { |
break; |
} |
} |
- for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); it++) { |
+ for (TileVector::iterator it = live_or_allocated_tiles_.begin(); |
+ it != live_or_allocated_tiles_.end(); it++) { |
+ if (*it == tile) { |
+ live_or_allocated_tiles_.erase(it); |
+ break; |
+ } |
+ } |
+ for (TileVector::iterator it = all_tiles_.begin(); |
+ it != all_tiles_.end(); it++) { |
if (*it == tile) { |
const ManagedTileState& mts = tile->managed_state(); |
for (int i = 0; i < NUM_TREES; ++i) |
--raster_state_count_[mts.raster_state][i][mts.tree_bin[i]]; |
FreeResourcesForTile(tile); |
- tiles_.erase(it); |
+ all_tiles_.erase(it); |
return; |
} |
} |
@@ -272,41 +281,11 @@ public: |
void TileManager::SortTiles() { |
TRACE_EVENT0("cc", "TileManager::SortTiles"); |
- |
- if (tiles_.size() == 0) { |
- TRACE_COUNTER_ID1("cc", "LiveTileCount", this, 0); |
- return; |
- } |
- |
- TileVector::iterator i = tiles_.begin(); |
- TileVector::iterator j = tiles_.end() - 1; |
- |
- // Sift the live tiles to the front of the list. |
- while (i != j) { |
- while (i != j && ( |
- !(*j)->priority( ACTIVE_TREE).is_live && |
- !(*j)->priority(PENDING_TREE).is_live)) |
- j--; |
- |
- // j now points to i or a live tile. |
- while (i != j && ( |
- (*i)->priority( ACTIVE_TREE).is_live || |
- (*i)->priority(PENDING_TREE).is_live)) |
- i++; |
- // i now points to j or a non-live tile. |
- if (i == j) |
- break; |
- |
- // If i does not equal j then we'll swap them. |
- Tile* temp = *i; |
- *i = *j; |
- *j = temp; |
- } |
- |
- TRACE_COUNTER_ID1("cc", "LiveTileCount", this, i + 1 - tiles_.begin()); |
+ TRACE_COUNTER_ID1("cc", "LiveTileCount", this, live_or_allocated_tiles_.size()); |
// Sort by bin, resolution and time until needed. |
- std::sort(tiles_.begin(), i + 1, BinComparator()); |
+ std::sort(live_or_allocated_tiles_.begin(), |
+ live_or_allocated_tiles_.end(), BinComparator()); |
} |
void TileManager::ManageTiles() { |
@@ -315,10 +294,36 @@ void TileManager::ManageTiles() { |
++manage_tiles_call_count_; |
const TreePriority tree_priority = global_state_.tree_priority; |
- TRACE_COUNTER_ID1("cc", "TileCount", this, tiles_.size()); |
+ TRACE_COUNTER_ID1("cc", "TileCount", this, all_tiles_.size()); |
+ |
+ // Memory limit policy works by mapping some bin states to the NEVER bin. |
+ TileManagerBin bin_map[NUM_BINS]; |
+ if (global_state_.memory_limit_policy == ALLOW_NOTHING) { |
+ bin_map[NOW_BIN] = NEVER_BIN; |
+ bin_map[SOON_BIN] = NEVER_BIN; |
+ bin_map[EVENTUALLY_BIN] = NEVER_BIN; |
+ bin_map[NEVER_BIN] = NEVER_BIN; |
+ } else if (global_state_.memory_limit_policy == ALLOW_ABSOLUTE_MINIMUM) { |
+ bin_map[NOW_BIN] = NOW_BIN; |
+ bin_map[SOON_BIN] = NEVER_BIN; |
+ bin_map[EVENTUALLY_BIN] = NEVER_BIN; |
+ bin_map[NEVER_BIN] = NEVER_BIN; |
+ } else if (global_state_.memory_limit_policy == ALLOW_PREPAINT_ONLY) { |
+ bin_map[NOW_BIN] = NOW_BIN; |
+ bin_map[SOON_BIN] = SOON_BIN; |
+ bin_map[EVENTUALLY_BIN] = NEVER_BIN; |
+ bin_map[NEVER_BIN] = NEVER_BIN; |
+ } else { |
+ bin_map[NOW_BIN] = NOW_BIN; |
+ bin_map[SOON_BIN] = SOON_BIN; |
+ bin_map[EVENTUALLY_BIN] = EVENTUALLY_BIN; |
+ bin_map[NEVER_BIN] = NEVER_BIN; |
+ } |
+ live_or_allocated_tiles_.clear(); |
// For each tree, bin into different categories of tiles. |
- for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
+ for (TileVector::iterator it = all_tiles_.begin(); |
+ it != all_tiles_.end(); ++it) { |
Tile* tile = *it; |
ManagedTileState& mts = tile->managed_state(); |
@@ -345,46 +350,30 @@ void TileManager::ManageTiles() { |
mts.bin[LOW_PRIORITY_BIN] = BinFromTilePriority(prio[LOW_PRIORITY_BIN]); |
mts.gpu_memmgr_stats_bin = BinFromTilePriority(tile->combined_priority()); |
- DidTileBinChange(tile, |
- BinFromTilePriority(tile->priority(ACTIVE_TREE)), |
- ACTIVE_TREE); |
- DidTileBinChange(tile, |
- BinFromTilePriority(tile->priority(PENDING_TREE)), |
- PENDING_TREE); |
- } |
+ DidTileTreeBinChange(tile, |
+ BinFromTilePriority(tile->priority(ACTIVE_TREE)), |
+ ACTIVE_TREE); |
+ DidTileTreeBinChange(tile, |
+ BinFromTilePriority(tile->priority(PENDING_TREE)), |
+ PENDING_TREE); |
- // Memory limit policy works by mapping some bin states to the NEVER bin. |
- TileManagerBin bin_map[NUM_BINS]; |
- if (global_state_.memory_limit_policy == ALLOW_NOTHING) { |
- bin_map[NOW_BIN] = NEVER_BIN; |
- bin_map[SOON_BIN] = NEVER_BIN; |
- bin_map[EVENTUALLY_BIN] = NEVER_BIN; |
- bin_map[NEVER_BIN] = NEVER_BIN; |
- } else if (global_state_.memory_limit_policy == ALLOW_ABSOLUTE_MINIMUM) { |
- bin_map[NOW_BIN] = NOW_BIN; |
- bin_map[SOON_BIN] = NEVER_BIN; |
- bin_map[EVENTUALLY_BIN] = NEVER_BIN; |
- bin_map[NEVER_BIN] = NEVER_BIN; |
- } else if (global_state_.memory_limit_policy == ALLOW_PREPAINT_ONLY) { |
- bin_map[NOW_BIN] = NOW_BIN; |
- bin_map[SOON_BIN] = SOON_BIN; |
- bin_map[EVENTUALLY_BIN] = NEVER_BIN; |
- bin_map[NEVER_BIN] = NEVER_BIN; |
- } else { |
- bin_map[NOW_BIN] = NOW_BIN; |
- bin_map[SOON_BIN] = SOON_BIN; |
- bin_map[EVENTUALLY_BIN] = EVENTUALLY_BIN; |
- bin_map[NEVER_BIN] = NEVER_BIN; |
- } |
- for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
- Tile* tile = *it; |
- ManagedTileState& mts = tile->managed_state(); |
for (int i = 0; i < NUM_BIN_PRIORITIES; ++i) |
mts.bin[i] = bin_map[mts.bin[i]]; |
- DidTileBinChange(tile, bin_map[mts.tree_bin[ACTIVE_TREE]], ACTIVE_TREE); |
- DidTileBinChange(tile, bin_map[mts.tree_bin[PENDING_TREE]], PENDING_TREE); |
+ DidTileTreeBinChange(tile, bin_map[mts.tree_bin[ACTIVE_TREE]], |
+ ACTIVE_TREE); |
+ DidTileTreeBinChange(tile, bin_map[mts.tree_bin[PENDING_TREE]], |
+ PENDING_TREE); |
+ |
+ if (tile->priority(ACTIVE_TREE).is_live || |
+ tile->priority(PENDING_TREE).is_live || |
+ tile->managed_state().resource || |
+ tile->managed_state().resource_is_being_initialized) { |
+ live_or_allocated_tiles_.push_back(tile); |
+ } |
} |
+ TRACE_COUNTER_ID1("cc", "LiveOrAllocatedTileCount", this, |
+ live_or_allocated_tiles_.size()); |
SortTiles(); |
@@ -456,8 +445,8 @@ void TileManager::GetMemoryStats( |
*memoryRequiredBytes = 0; |
*memoryNiceToHaveBytes = 0; |
*memoryUsedBytes = 0; |
- for(size_t i = 0; i < tiles_.size(); i++) { |
- const Tile* tile = tiles_[i]; |
+ for (size_t i = 0; i < live_or_allocated_tiles_.size(); i++) { |
+ const Tile* tile = live_or_allocated_tiles_[i]; |
const ManagedTileState& mts = tile->managed_state(); |
size_t tile_bytes = tile->bytes_consumed_if_allocated(); |
if (mts.gpu_memmgr_stats_bin == NOW_BIN) |
@@ -471,7 +460,7 @@ void TileManager::GetMemoryStats( |
scoped_ptr<base::Value> TileManager::BasicStateAsValue() const { |
scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); |
- state->SetInteger("tile_count", tiles_.size()); |
+ state->SetInteger("tile_count", all_tiles_.size()); |
state->Set("global_state", global_state_.AsValue().release()); |
@@ -480,8 +469,8 @@ scoped_ptr<base::Value> TileManager::BasicStateAsValue() const { |
} |
scoped_ptr<base::Value> TileManager::AllTilesAsValue() const { |
scoped_ptr<base::ListValue> state(new base::ListValue()); |
- for (size_t i = 0; i < tiles_.size(); i++) |
- state->Append(tiles_[i]->AsValue().release()); |
+ for (size_t i = 0; i < all_tiles_.size(); i++) |
+ state->Append(all_tiles_[i]->AsValue().release()); |
return state.PassAs<base::Value>(); |
} |
@@ -546,19 +535,11 @@ bool TileManager::HasPendingWorkScheduled(WhichTree tree) const { |
void TileManager::AssignGpuMemoryToTiles() { |
TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles"); |
- // Some memory cannot be released. Figure out which. |
size_t unreleasable_bytes = 0; |
- for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
- Tile* tile = *it; |
- if (!tile->managed_state().can_be_freed) |
- unreleasable_bytes += tile->bytes_consumed_if_allocated(); |
- } |
// Now give memory out to the tiles until we're out, and build |
// the needs-to-be-rasterized queue. |
- tiles_that_need_to_be_rasterized_.erase( |
- tiles_that_need_to_be_rasterized_.begin(), |
- tiles_that_need_to_be_rasterized_.end()); |
+ tiles_that_need_to_be_rasterized_.clear(); |
// Reset the image decoding list so that we don't mess up with tile |
// priorities. Tiles will be added to the image decoding list again |
@@ -570,8 +551,13 @@ void TileManager::AssignGpuMemoryToTiles() { |
// currently waiting for raster to idle state. |
// Call DidTileRasterStateChange() for each of these tiles to |
// have this state change take effect. |
- for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
+ // Some memory cannot be released. We figure out how much in this |
+ // loop as well. |
+ for (TileVector::iterator it = live_or_allocated_tiles_.begin(); |
+ it != live_or_allocated_tiles_.end(); ++it) { |
Tile* tile = *it; |
+ if (!tile->managed_state().can_be_freed) |
+ unreleasable_bytes += tile->bytes_consumed_if_allocated(); |
if (tile->managed_state().raster_state == WAITING_FOR_RASTER_STATE) |
DidTileRasterStateChange(tile, IDLE_STATE); |
} |
@@ -579,7 +565,8 @@ void TileManager::AssignGpuMemoryToTiles() { |
size_t bytes_allocatable = global_state_.memory_limit_in_bytes - unreleasable_bytes; |
size_t bytes_that_exceeded_memory_budget = 0; |
size_t bytes_left = bytes_allocatable; |
- for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
+ for (TileVector::iterator it = live_or_allocated_tiles_.begin(); |
+ it != live_or_allocated_tiles_.end(); ++it) { |
Tile* tile = *it; |
size_t tile_bytes = tile->bytes_consumed_if_allocated(); |
ManagedTileState& managed_tile_state = tile->managed_state(); |
@@ -887,9 +874,9 @@ void TileManager::DidTileRasterStateChange(Tile* tile, TileRasterState state) { |
mts.raster_state = state; |
} |
-void TileManager::DidTileBinChange(Tile* tile, |
- TileManagerBin bin, |
- WhichTree tree) { |
+void TileManager::DidTileTreeBinChange(Tile* tile, |
+ TileManagerBin new_tree_bin, |
+ WhichTree tree) { |
ManagedTileState& mts = tile->managed_state(); |
// Decrement count for current bin. |
@@ -897,9 +884,9 @@ void TileManager::DidTileBinChange(Tile* tile, |
DCHECK_GE(raster_state_count_[mts.raster_state][tree][mts.tree_bin[tree]], 0); |
// Increment count for new bin. |
- ++raster_state_count_[mts.raster_state][tree][bin]; |
+ ++raster_state_count_[mts.raster_state][tree][new_tree_bin]; |
- mts.tree_bin[tree] = bin; |
+ mts.tree_bin[tree] = new_tree_bin; |
} |
// static |