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. |
| 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 |