| 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/tiles/tile_manager.h" | 5 #include "cc/tiles/tile_manager.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 RasterTaskCompletionStatsAsValue(const RasterTaskCompletionStats& stats) { | 297 RasterTaskCompletionStatsAsValue(const RasterTaskCompletionStats& stats) { |
| 298 std::unique_ptr<base::trace_event::TracedValue> state( | 298 std::unique_ptr<base::trace_event::TracedValue> state( |
| 299 new base::trace_event::TracedValue()); | 299 new base::trace_event::TracedValue()); |
| 300 state->SetInteger("completed_count", | 300 state->SetInteger("completed_count", |
| 301 base::saturated_cast<int>(stats.completed_count)); | 301 base::saturated_cast<int>(stats.completed_count)); |
| 302 state->SetInteger("canceled_count", | 302 state->SetInteger("canceled_count", |
| 303 base::saturated_cast<int>(stats.canceled_count)); | 303 base::saturated_cast<int>(stats.canceled_count)); |
| 304 return std::move(state); | 304 return std::move(state); |
| 305 } | 305 } |
| 306 | 306 |
| 307 // static | |
| 308 std::unique_ptr<TileManager> TileManager::Create( | |
| 309 TileManagerClient* client, | |
| 310 base::SequencedTaskRunner* task_runner, | |
| 311 size_t scheduled_raster_task_limit, | |
| 312 bool use_partial_raster) { | |
| 313 // TODO(vmpstr): |task_runner| is a raw pointer that is implicitly converted | |
| 314 // into a scoped_refptr. Figure out whether to plumb a ref pointer or whether | |
| 315 // tile manager can have a non-owning pointer and fix. | |
| 316 return base::WrapUnique(new TileManager( | |
| 317 client, task_runner, scheduled_raster_task_limit, use_partial_raster)); | |
| 318 } | |
| 319 | |
| 320 TileManager::TileManager(TileManagerClient* client, | 307 TileManager::TileManager(TileManagerClient* client, |
| 321 scoped_refptr<base::SequencedTaskRunner> task_runner, | 308 scoped_refptr<base::SequencedTaskRunner> task_runner, |
| 322 size_t scheduled_raster_task_limit, | 309 size_t scheduled_raster_task_limit, |
| 323 bool use_partial_raster) | 310 bool use_partial_raster) |
| 324 : client_(client), | 311 : client_(client), |
| 325 task_runner_(std::move(task_runner)), | 312 task_runner_(std::move(task_runner)), |
| 326 resource_pool_(nullptr), | 313 resource_pool_(nullptr), |
| 327 tile_task_manager_(nullptr), | 314 tile_task_manager_(nullptr), |
| 328 scheduled_raster_task_limit_(scheduled_raster_task_limit), | 315 scheduled_raster_task_limit_(scheduled_raster_task_limit), |
| 329 use_partial_raster_(use_partial_raster), | 316 use_partial_raster_(use_partial_raster), |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 474 // We need to call CheckForCompletedTasks() once in-between each call | 461 // We need to call CheckForCompletedTasks() once in-between each call |
| 475 // to ScheduleTasks() to prevent canceled tasks from being scheduled. | 462 // to ScheduleTasks() to prevent canceled tasks from being scheduled. |
| 476 if (!did_check_for_completed_tasks_since_last_schedule_tasks_) { | 463 if (!did_check_for_completed_tasks_since_last_schedule_tasks_) { |
| 477 tile_task_manager_->CheckForCompletedTasks(); | 464 tile_task_manager_->CheckForCompletedTasks(); |
| 478 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; | 465 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; |
| 479 } | 466 } |
| 480 | 467 |
| 481 FreeResourcesForReleasedTiles(); | 468 FreeResourcesForReleasedTiles(); |
| 482 CleanUpReleasedTiles(); | 469 CleanUpReleasedTiles(); |
| 483 | 470 |
| 484 PrioritizedTileVector tiles_that_need_to_be_rasterized; | 471 std::vector<PrioritizedTile> tiles_that_need_to_be_rasterized = |
| 485 std::unique_ptr<RasterTilePriorityQueue> raster_priority_queue( | 472 AssignGpuMemoryToTiles(); |
| 486 client_->BuildRasterQueue(global_state_.tree_priority, | |
| 487 RasterTilePriorityQueue::Type::ALL)); | |
| 488 AssignGpuMemoryToTiles(raster_priority_queue.get(), | |
| 489 scheduled_raster_task_limit_, | |
| 490 &tiles_that_need_to_be_rasterized); | |
| 491 | 473 |
| 492 // Inform the client that will likely require a draw if the highest priority | 474 // Inform the client that will likely require a draw if the highest priority |
| 493 // tile that will be rasterized is required for draw. | 475 // tile that will be rasterized is required for draw. |
| 494 client_->SetIsLikelyToRequireADraw( | 476 client_->SetIsLikelyToRequireADraw( |
| 495 !tiles_that_need_to_be_rasterized.empty() && | 477 !tiles_that_need_to_be_rasterized.empty() && |
| 496 tiles_that_need_to_be_rasterized.front().tile()->required_for_draw()); | 478 tiles_that_need_to_be_rasterized.front().tile()->required_for_draw()); |
| 497 | 479 |
| 498 // Schedule tile tasks. | 480 // Schedule tile tasks. |
| 499 ScheduleTasks(tiles_that_need_to_be_rasterized); | 481 ScheduleTasks(tiles_that_need_to_be_rasterized); |
| 500 | 482 |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 593 case ALLOW_PREPAINT_ONLY: | 575 case ALLOW_PREPAINT_ONLY: |
| 594 return priority.priority_bin > TilePriority::SOON; | 576 return priority.priority_bin > TilePriority::SOON; |
| 595 case ALLOW_ANYTHING: | 577 case ALLOW_ANYTHING: |
| 596 return priority.distance_to_visible == | 578 return priority.distance_to_visible == |
| 597 std::numeric_limits<float>::infinity(); | 579 std::numeric_limits<float>::infinity(); |
| 598 } | 580 } |
| 599 NOTREACHED(); | 581 NOTREACHED(); |
| 600 return true; | 582 return true; |
| 601 } | 583 } |
| 602 | 584 |
| 603 void TileManager::AssignGpuMemoryToTiles( | 585 std::vector<PrioritizedTile> TileManager::AssignGpuMemoryToTiles() { |
| 604 RasterTilePriorityQueue* raster_priority_queue, | |
| 605 size_t scheduled_raster_task_limit, | |
| 606 PrioritizedTileVector* tiles_that_need_to_be_rasterized) { | |
| 607 TRACE_EVENT_BEGIN0("cc", "TileManager::AssignGpuMemoryToTiles"); | 586 TRACE_EVENT_BEGIN0("cc", "TileManager::AssignGpuMemoryToTiles"); |
| 608 | 587 |
| 609 DCHECK(resource_pool_); | 588 DCHECK(resource_pool_); |
| 610 DCHECK(tile_task_manager_); | 589 DCHECK(tile_task_manager_); |
| 611 | 590 |
| 612 // Maintain the list of released resources that can potentially be re-used | 591 // Maintain the list of released resources that can potentially be re-used |
| 613 // or deleted. If this operation becomes expensive too, only do this after | 592 // or deleted. If this operation becomes expensive too, only do this after |
| 614 // some resource(s) was returned. Note that in that case, one also need to | 593 // some resource(s) was returned. Note that in that case, one also need to |
| 615 // invalidate when releasing some resource from the pool. | 594 // invalidate when releasing some resource from the pool. |
| 616 resource_pool_->CheckBusyResources(); | 595 resource_pool_->CheckBusyResources(); |
| 617 | 596 |
| 618 // Now give memory out to the tiles until we're out, and build | 597 // Now give memory out to the tiles until we're out, and build |
| 619 // the needs-to-be-rasterized queue. | 598 // the needs-to-be-rasterized queue. |
| 620 unsigned schedule_priority = 1u; | 599 unsigned schedule_priority = 1u; |
| 621 all_tiles_that_need_to_be_rasterized_are_scheduled_ = true; | 600 all_tiles_that_need_to_be_rasterized_are_scheduled_ = true; |
| 622 bool had_enough_memory_to_schedule_tiles_needed_now = true; | 601 bool had_enough_memory_to_schedule_tiles_needed_now = true; |
| 623 | 602 |
| 624 MemoryUsage hard_memory_limit(global_state_.hard_memory_limit_in_bytes, | 603 MemoryUsage hard_memory_limit(global_state_.hard_memory_limit_in_bytes, |
| 625 global_state_.num_resources_limit); | 604 global_state_.num_resources_limit); |
| 626 MemoryUsage soft_memory_limit(global_state_.soft_memory_limit_in_bytes, | 605 MemoryUsage soft_memory_limit(global_state_.soft_memory_limit_in_bytes, |
| 627 global_state_.num_resources_limit); | 606 global_state_.num_resources_limit); |
| 628 MemoryUsage memory_usage(resource_pool_->memory_usage_bytes(), | 607 MemoryUsage memory_usage(resource_pool_->memory_usage_bytes(), |
| 629 resource_pool_->resource_count()); | 608 resource_pool_->resource_count()); |
| 630 | 609 |
| 610 std::unique_ptr<RasterTilePriorityQueue> raster_priority_queue( |
| 611 client_->BuildRasterQueue(global_state_.tree_priority, |
| 612 RasterTilePriorityQueue::Type::ALL)); |
| 631 std::unique_ptr<EvictionTilePriorityQueue> eviction_priority_queue; | 613 std::unique_ptr<EvictionTilePriorityQueue> eviction_priority_queue; |
| 614 std::vector<PrioritizedTile> tiles_that_need_to_be_rasterized; |
| 632 for (; !raster_priority_queue->IsEmpty(); raster_priority_queue->Pop()) { | 615 for (; !raster_priority_queue->IsEmpty(); raster_priority_queue->Pop()) { |
| 633 const PrioritizedTile& prioritized_tile = raster_priority_queue->Top(); | 616 const PrioritizedTile& prioritized_tile = raster_priority_queue->Top(); |
| 634 Tile* tile = prioritized_tile.tile(); | 617 Tile* tile = prioritized_tile.tile(); |
| 635 TilePriority priority = prioritized_tile.priority(); | 618 TilePriority priority = prioritized_tile.priority(); |
| 636 | 619 |
| 637 if (TilePriorityViolatesMemoryPolicy(priority)) { | 620 if (TilePriorityViolatesMemoryPolicy(priority)) { |
| 638 TRACE_EVENT_INSTANT0( | 621 TRACE_EVENT_INSTANT0( |
| 639 "cc", "TileManager::AssignGpuMemory tile violates memory policy", | 622 "cc", "TileManager::AssignGpuMemory tile violates memory policy", |
| 640 TRACE_EVENT_SCOPE_THREAD); | 623 TRACE_EVENT_SCOPE_THREAD); |
| 641 break; | 624 break; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 655 tile->draw_info().set_solid_color(color); | 638 tile->draw_info().set_solid_color(color); |
| 656 tile->draw_info().set_was_ever_ready_to_draw(); | 639 tile->draw_info().set_was_ever_ready_to_draw(); |
| 657 if (!tile_is_needed_now) | 640 if (!tile_is_needed_now) |
| 658 tile->draw_info().set_was_a_prepaint_tile(); | 641 tile->draw_info().set_was_a_prepaint_tile(); |
| 659 client_->NotifyTileStateChanged(tile); | 642 client_->NotifyTileStateChanged(tile); |
| 660 continue; | 643 continue; |
| 661 } | 644 } |
| 662 } | 645 } |
| 663 | 646 |
| 664 // We won't be able to schedule this tile, so break out early. | 647 // We won't be able to schedule this tile, so break out early. |
| 665 if (tiles_that_need_to_be_rasterized->size() >= | 648 if (tiles_that_need_to_be_rasterized.size() >= |
| 666 scheduled_raster_task_limit) { | 649 scheduled_raster_task_limit_) { |
| 667 all_tiles_that_need_to_be_rasterized_are_scheduled_ = false; | 650 all_tiles_that_need_to_be_rasterized_are_scheduled_ = false; |
| 668 break; | 651 break; |
| 669 } | 652 } |
| 670 | 653 |
| 671 tile->scheduled_priority_ = schedule_priority++; | 654 tile->scheduled_priority_ = schedule_priority++; |
| 672 | 655 |
| 673 DCHECK(tile->draw_info().mode() == TileDrawInfo::OOM_MODE || | 656 DCHECK(tile->draw_info().mode() == TileDrawInfo::OOM_MODE || |
| 674 !tile->draw_info().IsReadyToDraw()); | 657 !tile->draw_info().IsReadyToDraw()); |
| 675 | 658 |
| 676 // If the tile already has a raster_task, then the memory used by it is | 659 // If the tile already has a raster_task, then the memory used by it is |
| (...skipping 23 matching lines...) Expand all Loading... |
| 700 // If we couldn't fit the tile into our current memory limit, then we're | 683 // If we couldn't fit the tile into our current memory limit, then we're |
| 701 // done. | 684 // done. |
| 702 if (!memory_usage_is_within_limit) { | 685 if (!memory_usage_is_within_limit) { |
| 703 if (tile_is_needed_now) | 686 if (tile_is_needed_now) |
| 704 had_enough_memory_to_schedule_tiles_needed_now = false; | 687 had_enough_memory_to_schedule_tiles_needed_now = false; |
| 705 all_tiles_that_need_to_be_rasterized_are_scheduled_ = false; | 688 all_tiles_that_need_to_be_rasterized_are_scheduled_ = false; |
| 706 break; | 689 break; |
| 707 } | 690 } |
| 708 | 691 |
| 709 memory_usage += memory_required_by_tile_to_be_scheduled; | 692 memory_usage += memory_required_by_tile_to_be_scheduled; |
| 710 tiles_that_need_to_be_rasterized->push_back(prioritized_tile); | 693 tiles_that_need_to_be_rasterized.push_back(prioritized_tile); |
| 711 | 694 |
| 712 // Since we scheduled the tile, set whether it was a prepaint or not | 695 // Since we scheduled the tile, set whether it was a prepaint or not |
| 713 // assuming that the tile will successfully finish running. We don't have | 696 // assuming that the tile will successfully finish running. We don't have |
| 714 // priority information at the time the tile completes, so it should be done | 697 // priority information at the time the tile completes, so it should be done |
| 715 // here. | 698 // here. |
| 716 if (!tile_is_needed_now) | 699 if (!tile_is_needed_now) |
| 717 tile->draw_info().set_was_a_prepaint_tile(); | 700 tile->draw_info().set_was_a_prepaint_tile(); |
| 718 } | 701 } |
| 719 | 702 |
| 720 // Note that we should try and further reduce memory in case the above loop | 703 // Note that we should try and further reduce memory in case the above loop |
| (...skipping 11 matching lines...) Expand all Loading... |
| 732 memory_stats_from_last_assign_.total_bytes_used = memory_usage.memory_bytes(); | 715 memory_stats_from_last_assign_.total_bytes_used = memory_usage.memory_bytes(); |
| 733 DCHECK_GE(memory_stats_from_last_assign_.total_bytes_used, 0); | 716 DCHECK_GE(memory_stats_from_last_assign_.total_bytes_used, 0); |
| 734 memory_stats_from_last_assign_.had_enough_memory = | 717 memory_stats_from_last_assign_.had_enough_memory = |
| 735 had_enough_memory_to_schedule_tiles_needed_now; | 718 had_enough_memory_to_schedule_tiles_needed_now; |
| 736 | 719 |
| 737 TRACE_EVENT_END2("cc", "TileManager::AssignGpuMemoryToTiles", | 720 TRACE_EVENT_END2("cc", "TileManager::AssignGpuMemoryToTiles", |
| 738 "all_tiles_that_need_to_be_rasterized_are_scheduled", | 721 "all_tiles_that_need_to_be_rasterized_are_scheduled", |
| 739 all_tiles_that_need_to_be_rasterized_are_scheduled_, | 722 all_tiles_that_need_to_be_rasterized_are_scheduled_, |
| 740 "had_enough_memory_to_schedule_tiles_needed_now", | 723 "had_enough_memory_to_schedule_tiles_needed_now", |
| 741 had_enough_memory_to_schedule_tiles_needed_now); | 724 had_enough_memory_to_schedule_tiles_needed_now); |
| 725 return tiles_that_need_to_be_rasterized; |
| 742 } | 726 } |
| 743 | 727 |
| 744 void TileManager::FreeResourcesForTile(Tile* tile) { | 728 void TileManager::FreeResourcesForTile(Tile* tile) { |
| 745 TileDrawInfo& draw_info = tile->draw_info(); | 729 TileDrawInfo& draw_info = tile->draw_info(); |
| 746 if (draw_info.resource_) { | 730 if (draw_info.resource_) { |
| 747 resource_pool_->ReleaseResource(draw_info.resource_, tile->id()); | 731 resource_pool_->ReleaseResource(draw_info.resource_, tile->id()); |
| 748 draw_info.resource_ = nullptr; | 732 draw_info.resource_ = nullptr; |
| 749 } | 733 } |
| 750 } | 734 } |
| 751 | 735 |
| 752 void TileManager::FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw( | 736 void TileManager::FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw( |
| 753 Tile* tile) { | 737 Tile* tile) { |
| 754 bool was_ready_to_draw = tile->draw_info().IsReadyToDraw(); | 738 bool was_ready_to_draw = tile->draw_info().IsReadyToDraw(); |
| 755 FreeResourcesForTile(tile); | 739 FreeResourcesForTile(tile); |
| 756 if (was_ready_to_draw) | 740 if (was_ready_to_draw) |
| 757 client_->NotifyTileStateChanged(tile); | 741 client_->NotifyTileStateChanged(tile); |
| 758 } | 742 } |
| 759 | 743 |
| 760 void TileManager::ScheduleTasks( | 744 void TileManager::ScheduleTasks( |
| 761 const PrioritizedTileVector& tiles_that_need_to_be_rasterized) { | 745 const std::vector<PrioritizedTile>& tiles_that_need_to_be_rasterized) { |
| 762 TRACE_EVENT1("cc", "TileManager::ScheduleTasks", "count", | 746 TRACE_EVENT1("cc", "TileManager::ScheduleTasks", "count", |
| 763 tiles_that_need_to_be_rasterized.size()); | 747 tiles_that_need_to_be_rasterized.size()); |
| 764 | 748 |
| 765 DCHECK(did_check_for_completed_tasks_since_last_schedule_tasks_); | 749 DCHECK(did_check_for_completed_tasks_since_last_schedule_tasks_); |
| 766 | 750 |
| 767 if (!has_scheduled_tile_tasks_) { | 751 if (!has_scheduled_tile_tasks_) { |
| 768 TRACE_EVENT_ASYNC_BEGIN0("cc", "ScheduledTasks", this); | 752 TRACE_EVENT_ASYNC_BEGIN0("cc", "ScheduledTasks", this); |
| 769 } | 753 } |
| 770 | 754 |
| 771 // Cancel existing OnTaskSetFinished callbacks. | 755 // Cancel existing OnTaskSetFinished callbacks. |
| (...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1078 } | 1062 } |
| 1079 } | 1063 } |
| 1080 } | 1064 } |
| 1081 | 1065 |
| 1082 void TileManager::CheckIfMoreTilesNeedToBePrepared() { | 1066 void TileManager::CheckIfMoreTilesNeedToBePrepared() { |
| 1083 tile_task_manager_->CheckForCompletedTasks(); | 1067 tile_task_manager_->CheckForCompletedTasks(); |
| 1084 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; | 1068 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; |
| 1085 | 1069 |
| 1086 // When OOM, keep re-assigning memory until we reach a steady state | 1070 // When OOM, keep re-assigning memory until we reach a steady state |
| 1087 // where top-priority tiles are initialized. | 1071 // where top-priority tiles are initialized. |
| 1088 PrioritizedTileVector tiles_that_need_to_be_rasterized; | 1072 std::vector<PrioritizedTile> tiles_that_need_to_be_rasterized = |
| 1089 std::unique_ptr<RasterTilePriorityQueue> raster_priority_queue( | 1073 AssignGpuMemoryToTiles(); |
| 1090 client_->BuildRasterQueue(global_state_.tree_priority, | |
| 1091 RasterTilePriorityQueue::Type::ALL)); | |
| 1092 AssignGpuMemoryToTiles(raster_priority_queue.get(), | |
| 1093 scheduled_raster_task_limit_, | |
| 1094 &tiles_that_need_to_be_rasterized); | |
| 1095 | 1074 |
| 1096 // Inform the client that will likely require a draw if the highest priority | 1075 // Inform the client that will likely require a draw if the highest priority |
| 1097 // tile that will be rasterized is required for draw. | 1076 // tile that will be rasterized is required for draw. |
| 1098 client_->SetIsLikelyToRequireADraw( | 1077 client_->SetIsLikelyToRequireADraw( |
| 1099 !tiles_that_need_to_be_rasterized.empty() && | 1078 !tiles_that_need_to_be_rasterized.empty() && |
| 1100 tiles_that_need_to_be_rasterized.front().tile()->required_for_draw()); | 1079 tiles_that_need_to_be_rasterized.front().tile()->required_for_draw()); |
| 1101 | 1080 |
| 1102 // |tiles_that_need_to_be_rasterized| will be empty when we reach a | 1081 // |tiles_that_need_to_be_rasterized| will be empty when we reach a |
| 1103 // steady memory state. Keep scheduling tasks until we reach this state. | 1082 // steady memory state. Keep scheduling tasks until we reach this state. |
| 1104 if (!tiles_that_need_to_be_rasterized.empty()) { | 1083 if (!tiles_that_need_to_be_rasterized.empty()) { |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1268 void TileManager::Signals::reset() { | 1247 void TileManager::Signals::reset() { |
| 1269 ready_to_activate = false; | 1248 ready_to_activate = false; |
| 1270 did_notify_ready_to_activate = false; | 1249 did_notify_ready_to_activate = false; |
| 1271 ready_to_draw = false; | 1250 ready_to_draw = false; |
| 1272 did_notify_ready_to_draw = false; | 1251 did_notify_ready_to_draw = false; |
| 1273 all_tile_tasks_completed = false; | 1252 all_tile_tasks_completed = false; |
| 1274 did_notify_all_tile_tasks_completed = false; | 1253 did_notify_all_tile_tasks_completed = false; |
| 1275 } | 1254 } |
| 1276 | 1255 |
| 1277 } // namespace cc | 1256 } // namespace cc |
| OLD | NEW |