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