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 |