Chromium Code Reviews| Index: cc/resources/tile_manager.cc | 
| diff --git a/cc/resources/tile_manager.cc b/cc/resources/tile_manager.cc | 
| index 85c7fa15ef6a8aaa239a43d79ff63423a9ff0bac..92af37a6510c160a377309411d7abcfa748f47e5 100644 | 
| --- a/cc/resources/tile_manager.cc | 
| +++ b/cc/resources/tile_manager.cc | 
| @@ -16,6 +16,7 @@ | 
| #include "cc/debug/traced_value.h" | 
| #include "cc/resources/image_raster_worker_pool.h" | 
| #include "cc/resources/pixel_buffer_raster_worker_pool.h" | 
| +#include "cc/resources/shared_tile_bundle.h" | 
| #include "cc/resources/tile.h" | 
| #include "third_party/skia/include/core/SkCanvas.h" | 
| #include "ui/gfx/rect_conversions.h" | 
| @@ -219,6 +220,7 @@ TileManager::~TileManager() { | 
| global_state_ = GlobalStateThatImpactsTilePriority(); | 
| CleanUpReleasedTiles(); | 
| + DCHECK_EQ(0u, bundles_.size()); | 
| DCHECK_EQ(0u, tiles_.size()); | 
| RasterWorkerPool::RasterTask::Queue empty; | 
| @@ -238,6 +240,10 @@ void TileManager::Release(Tile* tile) { | 
| released_tiles_.push_back(tile); | 
| } | 
| +void TileManager::Release(TileBundle* bundle) { | 
| + released_tile_bundles_.push_back(bundle); | 
| +} | 
| + | 
| void TileManager::DidChangeTilePriority(Tile* tile) { | 
| prioritized_tiles_dirty_ = true; | 
| } | 
| @@ -247,6 +253,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) { | 
| @@ -267,7 +285,6 @@ void TileManager::CleanUpReleasedTiles() { | 
| delete tile; | 
| } | 
| - | 
| released_tiles_.clear(); | 
| } | 
| @@ -353,114 +370,118 @@ 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 (BundleSetIterator bundle_it(&bundles_); bundle_it; ++bundle_it) { | 
| + TilePriority active_priority = bundle_it->active_priority(); | 
| + TilePriority pending_priority = bundle_it->pending_priority(); | 
| + TilePriority combined_priority(active_priority, pending_priority); | 
| + ManagedTileBin base_active_bin = BinFromTilePriority(active_priority); | 
| + ManagedTileBin base_pending_bin = BinFromTilePriority(pending_priority); | 
| + | 
| + for (SharedTileBundle::Iterator it(*bundle_it); it; ++it) { | 
| + Tile* tile = *it; | 
| + tile->set_is_visible(active_priority.distance_to_visible_in_pixels == 0); | 
| + 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(); | 
| + | 
| + ManagedTileBin active_bin = base_active_bin; | 
| + ManagedTileBin pending_bin = base_pending_bin; | 
| + | 
| + // Adjust pending bin state for low res tiles. This prevents | 
| + // pending tree low-res tiles from being initialized before | 
| + // high-res tiles. | 
| + if (pending_priority.resolution == LOW_RESOLUTION) | 
| + pending_bin = std::max(pending_bin, EVENTUALLY_BIN); | 
| + | 
| + // Compute combined bin. | 
| + ManagedTileBin combined_bin = std::min(active_bin, pending_bin); | 
| + | 
| + // Adjust bin state based on if ready to draw. | 
| + active_bin = kBinReadyToDrawMap[tile_is_ready_to_draw][active_bin]; | 
| 
 
enne (OOO)
2013/11/20 21:20:30
Ugh, all this logic is so complicated.  Maybe afte
 
 | 
| + pending_bin = kBinReadyToDrawMap[tile_is_ready_to_draw][pending_bin]; | 
| + combined_bin = kBinReadyToDrawMap[tile_is_ready_to_draw][combined_bin]; | 
| + | 
| + // Adjust bin state based on if active. | 
| + active_bin = kBinIsActiveMap[tile_is_active][active_bin]; | 
| + pending_bin = kBinIsActiveMap[tile_is_active][pending_bin]; | 
| + combined_bin = kBinIsActiveMap[tile_is_active][combined_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 = 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; | 
| + } | 
| - 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); | 
| - | 
| - // Adjust pending bin state for low res tiles. This prevents | 
| - // pending tree low-res tiles from being initialized before | 
| - // high-res tiles. | 
| - if (pending_priority.resolution == LOW_RESOLUTION) | 
| - pending_bin = std::max(pending_bin, EVENTUALLY_BIN); | 
| - | 
| - // Compute combined bin. | 
| - ManagedTileBin combined_bin = std::min(active_bin, pending_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]; | 
| - combined_bin = kBinReadyToDrawMap[tile_is_ready_to_draw][combined_bin]; | 
| - | 
| - // Adjust bin state based on if active. | 
| - active_bin = kBinIsActiveMap[tile_is_active][active_bin]; | 
| - pending_bin = kBinIsActiveMap[tile_is_active][pending_bin]; | 
| - combined_bin = kBinIsActiveMap[tile_is_active][combined_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); | 
| 
 
enne (OOO)
2013/11/20 00:14:34
Curious why tiles are in bins and not bundles, sin
 
vmpstr
2013/11/20 00:54:09
There's a few cases (namely required for activatio
 
 | 
| } | 
| - | 
| - // 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); | 
| } | 
| } | 
| @@ -944,7 +965,7 @@ void TileManager::OnRasterTaskCompleted( | 
| } | 
| FreeUnusedResourcesForTile(tile); | 
| - if (tile->priority(ACTIVE_TREE).distance_to_visible_in_pixels == 0) | 
| + if (tile->is_visible() == 0) | 
| 
 
reveman
2013/11/20 01:34:37
is_visible() returning 0 means tile is visible?
 
 | 
| did_initialize_visible_tile_ = true; | 
| } | 
| @@ -973,4 +994,14 @@ scoped_refptr<Tile> TileManager::CreateTile(PicturePileImpl* picture_pile, | 
| return tile; | 
| } | 
| +scoped_refptr<TileBundle> TileManager::CreateTileBundle(int width, | 
| + int height, | 
| + int offset_x, | 
| + int offset_y) { | 
| + scoped_refptr<TileBundle> bundle = make_scoped_refptr( | 
| + new TileBundle(this, width, height, offset_x, offset_y)); | 
| + bundles_[bundle->id()] = bundle; | 
| + return bundle; | 
| +} | 
| + | 
| } // namespace cc |