diff options
-rw-r--r-- | cc/resources/managed_tile_state.cc | 3 | ||||
-rw-r--r-- | cc/resources/managed_tile_state.h | 1 | ||||
-rw-r--r-- | cc/resources/tile_manager.cc | 144 | ||||
-rw-r--r-- | cc/resources/tile_manager.h | 7 | ||||
-rw-r--r-- | cc/resources/tile_manager_unittest.cc | 23 | ||||
-rw-r--r-- | cc/test/fake_tile_manager.cc | 9 | ||||
-rw-r--r-- | cc/test/fake_tile_manager.h | 2 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_impl.cc | 3 |
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", |