summaryrefslogtreecommitdiffstats
path: root/cc
diff options
context:
space:
mode:
authorvmpstr@chromium.org <vmpstr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-30 00:53:36 +0000
committervmpstr@chromium.org <vmpstr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-30 00:53:36 +0000
commit09059df297af201421abdd3be516cf3ca21dab87 (patch)
treeaf0e91da77525d4b9432f4ec73faedb14ac77acb /cc
parent5f01ce2a2ae37642c94d7be68f9b32423f69eddd (diff)
downloadchromium_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.cc46
-rw-r--r--cc/resources/managed_tile_state.h33
-rw-r--r--cc/resources/picture_layer_tiling_set_unittest.cc2
-rw-r--r--cc/resources/tile.h4
-rw-r--r--cc/resources/tile_manager.cc96
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;
}