summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cc/resources/managed_tile_state.cc32
-rw-r--r--cc/resources/managed_tile_state.h24
-rw-r--r--cc/resources/picture_layer_tiling_set_unittest.cc2
-rw-r--r--cc/resources/resource_pool.h4
-rw-r--r--cc/resources/tile.h8
-rw-r--r--cc/resources/tile_manager.cc67
-rw-r--r--cc/resources/tile_manager_unittest.cc12
-rw-r--r--cc/test/fake_tile_manager.cc9
-rw-r--r--cc/test/fake_tile_manager.h6
9 files changed, 67 insertions, 97 deletions
diff --git a/cc/resources/managed_tile_state.cc b/cc/resources/managed_tile_state.cc
index 836dd22..d137b8d 100644
--- a/cc/resources/managed_tile_state.cc
+++ b/cc/resources/managed_tile_state.cc
@@ -9,30 +9,6 @@
#include "cc/base/math_util.h"
namespace cc {
-namespace {
-
-scoped_ptr<base::Value> MemoryStateAsValue(TileVersionMemoryState 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 TileVersionMemoryState value " << state;
- return scoped_ptr<base::Value>(base::Value::CreateStringValue(
- "<unknown TileVersionMemoryState value>"));
- }
-}
-
-} // namespace
ManagedTileState::ManagedTileState()
: picture_pile_analyzed(false),
@@ -51,21 +27,17 @@ ManagedTileState::TileVersion::TileVersion()
: mode_(RESOURCE_MODE),
resource_id_(0),
resource_format_(GL_RGBA),
- memory_state_(NOT_ALLOWED_TO_USE_MEMORY),
forced_upload_(false) {
}
ManagedTileState::TileVersion::~TileVersion() {
DCHECK(!resource_);
- DCHECK(memory_state_ == NOT_ALLOWED_TO_USE_MEMORY);
}
bool ManagedTileState::TileVersion::IsReadyToDraw() const {
switch (mode_) {
case RESOURCE_MODE:
- return resource_id_ &&
- (memory_state_ == USING_RELEASABLE_MEMORY ||
- (memory_state_ == USING_UNRELEASABLE_MEMORY && forced_upload_));
+ return resource_id_ && (resource_ || forced_upload_);
case SOLID_COLOR_MODE:
case PICTURE_PILE_MODE:
return true;
@@ -87,8 +59,6 @@ ManagedTileState::~ManagedTileState() {
scoped_ptr<base::Value> ManagedTileState::AsValue() const {
scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
state->SetBoolean("has_resource", tile_version.resource_.get() != 0);
- state->Set("memory_state",
- MemoryStateAsValue(tile_version.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 51271ec..2305b26 100644
--- a/cc/resources/managed_tile_state.h
+++ b/cc/resources/managed_tile_state.h
@@ -14,13 +14,6 @@
namespace cc {
-enum TileVersionMemoryState {
- 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 {
@@ -45,8 +38,14 @@ class CC_EXPORT ManagedTileState {
ResourceProvider::ResourceId get_resource_id() const {
DCHECK(mode_ == RESOURCE_MODE);
+
+ // We have to have a resource ID here.
DCHECK(resource_id_);
- DCHECK(memory_state_ == USING_RELEASABLE_MEMORY || forced_upload_);
+ // If we have a resource, it implies IDs are equal.
+ DCHECK(!resource_ || (resource_id_ == resource_->id()));
+ // If we don't have a resource, it implies that we're in forced upload.
+ DCHECK(resource_ || (resource_id_ && forced_upload_));
+
return resource_id_;
}
@@ -76,10 +75,6 @@ class CC_EXPORT ManagedTileState {
return resource_;
}
- void SetMemoryStateForTesting(TileVersionMemoryState state) {
- memory_state_ = state;
- }
-
private:
friend class TileManager;
friend class Tile;
@@ -87,20 +82,16 @@ class CC_EXPORT ManagedTileState {
void set_use_resource() {
mode_ = RESOURCE_MODE;
- if (memory_state_ == NOT_ALLOWED_TO_USE_MEMORY)
- memory_state_ = CAN_USE_MEMORY;
}
void set_solid_color(const SkColor& color) {
mode_ = SOLID_COLOR_MODE;
solid_color_ = color;
- memory_state_ = NOT_ALLOWED_TO_USE_MEMORY;
resource_id_ = 0;
}
void set_rasterize_on_demand() {
mode_ = PICTURE_PILE_MODE;
- memory_state_ = NOT_ALLOWED_TO_USE_MEMORY;
resource_id_ = 0;
}
@@ -113,7 +104,6 @@ class CC_EXPORT ManagedTileState {
ResourceProvider::ResourceId resource_id_;
scoped_ptr<ResourcePool::Resource> resource_;
GLenum resource_format_;
- TileVersionMemoryState memory_state_;
bool forced_upload_;
};
diff --git a/cc/resources/picture_layer_tiling_set_unittest.cc b/cc/resources/picture_layer_tiling_set_unittest.cc
index 50a499a..46473c8 100644
--- a/cc/resources/picture_layer_tiling_set_unittest.cc
+++ b/cc/resources/picture_layer_tiling_set_unittest.cc
@@ -81,8 +81,6 @@ class PictureLayerTilingSetTestWithResources : public testing::Test {
resource_provider.get(),
gfx::Size(1, 1),
resource_provider->best_texture_format())));
- tiles[i]->tile_version().SetMemoryStateForTesting(
- USING_RELEASABLE_MEMORY);
}
}
diff --git a/cc/resources/resource_pool.h b/cc/resources/resource_pool.h
index 651f1d4..0f3b2b8 100644
--- a/cc/resources/resource_pool.h
+++ b/cc/resources/resource_pool.h
@@ -46,6 +46,10 @@ class CC_EXPORT ResourcePool {
size_t max_memory_usage_bytes,
size_t max_unused_memory_usage_bytes);
+ size_t acquired_memory_usage_bytes() const {
+ return memory_usage_bytes_ - unused_memory_usage_bytes_;
+ }
+
protected:
explicit ResourcePool(ResourceProvider* resource_provider);
diff --git a/cc/resources/tile.h b/cc/resources/tile.h
index 7a94d2b..2aa4c65 100644
--- a/cc/resources/tile.h
+++ b/cc/resources/tile.h
@@ -82,8 +82,12 @@ class CC_EXPORT Tile : public base::RefCounted<Tile> {
picture_pile_ = pile;
}
- bool IsAssignedGpuMemory() const {
- return tile_version().memory_state_ != NOT_ALLOWED_TO_USE_MEMORY;
+ // For test only methods.
+ bool HasRasterTaskForTesting() const {
+ return !managed_state().raster_task.is_null();
+ }
+ void ResetRasterTaskForTesting() {
+ managed_state().raster_task.Reset();
}
private:
diff --git a/cc/resources/tile_manager.cc b/cc/resources/tile_manager.cc
index 14012a9..8edacf6 100644
--- a/cc/resources/tile_manager.cc
+++ b/cc/resources/tile_manager.cc
@@ -307,7 +307,6 @@ void TileManager::CheckForCompletedTileUploads() {
++it) {
Tile* tile = *it;
if (!tile->managed_state().raster_task.is_null() &&
- tile->tile_version().memory_state_ == USING_UNRELEASABLE_MEMORY &&
!tile->tile_version().forced_upload_) {
if (!raster_worker_pool_->ForceUploadToComplete(
tile->managed_state().raster_task))
@@ -334,7 +333,7 @@ void TileManager::GetMemoryStats(
size_t* memory_used_bytes) const {
*memory_required_bytes = 0;
*memory_nice_to_have_bytes = 0;
- *memory_used_bytes = 0;
+ *memory_used_bytes = resource_pool_->acquired_memory_usage_bytes();
for (TileVector::const_iterator it = tiles_.begin();
it != tiles_.end();
++it) {
@@ -348,8 +347,6 @@ void TileManager::GetMemoryStats(
*memory_required_bytes += tile_bytes;
if (mts.gpu_memmgr_stats_bin != NEVER_BIN)
*memory_nice_to_have_bytes += tile_bytes;
- if (tile->tile_version().memory_state_ != NOT_ALLOWED_TO_USE_MEMORY)
- *memory_used_bytes += tile_bytes;
}
}
@@ -398,31 +395,30 @@ void TileManager::AddRequiredTileForActivation(Tile* tile) {
void TileManager::AssignGpuMemoryToTiles() {
TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles");
- size_t unreleasable_bytes = 0;
// Now give memory out to the tiles until we're out, and build
// the needs-to-be-rasterized queue.
tiles_that_need_to_be_rasterized_.clear();
tiles_that_need_to_be_initialized_for_activation_.clear();
- // By clearing the tiles_that_need_to_be_rasterized_ vector list
- // above we move all tiles currently waiting for raster to idle state.
- // Some memory cannot be released. We figure out how much in this
- // loop.
+ size_t bytes_releasable = 0;
for (TileVector::const_iterator it = tiles_.begin();
it != tiles_.end();
++it) {
const Tile* tile = *it;
- if (tile->tile_version().memory_state_ == USING_UNRELEASABLE_MEMORY)
- unreleasable_bytes += tile->bytes_consumed_if_allocated();
+ if (tile->tile_version().resource_)
+ bytes_releasable += tile->bytes_consumed_if_allocated();
}
- // Global state's memory limit can decrease, causing
- // it to be less than unreleasable_bytes
+ // Cast to prevent overflow.
+ int64 bytes_available =
+ static_cast<int64>(bytes_releasable) +
+ static_cast<int64>(global_state_.memory_limit_in_bytes) -
+ static_cast<int64>(resource_pool_->acquired_memory_usage_bytes());
+
size_t bytes_allocatable =
- global_state_.memory_limit_in_bytes > unreleasable_bytes ?
- global_state_.memory_limit_in_bytes - unreleasable_bytes :
- 0;
+ std::max(static_cast<int64>(0), bytes_available);
+
size_t bytes_that_exceeded_memory_budget_in_now_bin = 0;
size_t bytes_left = bytes_allocatable;
size_t bytes_oom_in_now_bin_on_pending_tree = 0;
@@ -439,22 +435,24 @@ void TileManager::AssignGpuMemoryToTiles() {
if (!tile_version.requires_resource())
continue;
- size_t tile_bytes = tile->bytes_consumed_if_allocated();
- // Memory is already reserved for tile with unreleasable memory
- // so adding it to |tiles_that_need_to_be_rasterized_| doesn't
- // affect bytes_allocatable.
- if (tile_version.memory_state_ == USING_UNRELEASABLE_MEMORY)
- tile_bytes = 0;
-
// If the tile is not needed, free it up.
if (mts.is_in_never_bin_on_both_trees()) {
- if (tile_version.memory_state_ != USING_UNRELEASABLE_MEMORY) {
- FreeResourcesForTile(tile);
- tile_version.memory_state_ = NOT_ALLOWED_TO_USE_MEMORY;
- }
+ FreeResourcesForTile(tile);
continue;
}
+ size_t tile_bytes = 0;
+
+ // It costs to maintain a resource.
+ if (tile_version.resource_)
+ tile_bytes += tile->bytes_consumed_if_allocated();
+
+ // It will cost to allocate a resource.
+ // Note that this is separate from the above condition,
+ // so that it's clear why we're adding memory.
+ if (!tile_version.resource_ && mts.raster_task.is_null())
+ tile_bytes += tile->bytes_consumed_if_allocated();
+
// Tile is OOM.
if (tile_bytes > bytes_left) {
tile->tile_version().set_rasterize_on_demand();
@@ -494,8 +492,7 @@ void TileManager::AssignGpuMemoryToTiles() {
Tile* tile = *it;
ManagedTileState& mts = tile->managed_state();
ManagedTileState::TileVersion& tile_version = tile->tile_version();
- if ((tile_version.memory_state_ == CAN_USE_MEMORY ||
- tile_version.memory_state_ == USING_RELEASABLE_MEMORY) &&
+ if (tile_version.resource_ &&
mts.tree_bin[PENDING_TREE] == NEVER_BIN &&
mts.tree_bin[ACTIVE_TREE] != NOW_BIN) {
DCHECK(!tile->required_for_activation());
@@ -539,18 +536,17 @@ void TileManager::AssignGpuMemoryToTiles() {
global_state_.memory_limit_in_bytes;
memory_stats_from_last_assign_.bytes_allocated =
bytes_allocatable - bytes_left;
- memory_stats_from_last_assign_.bytes_unreleasable = unreleasable_bytes;
+ memory_stats_from_last_assign_.bytes_unreleasable =
+ bytes_allocatable - bytes_releasable;
memory_stats_from_last_assign_.bytes_over =
bytes_that_exceeded_memory_budget_in_now_bin;
}
void TileManager::FreeResourcesForTile(Tile* tile) {
- DCHECK_NE(USING_UNRELEASABLE_MEMORY, tile->tile_version().memory_state_);
if (tile->tile_version().resource_) {
resource_pool_->ReleaseResource(
tile->tile_version().resource_.Pass());
}
- tile->tile_version().memory_state_ = NOT_ALLOWED_TO_USE_MEMORY;
}
void TileManager::ScheduleTasks() {
@@ -627,8 +623,6 @@ RasterWorkerPool::RasterTask TileManager::CreateRasterTask(Tile* tile) {
tile->tile_version().resource_format_);
const Resource* const_resource = resource.get();
- DCHECK_EQ(CAN_USE_MEMORY, tile->tile_version().memory_state_);
- tile->tile_version().memory_state_ = USING_UNRELEASABLE_MEMORY;
tile->tile_version().resource_id_ = resource->id();
PicturePileImpl::Analysis* analysis = new PicturePileImpl::Analysis;
@@ -699,11 +693,7 @@ void TileManager::OnRasterTaskCompleted(
DCHECK(!mts.raster_task.is_null());
mts.raster_task.Reset();
- // Tile resources can't be freed until task has completed.
- DCHECK_EQ(USING_UNRELEASABLE_MEMORY, tile->tile_version().memory_state_);
-
if (was_canceled) {
- tile->tile_version().memory_state_ = CAN_USE_MEMORY;
resource_pool_->ReleaseResource(resource.Pass());
return;
}
@@ -715,7 +705,6 @@ void TileManager::OnRasterTaskCompleted(
tile->tile_version().set_solid_color(analysis->solid_color);
resource_pool_->ReleaseResource(resource.Pass());
} else {
- tile->tile_version().memory_state_ = USING_RELEASABLE_MEMORY;
tile->tile_version().resource_ = resource.Pass();
}
diff --git a/cc/resources/tile_manager_unittest.cc b/cc/resources/tile_manager_unittest.cc
index 80290e6..5f432b0 100644
--- a/cc/resources/tile_manager_unittest.cc
+++ b/cc/resources/tile_manager_unittest.cc
@@ -4,6 +4,7 @@
#include "cc/resources/tile.h"
#include "cc/resources/tile_priority.h"
+#include "cc/test/fake_output_surface.h"
#include "cc/test/fake_tile_manager.h"
#include "cc/test/fake_tile_manager_client.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -55,7 +56,10 @@ class TileManagerTest : public testing::Test {
void Initialize(int max_memory_tiles,
TileMemoryLimitPolicy memory_limit_policy,
TreePriority tree_priority) {
- tile_manager_ = make_scoped_ptr(new FakeTileManager(&tile_manager_client_));
+ output_surface_ = FakeOutputSurface::Create3d();
+ resource_provider_ = ResourceProvider::Create(output_surface_.get(), 0);
+ tile_manager_ = make_scoped_ptr(
+ new FakeTileManager(&tile_manager_client_, resource_provider_.get()));
GlobalStateThatImpactsTilePriority state;
gfx::Size tile_size = settings_.default_tile_size;
@@ -105,8 +109,9 @@ class TileManagerTest : public testing::Test {
for (TileVector::const_iterator it = tiles.begin();
it != tiles.end();
++it) {
- if ((*it)->IsAssignedGpuMemory())
+ if ((*it)->HasRasterTaskForTesting())
++has_memory_count;
+ (*it)->ResetRasterTaskForTesting();
}
return has_memory_count;
}
@@ -116,6 +121,8 @@ class TileManagerTest : public testing::Test {
LayerTreeSettings settings_;
scoped_ptr<FakeTileManager> tile_manager_;
scoped_refptr<FakePicturePileImpl> picture_pile_;
+ scoped_ptr<FakeOutputSurface> output_surface_;
+ scoped_ptr<ResourceProvider> resource_provider_;
};
TEST_F(TileManagerTest, EnoughMemoryAllowAnything) {
@@ -141,6 +148,7 @@ TEST_F(TileManagerTest, EnoughMemoryAllowAnything) {
pending_now.clear();
active_pending_soon.clear();
never_bin.clear();
+
TearDown();
}
diff --git a/cc/test/fake_tile_manager.cc b/cc/test/fake_tile_manager.cc
index c3af876..e87b159 100644
--- a/cc/test/fake_tile_manager.cc
+++ b/cc/test/fake_tile_manager.cc
@@ -26,4 +26,13 @@ FakeTileManager::FakeTileManager(TileManagerClient* client)
1,
false,
NULL) {}
+
+FakeTileManager::FakeTileManager(TileManagerClient* client,
+ ResourceProvider* resource_provider)
+ : TileManager(client,
+ resource_provider,
+ make_scoped_ptr<RasterWorkerPool>(new FakeRasterWorkerPool),
+ 1,
+ false,
+ NULL) {}
}
diff --git a/cc/test/fake_tile_manager.h b/cc/test/fake_tile_manager.h
index fb62ce3..a061ee0 100644
--- a/cc/test/fake_tile_manager.h
+++ b/cc/test/fake_tile_manager.h
@@ -12,12 +12,10 @@ namespace cc {
class FakeTileManager : public TileManager {
public:
explicit FakeTileManager(TileManagerClient* client);
+ FakeTileManager(TileManagerClient* client,
+ ResourceProvider* resource_provider);
virtual ~FakeTileManager() { }
-
- protected:
- // Do nothing
- virtual void ScheduleTasks() OVERRIDE { }
};
} // namespace cc