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 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
414 DCHECK(TilePriority() == tile->combined_priority()); | 414 DCHECK(TilePriority() == tile->combined_priority()); |
415 | 415 |
416 prioritized_tiles_dirty_ = true; | 416 prioritized_tiles_dirty_ = true; |
417 released_tiles_.push_back(tile); | 417 released_tiles_.push_back(tile); |
418 } | 418 } |
419 | 419 |
420 void TileManager::DidChangeTilePriority(Tile* tile) { | 420 void TileManager::DidChangeTilePriority(Tile* tile) { |
421 prioritized_tiles_dirty_ = true; | 421 prioritized_tiles_dirty_ = true; |
422 } | 422 } |
423 | 423 |
424 bool TileManager::ShouldForceTasksRequiredForActivationToComplete() const { | 424 TaskSetCollection TileManager::TasksThatShouldBeForcedToComplete() const { |
425 return global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY; | 425 TaskSetCollection tasks_that_should_be_forced_to_complete; |
| 426 if (global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY) |
| 427 tasks_that_should_be_forced_to_complete[REQUIRED_FOR_ACTIVATION] = true; |
| 428 return tasks_that_should_be_forced_to_complete; |
426 } | 429 } |
427 | 430 |
428 void TileManager::FreeResourcesForReleasedTiles() { | 431 void TileManager::FreeResourcesForReleasedTiles() { |
429 for (std::vector<Tile*>::iterator it = released_tiles_.begin(); | 432 for (std::vector<Tile*>::iterator it = released_tiles_.begin(); |
430 it != released_tiles_.end(); | 433 it != released_tiles_.end(); |
431 ++it) { | 434 ++it) { |
432 Tile* tile = *it; | 435 Tile* tile = *it; |
433 FreeResourcesForTile(tile); | 436 FreeResourcesForTile(tile); |
434 } | 437 } |
435 } | 438 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
471 | 474 |
472 prioritized_tiles_.Clear(); | 475 prioritized_tiles_.Clear(); |
473 | 476 |
474 FreeResourcesForReleasedTiles(); | 477 FreeResourcesForReleasedTiles(); |
475 CleanUpReleasedTiles(); | 478 CleanUpReleasedTiles(); |
476 | 479 |
477 GetTilesWithAssignedBins(&prioritized_tiles_); | 480 GetTilesWithAssignedBins(&prioritized_tiles_); |
478 prioritized_tiles_dirty_ = false; | 481 prioritized_tiles_dirty_ = false; |
479 } | 482 } |
480 | 483 |
481 void TileManager::DidFinishRunningTasks() { | 484 void TileManager::DidFinishRunningTasks(TaskSet task_set) { |
482 TRACE_EVENT0("cc", "TileManager::DidFinishRunningTasks"); | 485 TRACE_EVENT1( |
| 486 "cc", "TileManager::DidFinishRunningTasks", "task_set", task_set); |
483 | 487 |
484 bool memory_usage_above_limit = resource_pool_->total_memory_usage_bytes() > | 488 if (task_set == ALL) { |
485 global_state_.soft_memory_limit_in_bytes; | 489 bool memory_usage_above_limit = resource_pool_->total_memory_usage_bytes() > |
| 490 global_state_.soft_memory_limit_in_bytes; |
486 | 491 |
487 // When OOM, keep re-assigning memory until we reach a steady state | 492 // When OOM, keep re-assigning memory until we reach a steady state |
488 // where top-priority tiles are initialized. | 493 // where top-priority tiles are initialized. |
489 if (all_tiles_that_need_to_be_rasterized_have_memory_ && | 494 if (all_tiles_that_need_to_be_rasterized_have_memory_ && |
490 !memory_usage_above_limit) | 495 !memory_usage_above_limit) |
491 return; | 496 return; |
492 | 497 |
493 rasterizer_->CheckForCompletedTasks(); | 498 rasterizer_->CheckForCompletedTasks(); |
494 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; | 499 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; |
495 | 500 |
496 TileVector tiles_that_need_to_be_rasterized; | 501 TileVector tiles_that_need_to_be_rasterized; |
497 AssignGpuMemoryToTiles(&prioritized_tiles_, | 502 AssignGpuMemoryToTiles(&prioritized_tiles_, |
498 &tiles_that_need_to_be_rasterized); | 503 &tiles_that_need_to_be_rasterized); |
499 | 504 |
500 // |tiles_that_need_to_be_rasterized| will be empty when we reach a | 505 // |tiles_that_need_to_be_rasterized| will be empty when we reach a |
501 // steady memory state. Keep scheduling tasks until we reach this state. | 506 // steady memory state. Keep scheduling tasks until we reach this state. |
502 if (!tiles_that_need_to_be_rasterized.empty()) { | 507 if (!tiles_that_need_to_be_rasterized.empty()) { |
503 ScheduleTasks(tiles_that_need_to_be_rasterized); | 508 ScheduleTasks(tiles_that_need_to_be_rasterized); |
| 509 return; |
| 510 } |
| 511 |
| 512 FreeResourcesForReleasedTiles(); |
| 513 |
| 514 resource_pool_->ReduceResourceUsage(); |
| 515 |
| 516 // We don't reserve memory for required-for-activation tiles during |
| 517 // accelerated gestures, so we just postpone activation when we don't |
| 518 // have these tiles, and activate after the accelerated gesture. |
| 519 bool allow_rasterize_on_demand = |
| 520 global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY; |
| 521 |
| 522 // Use on-demand raster for any required-for-activation tiles that have not |
| 523 // been been assigned memory after reaching a steady memory state. This |
| 524 // ensures that we activate even when OOM. |
| 525 for (TileMap::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
| 526 Tile* tile = it->second; |
| 527 ManagedTileState& mts = tile->managed_state(); |
| 528 ManagedTileState::TileVersion& tile_version = |
| 529 mts.tile_versions[mts.raster_mode]; |
| 530 |
| 531 if (tile->required_for_activation() && !tile_version.IsReadyToDraw()) { |
| 532 // If we can't raster on demand, give up early (and don't activate). |
| 533 if (!allow_rasterize_on_demand) |
| 534 return; |
| 535 |
| 536 tile_version.set_rasterize_on_demand(); |
| 537 client_->NotifyTileStateChanged(tile); |
| 538 } |
| 539 } |
| 540 |
| 541 DCHECK(IsReadyToActivate()); |
| 542 ready_to_activate_check_notifier_.Schedule(); |
504 return; | 543 return; |
505 } | 544 } |
506 | 545 |
507 FreeResourcesForReleasedTiles(); | 546 if (task_set == REQUIRED_FOR_ACTIVATION) { |
| 547 // This is only a true indication that all tiles required for |
| 548 // activation are initialized when no tiles are OOM. We need to |
| 549 // wait for DidFinishRunningTasks() to be called, try to re-assign |
| 550 // memory and in worst case use on-demand raster when tiles |
| 551 // required for activation are OOM. |
| 552 if (!all_tiles_required_for_activation_have_memory_) |
| 553 return; |
508 | 554 |
509 resource_pool_->ReduceResourceUsage(); | 555 ready_to_activate_check_notifier_.Schedule(); |
510 | |
511 // We don't reserve memory for required-for-activation tiles during | |
512 // accelerated gestures, so we just postpone activation when we don't | |
513 // have these tiles, and activate after the accelerated gesture. | |
514 bool allow_rasterize_on_demand = | |
515 global_state_.tree_priority != SMOOTHNESS_TAKES_PRIORITY; | |
516 | |
517 // Use on-demand raster for any required-for-activation tiles that have not | |
518 // been been assigned memory after reaching a steady memory state. This | |
519 // ensures that we activate even when OOM. | |
520 for (TileMap::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | |
521 Tile* tile = it->second; | |
522 ManagedTileState& mts = tile->managed_state(); | |
523 ManagedTileState::TileVersion& tile_version = | |
524 mts.tile_versions[mts.raster_mode]; | |
525 | |
526 if (tile->required_for_activation() && !tile_version.IsReadyToDraw()) { | |
527 // If we can't raster on demand, give up early (and don't activate). | |
528 if (!allow_rasterize_on_demand) | |
529 return; | |
530 | |
531 tile_version.set_rasterize_on_demand(); | |
532 client_->NotifyTileStateChanged(tile); | |
533 } | |
534 } | 556 } |
535 | |
536 DCHECK(IsReadyToActivate()); | |
537 ready_to_activate_check_notifier_.Schedule(); | |
538 } | |
539 | |
540 void TileManager::DidFinishRunningTasksRequiredForActivation() { | |
541 // This is only a true indication that all tiles required for | |
542 // activation are initialized when no tiles are OOM. We need to | |
543 // wait for DidFinishRunningTasks() to be called, try to re-assign | |
544 // memory and in worst case use on-demand raster when tiles | |
545 // required for activation are OOM. | |
546 if (!all_tiles_required_for_activation_have_memory_) | |
547 return; | |
548 | |
549 ready_to_activate_check_notifier_.Schedule(); | |
550 } | 557 } |
551 | 558 |
552 void TileManager::GetTilesWithAssignedBins(PrioritizedTileSet* tiles) { | 559 void TileManager::GetTilesWithAssignedBins(PrioritizedTileSet* tiles) { |
553 TRACE_EVENT0("cc", "TileManager::GetTilesWithAssignedBins"); | 560 TRACE_EVENT0("cc", "TileManager::GetTilesWithAssignedBins"); |
554 | 561 |
555 const TileMemoryLimitPolicy memory_policy = global_state_.memory_limit_policy; | 562 const TileMemoryLimitPolicy memory_policy = global_state_.memory_limit_policy; |
556 const TreePriority tree_priority = global_state_.tree_priority; | 563 const TreePriority tree_priority = global_state_.tree_priority; |
557 | 564 |
558 // For each tree, bin into different categories of tiles. | 565 // For each tree, bin into different categories of tiles. |
559 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 566 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
969 ManagedTileState& mts = tile->managed_state(); | 976 ManagedTileState& mts = tile->managed_state(); |
970 ManagedTileState::TileVersion& tile_version = | 977 ManagedTileState::TileVersion& tile_version = |
971 mts.tile_versions[mts.raster_mode]; | 978 mts.tile_versions[mts.raster_mode]; |
972 | 979 |
973 DCHECK(tile_version.requires_resource()); | 980 DCHECK(tile_version.requires_resource()); |
974 DCHECK(!tile_version.resource_); | 981 DCHECK(!tile_version.resource_); |
975 | 982 |
976 if (!tile_version.raster_task_.get()) | 983 if (!tile_version.raster_task_.get()) |
977 tile_version.raster_task_ = CreateRasterTask(tile); | 984 tile_version.raster_task_ = CreateRasterTask(tile); |
978 | 985 |
979 raster_queue_.items.push_back(RasterTaskQueue::Item( | 986 TaskSetCollection task_sets; |
980 tile_version.raster_task_.get(), tile->required_for_activation())); | 987 if (tile->required_for_activation()) |
| 988 task_sets.set(REQUIRED_FOR_ACTIVATION); |
| 989 task_sets.set(ALL); |
| 990 raster_queue_.items.push_back( |
| 991 RasterTaskQueue::Item(tile_version.raster_task_.get(), task_sets)); |
981 } | 992 } |
982 | 993 |
983 // We must reduce the amount of unused resoruces before calling | 994 // We must reduce the amount of unused resoruces before calling |
984 // ScheduleTasks to prevent usage from rising above limits. | 995 // ScheduleTasks to prevent usage from rising above limits. |
985 resource_pool_->ReduceResourceUsage(); | 996 resource_pool_->ReduceResourceUsage(); |
986 | 997 |
987 // Schedule running of |raster_tasks_|. This replaces any previously | 998 // Schedule running of |raster_tasks_|. This replaces any previously |
988 // scheduled tasks and effectively cancels all tasks not present | 999 // scheduled tasks and effectively cancels all tasks not present |
989 // in |raster_tasks_|. | 1000 // in |raster_tasks_|. |
990 rasterizer_->ScheduleTasks(&raster_queue_); | 1001 rasterizer_->ScheduleTasks(&raster_queue_); |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1169 TRACE_EVENT0("cc", "TileManager::CheckIfReadyToActivate"); | 1180 TRACE_EVENT0("cc", "TileManager::CheckIfReadyToActivate"); |
1170 | 1181 |
1171 rasterizer_->CheckForCompletedTasks(); | 1182 rasterizer_->CheckForCompletedTasks(); |
1172 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; | 1183 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; |
1173 | 1184 |
1174 if (IsReadyToActivate()) | 1185 if (IsReadyToActivate()) |
1175 client_->NotifyReadyToActivate(); | 1186 client_->NotifyReadyToActivate(); |
1176 } | 1187 } |
1177 | 1188 |
1178 } // namespace cc | 1189 } // namespace cc |
OLD | NEW |