Chromium Code Reviews| Index: cc/resources/tile_manager.cc | 
| diff --git a/cc/resources/tile_manager.cc b/cc/resources/tile_manager.cc | 
| index b443516887c8e65c6c0ba464dec3820ef926042b..083a00d01857cc19eba3f4d9d3c50fafbdbb52b6 100644 | 
| --- a/cc/resources/tile_manager.cc | 
| +++ b/cc/resources/tile_manager.cc | 
| @@ -225,6 +225,7 @@ TileManager::~TileManager() { | 
| global_state_ = GlobalStateThatImpactsTilePriority(); | 
| CleanUpReleasedTiles(); | 
| + DCHECK_EQ(0u, bundles_.size()); | 
| DCHECK_EQ(0u, tiles_.size()); | 
| RasterWorkerPool::RasterTask::Queue empty; | 
| @@ -244,7 +245,15 @@ void TileManager::Release(Tile* tile) { | 
| released_tiles_.push_back(tile); | 
| } | 
| -void TileManager::DidChangeTilePriority(Tile* tile) { | 
| +void TileManager::Release(TileBundle* bundle) { | 
| + released_tile_bundles_.push_back(bundle); | 
| +} | 
| + | 
| +void TileManager::DidChangeTilePriority(Tile* bundle) { | 
| 
 
reveman
2013/12/02 01:46:08
s/bundle/tile/ ?
 
vmpstr
2013/12/02 23:08:00
Done.
 
 | 
| + prioritized_tiles_dirty_ = true; | 
| +} | 
| + | 
| +void TileManager::DidChangeTileBundlePriority(TileBundle* bundle) { | 
| prioritized_tiles_dirty_ = true; | 
| } | 
| @@ -253,6 +262,18 @@ bool TileManager::ShouldForceTasksRequiredForActivationToComplete() const { | 
| } | 
| void TileManager::CleanUpReleasedTiles() { | 
| + // Clean up bundles first, since they might have tiles that will become | 
| + // released as well. | 
| + for (std::vector<TileBundle*>::iterator it = released_tile_bundles_.begin(); | 
| + it != released_tile_bundles_.end(); | 
| + ++it) { | 
| + TileBundle* bundle = *it; | 
| + DCHECK(bundles_.find(bundle->id()) != bundles_.end()); | 
| + bundles_.erase(bundle->id()); | 
| + delete bundle; | 
| + } | 
| + released_tile_bundles_.clear(); | 
| + | 
| for (std::vector<Tile*>::iterator it = released_tiles_.begin(); | 
| it != released_tiles_.end(); | 
| ++it) { | 
| @@ -273,7 +294,6 @@ void TileManager::CleanUpReleasedTiles() { | 
| delete tile; | 
| } | 
| - | 
| released_tiles_.clear(); | 
| } | 
| @@ -359,126 +379,130 @@ void TileManager::GetTilesWithAssignedBins(PrioritizedTileSet* tiles) { | 
| const TreePriority tree_priority = global_state_.tree_priority; | 
| // For each tree, bin into different categories of tiles. | 
| - for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 
| - Tile* tile = it->second; | 
| - ManagedTileState& mts = tile->managed_state(); | 
| + for (TileBundleMap::iterator bundle_it = bundles_.begin(); | 
| + bundle_it != bundles_.end(); | 
| + ++bundle_it) { | 
| + for (TileBundle::Iterator it(bundle_it->second); it; ++it) { | 
| + Tile* tile = *it; | 
| + ManagedTileState& mts = tile->managed_state(); | 
| + | 
| + const ManagedTileState::TileVersion& tile_version = | 
| + tile->GetTileVersionForDrawing(); | 
| + bool tile_is_ready_to_draw = tile_version.IsReadyToDraw(); | 
| + bool tile_is_active = | 
| + tile_is_ready_to_draw || | 
| + !mts.tile_versions[mts.raster_mode].raster_task_.is_null(); | 
| + | 
| + // Get the active priority and bin. | 
| + TilePriority active_priority = it.priority(ACTIVE_TREE); | 
| + ManagedTileBin active_bin = BinFromTilePriority(active_priority); | 
| + | 
| + // Get the pending priority and bin. | 
| + TilePriority pending_priority = it.priority(PENDING_TREE); | 
| + ManagedTileBin pending_bin = BinFromTilePriority(pending_priority); | 
| + | 
| + bool pending_is_low_res = | 
| + pending_priority.resolution == LOW_RESOLUTION; | 
| + bool pending_is_non_ideal = | 
| + pending_priority.resolution == NON_IDEAL_RESOLUTION; | 
| + bool active_is_non_ideal = | 
| + active_priority.resolution == NON_IDEAL_RESOLUTION; | 
| + | 
| + // Adjust pending bin state for low res tiles. This prevents | 
| + // pending tree low-res tiles from being initialized before | 
| + // high-res tiles. | 
| + if (pending_is_low_res) | 
| + pending_bin = std::max(pending_bin, EVENTUALLY_BIN); | 
| + | 
| + // Adjust bin state based on if ready to draw. | 
| + active_bin = kBinReadyToDrawMap[tile_is_ready_to_draw][active_bin]; | 
| + pending_bin = kBinReadyToDrawMap[tile_is_ready_to_draw][pending_bin]; | 
| + | 
| + // Adjust bin state based on if active. | 
| + active_bin = kBinIsActiveMap[tile_is_active][active_bin]; | 
| + pending_bin = kBinIsActiveMap[tile_is_active][pending_bin]; | 
| + | 
| + // We never want to paint new non-ideal tiles, as we always have | 
| + // a high-res tile covering that content (paint that instead). | 
| + if (!tile_is_ready_to_draw && active_is_non_ideal) | 
| + active_bin = NEVER_BIN; | 
| + if (!tile_is_ready_to_draw && pending_is_non_ideal) | 
| + pending_bin = NEVER_BIN; | 
| + | 
| + // Compute combined bin. | 
| + ManagedTileBin combined_bin = std::min(active_bin, pending_bin); | 
| + | 
| + ManagedTileBin tree_bin[NUM_TREES]; | 
| + tree_bin[ACTIVE_TREE] = kBinPolicyMap[memory_policy][active_bin]; | 
| + tree_bin[PENDING_TREE] = kBinPolicyMap[memory_policy][pending_bin]; | 
| + | 
| + // The bin that the tile would have if the GPU memory manager had | 
| + // a maximally permissive policy, send to the GPU memory manager | 
| + // to determine policy. | 
| + ManagedTileBin gpu_memmgr_stats_bin = NEVER_BIN; | 
| + TilePriority tile_priority; | 
| + | 
| + switch (tree_priority) { | 
| + case SAME_PRIORITY_FOR_BOTH_TREES: | 
| + mts.bin = kBinPolicyMap[memory_policy][combined_bin]; | 
| + gpu_memmgr_stats_bin = combined_bin; | 
| + tile_priority = TilePriority(active_priority, pending_priority); | 
| + break; | 
| + case SMOOTHNESS_TAKES_PRIORITY: | 
| + mts.bin = tree_bin[ACTIVE_TREE]; | 
| + gpu_memmgr_stats_bin = active_bin; | 
| + tile_priority = active_priority; | 
| + break; | 
| + case NEW_CONTENT_TAKES_PRIORITY: | 
| + mts.bin = tree_bin[PENDING_TREE]; | 
| + gpu_memmgr_stats_bin = pending_bin; | 
| + tile_priority = pending_priority; | 
| + break; | 
| + } | 
| - const ManagedTileState::TileVersion& tile_version = | 
| - tile->GetTileVersionForDrawing(); | 
| - bool tile_is_ready_to_draw = tile_version.IsReadyToDraw(); | 
| - bool tile_is_active = | 
| - tile_is_ready_to_draw || | 
| - !mts.tile_versions[mts.raster_mode].raster_task_.is_null(); | 
| - | 
| - // Get the active priority and bin. | 
| - TilePriority active_priority = tile->priority(ACTIVE_TREE); | 
| - ManagedTileBin active_bin = BinFromTilePriority(active_priority); | 
| - | 
| - // Get the pending priority and bin. | 
| - TilePriority pending_priority = tile->priority(PENDING_TREE); | 
| - ManagedTileBin pending_bin = BinFromTilePriority(pending_priority); | 
| - | 
| - bool pending_is_low_res = | 
| - pending_priority.resolution == LOW_RESOLUTION; | 
| - bool pending_is_non_ideal = | 
| - pending_priority.resolution == NON_IDEAL_RESOLUTION; | 
| - bool active_is_non_ideal = | 
| - active_priority.resolution == NON_IDEAL_RESOLUTION; | 
| - | 
| - // Adjust pending bin state for low res tiles. This prevents | 
| - // pending tree low-res tiles from being initialized before | 
| - // high-res tiles. | 
| - if (pending_is_low_res) | 
| - pending_bin = std::max(pending_bin, EVENTUALLY_BIN); | 
| - | 
| - // Adjust bin state based on if ready to draw. | 
| - active_bin = kBinReadyToDrawMap[tile_is_ready_to_draw][active_bin]; | 
| - pending_bin = kBinReadyToDrawMap[tile_is_ready_to_draw][pending_bin]; | 
| - | 
| - // Adjust bin state based on if active. | 
| - active_bin = kBinIsActiveMap[tile_is_active][active_bin]; | 
| - pending_bin = kBinIsActiveMap[tile_is_active][pending_bin]; | 
| - | 
| - // We never want to paint new non-ideal tiles, as we always have | 
| - // a high-res tile covering that content (paint that instead). | 
| - if (!tile_is_ready_to_draw && active_is_non_ideal) | 
| - active_bin = NEVER_BIN; | 
| - if (!tile_is_ready_to_draw && pending_is_non_ideal) | 
| - pending_bin = NEVER_BIN; | 
| - | 
| - // Compute combined bin. | 
| - ManagedTileBin combined_bin = std::min(active_bin, pending_bin); | 
| - | 
| - ManagedTileBin tree_bin[NUM_TREES]; | 
| - tree_bin[ACTIVE_TREE] = kBinPolicyMap[memory_policy][active_bin]; | 
| - tree_bin[PENDING_TREE] = kBinPolicyMap[memory_policy][pending_bin]; | 
| - | 
| - // The bin that the tile would have if the GPU memory manager had | 
| - // a maximally permissive policy, send to the GPU memory manager | 
| - // to determine policy. | 
| - ManagedTileBin gpu_memmgr_stats_bin = NEVER_BIN; | 
| - TilePriority tile_priority; | 
| - | 
| - switch (tree_priority) { | 
| - case SAME_PRIORITY_FOR_BOTH_TREES: | 
| - mts.bin = kBinPolicyMap[memory_policy][combined_bin]; | 
| - gpu_memmgr_stats_bin = combined_bin; | 
| - tile_priority = tile->combined_priority(); | 
| - break; | 
| - case SMOOTHNESS_TAKES_PRIORITY: | 
| - mts.bin = tree_bin[ACTIVE_TREE]; | 
| - gpu_memmgr_stats_bin = active_bin; | 
| - tile_priority = active_priority; | 
| - break; | 
| - case NEW_CONTENT_TAKES_PRIORITY: | 
| - mts.bin = tree_bin[PENDING_TREE]; | 
| - gpu_memmgr_stats_bin = pending_bin; | 
| - tile_priority = pending_priority; | 
| - break; | 
| - } | 
| + if (!tile_is_ready_to_draw || tile_version.requires_resource()) { | 
| + if ((gpu_memmgr_stats_bin == NOW_BIN) || | 
| + (gpu_memmgr_stats_bin == NOW_AND_READY_TO_DRAW_BIN)) | 
| + memory_required_bytes_ += BytesConsumedIfAllocated(tile); | 
| + if (gpu_memmgr_stats_bin != NEVER_BIN) | 
| + memory_nice_to_have_bytes_ += BytesConsumedIfAllocated(tile); | 
| + } | 
| - if (!tile_is_ready_to_draw || tile_version.requires_resource()) { | 
| - if ((gpu_memmgr_stats_bin == NOW_BIN) || | 
| - (gpu_memmgr_stats_bin == NOW_AND_READY_TO_DRAW_BIN)) | 
| - memory_required_bytes_ += BytesConsumedIfAllocated(tile); | 
| - if (gpu_memmgr_stats_bin != NEVER_BIN) | 
| - memory_nice_to_have_bytes_ += BytesConsumedIfAllocated(tile); | 
| - } | 
| + // Bump up the priority if we determined it's NEVER_BIN on one tree, | 
| + // but is still required on the other tree. | 
| + bool is_in_never_bin_on_both_trees = | 
| + tree_bin[ACTIVE_TREE] == NEVER_BIN && | 
| + tree_bin[PENDING_TREE] == NEVER_BIN; | 
| - // Bump up the priority if we determined it's NEVER_BIN on one tree, | 
| - // but is still required on the other tree. | 
| - bool is_in_never_bin_on_both_trees = | 
| - tree_bin[ACTIVE_TREE] == NEVER_BIN && | 
| - tree_bin[PENDING_TREE] == NEVER_BIN; | 
| + if (mts.bin == NEVER_BIN && !is_in_never_bin_on_both_trees) | 
| + mts.bin = tile_is_active ? AT_LAST_AND_ACTIVE_BIN : AT_LAST_BIN; | 
| - if (mts.bin == NEVER_BIN && !is_in_never_bin_on_both_trees) | 
| - mts.bin = tile_is_active ? AT_LAST_AND_ACTIVE_BIN : AT_LAST_BIN; | 
| + mts.resolution = tile_priority.resolution; | 
| + mts.time_to_needed_in_seconds = tile_priority.time_to_visible_in_seconds; | 
| + mts.distance_to_visible_in_pixels = | 
| + tile_priority.distance_to_visible_in_pixels; | 
| + mts.required_for_activation = tile_priority.required_for_activation; | 
| - mts.resolution = tile_priority.resolution; | 
| - mts.time_to_needed_in_seconds = tile_priority.time_to_visible_in_seconds; | 
| - mts.distance_to_visible_in_pixels = | 
| - tile_priority.distance_to_visible_in_pixels; | 
| - mts.required_for_activation = tile_priority.required_for_activation; | 
| + mts.visible_and_ready_to_draw = | 
| + tree_bin[ACTIVE_TREE] == NOW_AND_READY_TO_DRAW_BIN; | 
| - mts.visible_and_ready_to_draw = | 
| - tree_bin[ACTIVE_TREE] == NOW_AND_READY_TO_DRAW_BIN; | 
| + if (mts.bin == NEVER_BIN) { | 
| + FreeResourcesForTile(tile); | 
| + continue; | 
| + } | 
| - if (mts.bin == NEVER_BIN) { | 
| - FreeResourcesForTile(tile); | 
| - continue; | 
| + // Note that if the tile is visible_and_ready_to_draw, then we always want | 
| + // the priority to be NOW_AND_READY_TO_DRAW_BIN, even if HIGH_PRIORITY_BIN | 
| + // is something different. The reason for this is that if we're | 
| + // prioritizing the pending tree, we still want visible tiles to take the | 
| + // highest priority. | 
| + ManagedTileBin priority_bin = mts.visible_and_ready_to_draw | 
| + ? NOW_AND_READY_TO_DRAW_BIN | 
| + : mts.bin; | 
| + | 
| + // Insert the tile into a priority set. | 
| + tiles->InsertTile(tile, priority_bin); | 
| } | 
| - | 
| - // Note that if the tile is visible_and_ready_to_draw, then we always want | 
| - // the priority to be NOW_AND_READY_TO_DRAW_BIN, even if HIGH_PRIORITY_BIN | 
| - // is something different. The reason for this is that if we're prioritizing | 
| - // the pending tree, we still want visible tiles to take the highest | 
| - // priority. | 
| - ManagedTileBin priority_bin = mts.visible_and_ready_to_draw | 
| - ? NOW_AND_READY_TO_DRAW_BIN | 
| - : mts.bin; | 
| - | 
| - // Insert the tile into a priority set. | 
| - tiles->InsertTile(tile, priority_bin); | 
| } | 
| } | 
| @@ -960,7 +984,7 @@ void TileManager::OnRasterTaskCompleted( | 
| } | 
| FreeUnusedResourcesForTile(tile); | 
| - if (tile->priority(ACTIVE_TREE).distance_to_visible_in_pixels == 0) | 
| + if (tile->is_visible()) | 
| did_initialize_visible_tile_ = true; | 
| } | 
| @@ -989,4 +1013,14 @@ scoped_refptr<Tile> TileManager::CreateTile(PicturePileImpl* picture_pile, | 
| return tile; | 
| } | 
| +scoped_refptr<TileBundle> TileManager::CreateTileBundle(int offset_x, | 
| + int offset_y, | 
| + int width, | 
| + int height) { | 
| + scoped_refptr<TileBundle> bundle = make_scoped_refptr( | 
| + new TileBundle(this, offset_x, offset_y, width, height)); | 
| + bundles_[bundle->id()] = bundle; | 
| + return bundle; | 
| +} | 
| + | 
| } // namespace cc |