| OLD | NEW |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "cc/resources/tile_manager.h" | 5 #include "cc/resources/tile_manager.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <limits> | 8 #include <limits> |
| 9 #include <string> | 9 #include <string> |
| 10 | 10 |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 82 TileManagerClient* client, | 82 TileManagerClient* client, |
| 83 ResourceProvider* resource_provider, | 83 ResourceProvider* resource_provider, |
| 84 scoped_ptr<RasterWorkerPool> raster_worker_pool, | 84 scoped_ptr<RasterWorkerPool> raster_worker_pool, |
| 85 size_t num_raster_threads, | 85 size_t num_raster_threads, |
| 86 bool use_color_estimator, | 86 bool use_color_estimator, |
| 87 RenderingStatsInstrumentation* rendering_stats_instrumentation, | 87 RenderingStatsInstrumentation* rendering_stats_instrumentation, |
| 88 GLenum texture_format) | 88 GLenum texture_format) |
| 89 : client_(client), | 89 : client_(client), |
| 90 resource_pool_(ResourcePool::Create(resource_provider)), | 90 resource_pool_(ResourcePool::Create(resource_provider)), |
| 91 raster_worker_pool_(raster_worker_pool.Pass()), | 91 raster_worker_pool_(raster_worker_pool.Pass()), |
| 92 all_tiles_required_for_activation_have_been_initialized_(true), |
| 93 all_tiles_required_for_activation_have_memory_(true), |
| 92 ever_exceeded_memory_budget_(false), | 94 ever_exceeded_memory_budget_(false), |
| 93 rendering_stats_instrumentation_(rendering_stats_instrumentation), | 95 rendering_stats_instrumentation_(rendering_stats_instrumentation), |
| 94 use_color_estimator_(use_color_estimator), | 96 use_color_estimator_(use_color_estimator), |
| 95 did_initialize_visible_tile_(false), | 97 did_initialize_visible_tile_(false), |
| 96 texture_format_(texture_format) { | 98 texture_format_(texture_format) { |
| 97 raster_worker_pool_->SetClient(this); | 99 raster_worker_pool_->SetClient(this); |
| 98 } | 100 } |
| 99 | 101 |
| 100 TileManager::~TileManager() { | 102 TileManager::~TileManager() { |
| 101 // Reset global state and manage. This should cause | 103 // Reset global state and manage. This should cause |
| 102 // our memory usage to drop to zero. | 104 // our memory usage to drop to zero. |
| 103 global_state_ = GlobalStateThatImpactsTilePriority(); | 105 global_state_ = GlobalStateThatImpactsTilePriority(); |
| 104 AssignGpuMemoryToTiles(); | 106 |
| 105 CleanUpUnusedImageDecodeTasks(); | 107 // Clear |sorted_tiles_| so that tiles kept alive by it can be freed. |
| 108 sorted_tiles_.clear(); |
| 109 DCHECK_EQ(0u, tiles_.size()); |
| 110 |
| 111 TileVector empty; |
| 112 ScheduleTasks(empty); |
| 113 |
| 106 // This should finish all pending tasks and release any uninitialized | 114 // This should finish all pending tasks and release any uninitialized |
| 107 // resources. | 115 // resources. |
| 108 raster_worker_pool_->Shutdown(); | 116 raster_worker_pool_->Shutdown(); |
| 109 raster_worker_pool_->CheckForCompletedTasks(); | 117 raster_worker_pool_->CheckForCompletedTasks(); |
| 110 DCHECK_EQ(0u, tiles_.size()); | |
| 111 } | 118 } |
| 112 | 119 |
| 113 void TileManager::SetGlobalState( | 120 void TileManager::SetGlobalState( |
| 114 const GlobalStateThatImpactsTilePriority& global_state) { | 121 const GlobalStateThatImpactsTilePriority& global_state) { |
| 115 global_state_ = global_state; | 122 global_state_ = global_state; |
| 116 resource_pool_->SetMaxMemoryUsageBytes( | 123 resource_pool_->SetMaxMemoryUsageBytes( |
| 117 global_state_.memory_limit_in_bytes, | 124 global_state_.memory_limit_in_bytes, |
| 118 global_state_.unused_memory_limit_in_bytes); | 125 global_state_.unused_memory_limit_in_bytes); |
| 119 } | 126 } |
| 120 | 127 |
| 121 void TileManager::RegisterTile(Tile* tile) { | 128 void TileManager::RegisterTile(Tile* tile) { |
| 122 DCHECK(std::find(tiles_.begin(), tiles_.end(), tile) == tiles_.end()); | |
| 123 DCHECK(!tile->required_for_activation()); | 129 DCHECK(!tile->required_for_activation()); |
| 124 tiles_.push_back(tile); | 130 DCHECK(tiles_.find(tile->id()) == tiles_.end()); |
| 131 |
| 132 tiles_[tile->id()] = tile; |
| 125 } | 133 } |
| 126 | 134 |
| 127 void TileManager::UnregisterTile(Tile* tile) { | 135 void TileManager::UnregisterTile(Tile* tile) { |
| 128 TileVector::iterator raster_iter = | 136 FreeResourcesForTile(tile); |
| 129 std::find(tiles_that_need_to_be_rasterized_.begin(), | |
| 130 tiles_that_need_to_be_rasterized_.end(), | |
| 131 tile); | |
| 132 if (raster_iter != tiles_that_need_to_be_rasterized_.end()) | |
| 133 tiles_that_need_to_be_rasterized_.erase(raster_iter); | |
| 134 | 137 |
| 135 tiles_that_need_to_be_initialized_for_activation_.erase(tile); | 138 DCHECK(tiles_.find(tile->id()) != tiles_.end()); |
| 136 oom_tiles_that_need_to_be_initialized_for_activation_.erase(tile); | 139 tiles_.erase(tile->id()); |
| 137 | |
| 138 DCHECK(std::find(tiles_.begin(), tiles_.end(), tile) != tiles_.end()); | |
| 139 FreeResourcesForTile(tile); | |
| 140 tiles_.erase(std::remove(tiles_.begin(), tiles_.end(), tile)); | |
| 141 } | 140 } |
| 142 | 141 |
| 143 bool TileManager::ShouldForceTasksRequiredForActivationToComplete() const { | 142 bool TileManager::ShouldForceTasksRequiredForActivationToComplete() const { |
| 144 return GlobalState().tree_priority != SMOOTHNESS_TAKES_PRIORITY; | 143 return GlobalState().tree_priority != SMOOTHNESS_TAKES_PRIORITY; |
| 145 } | 144 } |
| 146 | 145 |
| 147 void TileManager::DidFinishedRunningTasks() { | 146 void TileManager::DidFinishedRunningTasks() { |
| 147 TRACE_EVENT0("cc", "TileManager::DidFinishedRunningTasks"); |
| 148 |
| 148 // When OOM, keep re-assigning memory until we reach a steady state | 149 // When OOM, keep re-assigning memory until we reach a steady state |
| 149 // where top-priority tiles are initialized. | 150 // where top-priority tiles are initialized. |
| 150 if (!memory_stats_from_last_assign_.bytes_over) | 151 if (!memory_stats_from_last_assign_.bytes_over) |
| 151 return; | 152 return; |
| 152 | 153 |
| 153 raster_worker_pool_->CheckForCompletedTasks(); | 154 raster_worker_pool_->CheckForCompletedTasks(); |
| 154 | 155 |
| 155 AssignGpuMemoryToTiles(); | 156 TileVector tiles_that_need_to_be_rasterized; |
| 157 TileSet oom_tiles_required_for_activation; |
| 158 AssignGpuMemoryToTiles(sorted_tiles_, |
| 159 &tiles_that_need_to_be_rasterized, |
| 160 &oom_tiles_required_for_activation); |
| 156 | 161 |
| 157 if (!oom_tiles_that_need_to_be_initialized_for_activation_.empty()) | 162 if (!oom_tiles_required_for_activation.empty()) { |
| 158 ReassignGpuMemoryToOOMTilesRequiredForActivation(); | 163 ReassignGpuMemoryToOOMTilesRequiredForActivation( |
| 164 sorted_tiles_, |
| 165 &tiles_that_need_to_be_rasterized, |
| 166 &oom_tiles_required_for_activation); |
| 167 } |
| 168 all_tiles_required_for_activation_have_memory_ = |
| 169 oom_tiles_required_for_activation.empty(); |
| 159 | 170 |
| 160 // |tiles_that_need_to_be_rasterized_| will be empty when we reach a | 171 // |tiles_that_need_to_be_rasterized| will be empty when we reach a |
| 161 // steady memory state. Keep scheduling tasks until we reach this state. | 172 // steady memory state. Keep scheduling tasks until we reach this state. |
| 162 if (!tiles_that_need_to_be_rasterized_.empty()) { | 173 if (!tiles_that_need_to_be_rasterized.empty()) { |
| 163 ScheduleTasks(); | 174 ScheduleTasks(tiles_that_need_to_be_rasterized); |
| 164 return; | 175 return; |
| 165 } | 176 } |
| 166 | 177 |
| 167 // Use on-demand raster for any tiles that have not been been assigned | 178 // Use on-demand raster for any tiles that have not been been assigned |
| 168 // memory after reaching a steady memory state. | 179 // memory after reaching a steady memory state. |
| 169 for (TileSet::iterator it = | 180 for (TileSet::iterator it = oom_tiles_required_for_activation.begin(); |
| 170 oom_tiles_that_need_to_be_initialized_for_activation_.begin(); | 181 it != oom_tiles_required_for_activation.end(); |
| 171 it != oom_tiles_that_need_to_be_initialized_for_activation_.end(); | |
| 172 ++it) { | 182 ++it) { |
| 173 Tile* tile = *it; | 183 Tile* tile = *it; |
| 174 ManagedTileState& mts = tile->managed_state(); | 184 ManagedTileState& mts = tile->managed_state(); |
| 175 mts.tile_versions[mts.raster_mode].set_rasterize_on_demand(); | 185 mts.tile_versions[mts.raster_mode].set_rasterize_on_demand(); |
| 176 } | 186 } |
| 177 oom_tiles_that_need_to_be_initialized_for_activation_.clear(); | |
| 178 | 187 |
| 179 DCHECK_EQ(0u, tiles_that_need_to_be_initialized_for_activation_.size()); | 188 DCHECK(all_tiles_required_for_activation_have_been_initialized_); |
| 180 client_->NotifyReadyToActivate(); | 189 client_->NotifyReadyToActivate(); |
| 181 } | 190 } |
| 182 | 191 |
| 183 void TileManager::DidFinishedRunningTasksRequiredForActivation() { | 192 void TileManager::DidFinishedRunningTasksRequiredForActivation() { |
| 184 // This is only a true indication that all tiles required for | 193 // This is only a true indication that all tiles required for |
| 185 // activation are initialized when no tiles are OOM. We need to | 194 // activation are initialized when no tiles are OOM. We need to |
| 186 // wait for DidFinishRunningTasks() to be called, try to re-assign | 195 // wait for DidFinishRunningTasks() to be called, try to re-assign |
| 187 // memory and in worst case use on-demand raster when tiles | 196 // memory and in worst case use on-demand raster when tiles |
| 188 // required for activation are OOM. | 197 // required for activation are OOM. |
| 189 if (!oom_tiles_that_need_to_be_initialized_for_activation_.empty()) | 198 if (!all_tiles_required_for_activation_have_memory_) |
| 190 return; | 199 return; |
| 191 | 200 |
| 192 client_->NotifyReadyToActivate(); | 201 client_->NotifyReadyToActivate(); |
| 193 } | 202 } |
| 194 | 203 |
| 195 class BinComparator { | 204 class BinComparator { |
| 196 public: | 205 public: |
| 197 bool operator() (const Tile* a, const Tile* b) const { | 206 bool operator()(const scoped_refptr<Tile> a, |
| 207 const scoped_refptr<Tile> b) const { |
| 198 const ManagedTileState& ams = a->managed_state(); | 208 const ManagedTileState& ams = a->managed_state(); |
| 199 const ManagedTileState& bms = b->managed_state(); | 209 const ManagedTileState& bms = b->managed_state(); |
| 200 if (ams.bin[HIGH_PRIORITY_BIN] != bms.bin[HIGH_PRIORITY_BIN]) | 210 if (ams.bin[HIGH_PRIORITY_BIN] != bms.bin[HIGH_PRIORITY_BIN]) |
| 201 return ams.bin[HIGH_PRIORITY_BIN] < bms.bin[HIGH_PRIORITY_BIN]; | 211 return ams.bin[HIGH_PRIORITY_BIN] < bms.bin[HIGH_PRIORITY_BIN]; |
| 202 | 212 |
| 203 if (ams.bin[LOW_PRIORITY_BIN] != bms.bin[LOW_PRIORITY_BIN]) | 213 if (ams.bin[LOW_PRIORITY_BIN] != bms.bin[LOW_PRIORITY_BIN]) |
| 204 return ams.bin[LOW_PRIORITY_BIN] < bms.bin[LOW_PRIORITY_BIN]; | 214 return ams.bin[LOW_PRIORITY_BIN] < bms.bin[LOW_PRIORITY_BIN]; |
| 205 | 215 |
| 206 if (ams.required_for_activation != bms.required_for_activation) | 216 if (ams.required_for_activation != bms.required_for_activation) |
| 207 return ams.required_for_activation; | 217 return ams.required_for_activation; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 219 } | 229 } |
| 220 | 230 |
| 221 gfx::Rect a_rect = a->content_rect(); | 231 gfx::Rect a_rect = a->content_rect(); |
| 222 gfx::Rect b_rect = b->content_rect(); | 232 gfx::Rect b_rect = b->content_rect(); |
| 223 if (a_rect.y() != b_rect.y()) | 233 if (a_rect.y() != b_rect.y()) |
| 224 return a_rect.y() < b_rect.y(); | 234 return a_rect.y() < b_rect.y(); |
| 225 return a_rect.x() < b_rect.x(); | 235 return a_rect.x() < b_rect.x(); |
| 226 } | 236 } |
| 227 }; | 237 }; |
| 228 | 238 |
| 229 void TileManager::AssignBinsToTiles() { | 239 void TileManager::AssignBinsToTiles(TileRefVector* tiles) { |
| 230 const TreePriority tree_priority = global_state_.tree_priority; | 240 const TreePriority tree_priority = global_state_.tree_priority; |
| 231 | 241 |
| 232 // Memory limit policy works by mapping some bin states to the NEVER bin. | 242 // Memory limit policy works by mapping some bin states to the NEVER bin. |
| 233 ManagedTileBin bin_map[NUM_BINS]; | 243 ManagedTileBin bin_map[NUM_BINS]; |
| 234 if (global_state_.memory_limit_policy == ALLOW_NOTHING) { | 244 if (global_state_.memory_limit_policy == ALLOW_NOTHING) { |
| 235 bin_map[NOW_BIN] = NEVER_BIN; | 245 bin_map[NOW_BIN] = NEVER_BIN; |
| 236 bin_map[SOON_BIN] = NEVER_BIN; | 246 bin_map[SOON_BIN] = NEVER_BIN; |
| 237 bin_map[EVENTUALLY_BIN] = NEVER_BIN; | 247 bin_map[EVENTUALLY_BIN] = NEVER_BIN; |
| 238 bin_map[NEVER_BIN] = NEVER_BIN; | 248 bin_map[NEVER_BIN] = NEVER_BIN; |
| 239 } else if (global_state_.memory_limit_policy == ALLOW_ABSOLUTE_MINIMUM) { | 249 } else if (global_state_.memory_limit_policy == ALLOW_ABSOLUTE_MINIMUM) { |
| 240 bin_map[NOW_BIN] = NOW_BIN; | 250 bin_map[NOW_BIN] = NOW_BIN; |
| 241 bin_map[SOON_BIN] = NEVER_BIN; | 251 bin_map[SOON_BIN] = NEVER_BIN; |
| 242 bin_map[EVENTUALLY_BIN] = NEVER_BIN; | 252 bin_map[EVENTUALLY_BIN] = NEVER_BIN; |
| 243 bin_map[NEVER_BIN] = NEVER_BIN; | 253 bin_map[NEVER_BIN] = NEVER_BIN; |
| 244 } else if (global_state_.memory_limit_policy == ALLOW_PREPAINT_ONLY) { | 254 } else if (global_state_.memory_limit_policy == ALLOW_PREPAINT_ONLY) { |
| 245 bin_map[NOW_BIN] = NOW_BIN; | 255 bin_map[NOW_BIN] = NOW_BIN; |
| 246 bin_map[SOON_BIN] = SOON_BIN; | 256 bin_map[SOON_BIN] = SOON_BIN; |
| 247 bin_map[EVENTUALLY_BIN] = NEVER_BIN; | 257 bin_map[EVENTUALLY_BIN] = NEVER_BIN; |
| 248 bin_map[NEVER_BIN] = NEVER_BIN; | 258 bin_map[NEVER_BIN] = NEVER_BIN; |
| 249 } else { | 259 } else { |
| 250 bin_map[NOW_BIN] = NOW_BIN; | 260 bin_map[NOW_BIN] = NOW_BIN; |
| 251 bin_map[SOON_BIN] = SOON_BIN; | 261 bin_map[SOON_BIN] = SOON_BIN; |
| 252 bin_map[EVENTUALLY_BIN] = EVENTUALLY_BIN; | 262 bin_map[EVENTUALLY_BIN] = EVENTUALLY_BIN; |
| 253 bin_map[NEVER_BIN] = NEVER_BIN; | 263 bin_map[NEVER_BIN] = NEVER_BIN; |
| 254 } | 264 } |
| 255 | 265 |
| 256 // For each tree, bin into different categories of tiles. | 266 // For each tree, bin into different categories of tiles. |
| 257 for (TileVector::iterator it = tiles_.begin(); | 267 for (TileRefVector::iterator it = tiles->begin(); it != tiles->end(); ++it) { |
| 258 it != tiles_.end(); | 268 Tile* tile = it->get(); |
| 259 ++it) { | |
| 260 Tile* tile = *it; | |
| 261 ManagedTileState& mts = tile->managed_state(); | 269 ManagedTileState& mts = tile->managed_state(); |
| 262 | 270 |
| 263 TilePriority prio[NUM_BIN_PRIORITIES]; | 271 TilePriority prio[NUM_BIN_PRIORITIES]; |
| 264 switch (tree_priority) { | 272 switch (tree_priority) { |
| 265 case SAME_PRIORITY_FOR_BOTH_TREES: | 273 case SAME_PRIORITY_FOR_BOTH_TREES: |
| 266 prio[HIGH_PRIORITY_BIN] = prio[LOW_PRIORITY_BIN] = | 274 prio[HIGH_PRIORITY_BIN] = prio[LOW_PRIORITY_BIN] = |
| 267 tile->combined_priority(); | 275 tile->combined_priority(); |
| 268 break; | 276 break; |
| 269 case SMOOTHNESS_TAKES_PRIORITY: | 277 case SMOOTHNESS_TAKES_PRIORITY: |
| 270 prio[HIGH_PRIORITY_BIN] = tile->priority(ACTIVE_TREE); | 278 prio[HIGH_PRIORITY_BIN] = tile->priority(ACTIVE_TREE); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 283 prio[HIGH_PRIORITY_BIN].distance_to_visible_in_pixels; | 291 prio[HIGH_PRIORITY_BIN].distance_to_visible_in_pixels; |
| 284 mts.required_for_activation = | 292 mts.required_for_activation = |
| 285 prio[HIGH_PRIORITY_BIN].required_for_activation; | 293 prio[HIGH_PRIORITY_BIN].required_for_activation; |
| 286 mts.bin[HIGH_PRIORITY_BIN] = | 294 mts.bin[HIGH_PRIORITY_BIN] = |
| 287 BinFromTilePriority(prio[HIGH_PRIORITY_BIN], tree_priority); | 295 BinFromTilePriority(prio[HIGH_PRIORITY_BIN], tree_priority); |
| 288 mts.bin[LOW_PRIORITY_BIN] = | 296 mts.bin[LOW_PRIORITY_BIN] = |
| 289 BinFromTilePriority(prio[LOW_PRIORITY_BIN], tree_priority); | 297 BinFromTilePriority(prio[LOW_PRIORITY_BIN], tree_priority); |
| 290 mts.gpu_memmgr_stats_bin = | 298 mts.gpu_memmgr_stats_bin = |
| 291 BinFromTilePriority(tile->combined_priority(), tree_priority); | 299 BinFromTilePriority(tile->combined_priority(), tree_priority); |
| 292 | 300 |
| 293 DidTileTreeBinChange(tile, | 301 mts.tree_bin[ACTIVE_TREE] = bin_map[ |
| 294 bin_map[BinFromTilePriority( | 302 BinFromTilePriority(tile->priority(ACTIVE_TREE), tree_priority)]; |
| 295 tile->priority(ACTIVE_TREE), tree_priority)], | 303 mts.tree_bin[PENDING_TREE] = bin_map[ |
| 296 ACTIVE_TREE); | 304 BinFromTilePriority(tile->priority(PENDING_TREE), tree_priority)]; |
| 297 DidTileTreeBinChange(tile, | |
| 298 bin_map[BinFromTilePriority( | |
| 299 tile->priority(PENDING_TREE), tree_priority)], | |
| 300 PENDING_TREE); | |
| 301 | 305 |
| 302 for (int i = 0; i < NUM_BIN_PRIORITIES; ++i) | 306 for (int i = 0; i < NUM_BIN_PRIORITIES; ++i) |
| 303 mts.bin[i] = bin_map[mts.bin[i]]; | 307 mts.bin[i] = bin_map[mts.bin[i]]; |
| 304 } | 308 } |
| 305 } | 309 } |
| 306 | 310 |
| 307 void TileManager::SortTiles() { | 311 void TileManager::SortTiles(TileRefVector* tiles) { |
| 308 TRACE_EVENT0("cc", "TileManager::SortTiles"); | 312 TRACE_EVENT0("cc", "TileManager::SortTiles"); |
| 309 | 313 |
| 310 // Sort by bin, resolution and time until needed. | 314 // Sort by bin, resolution and time until needed. |
| 311 std::sort(tiles_.begin(), tiles_.end(), BinComparator()); | 315 std::sort(tiles->begin(), tiles->end(), BinComparator()); |
| 316 } |
| 317 |
| 318 void TileManager::GetSortedTiles(TileRefVector* tiles) { |
| 319 TRACE_EVENT0("cc", "TileManager::GetSortedTiles"); |
| 320 |
| 321 DCHECK_EQ(0u, tiles->size()); |
| 322 |
| 323 tiles->reserve(tiles_.size()); |
| 324 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) |
| 325 tiles->push_back(make_scoped_refptr(it->second)); |
| 326 |
| 327 AssignBinsToTiles(tiles); |
| 328 SortTiles(tiles); |
| 312 } | 329 } |
| 313 | 330 |
| 314 void TileManager::ManageTiles() { | 331 void TileManager::ManageTiles() { |
| 315 TRACE_EVENT0("cc", "TileManager::ManageTiles"); | 332 TRACE_EVENT0("cc", "TileManager::ManageTiles"); |
| 316 AssignBinsToTiles(); | 333 |
| 317 SortTiles(); | 334 // Clear |sorted_tiles_| so that tiles kept alive by it can be freed. |
| 318 AssignGpuMemoryToTiles(); | 335 sorted_tiles_.clear(); |
| 336 |
| 337 GetSortedTiles(&sorted_tiles_); |
| 338 |
| 339 TileVector tiles_that_need_to_be_rasterized; |
| 340 TileSet oom_tiles_required_for_activation; |
| 341 AssignGpuMemoryToTiles(sorted_tiles_, |
| 342 &tiles_that_need_to_be_rasterized, |
| 343 &oom_tiles_required_for_activation); |
| 344 all_tiles_required_for_activation_have_memory_ = |
| 345 oom_tiles_required_for_activation.empty(); |
| 319 CleanUpUnusedImageDecodeTasks(); | 346 CleanUpUnusedImageDecodeTasks(); |
| 320 | 347 |
| 321 TRACE_EVENT_INSTANT1( | 348 TRACE_EVENT_INSTANT1( |
| 322 "cc", "DidManage", TRACE_EVENT_SCOPE_THREAD, | 349 "cc", "DidManage", TRACE_EVENT_SCOPE_THREAD, |
| 323 "state", TracedValue::FromValue(BasicStateAsValue().release())); | 350 "state", TracedValue::FromValue(BasicStateAsValue().release())); |
| 324 | 351 |
| 325 // Finally, schedule rasterizer tasks. | 352 // Finally, schedule rasterizer tasks. |
| 326 ScheduleTasks(); | 353 ScheduleTasks(tiles_that_need_to_be_rasterized); |
| 327 } | 354 } |
| 328 | 355 |
| 329 void TileManager::CheckForCompletedTileUploads() { | 356 void TileManager::CheckForCompletedTileUploads() { |
| 330 raster_worker_pool_->CheckForCompletedTasks(); | 357 raster_worker_pool_->CheckForCompletedTasks(); |
| 331 | 358 |
| 332 if (did_initialize_visible_tile_) { | 359 if (did_initialize_visible_tile_) { |
| 333 client_->DidInitializeVisibleTile(); | 360 client_->DidInitializeVisibleTile(); |
| 334 did_initialize_visible_tile_ = false; | 361 did_initialize_visible_tile_ = false; |
| 335 } | 362 } |
| 336 } | 363 } |
| 337 | 364 |
| 338 void TileManager::GetMemoryStats( | 365 void TileManager::GetMemoryStats( |
| 339 size_t* memory_required_bytes, | 366 size_t* memory_required_bytes, |
| 340 size_t* memory_nice_to_have_bytes, | 367 size_t* memory_nice_to_have_bytes, |
| 341 size_t* memory_used_bytes) const { | 368 size_t* memory_used_bytes) const { |
| 342 *memory_required_bytes = 0; | 369 *memory_required_bytes = 0; |
| 343 *memory_nice_to_have_bytes = 0; | 370 *memory_nice_to_have_bytes = 0; |
| 344 *memory_used_bytes = resource_pool_->acquired_memory_usage_bytes(); | 371 *memory_used_bytes = resource_pool_->acquired_memory_usage_bytes(); |
| 345 for (TileVector::const_iterator it = tiles_.begin(); | 372 for (TileMap::const_iterator it = tiles_.begin(); |
| 346 it != tiles_.end(); | 373 it != tiles_.end(); |
| 347 ++it) { | 374 ++it) { |
| 348 const Tile* tile = *it; | 375 const Tile* tile = it->second; |
| 349 const ManagedTileState& mts = tile->managed_state(); | 376 const ManagedTileState& mts = tile->managed_state(); |
| 350 | 377 |
| 351 RasterMode mode = HIGH_QUALITY_RASTER_MODE; | 378 RasterMode mode = HIGH_QUALITY_RASTER_MODE; |
| 352 if (tile->IsReadyToDraw(&mode) && | 379 if (tile->IsReadyToDraw(&mode) && |
| 353 !mts.tile_versions[mode].requires_resource()) | 380 !mts.tile_versions[mode].requires_resource()) |
| 354 continue; | 381 continue; |
| 355 | 382 |
| 356 size_t tile_bytes = tile->bytes_consumed_if_allocated(); | 383 size_t tile_bytes = tile->bytes_consumed_if_allocated(); |
| 357 if (mts.gpu_memmgr_stats_bin == NOW_BIN) | 384 if (mts.gpu_memmgr_stats_bin == NOW_BIN) |
| 358 *memory_required_bytes += tile_bytes; | 385 *memory_required_bytes += tile_bytes; |
| 359 if (mts.gpu_memmgr_stats_bin != NEVER_BIN) | 386 if (mts.gpu_memmgr_stats_bin != NEVER_BIN) |
| 360 *memory_nice_to_have_bytes += tile_bytes; | 387 *memory_nice_to_have_bytes += tile_bytes; |
| 361 } | 388 } |
| 362 } | 389 } |
| 363 | 390 |
| 364 scoped_ptr<base::Value> TileManager::BasicStateAsValue() const { | 391 scoped_ptr<base::Value> TileManager::BasicStateAsValue() const { |
| 365 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); | 392 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); |
| 366 state->SetInteger("tile_count", tiles_.size()); | 393 state->SetInteger("tile_count", tiles_.size()); |
| 367 state->Set("global_state", global_state_.AsValue().release()); | 394 state->Set("global_state", global_state_.AsValue().release()); |
| 368 state->Set("memory_requirements", GetMemoryRequirementsAsValue().release()); | 395 state->Set("memory_requirements", GetMemoryRequirementsAsValue().release()); |
| 369 return state.PassAs<base::Value>(); | 396 return state.PassAs<base::Value>(); |
| 370 } | 397 } |
| 371 | 398 |
| 372 scoped_ptr<base::Value> TileManager::AllTilesAsValue() const { | 399 scoped_ptr<base::Value> TileManager::AllTilesAsValue() const { |
| 373 scoped_ptr<base::ListValue> state(new base::ListValue()); | 400 scoped_ptr<base::ListValue> state(new base::ListValue()); |
| 374 for (TileVector::const_iterator it = tiles_.begin(); | 401 for (TileMap::const_iterator it = tiles_.begin(); |
| 375 it != tiles_.end(); | 402 it != tiles_.end(); |
| 376 it++) { | 403 it++) { |
| 377 state->Append((*it)->AsValue().release()); | 404 state->Append(it->second->AsValue().release()); |
| 378 } | 405 } |
| 379 return state.PassAs<base::Value>(); | 406 return state.PassAs<base::Value>(); |
| 380 } | 407 } |
| 381 | 408 |
| 382 scoped_ptr<base::Value> TileManager::GetMemoryRequirementsAsValue() const { | 409 scoped_ptr<base::Value> TileManager::GetMemoryRequirementsAsValue() const { |
| 383 scoped_ptr<base::DictionaryValue> requirements( | 410 scoped_ptr<base::DictionaryValue> requirements( |
| 384 new base::DictionaryValue()); | 411 new base::DictionaryValue()); |
| 385 | 412 |
| 386 size_t memory_required_bytes; | 413 size_t memory_required_bytes; |
| 387 size_t memory_nice_to_have_bytes; | 414 size_t memory_nice_to_have_bytes; |
| 388 size_t memory_used_bytes; | 415 size_t memory_used_bytes; |
| 389 GetMemoryStats(&memory_required_bytes, | 416 GetMemoryStats(&memory_required_bytes, |
| 390 &memory_nice_to_have_bytes, | 417 &memory_nice_to_have_bytes, |
| 391 &memory_used_bytes); | 418 &memory_used_bytes); |
| 392 requirements->SetInteger("memory_required_bytes", memory_required_bytes); | 419 requirements->SetInteger("memory_required_bytes", memory_required_bytes); |
| 393 requirements->SetInteger("memory_nice_to_have_bytes", | 420 requirements->SetInteger("memory_nice_to_have_bytes", |
| 394 memory_nice_to_have_bytes); | 421 memory_nice_to_have_bytes); |
| 395 requirements->SetInteger("memory_used_bytes", memory_used_bytes); | 422 requirements->SetInteger("memory_used_bytes", memory_used_bytes); |
| 396 return requirements.PassAs<base::Value>(); | 423 return requirements.PassAs<base::Value>(); |
| 397 } | 424 } |
| 398 | 425 |
| 399 void TileManager::AddRequiredTileForActivation(Tile* tile) { | |
| 400 DCHECK(std::find(tiles_that_need_to_be_initialized_for_activation_.begin(), | |
| 401 tiles_that_need_to_be_initialized_for_activation_.end(), | |
| 402 tile) == | |
| 403 tiles_that_need_to_be_initialized_for_activation_.end()); | |
| 404 tiles_that_need_to_be_initialized_for_activation_.insert(tile); | |
| 405 } | |
| 406 | |
| 407 RasterMode TileManager::DetermineRasterMode(const Tile* tile) const { | 426 RasterMode TileManager::DetermineRasterMode(const Tile* tile) const { |
| 408 DCHECK(tile); | 427 DCHECK(tile); |
| 409 DCHECK(tile->picture_pile()); | 428 DCHECK(tile->picture_pile()); |
| 410 | 429 |
| 411 RasterMode raster_mode; | 430 RasterMode raster_mode; |
| 412 | 431 |
| 413 if (tile->managed_state().resolution == LOW_RESOLUTION) | 432 if (tile->managed_state().resolution == LOW_RESOLUTION) |
| 414 raster_mode = LOW_QUALITY_RASTER_MODE; | 433 raster_mode = LOW_QUALITY_RASTER_MODE; |
| 415 else if (!tile->picture_pile()->can_use_lcd_text()) | 434 else if (!tile->picture_pile()->can_use_lcd_text()) |
| 416 raster_mode = HIGH_QUALITY_NO_LCD_RASTER_MODE; | 435 raster_mode = HIGH_QUALITY_NO_LCD_RASTER_MODE; |
| 417 else | 436 else |
| 418 raster_mode = HIGH_QUALITY_RASTER_MODE; | 437 raster_mode = HIGH_QUALITY_RASTER_MODE; |
| 419 | 438 |
| 420 return raster_mode; | 439 return raster_mode; |
| 421 } | 440 } |
| 422 | 441 |
| 423 void TileManager::AssignGpuMemoryToTiles() { | 442 void TileManager::AssignGpuMemoryToTiles( |
| 443 const TileRefVector& sorted_tiles, |
| 444 TileVector* tiles_that_need_to_be_rasterized, |
| 445 TileSet* oom_tiles_required_for_activation) { |
| 424 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles"); | 446 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles"); |
| 425 | 447 |
| 448 // Reset activation tiles flag, to ensure we can activate |
| 449 // if we don't have any required-for-activation tiles here. |
| 450 all_tiles_required_for_activation_have_been_initialized_ = true; |
| 451 |
| 426 // Now give memory out to the tiles until we're out, and build | 452 // Now give memory out to the tiles until we're out, and build |
| 427 // the needs-to-be-rasterized queue. | 453 // the needs-to-be-rasterized queue. |
| 428 tiles_that_need_to_be_rasterized_.clear(); | |
| 429 tiles_that_need_to_be_initialized_for_activation_.clear(); | |
| 430 oom_tiles_that_need_to_be_initialized_for_activation_.clear(); | |
| 431 | |
| 432 size_t bytes_releasable = 0; | 454 size_t bytes_releasable = 0; |
| 433 for (TileVector::const_iterator it = tiles_.begin(); | 455 for (TileRefVector::const_iterator it = sorted_tiles.begin(); |
| 434 it != tiles_.end(); | 456 it != sorted_tiles.end(); |
| 435 ++it) { | 457 ++it) { |
| 436 const Tile* tile = *it; | 458 const Tile* tile = it->get(); |
| 437 const ManagedTileState& mts = tile->managed_state(); | 459 const ManagedTileState& mts = tile->managed_state(); |
| 438 for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { | 460 for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { |
| 439 if (mts.tile_versions[mode].resource_) | 461 if (mts.tile_versions[mode].resource_) |
| 440 bytes_releasable += tile->bytes_consumed_if_allocated(); | 462 bytes_releasable += tile->bytes_consumed_if_allocated(); |
| 441 } | 463 } |
| 442 } | 464 } |
| 443 | 465 |
| 444 // Cast to prevent overflow. | 466 // Cast to prevent overflow. |
| 445 int64 bytes_available = | 467 int64 bytes_available = |
| 446 static_cast<int64>(bytes_releasable) + | 468 static_cast<int64>(bytes_releasable) + |
| 447 static_cast<int64>(global_state_.memory_limit_in_bytes) - | 469 static_cast<int64>(global_state_.memory_limit_in_bytes) - |
| 448 static_cast<int64>(resource_pool_->acquired_memory_usage_bytes()); | 470 static_cast<int64>(resource_pool_->acquired_memory_usage_bytes()); |
| 449 | 471 |
| 450 size_t bytes_allocatable = | 472 size_t bytes_allocatable = |
| 451 std::max(static_cast<int64>(0), bytes_available); | 473 std::max(static_cast<int64>(0), bytes_available); |
| 452 | 474 |
| 453 size_t bytes_that_exceeded_memory_budget = 0; | 475 size_t bytes_that_exceeded_memory_budget = 0; |
| 454 size_t bytes_left = bytes_allocatable; | 476 size_t bytes_left = bytes_allocatable; |
| 455 size_t bytes_oom_tiles_that_need_to_be_initialized_for_activation = 0; | 477 size_t bytes_oom_tiles_that_need_to_be_initialized_for_activation = 0; |
| 456 bool higher_priority_tile_oomed = false; | 478 bool higher_priority_tile_oomed = false; |
| 457 for (TileVector::iterator it = tiles_.begin(); | 479 for (TileRefVector::const_iterator it = sorted_tiles.begin(); |
| 458 it != tiles_.end(); | 480 it != sorted_tiles.end(); |
| 459 ++it) { | 481 ++it) { |
| 460 Tile* tile = *it; | 482 Tile* tile = it->get(); |
| 461 ManagedTileState& mts = tile->managed_state(); | 483 ManagedTileState& mts = tile->managed_state(); |
| 462 | 484 |
| 463 // Pick the better version out of the one we already set, | 485 // Pick the better version out of the one we already set, |
| 464 // and the one that is required. | 486 // and the one that is required. |
| 465 mts.raster_mode = std::min(mts.raster_mode, DetermineRasterMode(tile)); | 487 mts.raster_mode = std::min(mts.raster_mode, DetermineRasterMode(tile)); |
| 466 | 488 |
| 467 ManagedTileState::TileVersion& tile_version = | 489 ManagedTileState::TileVersion& tile_version = |
| 468 mts.tile_versions[mts.raster_mode]; | 490 mts.tile_versions[mts.raster_mode]; |
| 469 | 491 |
| 470 // If this tile doesn't need a resource, then nothing to do. | 492 // If this tile doesn't need a resource, then nothing to do. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 491 tile_bytes += tile->bytes_consumed_if_allocated(); | 513 tile_bytes += tile->bytes_consumed_if_allocated(); |
| 492 | 514 |
| 493 // Tile is OOM. | 515 // Tile is OOM. |
| 494 if (tile_bytes > bytes_left) { | 516 if (tile_bytes > bytes_left) { |
| 495 if (tile->required_for_activation()) { | 517 if (tile->required_for_activation()) { |
| 496 // Immediately mark tiles for on-demand raster once the amount | 518 // Immediately mark tiles for on-demand raster once the amount |
| 497 // of memory for oom tiles required for activation exceeds our | 519 // of memory for oom tiles required for activation exceeds our |
| 498 // memory limit. | 520 // memory limit. |
| 499 if (bytes_oom_tiles_that_need_to_be_initialized_for_activation < | 521 if (bytes_oom_tiles_that_need_to_be_initialized_for_activation < |
| 500 global_state_.memory_limit_in_bytes) { | 522 global_state_.memory_limit_in_bytes) { |
| 501 oom_tiles_that_need_to_be_initialized_for_activation_.insert(tile); | 523 oom_tiles_required_for_activation->insert(tile); |
| 502 bytes_oom_tiles_that_need_to_be_initialized_for_activation += | 524 bytes_oom_tiles_that_need_to_be_initialized_for_activation += |
| 503 tile_bytes; | 525 tile_bytes; |
| 504 } else { | 526 } else { |
| 505 tile_version.set_rasterize_on_demand(); | 527 tile_version.set_rasterize_on_demand(); |
| 506 } | 528 } |
| 507 } | 529 } |
| 508 FreeResourcesForTile(tile); | 530 FreeResourcesForTile(tile); |
| 509 higher_priority_tile_oomed = true; | 531 higher_priority_tile_oomed = true; |
| 510 bytes_that_exceeded_memory_budget += tile_bytes; | 532 bytes_that_exceeded_memory_budget += tile_bytes; |
| 511 continue; | 533 continue; |
| 512 } | 534 } |
| 513 | 535 |
| 514 tile_version.set_use_resource(); | 536 tile_version.set_use_resource(); |
| 515 bytes_left -= tile_bytes; | 537 bytes_left -= tile_bytes; |
| 516 | 538 |
| 517 // Tile shouldn't be rasterized if we've failed to assign | 539 // Tile shouldn't be rasterized if we've failed to assign |
| 518 // gpu memory to a higher priority tile. This is important for | 540 // gpu memory to a higher priority tile. This is important for |
| 519 // two reasons: | 541 // two reasons: |
| 520 // 1. Tile size should not impact raster priority. | 542 // 1. Tile size should not impact raster priority. |
| 521 // 2. Tile with unreleasable memory could otherwise incorrectly | 543 // 2. Tile with unreleasable memory could otherwise incorrectly |
| 522 // be added as it's not affected by |bytes_allocatable|. | 544 // be added as it's not affected by |bytes_allocatable|. |
| 523 if (higher_priority_tile_oomed) | 545 if (higher_priority_tile_oomed) |
| 524 continue; | 546 continue; |
| 525 | 547 |
| 526 if (!tile_version.resource_) | 548 if (!tile_version.resource_) |
| 527 tiles_that_need_to_be_rasterized_.push_back(tile); | 549 tiles_that_need_to_be_rasterized->push_back(tile); |
| 528 | 550 |
| 529 if (!tile->IsReadyToDraw(NULL) && | 551 if (!tile->IsReadyToDraw(NULL) && |
| 530 tile->required_for_activation()) { | 552 tile->required_for_activation()) { |
| 531 AddRequiredTileForActivation(tile); | 553 all_tiles_required_for_activation_have_been_initialized_ = false; |
| 532 } | 554 } |
| 533 } | 555 } |
| 534 | 556 |
| 535 ever_exceeded_memory_budget_ |= bytes_that_exceeded_memory_budget > 0; | 557 ever_exceeded_memory_budget_ |= bytes_that_exceeded_memory_budget > 0; |
| 536 if (ever_exceeded_memory_budget_) { | 558 if (ever_exceeded_memory_budget_) { |
| 537 TRACE_COUNTER_ID2("cc", "over_memory_budget", this, | 559 TRACE_COUNTER_ID2("cc", "over_memory_budget", this, |
| 538 "budget", global_state_.memory_limit_in_bytes, | 560 "budget", global_state_.memory_limit_in_bytes, |
| 539 "over", bytes_that_exceeded_memory_budget); | 561 "over", bytes_that_exceeded_memory_budget); |
| 540 } | 562 } |
| 541 memory_stats_from_last_assign_.total_budget_in_bytes = | 563 memory_stats_from_last_assign_.total_budget_in_bytes = |
| 542 global_state_.memory_limit_in_bytes; | 564 global_state_.memory_limit_in_bytes; |
| 543 memory_stats_from_last_assign_.bytes_allocated = | 565 memory_stats_from_last_assign_.bytes_allocated = |
| 544 bytes_allocatable - bytes_left; | 566 bytes_allocatable - bytes_left; |
| 545 memory_stats_from_last_assign_.bytes_unreleasable = | 567 memory_stats_from_last_assign_.bytes_unreleasable = |
| 546 bytes_allocatable - bytes_releasable; | 568 bytes_allocatable - bytes_releasable; |
| 547 memory_stats_from_last_assign_.bytes_over = | 569 memory_stats_from_last_assign_.bytes_over = |
| 548 bytes_that_exceeded_memory_budget; | 570 bytes_that_exceeded_memory_budget; |
| 549 } | 571 } |
| 550 | 572 |
| 551 void TileManager::ReassignGpuMemoryToOOMTilesRequiredForActivation() { | 573 void TileManager::ReassignGpuMemoryToOOMTilesRequiredForActivation( |
| 574 const TileRefVector& sorted_tiles, |
| 575 TileVector* tiles_that_need_to_be_rasterized, |
| 576 TileSet* oom_tiles_required_for_activation) { |
| 552 TRACE_EVENT0( | 577 TRACE_EVENT0( |
| 553 "cc", "TileManager::ReassignGpuMemoryToOOMTilesRequiredForActivation"); | 578 "cc", "TileManager::ReassignGpuMemoryToOOMTilesRequiredForActivation"); |
| 554 | 579 |
| 555 size_t bytes_oom_for_required_tiles = 0; | 580 size_t bytes_oom_for_required_tiles = 0; |
| 556 TileVector tiles_requiring_memory_but_oomed; | 581 TileVector tiles_requiring_memory_but_oomed; |
| 557 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 582 for (TileRefVector::const_iterator it = sorted_tiles.begin(); |
| 558 Tile* tile = *it; | 583 it != sorted_tiles.end(); |
| 559 if (oom_tiles_that_need_to_be_initialized_for_activation_.find(tile) == | 584 ++it) { |
| 560 oom_tiles_that_need_to_be_initialized_for_activation_.end()) | 585 Tile* tile = it->get(); |
| 586 if (oom_tiles_required_for_activation->find(tile) == |
| 587 oom_tiles_required_for_activation->end()) |
| 561 continue; | 588 continue; |
| 562 | 589 |
| 563 tiles_requiring_memory_but_oomed.push_back(tile); | 590 tiles_requiring_memory_but_oomed.push_back(tile); |
| 564 bytes_oom_for_required_tiles += tile->bytes_consumed_if_allocated(); | 591 bytes_oom_for_required_tiles += tile->bytes_consumed_if_allocated(); |
| 565 } | 592 } |
| 566 | 593 |
| 567 if (tiles_requiring_memory_but_oomed.empty()) | 594 if (tiles_requiring_memory_but_oomed.empty()) |
| 568 return; | 595 return; |
| 569 | 596 |
| 570 // In OOM situation, we iterate tiles_, remove the memory for active tree | 597 // In OOM situation, we iterate sorted_tiles, remove the memory for active |
| 571 // and not the now bin. And give them to bytes_oom_for_required_tiles | 598 // tree and not the now bin. And give them to bytes_oom_for_required_tiles |
| 572 size_t bytes_freed = 0; | 599 size_t bytes_freed = 0; |
| 573 for (TileVector::reverse_iterator it = tiles_.rbegin(); | 600 for (TileRefVector::const_reverse_iterator it = sorted_tiles.rbegin(); |
| 574 it != tiles_.rend(); ++it) { | 601 it != sorted_tiles.rend(); |
| 575 Tile* tile = *it; | 602 ++it) { |
| 603 Tile* tile = it->get(); |
| 576 ManagedTileState& mts = tile->managed_state(); | 604 ManagedTileState& mts = tile->managed_state(); |
| 577 if (mts.tree_bin[PENDING_TREE] == NEVER_BIN && | 605 if (mts.tree_bin[PENDING_TREE] == NEVER_BIN && |
| 578 mts.tree_bin[ACTIVE_TREE] != NOW_BIN) { | 606 mts.tree_bin[ACTIVE_TREE] != NOW_BIN) { |
| 579 ManagedTileState::TileVersion& tile_version = | 607 ManagedTileState::TileVersion& tile_version = |
| 580 mts.tile_versions[mts.raster_mode]; | 608 mts.tile_versions[mts.raster_mode]; |
| 581 | 609 |
| 582 // If the tile is in the to-rasterize list, but it has no task, | 610 // If the tile is in the to-rasterize list, but it has no task, |
| 583 // then it means that we have assigned memory for it. | 611 // then it means that we have assigned memory for it. |
| 584 TileVector::iterator raster_it = | 612 TileVector::iterator raster_it = |
| 585 std::find(tiles_that_need_to_be_rasterized_.begin(), | 613 std::find(tiles_that_need_to_be_rasterized->begin(), |
| 586 tiles_that_need_to_be_rasterized_.end(), | 614 tiles_that_need_to_be_rasterized->end(), |
| 587 tile); | 615 tile); |
| 588 if (raster_it != tiles_that_need_to_be_rasterized_.end() && | 616 if (raster_it != tiles_that_need_to_be_rasterized->end() && |
| 589 tile_version.raster_task_.is_null()) { | 617 tile_version.raster_task_.is_null()) { |
| 590 bytes_freed += tile->bytes_consumed_if_allocated(); | 618 bytes_freed += tile->bytes_consumed_if_allocated(); |
| 591 tiles_that_need_to_be_rasterized_.erase(raster_it); | 619 tiles_that_need_to_be_rasterized->erase(raster_it); |
| 592 } | 620 } |
| 593 | 621 |
| 594 // Also consider all of the completed resources for freeing. | 622 // Also consider all of the completed resources for freeing. |
| 595 for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { | 623 for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { |
| 596 if (mts.tile_versions[mode].resource_) { | 624 if (mts.tile_versions[mode].resource_) { |
| 597 DCHECK(!tile->required_for_activation()); | 625 DCHECK(!tile->required_for_activation()); |
| 598 FreeResourceForTile(tile, static_cast<RasterMode>(mode)); | 626 FreeResourceForTile(tile, static_cast<RasterMode>(mode)); |
| 599 bytes_freed += tile->bytes_consumed_if_allocated(); | 627 bytes_freed += tile->bytes_consumed_if_allocated(); |
| 600 } | 628 } |
| 601 } | 629 } |
| 602 } | 630 } |
| 603 | 631 |
| 604 if (bytes_oom_for_required_tiles <= bytes_freed) | 632 if (bytes_oom_for_required_tiles <= bytes_freed) |
| 605 break; | 633 break; |
| 606 } | 634 } |
| 607 | 635 |
| 608 for (TileVector::iterator it = tiles_requiring_memory_but_oomed.begin(); | 636 for (TileVector::iterator it = tiles_requiring_memory_but_oomed.begin(); |
| 609 it != tiles_requiring_memory_but_oomed.end() && bytes_freed > 0; | 637 it != tiles_requiring_memory_but_oomed.end() && bytes_freed > 0; |
| 610 ++it) { | 638 ++it) { |
| 611 Tile* tile = *it; | 639 Tile* tile = *it; |
| 612 ManagedTileState& mts = tile->managed_state(); | 640 ManagedTileState& mts = tile->managed_state(); |
| 613 size_t bytes_needed = tile->bytes_consumed_if_allocated(); | 641 size_t bytes_needed = tile->bytes_consumed_if_allocated(); |
| 614 if (bytes_needed > bytes_freed) | 642 if (bytes_needed > bytes_freed) |
| 615 continue; | 643 continue; |
| 616 mts.tile_versions[mts.raster_mode].set_use_resource(); | 644 mts.tile_versions[mts.raster_mode].set_use_resource(); |
| 617 bytes_freed -= bytes_needed; | 645 bytes_freed -= bytes_needed; |
| 618 tiles_that_need_to_be_rasterized_.push_back(tile); | 646 tiles_that_need_to_be_rasterized->push_back(tile); |
| 619 DCHECK(tile->required_for_activation()); | 647 DCHECK(tile->required_for_activation()); |
| 620 AddRequiredTileForActivation(tile); | 648 all_tiles_required_for_activation_have_been_initialized_ = false; |
| 621 oom_tiles_that_need_to_be_initialized_for_activation_.erase(tile); | 649 oom_tiles_required_for_activation->erase(tile); |
| 622 } | 650 } |
| 623 } | 651 } |
| 624 | 652 |
| 625 void TileManager::CleanUpUnusedImageDecodeTasks() { | 653 void TileManager::CleanUpUnusedImageDecodeTasks() { |
| 626 // Calculate a set of layers that are used by at least one tile. | 654 // Calculate a set of layers that are used by at least one tile. |
| 627 base::hash_set<int> used_layers; | 655 base::hash_set<int> used_layers; |
| 628 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) | 656 for (TileMap::iterator it = tiles_.begin(); it != tiles_.end(); ++it) |
| 629 used_layers.insert((*it)->layer_id()); | 657 used_layers.insert(it->second->layer_id()); |
| 630 | 658 |
| 631 // Now calculate the set of layers in |image_decode_tasks_| that are not used | 659 // Now calculate the set of layers in |image_decode_tasks_| that are not used |
| 632 // by any tile. | 660 // by any tile. |
| 633 std::vector<int> unused_layers; | 661 std::vector<int> unused_layers; |
| 634 for (LayerPixelRefTaskMap::iterator it = image_decode_tasks_.begin(); | 662 for (LayerPixelRefTaskMap::iterator it = image_decode_tasks_.begin(); |
| 635 it != image_decode_tasks_.end(); | 663 it != image_decode_tasks_.end(); |
| 636 ++it) { | 664 ++it) { |
| 637 if (used_layers.find(it->first) == used_layers.end()) | 665 if (used_layers.find(it->first) == used_layers.end()) |
| 638 unused_layers.push_back(it->first); | 666 unused_layers.push_back(it->first); |
| 639 } | 667 } |
| (...skipping 22 matching lines...) Expand all Loading... |
| 662 | 690 |
| 663 void TileManager::FreeUnusedResourcesForTile(Tile* tile) { | 691 void TileManager::FreeUnusedResourcesForTile(Tile* tile) { |
| 664 RasterMode used_mode = HIGH_QUALITY_RASTER_MODE; | 692 RasterMode used_mode = HIGH_QUALITY_RASTER_MODE; |
| 665 bool version_is_used = tile->IsReadyToDraw(&used_mode); | 693 bool version_is_used = tile->IsReadyToDraw(&used_mode); |
| 666 for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { | 694 for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { |
| 667 if (!version_is_used || mode != used_mode) | 695 if (!version_is_used || mode != used_mode) |
| 668 FreeResourceForTile(tile, static_cast<RasterMode>(mode)); | 696 FreeResourceForTile(tile, static_cast<RasterMode>(mode)); |
| 669 } | 697 } |
| 670 } | 698 } |
| 671 | 699 |
| 672 void TileManager::ScheduleTasks() { | 700 void TileManager::ScheduleTasks( |
| 701 const TileVector& tiles_that_need_to_be_rasterized) { |
| 673 TRACE_EVENT1("cc", "TileManager::ScheduleTasks", | 702 TRACE_EVENT1("cc", "TileManager::ScheduleTasks", |
| 674 "count", tiles_that_need_to_be_rasterized_.size()); | 703 "count", tiles_that_need_to_be_rasterized.size()); |
| 675 RasterWorkerPool::RasterTask::Queue tasks; | 704 RasterWorkerPool::RasterTask::Queue tasks; |
| 676 | 705 |
| 677 // Build a new task queue containing all task currently needed. Tasks | 706 // Build a new task queue containing all task currently needed. Tasks |
| 678 // are added in order of priority, highest priority task first. | 707 // are added in order of priority, highest priority task first. |
| 679 for (TileVector::iterator it = tiles_that_need_to_be_rasterized_.begin(); | 708 for (TileVector::const_iterator it = tiles_that_need_to_be_rasterized.begin(); |
| 680 it != tiles_that_need_to_be_rasterized_.end(); | 709 it != tiles_that_need_to_be_rasterized.end(); |
| 681 ++it) { | 710 ++it) { |
| 682 Tile* tile = *it; | 711 Tile* tile = *it; |
| 683 ManagedTileState& mts = tile->managed_state(); | 712 ManagedTileState& mts = tile->managed_state(); |
| 684 ManagedTileState::TileVersion& tile_version = | 713 ManagedTileState::TileVersion& tile_version = |
| 685 mts.tile_versions[mts.raster_mode]; | 714 mts.tile_versions[mts.raster_mode]; |
| 686 | 715 |
| 687 DCHECK(tile_version.requires_resource()); | 716 DCHECK(tile_version.requires_resource()); |
| 688 DCHECK(!tile_version.resource_); | 717 DCHECK(!tile_version.resource_); |
| 689 | 718 |
| 690 if (tile_version.raster_task_.is_null()) | 719 if (tile_version.raster_task_.is_null()) |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 751 mts.raster_mode, | 780 mts.raster_mode, |
| 752 use_color_estimator_, | 781 use_color_estimator_, |
| 753 mts.tree_bin[PENDING_TREE] == NOW_BIN, | 782 mts.tree_bin[PENDING_TREE] == NOW_BIN, |
| 754 mts.resolution, | 783 mts.resolution, |
| 755 tile->layer_id(), | 784 tile->layer_id(), |
| 756 &tile, | 785 &tile, |
| 757 tile->source_frame_number(), | 786 tile->source_frame_number(), |
| 758 rendering_stats_instrumentation_, | 787 rendering_stats_instrumentation_, |
| 759 base::Bind(&TileManager::OnRasterTaskCompleted, | 788 base::Bind(&TileManager::OnRasterTaskCompleted, |
| 760 base::Unretained(this), | 789 base::Unretained(this), |
| 761 make_scoped_refptr(tile), | 790 tile->id(), |
| 762 base::Passed(&resource), | 791 base::Passed(&resource), |
| 763 mts.raster_mode), | 792 mts.raster_mode), |
| 764 &decode_tasks); | 793 &decode_tasks); |
| 765 } | 794 } |
| 766 | 795 |
| 767 void TileManager::OnImageDecodeTaskCompleted( | 796 void TileManager::OnImageDecodeTaskCompleted( |
| 768 int layer_id, | 797 int layer_id, |
| 769 skia::LazyPixelRef* pixel_ref, | 798 skia::LazyPixelRef* pixel_ref, |
| 770 bool was_canceled) { | 799 bool was_canceled) { |
| 771 // If the task was canceled, we need to clean it up | 800 // If the task was canceled, we need to clean it up |
| 772 // from |image_decode_tasks_|. | 801 // from |image_decode_tasks_|. |
| 773 if (!was_canceled) | 802 if (!was_canceled) |
| 774 return; | 803 return; |
| 775 | 804 |
| 776 LayerPixelRefTaskMap::iterator layer_it = | 805 LayerPixelRefTaskMap::iterator layer_it = |
| 777 image_decode_tasks_.find(layer_id); | 806 image_decode_tasks_.find(layer_id); |
| 778 | 807 |
| 779 if (layer_it == image_decode_tasks_.end()) | 808 if (layer_it == image_decode_tasks_.end()) |
| 780 return; | 809 return; |
| 781 | 810 |
| 782 PixelRefTaskMap& pixel_ref_tasks = layer_it->second; | 811 PixelRefTaskMap& pixel_ref_tasks = layer_it->second; |
| 783 PixelRefTaskMap::iterator task_it = | 812 PixelRefTaskMap::iterator task_it = |
| 784 pixel_ref_tasks.find(pixel_ref->getGenerationID()); | 813 pixel_ref_tasks.find(pixel_ref->getGenerationID()); |
| 785 | 814 |
| 786 if (task_it != pixel_ref_tasks.end()) | 815 if (task_it != pixel_ref_tasks.end()) |
| 787 pixel_ref_tasks.erase(task_it); | 816 pixel_ref_tasks.erase(task_it); |
| 788 } | 817 } |
| 789 | 818 |
| 790 void TileManager::OnRasterTaskCompleted( | 819 void TileManager::OnRasterTaskCompleted( |
| 791 scoped_refptr<Tile> tile, | 820 Tile::Id tile_id, |
| 792 scoped_ptr<ResourcePool::Resource> resource, | 821 scoped_ptr<ResourcePool::Resource> resource, |
| 793 RasterMode raster_mode, | 822 RasterMode raster_mode, |
| 794 const PicturePileImpl::Analysis& analysis, | 823 const PicturePileImpl::Analysis& analysis, |
| 795 bool was_canceled) { | 824 bool was_canceled) { |
| 796 TRACE_EVENT1("cc", "TileManager::OnRasterTaskCompleted", | 825 TRACE_EVENT1("cc", "TileManager::OnRasterTaskCompleted", |
| 797 "was_canceled", was_canceled); | 826 "was_canceled", was_canceled); |
| 798 | 827 |
| 828 TileMap::iterator it = tiles_.find(tile_id); |
| 829 if (it == tiles_.end()) { |
| 830 resource_pool_->ReleaseResource(resource.Pass()); |
| 831 return; |
| 832 } |
| 833 |
| 834 Tile* tile = it->second; |
| 799 ManagedTileState& mts = tile->managed_state(); | 835 ManagedTileState& mts = tile->managed_state(); |
| 800 ManagedTileState::TileVersion& tile_version = | 836 ManagedTileState::TileVersion& tile_version = |
| 801 mts.tile_versions[raster_mode]; | 837 mts.tile_versions[raster_mode]; |
| 802 DCHECK(!tile_version.raster_task_.is_null()); | 838 DCHECK(!tile_version.raster_task_.is_null()); |
| 803 tile_version.raster_task_.Reset(); | 839 tile_version.raster_task_.Reset(); |
| 804 | 840 |
| 805 if (was_canceled) { | 841 if (was_canceled) { |
| 806 resource_pool_->ReleaseResource(resource.Pass()); | 842 resource_pool_->ReleaseResource(resource.Pass()); |
| 807 return; | 843 return; |
| 808 } | 844 } |
| 809 | 845 |
| 810 tile_version.set_has_text(analysis.has_text); | 846 tile_version.set_has_text(analysis.has_text); |
| 811 if (analysis.is_solid_color) { | 847 if (analysis.is_solid_color) { |
| 812 tile_version.set_solid_color(analysis.solid_color); | 848 tile_version.set_solid_color(analysis.solid_color); |
| 813 resource_pool_->ReleaseResource(resource.Pass()); | 849 resource_pool_->ReleaseResource(resource.Pass()); |
| 814 } else { | 850 } else { |
| 815 tile_version.resource_ = resource.Pass(); | 851 tile_version.resource_ = resource.Pass(); |
| 816 } | 852 } |
| 817 | 853 |
| 818 FreeUnusedResourcesForTile(tile.get()); | 854 FreeUnusedResourcesForTile(tile); |
| 819 | 855 |
| 820 DidFinishTileInitialization(tile.get()); | |
| 821 } | |
| 822 | |
| 823 void TileManager::DidFinishTileInitialization(Tile* tile) { | |
| 824 if (tile->priority(ACTIVE_TREE).distance_to_visible_in_pixels == 0) | 856 if (tile->priority(ACTIVE_TREE).distance_to_visible_in_pixels == 0) |
| 825 did_initialize_visible_tile_ = true; | 857 did_initialize_visible_tile_ = true; |
| 826 if (tile->required_for_activation()) { | |
| 827 // It's possible that a tile required for activation is not in this list | |
| 828 // if it was marked as being required after being dispatched for | |
| 829 // rasterization but before AssignGPUMemory was called again. | |
| 830 tiles_that_need_to_be_initialized_for_activation_.erase(tile); | |
| 831 } | |
| 832 } | |
| 833 | |
| 834 void TileManager::DidTileTreeBinChange(Tile* tile, | |
| 835 ManagedTileBin new_tree_bin, | |
| 836 WhichTree tree) { | |
| 837 ManagedTileState& mts = tile->managed_state(); | |
| 838 mts.tree_bin[tree] = new_tree_bin; | |
| 839 } | 858 } |
| 840 | 859 |
| 841 } // namespace cc | 860 } // namespace cc |
| OLD | NEW |