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