| 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 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 470 eviction_priority_queue_is_up_to_date_); | 470 eviction_priority_queue_is_up_to_date_); |
| 471 if (eviction_priority_queue_is_up_to_date_) | 471 if (eviction_priority_queue_is_up_to_date_) |
| 472 return; | 472 return; |
| 473 | 473 |
| 474 eviction_priority_queue_.Reset(); | 474 eviction_priority_queue_.Reset(); |
| 475 client_->BuildEvictionQueue(&eviction_priority_queue_, | 475 client_->BuildEvictionQueue(&eviction_priority_queue_, |
| 476 global_state_.tree_priority); | 476 global_state_.tree_priority); |
| 477 eviction_priority_queue_is_up_to_date_ = true; | 477 eviction_priority_queue_is_up_to_date_ = true; |
| 478 } | 478 } |
| 479 | 479 |
| 480 bool TileManager::FreeTileResourcesUntilUsageIsWithinLimit( | 480 bool TileManager::FreeTileResourcesUntilUsageIsWithinLimit(int64 limit, |
| 481 const MemoryUsage& limit, | 481 int64* usage) { |
| 482 MemoryUsage* usage) { | 482 while (*usage > limit) { |
| 483 while (usage->Exceeds(limit)) { | |
| 484 RebuildEvictionQueueIfNeeded(); | 483 RebuildEvictionQueueIfNeeded(); |
| 485 if (eviction_priority_queue_.IsEmpty()) | 484 if (eviction_priority_queue_.IsEmpty()) |
| 486 return false; | 485 return false; |
| 487 | 486 |
| 488 Tile* tile = eviction_priority_queue_.Top(); | 487 Tile* tile = eviction_priority_queue_.Top(); |
| 489 *usage -= MemoryUsage::FromTile(tile); | 488 *usage -= BytesLimitFromTile(tile); |
| 490 FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile); | 489 FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile); |
| 491 eviction_priority_queue_.Pop(); | 490 eviction_priority_queue_.Pop(); |
| 492 } | 491 } |
| 493 return true; | 492 return true; |
| 494 } | 493 } |
| 495 | 494 |
| 496 bool TileManager::FreeTileResourcesWithLowerPriorityUntilUsageIsWithinLimit( | 495 bool TileManager::FreeTileResourcesWithLowerPriorityUntilUsageIsWithinLimit( |
| 497 const MemoryUsage& limit, | 496 int64 limit, |
| 498 const TilePriority& other_priority, | 497 const TilePriority& other_priority, |
| 499 MemoryUsage* usage) { | 498 int64* usage) { |
| 500 while (usage->Exceeds(limit)) { | 499 while (*usage > limit) { |
| 501 RebuildEvictionQueueIfNeeded(); | 500 RebuildEvictionQueueIfNeeded(); |
| 502 if (eviction_priority_queue_.IsEmpty()) | 501 if (eviction_priority_queue_.IsEmpty()) |
| 503 return false; | 502 return false; |
| 504 | 503 |
| 505 Tile* tile = eviction_priority_queue_.Top(); | 504 Tile* tile = eviction_priority_queue_.Top(); |
| 506 if (!other_priority.IsHigherPriorityThan(tile->combined_priority())) | 505 if (!other_priority.IsHigherPriorityThan(tile->combined_priority())) |
| 507 return false; | 506 return false; |
| 508 | 507 |
| 509 *usage -= MemoryUsage::FromTile(tile); | 508 *usage -= BytesLimitFromTile(tile); |
| 510 FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile); | 509 FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(tile); |
| 511 eviction_priority_queue_.Pop(); | 510 eviction_priority_queue_.Pop(); |
| 512 } | 511 } |
| 513 return true; | 512 return true; |
| 514 } | 513 } |
| 515 | 514 |
| 516 bool TileManager::TilePriorityViolatesMemoryPolicy( | 515 bool TileManager::TilePriorityViolatesMemoryPolicy( |
| 517 const TilePriority& priority) { | 516 const TilePriority& priority) { |
| 518 switch (global_state_.memory_limit_policy) { | 517 switch (global_state_.memory_limit_policy) { |
| 519 case ALLOW_NOTHING: | 518 case ALLOW_NOTHING: |
| (...skipping 20 matching lines...) Expand all Loading... |
| 540 // resource(s) was returned. Note that in that case, one also need to | 539 // resource(s) was returned. Note that in that case, one also need to |
| 541 // invalidate when releasing some resource from the pool. | 540 // invalidate when releasing some resource from the pool. |
| 542 resource_pool_->CheckBusyResources(); | 541 resource_pool_->CheckBusyResources(); |
| 543 | 542 |
| 544 // Now give memory out to the tiles until we're out, and build | 543 // Now give memory out to the tiles until we're out, and build |
| 545 // the needs-to-be-rasterized queue. | 544 // the needs-to-be-rasterized queue. |
| 546 unsigned schedule_priority = 1u; | 545 unsigned schedule_priority = 1u; |
| 547 all_tiles_that_need_to_be_rasterized_are_scheduled_ = true; | 546 all_tiles_that_need_to_be_rasterized_are_scheduled_ = true; |
| 548 bool had_enough_memory_to_schedule_tiles_needed_now = true; | 547 bool had_enough_memory_to_schedule_tiles_needed_now = true; |
| 549 | 548 |
| 550 MemoryUsage hard_memory_limit(global_state_.hard_memory_limit_in_bytes, | 549 int64 hard_memory_limit = global_state_.hard_memory_limit_in_bytes; |
| 551 global_state_.num_resources_limit); | 550 int64 soft_memory_limit = global_state_.soft_memory_limit_in_bytes; |
| 552 MemoryUsage soft_memory_limit(global_state_.soft_memory_limit_in_bytes, | 551 int64 memory_usage = resource_pool_->acquired_memory_usage_bytes(); |
| 553 global_state_.num_resources_limit); | |
| 554 MemoryUsage memory_usage(resource_pool_->acquired_memory_usage_bytes(), | |
| 555 resource_pool_->acquired_resource_count()); | |
| 556 | 552 |
| 557 eviction_priority_queue_is_up_to_date_ = false; | 553 eviction_priority_queue_is_up_to_date_ = false; |
| 558 client_->BuildRasterQueue(&raster_priority_queue_, | 554 client_->BuildRasterQueue(&raster_priority_queue_, |
| 559 global_state_.tree_priority); | 555 global_state_.tree_priority); |
| 560 | 556 |
| 561 while (!raster_priority_queue_.IsEmpty()) { | 557 while (!raster_priority_queue_.IsEmpty()) { |
| 562 Tile* tile = raster_priority_queue_.Top(); | 558 Tile* tile = raster_priority_queue_.Top(); |
| 563 TilePriority priority = tile->combined_priority(); | 559 TilePriority priority = tile->combined_priority(); |
| 564 | 560 |
| 565 if (TilePriorityViolatesMemoryPolicy(priority)) { | 561 if (TilePriorityViolatesMemoryPolicy(priority)) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 580 ManagedTileState& mts = tile->managed_state(); | 576 ManagedTileState& mts = tile->managed_state(); |
| 581 mts.scheduled_priority = schedule_priority++; | 577 mts.scheduled_priority = schedule_priority++; |
| 582 | 578 |
| 583 DCHECK(mts.draw_info.mode() == | 579 DCHECK(mts.draw_info.mode() == |
| 584 ManagedTileState::DrawInfo::PICTURE_PILE_MODE || | 580 ManagedTileState::DrawInfo::PICTURE_PILE_MODE || |
| 585 !mts.draw_info.IsReadyToDraw()); | 581 !mts.draw_info.IsReadyToDraw()); |
| 586 | 582 |
| 587 // If the tile already has a raster_task, then the memory used by it is | 583 // If the tile already has a raster_task, then the memory used by it is |
| 588 // already accounted for in memory_usage. Otherwise, we'll have to acquire | 584 // already accounted for in memory_usage. Otherwise, we'll have to acquire |
| 589 // more memory to create a raster task. | 585 // more memory to create a raster task. |
| 590 MemoryUsage memory_required_by_tile_to_be_scheduled; | 586 int64 memory_required_by_tile_to_be_scheduled = 0; |
| 591 if (!mts.raster_task.get()) { | 587 if (!mts.raster_task.get()) { |
| 592 memory_required_by_tile_to_be_scheduled = MemoryUsage::FromConfig( | 588 memory_required_by_tile_to_be_scheduled = |
| 593 tile->size(), resource_pool_->resource_format()); | 589 BytesLimitFromConfig(tile->size(), resource_pool_->resource_format()); |
| 594 } | 590 } |
| 595 | 591 |
| 596 bool tile_is_needed_now = priority.priority_bin == TilePriority::NOW; | 592 bool tile_is_needed_now = priority.priority_bin == TilePriority::NOW; |
| 597 | 593 |
| 598 // This is the memory limit that will be used by this tile. Depending on | 594 // This is the memory limit that will be used by this tile. Depending on |
| 599 // the tile priority, it will be one of hard_memory_limit or | 595 // the tile priority, it will be one of hard_memory_limit or |
| 600 // soft_memory_limit. | 596 // soft_memory_limit. |
| 601 MemoryUsage& tile_memory_limit = | 597 int64 tile_memory_limit = |
| 602 tile_is_needed_now ? hard_memory_limit : soft_memory_limit; | 598 tile_is_needed_now ? hard_memory_limit : soft_memory_limit; |
| 603 | 599 |
| 604 bool memory_usage_is_within_limit = | 600 bool memory_usage_is_within_limit = |
| 605 FreeTileResourcesWithLowerPriorityUntilUsageIsWithinLimit( | 601 FreeTileResourcesWithLowerPriorityUntilUsageIsWithinLimit( |
| 606 tile_memory_limit - memory_required_by_tile_to_be_scheduled, | 602 tile_memory_limit - memory_required_by_tile_to_be_scheduled, |
| 607 priority, | 603 priority, |
| 608 &memory_usage); | 604 &memory_usage); |
| 609 | 605 |
| 610 // If we couldn't fit the tile into our current memory limit, then we're | 606 // If we couldn't fit the tile into our current memory limit, then we're |
| 611 // done. | 607 // done. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 625 // didn't reduce memory. This ensures that we always release as many resources | 621 // didn't reduce memory. This ensures that we always release as many resources |
| 626 // as possible to stay within the memory limit. | 622 // as possible to stay within the memory limit. |
| 627 FreeTileResourcesUntilUsageIsWithinLimit(hard_memory_limit, &memory_usage); | 623 FreeTileResourcesUntilUsageIsWithinLimit(hard_memory_limit, &memory_usage); |
| 628 | 624 |
| 629 UMA_HISTOGRAM_BOOLEAN("TileManager.ExceededMemoryBudget", | 625 UMA_HISTOGRAM_BOOLEAN("TileManager.ExceededMemoryBudget", |
| 630 !had_enough_memory_to_schedule_tiles_needed_now); | 626 !had_enough_memory_to_schedule_tiles_needed_now); |
| 631 did_oom_on_last_assign_ = !had_enough_memory_to_schedule_tiles_needed_now; | 627 did_oom_on_last_assign_ = !had_enough_memory_to_schedule_tiles_needed_now; |
| 632 | 628 |
| 633 memory_stats_from_last_assign_.total_budget_in_bytes = | 629 memory_stats_from_last_assign_.total_budget_in_bytes = |
| 634 global_state_.hard_memory_limit_in_bytes; | 630 global_state_.hard_memory_limit_in_bytes; |
| 635 memory_stats_from_last_assign_.total_bytes_used = memory_usage.memory_bytes(); | 631 memory_stats_from_last_assign_.total_bytes_used = memory_usage; |
| 636 memory_stats_from_last_assign_.had_enough_memory = | 632 memory_stats_from_last_assign_.had_enough_memory = |
| 637 had_enough_memory_to_schedule_tiles_needed_now; | 633 had_enough_memory_to_schedule_tiles_needed_now; |
| 638 | 634 |
| 639 raster_priority_queue_.Reset(); | 635 raster_priority_queue_.Reset(); |
| 640 | 636 |
| 641 TRACE_EVENT_END2("cc", | 637 TRACE_EVENT_END2("cc", |
| 642 "TileManager::AssignGpuMemoryToTiles", | 638 "TileManager::AssignGpuMemoryToTiles", |
| 643 "all_tiles_that_need_to_be_rasterized_are_scheduled", | 639 "all_tiles_that_need_to_be_rasterized_are_scheduled", |
| 644 all_tiles_that_need_to_be_rasterized_are_scheduled_, | 640 all_tiles_that_need_to_be_rasterized_are_scheduled_, |
| 645 "had_enough_memory_to_schedule_tiles_needed_now", | 641 "had_enough_memory_to_schedule_tiles_needed_now", |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 870 void TileManager::CheckIfReadyToActivate() { | 866 void TileManager::CheckIfReadyToActivate() { |
| 871 TRACE_EVENT0("cc", "TileManager::CheckIfReadyToActivate"); | 867 TRACE_EVENT0("cc", "TileManager::CheckIfReadyToActivate"); |
| 872 | 868 |
| 873 rasterizer_->CheckForCompletedTasks(); | 869 rasterizer_->CheckForCompletedTasks(); |
| 874 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; | 870 did_check_for_completed_tasks_since_last_schedule_tasks_ = true; |
| 875 | 871 |
| 876 if (IsReadyToActivate()) | 872 if (IsReadyToActivate()) |
| 877 client_->NotifyReadyToActivate(); | 873 client_->NotifyReadyToActivate(); |
| 878 } | 874 } |
| 879 | 875 |
| 880 TileManager::MemoryUsage::MemoryUsage() : memory_bytes_(0), resource_count_(0) { | 876 int64 TileManager::BytesLimitFromConfig(const gfx::Size& size, |
| 877 ResourceFormat format) { |
| 878 return Resource::MemorySizeBytes(size, format); |
| 881 } | 879 } |
| 882 | 880 |
| 883 TileManager::MemoryUsage::MemoryUsage(int64 memory_bytes, int resource_count) | 881 int64 TileManager::BytesLimitFromTile(const Tile* tile) { |
| 884 : memory_bytes_(memory_bytes), resource_count_(resource_count) { | |
| 885 } | |
| 886 | |
| 887 // static | |
| 888 TileManager::MemoryUsage TileManager::MemoryUsage::FromConfig( | |
| 889 const gfx::Size& size, | |
| 890 ResourceFormat format) { | |
| 891 return MemoryUsage(Resource::MemorySizeBytes(size, format), 1); | |
| 892 } | |
| 893 | |
| 894 // static | |
| 895 TileManager::MemoryUsage TileManager::MemoryUsage::FromTile(const Tile* tile) { | |
| 896 const ManagedTileState& mts = tile->managed_state(); | 882 const ManagedTileState& mts = tile->managed_state(); |
| 897 if (mts.draw_info.resource_) { | 883 if (mts.draw_info.resource_) { |
| 898 return MemoryUsage::FromConfig(tile->size(), | 884 return BytesLimitFromConfig(tile->size(), |
| 899 mts.draw_info.resource_->format()); | 885 mts.draw_info.resource_->format()); |
| 900 } | 886 } |
| 901 return MemoryUsage(); | 887 return 0; |
| 902 } | |
| 903 | |
| 904 TileManager::MemoryUsage& TileManager::MemoryUsage::operator+=( | |
| 905 const MemoryUsage& other) { | |
| 906 memory_bytes_ += other.memory_bytes_; | |
| 907 resource_count_ += other.resource_count_; | |
| 908 return *this; | |
| 909 } | |
| 910 | |
| 911 TileManager::MemoryUsage& TileManager::MemoryUsage::operator-=( | |
| 912 const MemoryUsage& other) { | |
| 913 memory_bytes_ -= other.memory_bytes_; | |
| 914 resource_count_ -= other.resource_count_; | |
| 915 return *this; | |
| 916 } | |
| 917 | |
| 918 TileManager::MemoryUsage TileManager::MemoryUsage::operator-( | |
| 919 const MemoryUsage& other) { | |
| 920 MemoryUsage result = *this; | |
| 921 result -= other; | |
| 922 return result; | |
| 923 } | |
| 924 | |
| 925 bool TileManager::MemoryUsage::Exceeds(const MemoryUsage& limit) const { | |
| 926 return memory_bytes_ > limit.memory_bytes_ || | |
| 927 resource_count_ > limit.resource_count_; | |
| 928 } | 888 } |
| 929 | 889 |
| 930 } // namespace cc | 890 } // namespace cc |
| OLD | NEW |