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 |