summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cc/resources/managed_tile_state.cc3
-rw-r--r--cc/resources/managed_tile_state.h1
-rw-r--r--cc/resources/tile_manager.cc144
-rw-r--r--cc/resources/tile_manager.h7
-rw-r--r--cc/resources/tile_manager_unittest.cc23
-rw-r--r--cc/test/fake_tile_manager.cc9
-rw-r--r--cc/test/fake_tile_manager.h2
-rw-r--r--cc/trees/layer_tree_host_impl.cc3
8 files changed, 60 insertions, 132 deletions
diff --git a/cc/resources/managed_tile_state.cc b/cc/resources/managed_tile_state.cc
index b496a78..e375a93 100644
--- a/cc/resources/managed_tile_state.cc
+++ b/cc/resources/managed_tile_state.cc
@@ -53,7 +53,8 @@ ManagedTileState::ManagedTileState()
resolution(NON_IDEAL_RESOLUTION),
required_for_activation(false),
time_to_needed_in_seconds(std::numeric_limits<float>::infinity()),
- distance_to_visible_in_pixels(std::numeric_limits<float>::infinity()) {
+ distance_to_visible_in_pixels(std::numeric_limits<float>::infinity()),
+ visible_and_ready_to_draw(false) {
for (int i = 0; i < NUM_TREES; ++i) {
tree_bin[i] = NEVER_BIN;
bin[i] = NEVER_BIN;
diff --git a/cc/resources/managed_tile_state.h b/cc/resources/managed_tile_state.h
index 6959f1d..4437134 100644
--- a/cc/resources/managed_tile_state.h
+++ b/cc/resources/managed_tile_state.h
@@ -154,6 +154,7 @@ class CC_EXPORT ManagedTileState {
bool required_for_activation;
float time_to_needed_in_seconds;
float distance_to_visible_in_pixels;
+ bool visible_and_ready_to_draw;
};
} // namespace cc
diff --git a/cc/resources/tile_manager.cc b/cc/resources/tile_manager.cc
index 6b71625..1e9dc64 100644
--- a/cc/resources/tile_manager.cc
+++ b/cc/resources/tile_manager.cc
@@ -150,19 +150,7 @@ void TileManager::DidFinishedRunningTasks() {
raster_worker_pool_->CheckForCompletedTasks();
TileVector tiles_that_need_to_be_rasterized;
- TileSet oom_tiles_required_for_activation;
- AssignGpuMemoryToTiles(sorted_tiles_,
- &tiles_that_need_to_be_rasterized,
- &oom_tiles_required_for_activation);
-
- if (!oom_tiles_required_for_activation.empty()) {
- ReassignGpuMemoryToOOMTilesRequiredForActivation(
- sorted_tiles_,
- &tiles_that_need_to_be_rasterized,
- &oom_tiles_required_for_activation);
- }
- all_tiles_required_for_activation_have_memory_ =
- oom_tiles_required_for_activation.empty();
+ AssignGpuMemoryToTiles(sorted_tiles_, &tiles_that_need_to_be_rasterized);
// |tiles_that_need_to_be_rasterized| will be empty when we reach a
// steady memory state. Keep scheduling tasks until we reach this state.
@@ -171,14 +159,17 @@ void TileManager::DidFinishedRunningTasks() {
return;
}
- // Use on-demand raster for any tiles that have not been been assigned
- // memory after reaching a steady memory state.
- for (TileSet::iterator it = oom_tiles_required_for_activation.begin();
- it != oom_tiles_required_for_activation.end();
- ++it) {
- Tile* tile = *it;
+ // Use on-demand raster for any required-for-activation tiles that have not
+ // been been assigned memory after reaching a steady memory state. This
+ // ensures that we activate even when OOM.
+ for (TileMap::iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
+ Tile* tile = it->second;
ManagedTileState& mts = tile->managed_state();
- mts.tile_versions[mts.raster_mode].set_rasterize_on_demand();
+ ManagedTileState::TileVersion& tile_version =
+ mts.tile_versions[mts.raster_mode];
+
+ if (tile->required_for_activation() && !tile_version.IsReadyToDraw())
+ tile_version.set_rasterize_on_demand();
}
DCHECK(all_tiles_required_for_activation_have_been_initialized_);
@@ -203,6 +194,10 @@ class BinComparator {
const scoped_refptr<Tile> b) const {
const ManagedTileState& ams = a->managed_state();
const ManagedTileState& bms = b->managed_state();
+
+ if (ams.visible_and_ready_to_draw != bms.visible_and_ready_to_draw)
+ return ams.visible_and_ready_to_draw;
+
if (ams.bin[HIGH_PRIORITY_BIN] != bms.bin[HIGH_PRIORITY_BIN])
return ams.bin[HIGH_PRIORITY_BIN] < bms.bin[HIGH_PRIORITY_BIN];
@@ -301,6 +296,9 @@ void TileManager::AssignBinsToTiles(TileRefVector* tiles) {
for (int i = 0; i < NUM_BIN_PRIORITIES; ++i)
mts.bin[i] = bin_map[mts.bin[i]];
+
+ mts.visible_and_ready_to_draw =
+ mts.tree_bin[ACTIVE_TREE] == NOW_BIN && tile->IsReadyToDraw();
}
}
@@ -333,12 +331,7 @@ void TileManager::ManageTiles() {
GetSortedTiles(&sorted_tiles_);
TileVector tiles_that_need_to_be_rasterized;
- TileSet oom_tiles_required_for_activation;
- AssignGpuMemoryToTiles(sorted_tiles_,
- &tiles_that_need_to_be_rasterized,
- &oom_tiles_required_for_activation);
- all_tiles_required_for_activation_have_memory_ =
- oom_tiles_required_for_activation.empty();
+ AssignGpuMemoryToTiles(sorted_tiles_, &tiles_that_need_to_be_rasterized);
CleanUpUnusedImageDecodeTasks();
TRACE_EVENT_INSTANT1(
@@ -441,8 +434,7 @@ RasterMode TileManager::DetermineRasterMode(const Tile* tile) const {
void TileManager::AssignGpuMemoryToTiles(
const TileRefVector& sorted_tiles,
- TileVector* tiles_that_need_to_be_rasterized,
- TileSet* oom_tiles_required_for_activation) {
+ TileVector* tiles_that_need_to_be_rasterized) {
TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles");
// Reset activation tiles flag, to ensure we can activate
@@ -463,6 +455,8 @@ void TileManager::AssignGpuMemoryToTiles(
}
}
+ all_tiles_required_for_activation_have_memory_ = true;
+
// Cast to prevent overflow.
int64 bytes_available =
static_cast<int64>(bytes_releasable) +
@@ -518,7 +512,7 @@ void TileManager::AssignGpuMemoryToTiles(
// memory limit.
if (bytes_oom_tiles_that_need_to_be_initialized_for_activation <
global_state_.memory_limit_in_bytes) {
- oom_tiles_required_for_activation->insert(tile);
+ all_tiles_required_for_activation_have_memory_ = false;
bytes_oom_tiles_that_need_to_be_initialized_for_activation +=
tile_bytes;
} else {
@@ -526,12 +520,18 @@ void TileManager::AssignGpuMemoryToTiles(
}
}
FreeResourcesForTile(tile);
+
+ // This tile was already on screen and now its resoruces have been
+ // released. In order to prevent checkerboarding, set this tile as
+ // rasterize on demand immediately.
+ if (mts.visible_and_ready_to_draw)
+ tile_version.set_rasterize_on_demand();
+
higher_priority_tile_oomed = true;
bytes_that_exceeded_memory_budget += tile_bytes;
continue;
}
- tile_version.set_use_resource();
bytes_left -= tile_bytes;
// Tile shouldn't be rasterized if we've failed to assign
@@ -549,8 +549,7 @@ void TileManager::AssignGpuMemoryToTiles(
if (!tile_version.resource_)
tiles_that_need_to_be_rasterized->push_back(tile);
- if (!tile->IsReadyToDraw() &&
- tile->required_for_activation()) {
+ if (!tile->IsReadyToDraw() && tile->required_for_activation()) {
all_tiles_required_for_activation_have_been_initialized_ = false;
}
}
@@ -571,86 +570,6 @@ void TileManager::AssignGpuMemoryToTiles(
bytes_that_exceeded_memory_budget;
}
-void TileManager::ReassignGpuMemoryToOOMTilesRequiredForActivation(
- const TileRefVector& sorted_tiles,
- TileVector* tiles_that_need_to_be_rasterized,
- TileSet* oom_tiles_required_for_activation) {
- TRACE_EVENT0(
- "cc", "TileManager::ReassignGpuMemoryToOOMTilesRequiredForActivation");
-
- size_t bytes_oom_for_required_tiles = 0;
- TileVector tiles_requiring_memory_but_oomed;
- for (TileRefVector::const_iterator it = sorted_tiles.begin();
- it != sorted_tiles.end();
- ++it) {
- Tile* tile = it->get();
- if (oom_tiles_required_for_activation->find(tile) ==
- oom_tiles_required_for_activation->end())
- continue;
-
- tiles_requiring_memory_but_oomed.push_back(tile);
- bytes_oom_for_required_tiles += tile->bytes_consumed_if_allocated();
- }
-
- if (tiles_requiring_memory_but_oomed.empty())
- return;
-
- // In OOM situation, we iterate sorted_tiles, remove the memory for active
- // tree and not the now bin. And give them to bytes_oom_for_required_tiles
- size_t bytes_freed = 0;
- for (TileRefVector::const_reverse_iterator it = sorted_tiles.rbegin();
- it != sorted_tiles.rend();
- ++it) {
- Tile* tile = it->get();
- ManagedTileState& mts = tile->managed_state();
- if (mts.tree_bin[PENDING_TREE] == NEVER_BIN &&
- mts.tree_bin[ACTIVE_TREE] != NOW_BIN) {
- ManagedTileState::TileVersion& tile_version =
- mts.tile_versions[mts.raster_mode];
-
- // If the tile is in the to-rasterize list, but it has no task,
- // then it means that we have assigned memory for it.
- TileVector::iterator raster_it =
- std::find(tiles_that_need_to_be_rasterized->begin(),
- tiles_that_need_to_be_rasterized->end(),
- tile);
- if (raster_it != tiles_that_need_to_be_rasterized->end() &&
- tile_version.raster_task_.is_null()) {
- bytes_freed += tile->bytes_consumed_if_allocated();
- tiles_that_need_to_be_rasterized->erase(raster_it);
- }
-
- // Also consider all of the completed resources for freeing.
- for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) {
- if (mts.tile_versions[mode].resource_) {
- DCHECK(!tile->required_for_activation());
- FreeResourceForTile(tile, static_cast<RasterMode>(mode));
- bytes_freed += tile->bytes_consumed_if_allocated();
- }
- }
- }
-
- if (bytes_oom_for_required_tiles <= bytes_freed)
- break;
- }
-
- for (TileVector::iterator it = tiles_requiring_memory_but_oomed.begin();
- it != tiles_requiring_memory_but_oomed.end() && bytes_freed > 0;
- ++it) {
- Tile* tile = *it;
- ManagedTileState& mts = tile->managed_state();
- size_t bytes_needed = tile->bytes_consumed_if_allocated();
- if (bytes_needed > bytes_freed)
- continue;
- mts.tile_versions[mts.raster_mode].set_use_resource();
- bytes_freed -= bytes_needed;
- tiles_that_need_to_be_rasterized->push_back(tile);
- DCHECK(tile->required_for_activation());
- all_tiles_required_for_activation_have_been_initialized_ = false;
- oom_tiles_required_for_activation->erase(tile);
- }
-}
-
void TileManager::CleanUpUnusedImageDecodeTasks() {
// Calculate a set of layers that are used by at least one tile.
base::hash_set<int> used_layers;
@@ -856,6 +775,7 @@ void TileManager::OnRasterTaskCompleted(
tile_version.set_solid_color(analysis.solid_color);
resource_pool_->ReleaseResource(resource.Pass());
} else {
+ tile_version.set_use_resource();
tile_version.resource_ = resource.Pass();
}
diff --git a/cc/resources/tile_manager.h b/cc/resources/tile_manager.h
index de98a4a..8454bc4 100644
--- a/cc/resources/tile_manager.h
+++ b/cc/resources/tile_manager.h
@@ -96,14 +96,9 @@ class CC_EXPORT TileManager : public RasterWorkerPoolClient {
virtual void ScheduleTasks(
const TileVector& tiles_that_need_to_be_rasterized);
- void ReassignGpuMemoryToOOMTilesRequiredForActivation(
- const TileRefVector& sorted_tiles,
- TileVector* tiles_that_need_to_be_rasterized,
- TileSet* oom_tiles_required_for_activation);
void AssignGpuMemoryToTiles(
const TileRefVector& sorted_tiles,
- TileVector* tiles_that_need_to_be_rasterized,
- TileSet* oom_tiles_required_for_activation);
+ TileVector* tiles_that_need_to_be_rasterized);
void AssignBinsToTiles(TileRefVector* tiles);
void SortTiles(TileRefVector* tiles);
void GetSortedTiles(TileRefVector* tiles);
diff --git a/cc/resources/tile_manager_unittest.cc b/cc/resources/tile_manager_unittest.cc
index b87ac69..12f46a3 100644
--- a/cc/resources/tile_manager_unittest.cc
+++ b/cc/resources/tile_manager_unittest.cc
@@ -71,6 +71,8 @@ class TileManagerTest : public testing::Test {
tile_manager_ = make_scoped_ptr(
new FakeTileManager(&tile_manager_client_, resource_provider_.get()));
+ memory_limit_policy_ = memory_limit_policy;
+ max_memory_tiles_ = max_memory_tiles;
GlobalStateThatImpactsTilePriority state;
gfx::Size tile_size = settings_.default_tile_size;
state.memory_limit_in_bytes =
@@ -82,6 +84,16 @@ class TileManagerTest : public testing::Test {
picture_pile_ = make_scoped_refptr(new FakePicturePileImpl());
}
+ void SetTreePriority(TreePriority tree_priority) {
+ GlobalStateThatImpactsTilePriority state;
+ gfx::Size tile_size = settings_.default_tile_size;
+ state.memory_limit_in_bytes =
+ max_memory_tiles_ * 4 * tile_size.width() * tile_size.height();
+ state.memory_limit_policy = memory_limit_policy_;
+ state.tree_priority = tree_priority;
+ tile_manager_->SetGlobalState(state);
+ }
+
virtual void TearDown() OVERRIDE {
tile_manager_.reset(NULL);
picture_pile_ = NULL;
@@ -144,6 +156,8 @@ class TileManagerTest : public testing::Test {
scoped_refptr<FakePicturePileImpl> picture_pile_;
scoped_ptr<FakeOutputSurface> output_surface_;
scoped_ptr<ResourceProvider> resource_provider_;
+ TileMemoryLimitPolicy memory_limit_policy_;
+ int max_memory_tiles_;
};
TEST_F(TileManagerTest, EnoughMemoryAllowAnything) {
@@ -246,7 +260,8 @@ TEST_F(TileManagerTest, PartialOOMMemoryToPending) {
EXPECT_EQ(5, AssignedMemoryCount(active_tree_tiles));
EXPECT_EQ(3, AssignedMemoryCount(pending_tree_tiles));
- tile_manager()->ReassignMemoryToOOMTilesRequiredForActivation();
+ SetTreePriority(SAME_PRIORITY_FOR_BOTH_TREES);
+ tile_manager()->AssignMemoryToTiles();
EXPECT_EQ(3, AssignedMemoryCount(active_tree_tiles));
EXPECT_EQ(5, AssignedMemoryCount(pending_tree_tiles));
@@ -286,7 +301,8 @@ TEST_F(TileManagerTest, TotalOOMMemoryToPending) {
EXPECT_EQ(4, AssignedMemoryCount(active_tree_tiles));
EXPECT_EQ(0, AssignedMemoryCount(pending_tree_tiles));
- tile_manager()->ReassignMemoryToOOMTilesRequiredForActivation();
+ SetTreePriority(SAME_PRIORITY_FOR_BOTH_TREES);
+ tile_manager()->AssignMemoryToTiles();
EXPECT_EQ(0, AssignedMemoryCount(active_tree_tiles));
EXPECT_EQ(4, AssignedMemoryCount(pending_tree_tiles));
@@ -309,7 +325,8 @@ TEST_F(TileManagerTest, TotalOOMActiveSoonMemoryToPending) {
EXPECT_EQ(4, AssignedMemoryCount(active_tree_tiles));
EXPECT_EQ(0, AssignedMemoryCount(pending_tree_tiles));
- tile_manager()->ReassignMemoryToOOMTilesRequiredForActivation();
+ SetTreePriority(SAME_PRIORITY_FOR_BOTH_TREES);
+ tile_manager()->AssignMemoryToTiles();
EXPECT_EQ(0, AssignedMemoryCount(active_tree_tiles));
EXPECT_EQ(4, AssignedMemoryCount(pending_tree_tiles));
diff --git a/cc/test/fake_tile_manager.cc b/cc/test/fake_tile_manager.cc
index eb4ab1f..c1b61f3 100644
--- a/cc/test/fake_tile_manager.cc
+++ b/cc/test/fake_tile_manager.cc
@@ -40,19 +40,12 @@ FakeTileManager::FakeTileManager(TileManagerClient* client,
FakeTileManager::~FakeTileManager() {}
-void FakeTileManager::ReassignMemoryToOOMTilesRequiredForActivation() {
- ReassignGpuMemoryToOOMTilesRequiredForActivation(
- all_tiles, &tiles_for_raster, &oom_tiles_required_for_activation);
-}
-
void FakeTileManager::AssignMemoryToTiles() {
tiles_for_raster.clear();
- oom_tiles_required_for_activation.clear();
all_tiles.clear();
GetSortedTiles(&all_tiles);
- AssignGpuMemoryToTiles(
- all_tiles, &tiles_for_raster, &oom_tiles_required_for_activation);
+ AssignGpuMemoryToTiles(all_tiles, &tiles_for_raster);
}
bool FakeTileManager::HasBeenAssignedMemory(Tile* tile) {
diff --git a/cc/test/fake_tile_manager.h b/cc/test/fake_tile_manager.h
index b22db6b..77dbb78 100644
--- a/cc/test/fake_tile_manager.h
+++ b/cc/test/fake_tile_manager.h
@@ -18,7 +18,6 @@ class FakeTileManager : public TileManager {
FakeTileManager(TileManagerClient* client,
ResourceProvider* resource_provider);
- void ReassignMemoryToOOMTilesRequiredForActivation();
bool HasBeenAssignedMemory(Tile* tile);
void AssignMemoryToTiles();
@@ -26,7 +25,6 @@ class FakeTileManager : public TileManager {
std::vector<Tile*> tiles_for_raster;
std::vector<scoped_refptr<Tile> > all_tiles;
- std::set<Tile*> oom_tiles_required_for_activation;
};
} // namespace cc
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index 282471f..51e9d25 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -1393,6 +1393,9 @@ void LayerTreeHostImpl::ActivatePendingTreeIfNeeded() {
return;
}
+ // Manage tiles in case state affecting tile priority has changed.
+ ManageTiles();
+
TRACE_EVENT_ASYNC_STEP1(
"cc",
"PendingTree", pending_tree_.get(), "activate",