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