Chromium Code Reviews| 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 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 223 all_tiles_that_need_to_be_rasterized_are_scheduled_(true), | 223 all_tiles_that_need_to_be_rasterized_are_scheduled_(true), |
| 224 did_check_for_completed_tasks_since_last_schedule_tasks_(true), | 224 did_check_for_completed_tasks_since_last_schedule_tasks_(true), |
| 225 did_oom_on_last_assign_(false), | 225 did_oom_on_last_assign_(false), |
| 226 ready_to_activate_check_notifier_( | 226 ready_to_activate_check_notifier_( |
| 227 task_runner_.get(), | 227 task_runner_.get(), |
| 228 base::Bind(&TileManager::CheckIfReadyToActivate, | 228 base::Bind(&TileManager::CheckIfReadyToActivate, |
| 229 base::Unretained(this))), | 229 base::Unretained(this))), |
| 230 ready_to_draw_check_notifier_( | 230 ready_to_draw_check_notifier_( |
| 231 task_runner_.get(), | 231 task_runner_.get(), |
| 232 base::Bind(&TileManager::CheckIfReadyToDraw, base::Unretained(this))), | 232 base::Bind(&TileManager::CheckIfReadyToDraw, base::Unretained(this))), |
| 233 more_tiles_need_prepare_check_notifier_( | |
| 234 task_runner_.get(), | |
| 235 base::Bind(&TileManager::CheckIfMoreTilesNeedPrepare, | |
| 236 base::Unretained(this))), | |
| 233 did_notify_ready_to_activate_(false), | 237 did_notify_ready_to_activate_(false), |
| 234 did_notify_ready_to_draw_(false) { | 238 did_notify_ready_to_draw_(false) { |
| 235 tile_task_runner_->SetClient(this); | 239 tile_task_runner_->SetClient(this); |
| 236 } | 240 } |
| 237 | 241 |
| 238 TileManager::~TileManager() { | 242 TileManager::~TileManager() { |
| 239 // Reset global state and manage. This should cause | 243 // Reset global state and manage. This should cause |
| 240 // our memory usage to drop to zero. | 244 // our memory usage to drop to zero. |
| 241 global_state_ = GlobalStateThatImpactsTilePriority(); | 245 global_state_ = GlobalStateThatImpactsTilePriority(); |
| 242 | 246 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 303 void TileManager::DidFinishRunningTileTasks(TaskSet task_set) { | 307 void TileManager::DidFinishRunningTileTasks(TaskSet task_set) { |
| 304 TRACE_EVENT1("cc", "TileManager::DidFinishRunningTileTasks", "task_set", | 308 TRACE_EVENT1("cc", "TileManager::DidFinishRunningTileTasks", "task_set", |
| 305 TaskSetName(task_set)); | 309 TaskSetName(task_set)); |
| 306 | 310 |
| 307 switch (task_set) { | 311 switch (task_set) { |
| 308 case ALL: { | 312 case ALL: { |
| 309 bool memory_usage_above_limit = | 313 bool memory_usage_above_limit = |
| 310 resource_pool_->total_memory_usage_bytes() > | 314 resource_pool_->total_memory_usage_bytes() > |
| 311 global_state_.soft_memory_limit_in_bytes; | 315 global_state_.soft_memory_limit_in_bytes; |
| 312 | 316 |
| 313 // When OOM, keep re-assigning memory until we reach a steady state | |
| 314 // where top-priority tiles are initialized. | |
| 315 if (all_tiles_that_need_to_be_rasterized_are_scheduled_ && | 317 if (all_tiles_that_need_to_be_rasterized_are_scheduled_ && |
| 316 !memory_usage_above_limit) | 318 !memory_usage_above_limit) |
| 317 return; | 319 return; |
| 318 | 320 |
| 319 tile_task_runner_->CheckForCompletedTasks(); | 321 more_tiles_need_prepare_check_notifier_.Schedule(); |
| 320 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; | |
| 321 | |
| 322 TileVector tiles_that_need_to_be_rasterized; | |
| 323 AssignGpuMemoryToTiles(&tiles_that_need_to_be_rasterized); | |
| 324 | |
| 325 // |tiles_that_need_to_be_rasterized| will be empty when we reach a | |
| 326 // steady memory state. Keep scheduling tasks until we reach this state. | |
| 327 if (!tiles_that_need_to_be_rasterized.empty()) { | |
| 328 ScheduleTasks(tiles_that_need_to_be_rasterized); | |
| 329 return; | |
| 330 } | |
| 331 | |
| 332 FreeResourcesForReleasedTiles(); | |
| 333 | |
| 334 resource_pool_->ReduceResourceUsage(); | |
| 335 | |
| 336 // We don't reserve memory for required-for-activation tiles during | |
| 337 // accelerated gestures, so we just postpone activation when we don't | |
| 338 // have these tiles, and activate after the accelerated gesture. | |
| 339 // Likewise if we don't allow any tiles (as is the case when we're | |
| 340 // invisible), if we have tiles that aren't ready, then we shouldn't | |
| 341 // activate as activation can cause checkerboards. | |
| 342 bool allow_rasterize_on_demand = | |
| 343 global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY && | |
| 344 global_state_.memory_limit_policy != ALLOW_NOTHING; | |
| 345 | |
| 346 // Use on-demand raster for any required-for-activation tiles that have | |
| 347 // not | |
| 348 // been been assigned memory after reaching a steady memory state. This | |
| 349 // ensures that we activate even when OOM. Note that we have to rebuilt | |
| 350 // the | |
| 351 // queue in case the last AssignGpuMemoryToTiles evicted some tiles that | |
| 352 // would otherwise not be picked up by the old raster queue. | |
| 353 client_->BuildRasterQueue(&raster_priority_queue_, | |
| 354 global_state_.tree_priority); | |
| 355 bool ready_to_activate = true; | |
| 356 while (!raster_priority_queue_.IsEmpty()) { | |
| 357 Tile* tile = raster_priority_queue_.Top(); | |
| 358 ManagedTileState& mts = tile->managed_state(); | |
| 359 | |
| 360 if (tile->required_for_activation() && !mts.draw_info.IsReadyToDraw()) { | |
| 361 // If we can't raster on demand, give up early (and don't activate). | |
| 362 if (!allow_rasterize_on_demand) { | |
| 363 ready_to_activate = false; | |
| 364 break; | |
| 365 } | |
| 366 | |
| 367 mts.draw_info.set_rasterize_on_demand(); | |
| 368 client_->NotifyTileStateChanged(tile); | |
| 369 } | |
| 370 raster_priority_queue_.Pop(); | |
| 371 } | |
| 372 | |
| 373 if (ready_to_activate) { | |
| 374 DCHECK(IsReadyToActivate()); | |
| 375 ready_to_activate_check_notifier_.Schedule(); | |
| 376 } | |
| 377 raster_priority_queue_.Reset(); | |
| 378 return; | 322 return; |
| 379 } | 323 } |
| 380 case REQUIRED_FOR_ACTIVATION: | 324 case REQUIRED_FOR_ACTIVATION: |
| 381 ready_to_activate_check_notifier_.Schedule(); | 325 ready_to_activate_check_notifier_.Schedule(); |
| 382 return; | 326 return; |
| 383 case REQUIRED_FOR_DRAW: | 327 case REQUIRED_FOR_DRAW: |
| 384 ready_to_draw_check_notifier_.Schedule(); | 328 ready_to_draw_check_notifier_.Schedule(); |
| 385 return; | 329 return; |
| 386 } | 330 } |
| 387 | 331 |
| (...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 889 | 833 |
| 890 if (did_notify_ready_to_draw_) | 834 if (did_notify_ready_to_draw_) |
| 891 return; | 835 return; |
| 892 if (!IsReadyToDraw()) | 836 if (!IsReadyToDraw()) |
| 893 return; | 837 return; |
| 894 | 838 |
| 895 client_->NotifyReadyToDraw(); | 839 client_->NotifyReadyToDraw(); |
| 896 did_notify_ready_to_draw_ = true; | 840 did_notify_ready_to_draw_ = true; |
| 897 } | 841 } |
| 898 | 842 |
| 843 void TileManager::CheckIfMoreTilesNeedPrepare() { | |
| 844 tile_task_runner_->CheckForCompletedTasks(); | |
| 845 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; | |
| 846 | |
| 847 // When OOM, keep re-assigning memory until we reach a steady state | |
| 848 // where top-priority tiles are initialized. | |
| 849 TileVector tiles_that_need_to_be_rasterized; | |
| 850 AssignGpuMemoryToTiles(&tiles_that_need_to_be_rasterized); | |
| 851 | |
| 852 // |tiles_that_need_to_be_rasterized| will be empty when we reach a | |
| 853 // steady memory state. Keep scheduling tasks until we reach this state. | |
| 854 if (!tiles_that_need_to_be_rasterized.empty()) { | |
| 855 ScheduleTasks(tiles_that_need_to_be_rasterized); | |
| 856 return; | |
| 857 } | |
| 858 | |
| 859 FreeResourcesForReleasedTiles(); | |
| 860 | |
| 861 resource_pool_->ReduceResourceUsage(); | |
| 862 | |
| 863 // We don't reserve memory for required-for-activation tiles during | |
| 864 // accelerated gestures, so we just postpone activation when we don't | |
| 865 // have these tiles, and activate after the accelerated gesture. | |
| 866 // Likewise if we don't allow any tiles (as is the case when we're | |
| 867 // invisible), if we have tiles that aren't ready, then we shouldn't | |
| 868 // activate as activation can cause checkerboards. | |
| 869 bool allow_rasterize_on_demand = | |
| 870 global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY && | |
| 871 global_state_.memory_limit_policy != ALLOW_NOTHING; | |
| 872 | |
| 873 // Use on-demand raster for any required-for-activation tiles that have | |
| 874 // not | |
| 875 // been been assigned memory after reaching a steady memory state. This | |
| 876 // ensures that we activate even when OOM. Note that we have to rebuilt | |
| 877 // the | |
| 878 // queue in case the last AssignGpuMemoryToTiles evicted some tiles that | |
| 879 // would otherwise not be picked up by the old raster queue. | |
|
reveman
2014/12/19 01:07:44
Not your patch but it would be nice if fixed the f
vmiura
2014/12/23 22:28:13
Done.
| |
| 880 client_->BuildRasterQueue(&raster_priority_queue_, | |
| 881 global_state_.tree_priority); | |
| 882 bool ready_to_activate = true; | |
| 883 while (!raster_priority_queue_.IsEmpty()) { | |
| 884 Tile* tile = raster_priority_queue_.Top(); | |
| 885 ManagedTileState& mts = tile->managed_state(); | |
| 886 | |
| 887 if (tile->required_for_activation() && !mts.draw_info.IsReadyToDraw()) { | |
| 888 // If we can't raster on demand, give up early (and don't activate). | |
| 889 if (!allow_rasterize_on_demand) { | |
| 890 ready_to_activate = false; | |
| 891 break; | |
| 892 } | |
| 893 | |
| 894 mts.draw_info.set_rasterize_on_demand(); | |
| 895 client_->NotifyTileStateChanged(tile); | |
| 896 } | |
| 897 raster_priority_queue_.Pop(); | |
| 898 } | |
| 899 | |
| 900 if (ready_to_activate) { | |
| 901 DCHECK(IsReadyToActivate()); | |
| 902 ready_to_activate_check_notifier_.Schedule(); | |
| 903 } | |
| 904 raster_priority_queue_.Reset(); | |
| 905 } | |
| 906 | |
| 899 TileManager::MemoryUsage::MemoryUsage() : memory_bytes_(0), resource_count_(0) { | 907 TileManager::MemoryUsage::MemoryUsage() : memory_bytes_(0), resource_count_(0) { |
| 900 } | 908 } |
| 901 | 909 |
| 902 TileManager::MemoryUsage::MemoryUsage(int64 memory_bytes, int resource_count) | 910 TileManager::MemoryUsage::MemoryUsage(int64 memory_bytes, int resource_count) |
| 903 : memory_bytes_(memory_bytes), resource_count_(resource_count) { | 911 : memory_bytes_(memory_bytes), resource_count_(resource_count) { |
| 904 } | 912 } |
| 905 | 913 |
| 906 // static | 914 // static |
| 907 TileManager::MemoryUsage TileManager::MemoryUsage::FromConfig( | 915 TileManager::MemoryUsage TileManager::MemoryUsage::FromConfig( |
| 908 const gfx::Size& size, | 916 const gfx::Size& size, |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 940 result -= other; | 948 result -= other; |
| 941 return result; | 949 return result; |
| 942 } | 950 } |
| 943 | 951 |
| 944 bool TileManager::MemoryUsage::Exceeds(const MemoryUsage& limit) const { | 952 bool TileManager::MemoryUsage::Exceeds(const MemoryUsage& limit) const { |
| 945 return memory_bytes_ > limit.memory_bytes_ || | 953 return memory_bytes_ > limit.memory_bytes_ || |
| 946 resource_count_ > limit.resource_count_; | 954 resource_count_ > limit.resource_count_; |
| 947 } | 955 } |
| 948 | 956 |
| 949 } // namespace cc | 957 } // namespace cc |
| OLD | NEW |