| 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 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 221 all_tiles_that_need_to_be_rasterized_are_scheduled_(true), | 221 all_tiles_that_need_to_be_rasterized_are_scheduled_(true), |
| 222 did_check_for_completed_tasks_since_last_schedule_tasks_(true), | 222 did_check_for_completed_tasks_since_last_schedule_tasks_(true), |
| 223 did_oom_on_last_assign_(false), | 223 did_oom_on_last_assign_(false), |
| 224 ready_to_activate_check_notifier_( | 224 ready_to_activate_check_notifier_( |
| 225 task_runner_.get(), | 225 task_runner_.get(), |
| 226 base::Bind(&TileManager::CheckIfReadyToActivate, | 226 base::Bind(&TileManager::CheckIfReadyToActivate, |
| 227 base::Unretained(this))), | 227 base::Unretained(this))), |
| 228 ready_to_draw_check_notifier_( | 228 ready_to_draw_check_notifier_( |
| 229 task_runner_.get(), | 229 task_runner_.get(), |
| 230 base::Bind(&TileManager::CheckIfReadyToDraw, base::Unretained(this))), | 230 base::Bind(&TileManager::CheckIfReadyToDraw, base::Unretained(this))), |
| 231 more_tiles_need_prepare_check_notifier_( |
| 232 task_runner_.get(), |
| 233 base::Bind(&TileManager::CheckIfMoreTilesNeedToBePrepared, |
| 234 base::Unretained(this))), |
| 231 did_notify_ready_to_activate_(false), | 235 did_notify_ready_to_activate_(false), |
| 232 did_notify_ready_to_draw_(false) { | 236 did_notify_ready_to_draw_(false) { |
| 233 tile_task_runner_->SetClient(this); | 237 tile_task_runner_->SetClient(this); |
| 234 } | 238 } |
| 235 | 239 |
| 236 TileManager::~TileManager() { | 240 TileManager::~TileManager() { |
| 237 // Reset global state and manage. This should cause | 241 // Reset global state and manage. This should cause |
| 238 // our memory usage to drop to zero. | 242 // our memory usage to drop to zero. |
| 239 global_state_ = GlobalStateThatImpactsTilePriority(); | 243 global_state_ = GlobalStateThatImpactsTilePriority(); |
| 240 | 244 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 301 void TileManager::DidFinishRunningTileTasks(TaskSet task_set) { | 305 void TileManager::DidFinishRunningTileTasks(TaskSet task_set) { |
| 302 TRACE_EVENT1("cc", "TileManager::DidFinishRunningTileTasks", "task_set", | 306 TRACE_EVENT1("cc", "TileManager::DidFinishRunningTileTasks", "task_set", |
| 303 TaskSetName(task_set)); | 307 TaskSetName(task_set)); |
| 304 | 308 |
| 305 switch (task_set) { | 309 switch (task_set) { |
| 306 case ALL: { | 310 case ALL: { |
| 307 bool memory_usage_above_limit = | 311 bool memory_usage_above_limit = |
| 308 resource_pool_->total_memory_usage_bytes() > | 312 resource_pool_->total_memory_usage_bytes() > |
| 309 global_state_.soft_memory_limit_in_bytes; | 313 global_state_.soft_memory_limit_in_bytes; |
| 310 | 314 |
| 311 // When OOM, keep re-assigning memory until we reach a steady state | |
| 312 // where top-priority tiles are initialized. | |
| 313 if (all_tiles_that_need_to_be_rasterized_are_scheduled_ && | 315 if (all_tiles_that_need_to_be_rasterized_are_scheduled_ && |
| 314 !memory_usage_above_limit) | 316 !memory_usage_above_limit) |
| 315 return; | 317 return; |
| 316 | 318 |
| 317 tile_task_runner_->CheckForCompletedTasks(); | 319 more_tiles_need_prepare_check_notifier_.Schedule(); |
| 318 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; | |
| 319 | |
| 320 TileVector tiles_that_need_to_be_rasterized; | |
| 321 AssignGpuMemoryToTiles(&tiles_that_need_to_be_rasterized); | |
| 322 | |
| 323 // |tiles_that_need_to_be_rasterized| will be empty when we reach a | |
| 324 // steady memory state. Keep scheduling tasks until we reach this state. | |
| 325 if (!tiles_that_need_to_be_rasterized.empty()) { | |
| 326 ScheduleTasks(tiles_that_need_to_be_rasterized); | |
| 327 return; | |
| 328 } | |
| 329 | |
| 330 FreeResourcesForReleasedTiles(); | |
| 331 | |
| 332 resource_pool_->ReduceResourceUsage(); | |
| 333 | |
| 334 // We don't reserve memory for required-for-activation tiles during | |
| 335 // accelerated gestures, so we just postpone activation when we don't | |
| 336 // have these tiles, and activate after the accelerated gesture. | |
| 337 // Likewise if we don't allow any tiles (as is the case when we're | |
| 338 // invisible), if we have tiles that aren't ready, then we shouldn't | |
| 339 // activate as activation can cause checkerboards. | |
| 340 bool allow_rasterize_on_demand = | |
| 341 global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY && | |
| 342 global_state_.memory_limit_policy != ALLOW_NOTHING; | |
| 343 | |
| 344 // Use on-demand raster for any required-for-activation tiles that have | |
| 345 // not | |
| 346 // been been assigned memory after reaching a steady memory state. This | |
| 347 // ensures that we activate even when OOM. Note that we have to rebuilt | |
| 348 // the | |
| 349 // queue in case the last AssignGpuMemoryToTiles evicted some tiles that | |
| 350 // would otherwise not be picked up by the old raster queue. | |
| 351 client_->BuildRasterQueue(&raster_priority_queue_, | |
| 352 global_state_.tree_priority); | |
| 353 bool ready_to_activate = true; | |
| 354 while (!raster_priority_queue_.IsEmpty()) { | |
| 355 Tile* tile = raster_priority_queue_.Top(); | |
| 356 TileDrawInfo& draw_info = tile->draw_info(); | |
| 357 | |
| 358 if (tile->required_for_activation() && !draw_info.IsReadyToDraw()) { | |
| 359 // If we can't raster on demand, give up early (and don't activate). | |
| 360 if (!allow_rasterize_on_demand) { | |
| 361 ready_to_activate = false; | |
| 362 break; | |
| 363 } | |
| 364 | |
| 365 draw_info.set_rasterize_on_demand(); | |
| 366 client_->NotifyTileStateChanged(tile); | |
| 367 } | |
| 368 raster_priority_queue_.Pop(); | |
| 369 } | |
| 370 | |
| 371 if (ready_to_activate) { | |
| 372 DCHECK(IsReadyToActivate()); | |
| 373 ready_to_activate_check_notifier_.Schedule(); | |
| 374 } | |
| 375 raster_priority_queue_.Reset(); | |
| 376 return; | 320 return; |
| 377 } | 321 } |
| 378 case REQUIRED_FOR_ACTIVATION: | 322 case REQUIRED_FOR_ACTIVATION: |
| 379 ready_to_activate_check_notifier_.Schedule(); | 323 ready_to_activate_check_notifier_.Schedule(); |
| 380 return; | 324 return; |
| 381 case REQUIRED_FOR_DRAW: | 325 case REQUIRED_FOR_DRAW: |
| 382 ready_to_draw_check_notifier_.Schedule(); | 326 ready_to_draw_check_notifier_.Schedule(); |
| 383 return; | 327 return; |
| 384 } | 328 } |
| 385 | 329 |
| (...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 876 | 820 |
| 877 if (did_notify_ready_to_draw_) | 821 if (did_notify_ready_to_draw_) |
| 878 return; | 822 return; |
| 879 if (!IsReadyToDraw()) | 823 if (!IsReadyToDraw()) |
| 880 return; | 824 return; |
| 881 | 825 |
| 882 client_->NotifyReadyToDraw(); | 826 client_->NotifyReadyToDraw(); |
| 883 did_notify_ready_to_draw_ = true; | 827 did_notify_ready_to_draw_ = true; |
| 884 } | 828 } |
| 885 | 829 |
| 830 void TileManager::CheckIfMoreTilesNeedToBePrepared() { |
| 831 tile_task_runner_->CheckForCompletedTasks(); |
| 832 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; |
| 833 |
| 834 // When OOM, keep re-assigning memory until we reach a steady state |
| 835 // where top-priority tiles are initialized. |
| 836 TileVector tiles_that_need_to_be_rasterized; |
| 837 AssignGpuMemoryToTiles(&tiles_that_need_to_be_rasterized); |
| 838 |
| 839 // |tiles_that_need_to_be_rasterized| will be empty when we reach a |
| 840 // steady memory state. Keep scheduling tasks until we reach this state. |
| 841 if (!tiles_that_need_to_be_rasterized.empty()) { |
| 842 ScheduleTasks(tiles_that_need_to_be_rasterized); |
| 843 return; |
| 844 } |
| 845 |
| 846 FreeResourcesForReleasedTiles(); |
| 847 |
| 848 resource_pool_->ReduceResourceUsage(); |
| 849 |
| 850 // We don't reserve memory for required-for-activation tiles during |
| 851 // accelerated gestures, so we just postpone activation when we don't |
| 852 // have these tiles, and activate after the accelerated gesture. |
| 853 // Likewise if we don't allow any tiles (as is the case when we're |
| 854 // invisible), if we have tiles that aren't ready, then we shouldn't |
| 855 // activate as activation can cause checkerboards. |
| 856 bool allow_rasterize_on_demand = |
| 857 global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY && |
| 858 global_state_.memory_limit_policy != ALLOW_NOTHING; |
| 859 |
| 860 // Use on-demand raster for any required-for-activation tiles that have |
| 861 // not been been assigned memory after reaching a steady memory state. This |
| 862 // ensures that we activate even when OOM. Note that we have to rebuilt the |
| 863 // queue in case the last AssignGpuMemoryToTiles evicted some tiles that |
| 864 // would otherwise not be picked up by the old raster queue. |
| 865 client_->BuildRasterQueue(&raster_priority_queue_, |
| 866 global_state_.tree_priority); |
| 867 bool ready_to_activate = true; |
| 868 while (!raster_priority_queue_.IsEmpty()) { |
| 869 Tile* tile = raster_priority_queue_.Top(); |
| 870 TileDrawInfo& draw_info = tile->draw_info(); |
| 871 |
| 872 if (tile->required_for_activation() && !draw_info.IsReadyToDraw()) { |
| 873 // If we can't raster on demand, give up early (and don't activate). |
| 874 if (!allow_rasterize_on_demand) { |
| 875 ready_to_activate = false; |
| 876 break; |
| 877 } |
| 878 |
| 879 draw_info.set_rasterize_on_demand(); |
| 880 client_->NotifyTileStateChanged(tile); |
| 881 } |
| 882 raster_priority_queue_.Pop(); |
| 883 } |
| 884 |
| 885 if (ready_to_activate) { |
| 886 DCHECK(IsReadyToActivate()); |
| 887 ready_to_activate_check_notifier_.Schedule(); |
| 888 } |
| 889 raster_priority_queue_.Reset(); |
| 890 } |
| 891 |
| 886 TileManager::MemoryUsage::MemoryUsage() : memory_bytes_(0), resource_count_(0) { | 892 TileManager::MemoryUsage::MemoryUsage() : memory_bytes_(0), resource_count_(0) { |
| 887 } | 893 } |
| 888 | 894 |
| 889 TileManager::MemoryUsage::MemoryUsage(int64 memory_bytes, int resource_count) | 895 TileManager::MemoryUsage::MemoryUsage(int64 memory_bytes, int resource_count) |
| 890 : memory_bytes_(memory_bytes), resource_count_(resource_count) { | 896 : memory_bytes_(memory_bytes), resource_count_(resource_count) { |
| 891 } | 897 } |
| 892 | 898 |
| 893 // static | 899 // static |
| 894 TileManager::MemoryUsage TileManager::MemoryUsage::FromConfig( | 900 TileManager::MemoryUsage TileManager::MemoryUsage::FromConfig( |
| 895 const gfx::Size& size, | 901 const gfx::Size& size, |
| (...skipping 30 matching lines...) Expand all Loading... |
| 926 result -= other; | 932 result -= other; |
| 927 return result; | 933 return result; |
| 928 } | 934 } |
| 929 | 935 |
| 930 bool TileManager::MemoryUsage::Exceeds(const MemoryUsage& limit) const { | 936 bool TileManager::MemoryUsage::Exceeds(const MemoryUsage& limit) const { |
| 931 return memory_bytes_ > limit.memory_bytes_ || | 937 return memory_bytes_ > limit.memory_bytes_ || |
| 932 resource_count_ > limit.resource_count_; | 938 resource_count_ > limit.resource_count_; |
| 933 } | 939 } |
| 934 | 940 |
| 935 } // namespace cc | 941 } // namespace cc |
| OLD | NEW |