diff options
author | vmpstr@chromium.org <vmpstr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-30 00:53:36 +0000 |
---|---|---|
committer | vmpstr@chromium.org <vmpstr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-30 00:53:36 +0000 |
commit | 09059df297af201421abdd3be516cf3ca21dab87 (patch) | |
tree | af0e91da77525d4b9432f4ec73faedb14ac77acb /cc | |
parent | 5f01ce2a2ae37642c94d7be68f9b32423f69eddd (diff) | |
download | chromium_src-09059df297af201421abdd3be516cf3ca21dab87.zip chromium_src-09059df297af201421abdd3be516cf3ca21dab87.tar.gz chromium_src-09059df297af201421abdd3be516cf3ca21dab87.tar.bz2 |
cc: TileManager AssignGpuMemory cleanup
This is work in progress. Some of the functionality to get
the currently used memory is moved into DrawingInfo, which
(hopefully) makes TileManager a bit more clear when dealing
with tile memory
BUG=225804
Review URL: https://chromiumcodereview.appspot.com/13771015
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@197193 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r-- | cc/resources/managed_tile_state.cc | 46 | ||||
-rw-r--r-- | cc/resources/managed_tile_state.h | 33 | ||||
-rw-r--r-- | cc/resources/picture_layer_tiling_set_unittest.cc | 2 | ||||
-rw-r--r-- | cc/resources/tile.h | 4 | ||||
-rw-r--r-- | cc/resources/tile_manager.cc | 96 |
5 files changed, 113 insertions, 68 deletions
diff --git a/cc/resources/managed_tile_state.cc b/cc/resources/managed_tile_state.cc index ae144be..40fb465 100644 --- a/cc/resources/managed_tile_state.cc +++ b/cc/resources/managed_tile_state.cc @@ -9,10 +9,33 @@ #include "cc/base/math_util.h" namespace cc { +namespace { + +scoped_ptr<base::Value> MemoryStateAsValue(DrawingInfoMemoryState state) { + switch (state) { + case NOT_ALLOWED_TO_USE_MEMORY: + return scoped_ptr<base::Value>( + base::Value::CreateStringValue("NOT_ALLOWED_TO_USE_MEMORY")); + case CAN_USE_MEMORY: + return scoped_ptr<base::Value>( + base::Value::CreateStringValue("CAN_USE_MEMORY")); + case USING_UNRELEASABLE_MEMORY: + return scoped_ptr<base::Value>( + base::Value::CreateStringValue("USING_UNRELEASABLE_MEMORY")); + case USING_RELEASABLE_MEMORY: + return scoped_ptr<base::Value>( + base::Value::CreateStringValue("USING_RELEASABLE_MEMORY")); + default: + NOTREACHED() << "Unrecognized DrawingInfoMemoryState value " << state; + return scoped_ptr<base::Value>(base::Value::CreateStringValue( + "<unknown DrawingInfoMemoryState value>")); + } +} + +} // namespace ManagedTileState::ManagedTileState() - : can_use_gpu_memory(false), - need_to_gather_pixel_refs(true), + : need_to_gather_pixel_refs(true), picture_pile_analyzed(false), gpu_memmgr_stats_bin(NEVER_BIN), resolution(NON_IDEAL_RESOLUTION), @@ -26,19 +49,22 @@ ManagedTileState::ManagedTileState() ManagedTileState::DrawingInfo::DrawingInfo() : mode_(RESOURCE_MODE), - resource_is_being_initialized_(false), - can_be_freed_(true), - resource_format_(GL_RGBA) { + resource_format_(GL_RGBA), + memory_state_(NOT_ALLOWED_TO_USE_MEMORY), + forced_upload_(false) { } ManagedTileState::DrawingInfo::~DrawingInfo() { + DCHECK(!resource_); + DCHECK(memory_state_ == NOT_ALLOWED_TO_USE_MEMORY); } bool ManagedTileState::DrawingInfo::IsReadyToDraw() const { switch (mode_) { case RESOURCE_MODE: return resource_ && - !resource_is_being_initialized_ && + (memory_state_ == USING_RELEASABLE_MEMORY || + (memory_state_ == USING_UNRELEASABLE_MEMORY && forced_upload_)) && resource_->id(); case SOLID_COLOR_MODE: case TRANSPARENT_MODE: @@ -51,17 +77,13 @@ bool ManagedTileState::DrawingInfo::IsReadyToDraw() const { } ManagedTileState::~ManagedTileState() { - DCHECK(!drawing_info.resource_); - DCHECK(!drawing_info.resource_is_being_initialized_); } scoped_ptr<base::Value> ManagedTileState::AsValue() const { scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); - state->SetBoolean("can_use_gpu_memory", can_use_gpu_memory); - state->SetBoolean("can_be_freed", drawing_info.can_be_freed_); state->SetBoolean("has_resource", drawing_info.resource_.get() != 0); - state->SetBoolean("resource_is_being_initialized", - drawing_info.resource_is_being_initialized_); + state->Set("memory_state", + MemoryStateAsValue(drawing_info.memory_state_).release()); state->Set("bin.0", TileManagerBinAsValue(bin[ACTIVE_TREE]).release()); state->Set("bin.1", TileManagerBinAsValue(bin[PENDING_TREE]).release()); state->Set("gpu_memmgr_stats_bin", diff --git a/cc/resources/managed_tile_state.h b/cc/resources/managed_tile_state.h index 78346e7..fa1fb67 100644 --- a/cc/resources/managed_tile_state.h +++ b/cc/resources/managed_tile_state.h @@ -15,6 +15,13 @@ namespace cc { +enum DrawingInfoMemoryState { + NOT_ALLOWED_TO_USE_MEMORY, + CAN_USE_MEMORY, + USING_UNRELEASABLE_MEMORY, + USING_RELEASABLE_MEMORY +}; + // This is state that is specific to a tile that is // managed by the TileManager. class CC_EXPORT ManagedTileState { @@ -41,7 +48,7 @@ class CC_EXPORT ManagedTileState { ResourceProvider::ResourceId get_resource_id() const { DCHECK(mode_ == RESOURCE_MODE); DCHECK(resource_); - DCHECK(!resource_is_being_initialized_); + DCHECK(memory_state_ == USING_RELEASABLE_MEMORY || forced_upload_); return resource_->id(); } @@ -64,34 +71,44 @@ class CC_EXPORT ManagedTileState { return resource_; } + void SetMemoryStateForTesting(DrawingInfoMemoryState state) { + memory_state_ = state; + } + private: friend class TileManager; + friend class Tile; friend class ManagedTileState; void set_use_resource() { mode_ = RESOURCE_MODE; + if (memory_state_ == NOT_ALLOWED_TO_USE_MEMORY) + memory_state_ = CAN_USE_MEMORY; } void set_transparent() { mode_ = TRANSPARENT_MODE; + memory_state_ = NOT_ALLOWED_TO_USE_MEMORY; } void set_solid_color(const SkColor& color) { mode_ = SOLID_COLOR_MODE; solid_color_ = color; + memory_state_ = NOT_ALLOWED_TO_USE_MEMORY; } void set_rasterize_on_demand() { mode_ = PICTURE_PILE_MODE; + memory_state_ = NOT_ALLOWED_TO_USE_MEMORY; } Mode mode_; SkColor solid_color_; scoped_ptr<ResourcePool::Resource> resource_; - bool resource_is_being_initialized_; - bool can_be_freed_; GLenum resource_format_; + DrawingInfoMemoryState memory_state_; + bool forced_upload_; }; @@ -100,7 +117,6 @@ class CC_EXPORT ManagedTileState { scoped_ptr<base::Value> AsValue() const; // Persisted state: valid all the time. - bool can_use_gpu_memory; bool need_to_gather_pixel_refs; std::list<skia::LazyPixelRef*> pending_pixel_refs; DrawingInfo drawing_info; @@ -108,6 +124,15 @@ class CC_EXPORT ManagedTileState { bool picture_pile_analyzed; // Ephemeral state, valid only during TileManager::ManageTiles. + bool is_in_never_bin_on_both_trees() const { + return bin[HIGH_PRIORITY_BIN] == NEVER_BIN && + bin[LOW_PRIORITY_BIN] == NEVER_BIN; + } + bool is_in_now_bin_on_either_tree() const { + return bin[HIGH_PRIORITY_BIN] == NOW_BIN || + bin[LOW_PRIORITY_BIN] == NOW_BIN; + } + TileManagerBin bin[NUM_BIN_PRIORITIES]; TileManagerBin tree_bin[NUM_TREES]; diff --git a/cc/resources/picture_layer_tiling_set_unittest.cc b/cc/resources/picture_layer_tiling_set_unittest.cc index d2af09a..90aa5ed 100644 --- a/cc/resources/picture_layer_tiling_set_unittest.cc +++ b/cc/resources/picture_layer_tiling_set_unittest.cc @@ -84,6 +84,8 @@ class PictureLayerTilingSetTestWithResources : public testing::Test { resource_provider.get(), gfx::Size(1, 1), resource_provider->best_texture_format())); + tiles[i]->drawing_info().SetMemoryStateForTesting( + USING_RELEASABLE_MEMORY); } } diff --git a/cc/resources/tile.h b/cc/resources/tile.h index fbb9002..f68fdf1 100644 --- a/cc/resources/tile.h +++ b/cc/resources/tile.h @@ -69,7 +69,9 @@ class CC_EXPORT Tile : public base::RefCounted<Tile> { picture_pile_ = pile; } - bool IsAssignedGpuMemory() const { return managed_state_.can_use_gpu_memory; } + bool IsAssignedGpuMemory() const { + return drawing_info().memory_state_ != NOT_ALLOWED_TO_USE_MEMORY; + } private: // Methods called by by tile manager. diff --git a/cc/resources/tile_manager.cc b/cc/resources/tile_manager.cc index 08cea05..5063080 100644 --- a/cc/resources/tile_manager.cc +++ b/cc/resources/tile_manager.cc @@ -284,8 +284,8 @@ void TileManager::AssignBinsToTiles() { for (int i = 0; i < NUM_BIN_PRIORITIES; ++i) mts.bin[i] = bin_map[mts.bin[i]]; - if (!tile->drawing_info().resource_ && - !tile->drawing_info().resource_is_being_initialized_ && + if ((tile->drawing_info().memory_state_ == CAN_USE_MEMORY || + tile->drawing_info().memory_state_ == NOT_ALLOWED_TO_USE_MEMORY) && !tile->priority(ACTIVE_TREE).is_live && !tile->priority(PENDING_TREE).is_live) continue; @@ -340,9 +340,10 @@ void TileManager::CheckForCompletedTileUploads() { resource_pool_->resource_provider()->ReleasePixelBuffer( tile->drawing_info().resource_->id()); - tile->drawing_info().can_be_freed_ = true; - bytes_pending_upload_ -= tile->bytes_consumed_if_allocated(); + // Reset forced_upload_ since we now got the upload completed notification. + tile->drawing_info().forced_upload_ = false; + tile->drawing_info().memory_state_ = USING_RELEASABLE_MEMORY; DidFinishTileInitialization(tile); tiles_with_pending_upload_.pop(); @@ -361,9 +362,6 @@ void TileManager::AbortPendingTileUploads() { resource_pool_->resource_provider()->ReleasePixelBuffer( tile->drawing_info().resource_->id()); - tile->drawing_info().resource_is_being_initialized_ = false; - tile->drawing_info().can_be_freed_ = true; - tile->managed_state().can_use_gpu_memory = false; FreeResourcesForTile(tile); bytes_pending_upload_ -= tile->bytes_consumed_if_allocated(); @@ -374,9 +372,17 @@ void TileManager::AbortPendingTileUploads() { void TileManager::ForceTileUploadToComplete(Tile* tile) { DCHECK(tile); if (tile->drawing_info().resource_ && - tile->drawing_info().resource_is_being_initialized_) { + tile->drawing_info().memory_state_ == USING_UNRELEASABLE_MEMORY && + !tile->drawing_info().forced_upload_) { resource_pool_->resource_provider()-> ForceSetPixelsToComplete(tile->drawing_info().resource_->id()); + + // We have to set the memory state to be unreleasable, to ensure + // that the tile will not be freed until we get the upload finished + // notification. However, setting |forced_upload_| to true makes + // this tile ready to draw. + tile->drawing_info().memory_state_ = USING_UNRELEASABLE_MEMORY; + tile->drawing_info().forced_upload_ = true; DidFinishTileInitialization(tile); } @@ -404,7 +410,7 @@ void TileManager::GetMemoryStats( *memory_required_bytes += tile_bytes; if (mts.gpu_memmgr_stats_bin != NEVER_BIN) *memory_nice_to_have_bytes += tile_bytes; - if (mts.can_use_gpu_memory) + if (tile->drawing_info().memory_state_ != NOT_ALLOWED_TO_USE_MEMORY) *memory_used_bytes += tile_bytes; } } @@ -469,10 +475,7 @@ void TileManager::AssignGpuMemoryToTiles() { for (TileVector::iterator it = live_or_allocated_tiles_.begin(); it != live_or_allocated_tiles_.end(); ++it) { Tile* tile = *it; - if (!tile->drawing_info().requires_resource()) - continue; - - if (!tile->drawing_info().can_be_freed_) + if (tile->drawing_info().memory_state_ == USING_UNRELEASABLE_MEMORY) unreleasable_bytes += tile->bytes_consumed_if_allocated(); } @@ -491,23 +494,24 @@ void TileManager::AssignGpuMemoryToTiles() { ++it) { Tile* tile = *it; ManagedTileState& mts = tile->managed_state(); - if (!tile->drawing_info().requires_resource()) + ManagedTileState::DrawingInfo& drawing_info = tile->drawing_info(); + + // If this tile doesn't need a resource, or if the memory + // is unreleasable, then we do not need to do anything. + if (!drawing_info.requires_resource() || + drawing_info.memory_state_ == USING_UNRELEASABLE_MEMORY) { continue; + } size_t tile_bytes = tile->bytes_consumed_if_allocated(); - if (!tile->drawing_info().can_be_freed_) - continue; - if (mts.bin[HIGH_PRIORITY_BIN] == NEVER_BIN && - mts.bin[LOW_PRIORITY_BIN] == NEVER_BIN) { - mts.can_use_gpu_memory = false; + // If the tile is not needed, free it up. + if (mts.is_in_never_bin_on_both_trees()) { FreeResourcesForTile(tile); + drawing_info.memory_state_ = NOT_ALLOWED_TO_USE_MEMORY; continue; } + // Tile is OOM. if (tile_bytes > bytes_left) { - mts.can_use_gpu_memory = false; - if (mts.bin[HIGH_PRIORITY_BIN] == NOW_BIN || - mts.bin[LOW_PRIORITY_BIN] == NOW_BIN) - bytes_that_exceeded_memory_budget_in_now_bin += tile_bytes; FreeResourcesForTile(tile); tile->drawing_info().set_rasterize_on_demand(); if (mts.tree_bin[PENDING_TREE] == NOW_BIN) { @@ -516,11 +520,10 @@ void TileManager::AssignGpuMemoryToTiles() { } continue; } - tile->drawing_info().set_use_resource(); + drawing_info.set_use_resource(); bytes_left -= tile_bytes; - mts.can_use_gpu_memory = true; - if (!tile->drawing_info().resource_ && - !tile->drawing_info().resource_is_being_initialized_) { + if (!drawing_info.resource_ && + drawing_info.memory_state_ == CAN_USE_MEMORY) { tiles_that_need_to_be_rasterized_.push_back(tile); } } @@ -533,12 +536,13 @@ void TileManager::AssignGpuMemoryToTiles() { it != all_tiles_.end(); ++it) { Tile* tile = *it; ManagedTileState& mts = tile->managed_state(); - if (mts.can_use_gpu_memory == true && + ManagedTileState::DrawingInfo& drawing_info = tile->drawing_info(); + if ((drawing_info.memory_state_ == CAN_USE_MEMORY || + drawing_info.memory_state_ == USING_RELEASABLE_MEMORY) && mts.tree_bin[PENDING_TREE] == NEVER_BIN && - mts.tree_bin[ACTIVE_TREE] != NOW_BIN && - tile->drawing_info().can_be_freed_ ) { - mts.can_use_gpu_memory = false; + mts.tree_bin[ACTIVE_TREE] != NOW_BIN) { FreeResourcesForTile(tile); + drawing_info.set_rasterize_on_demand(); bytes_freed += tile->bytes_consumed_if_allocated(); TileVector::iterator it = std::find( tiles_that_need_to_be_rasterized_.begin(), @@ -556,16 +560,11 @@ void TileManager::AssignGpuMemoryToTiles() { ++it) { Tile* tile = *it; size_t bytes_needed = tile->bytes_consumed_if_allocated(); - ManagedTileState& mts = tile->managed_state(); if (bytes_needed > bytes_freed) continue; tile->drawing_info().set_use_resource(); bytes_freed -= bytes_needed; - mts.can_use_gpu_memory = true; - if (!mts.drawing_info.resource_ && - !mts.drawing_info.resource_is_being_initialized_) { - tiles_that_need_to_be_rasterized_.push_back(tile); - } + tiles_that_need_to_be_rasterized_.push_back(tile); } } @@ -592,10 +591,12 @@ void TileManager::AssignGpuMemoryToTiles() { } void TileManager::FreeResourcesForTile(Tile* tile) { - DCHECK(tile->drawing_info().can_be_freed_); - if (tile->drawing_info().resource_) + DCHECK(tile->drawing_info().memory_state_ != USING_UNRELEASABLE_MEMORY); + if (tile->drawing_info().resource_) { resource_pool_->ReleaseResource( tile->drawing_info().resource_.Pass()); + } + tile->drawing_info().memory_state_ = NOT_ALLOWED_TO_USE_MEMORY; } bool TileManager::CanDispatchRasterTask(Tile* tile) const { @@ -763,15 +764,12 @@ void TileManager::OnImageDecodeTaskCompleted( scoped_ptr<ResourcePool::Resource> TileManager::PrepareTileForRaster( Tile* tile) { - ManagedTileState& managed_tile_state = tile->managed_state(); - DCHECK(managed_tile_state.can_use_gpu_memory); scoped_ptr<ResourcePool::Resource> resource = resource_pool_->AcquireResource( tile->tile_size_.size(), tile->drawing_info().resource_format_); resource_pool_->resource_provider()->AcquirePixelBuffer(resource->id()); - tile->drawing_info().resource_is_being_initialized_ = true; - tile->drawing_info().can_be_freed_ = false; + tile->drawing_info().memory_state_ = USING_UNRELEASABLE_MEMORY; return resource.Pass(); } @@ -826,7 +824,7 @@ void TileManager::OnRasterTaskCompleted( // Release raster resources. resource_pool_->resource_provider()->UnmapPixelBuffer(resource->id()); - tile->drawing_info().can_be_freed_ = true; + tile->drawing_info().memory_state_ = USING_RELEASABLE_MEMORY; // Tile can be freed after the completion of the raster task. Call // AssignGpuMemoryToTiles() to re-assign gpu memory to highest priority @@ -837,12 +835,10 @@ void TileManager::OnRasterTaskCompleted( if (manage_tiles_call_count_when_dispatched != manage_tiles_call_count_) AssignGpuMemoryToTiles(); - ManagedTileState& managed_tile_state = tile->managed_state(); - - // Finish resource initialization if |can_use_gpu_memory| is true. - if (managed_tile_state.can_use_gpu_memory) { + // Finish resource initialization we're still using memory. + if (tile->drawing_info().memory_state_ == USING_RELEASABLE_MEMORY) { // Tile resources can't be freed until upload has completed. - tile->drawing_info().can_be_freed_ = false; + tile->drawing_info().memory_state_ = USING_UNRELEASABLE_MEMORY; resource_pool_->resource_provider()->BeginSetPixels(resource->id()); has_performed_uploads_since_last_flush_ = true; @@ -854,12 +850,10 @@ void TileManager::OnRasterTaskCompleted( } else { resource_pool_->resource_provider()->ReleasePixelBuffer(resource->id()); resource_pool_->ReleaseResource(resource.Pass()); - tile->drawing_info().resource_is_being_initialized_ = false; } } void TileManager::DidFinishTileInitialization(Tile* tile) { - tile->drawing_info().resource_is_being_initialized_ = false; if (tile->priority(ACTIVE_TREE).distance_to_visible_in_pixels == 0) did_initialize_visible_tile_ = true; } |