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 |