| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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 "content/common/gpu/gpu_memory_manager.h" | 5 #include "content/common/gpu/gpu_memory_manager.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| (...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 524 SendUmaStatsToBrowser(); | 524 SendUmaStatsToBrowser(); |
| 525 } | 525 } |
| 526 | 526 |
| 527 // static | 527 // static |
| 528 uint64 GpuMemoryManager::ComputeCap( | 528 uint64 GpuMemoryManager::ComputeCap( |
| 529 std::vector<uint64> bytes, uint64 bytes_sum_limit) | 529 std::vector<uint64> bytes, uint64 bytes_sum_limit) |
| 530 { | 530 { |
| 531 size_t bytes_size = bytes.size(); | 531 size_t bytes_size = bytes.size(); |
| 532 uint64 bytes_sum = 0; | 532 uint64 bytes_sum = 0; |
| 533 | 533 |
| 534 if (bytes_size == 0) | |
| 535 return std::numeric_limits<uint64>::max(); | |
| 536 | |
| 537 // Sort and add up all entries | 534 // Sort and add up all entries |
| 538 std::sort(bytes.begin(), bytes.end()); | 535 std::sort(bytes.begin(), bytes.end()); |
| 539 for (size_t i = 0; i < bytes_size; ++i) | 536 for (size_t i = 0; i < bytes_size; ++i) |
| 540 bytes_sum += bytes[i]; | 537 bytes_sum += bytes[i]; |
| 541 | 538 |
| 542 // As we go through the below loop, let bytes_partial_sum be the | 539 // As we go through the below loop, let bytes_partial_sum be the |
| 543 // sum of bytes[0] + ... + bytes[bytes_size - i - 1] | 540 // sum of bytes[0] + ... + bytes[bytes_size - i - 1] |
| 544 uint64 bytes_partial_sum = bytes_sum; | 541 uint64 bytes_partial_sum = bytes_sum; |
| 545 | 542 |
| 546 // Try using each entry as a cap, and see where we get cut off. | 543 // Try using each entry as a cap, and see where we get cut off. |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 738 // go to nonvisible clients. | 735 // go to nonvisible clients. |
| 739 uint64 bytes_available_total = GetAvailableGpuMemory(); | 736 uint64 bytes_available_total = GetAvailableGpuMemory(); |
| 740 uint64 bytes_available_nonvisible = 0; | 737 uint64 bytes_available_nonvisible = 0; |
| 741 uint64 bytes_allocated_nonvisible = 0; | 738 uint64 bytes_allocated_nonvisible = 0; |
| 742 if (bytes_available_total > bytes_allocated_visible) { | 739 if (bytes_available_total > bytes_allocated_visible) { |
| 743 bytes_available_nonvisible = std::min( | 740 bytes_available_nonvisible = std::min( |
| 744 bytes_available_total / 4, | 741 bytes_available_total / 4, |
| 745 bytes_available_total - bytes_allocated_visible); | 742 bytes_available_total - bytes_allocated_visible); |
| 746 } | 743 } |
| 747 | 744 |
| 748 // On Android, always discard everything that is nonvisible. | |
| 749 #if defined(OS_ANDROID) | |
| 750 bytes_available_nonvisible = 0; | |
| 751 #endif | |
| 752 | |
| 753 // Determine which now-visible clients should keep their contents when | 745 // Determine which now-visible clients should keep their contents when |
| 754 // they are made nonvisible. | 746 // they are made nonvisible. |
| 755 for (ClientStateList::const_iterator it = clients_visible_mru_.begin(); | 747 for (ClientStateList::const_iterator it = clients_visible_mru_.begin(); |
| 756 it != clients_visible_mru_.end(); | 748 it != clients_visible_mru_.end(); |
| 757 ++it) { | 749 ++it) { |
| 758 GpuMemoryManagerClientState* client_state = *it; | 750 GpuMemoryManagerClientState* client_state = *it; |
| 759 | 751 |
| 760 // Compute the amount of space available have for this renderer when it is | 752 // Compute the amount of space available have for this renderer when it is |
| 761 // nonvisible. Do not count this client's allocation while visible against | 753 // nonvisible. Do not count this client's allocation while visible against |
| 762 // the nonvisible clients' allocation total. | 754 // the nonvisible clients' allocation total. |
| (...skipping 29 matching lines...) Expand all Loading... |
| 792 if (bytes_allocated_nonvisible + | 784 if (bytes_allocated_nonvisible + |
| 793 client_state->bytes_allocation_when_nonvisible_ > | 785 client_state->bytes_allocation_when_nonvisible_ > |
| 794 bytes_available_nonvisible) { | 786 bytes_available_nonvisible) { |
| 795 client_state->bytes_allocation_when_nonvisible_ = 0; | 787 client_state->bytes_allocation_when_nonvisible_ = 0; |
| 796 } | 788 } |
| 797 bytes_allocated_nonvisible += | 789 bytes_allocated_nonvisible += |
| 798 client_state->bytes_allocation_when_nonvisible_; | 790 client_state->bytes_allocation_when_nonvisible_; |
| 799 } | 791 } |
| 800 } | 792 } |
| 801 | 793 |
| 802 void GpuMemoryManager::DistributeRemainingMemoryToVisibleSurfaces() { | |
| 803 uint64 bytes_available_total = GetAvailableGpuMemory(); | |
| 804 uint64 bytes_allocated_total = 0; | |
| 805 | |
| 806 for (ClientStateList::const_iterator it = clients_visible_mru_.begin(); | |
| 807 it != clients_visible_mru_.end(); | |
| 808 ++it) { | |
| 809 GpuMemoryManagerClientState* client_state = *it; | |
| 810 bytes_allocated_total += client_state->bytes_allocation_when_visible_; | |
| 811 } | |
| 812 for (ClientStateList::const_iterator it = clients_nonvisible_mru_.begin(); | |
| 813 it != clients_nonvisible_mru_.end(); | |
| 814 ++it) { | |
| 815 GpuMemoryManagerClientState* client_state = *it; | |
| 816 bytes_allocated_total += client_state->bytes_allocation_when_nonvisible_; | |
| 817 } | |
| 818 | |
| 819 if (bytes_allocated_total >= bytes_available_total) | |
| 820 return; | |
| 821 | |
| 822 std::vector<uint64> bytes_extra_requests; | |
| 823 for (ClientStateList::const_iterator it = clients_visible_mru_.begin(); | |
| 824 it != clients_visible_mru_.end(); | |
| 825 ++it) { | |
| 826 GpuMemoryManagerClientState* client_state = *it; | |
| 827 CHECK(GetMaximumClientAllocation() >= | |
| 828 client_state->bytes_allocation_when_visible_); | |
| 829 uint64 bytes_extra = GetMaximumClientAllocation() - | |
| 830 client_state->bytes_allocation_when_visible_; | |
| 831 bytes_extra_requests.push_back(bytes_extra); | |
| 832 } | |
| 833 uint64 bytes_extra_cap = ComputeCap( | |
| 834 bytes_extra_requests, bytes_available_total - bytes_allocated_total); | |
| 835 for (ClientStateList::const_iterator it = clients_visible_mru_.begin(); | |
| 836 it != clients_visible_mru_.end(); | |
| 837 ++it) { | |
| 838 GpuMemoryManagerClientState* client_state = *it; | |
| 839 uint64 bytes_extra = GetMaximumClientAllocation() - | |
| 840 client_state->bytes_allocation_when_visible_; | |
| 841 client_state->bytes_allocation_when_visible_ += std::min( | |
| 842 bytes_extra, bytes_extra_cap); | |
| 843 } | |
| 844 } | |
| 845 | |
| 846 void GpuMemoryManager::AssignSurfacesAllocationsNonuniform() { | 794 void GpuMemoryManager::AssignSurfacesAllocationsNonuniform() { |
| 847 // Compute allocation when for all clients. | 795 // Compute allocation when for all clients. |
| 848 ComputeVisibleSurfacesAllocationsNonuniform(); | 796 ComputeVisibleSurfacesAllocationsNonuniform(); |
| 849 ComputeNonvisibleSurfacesAllocationsNonuniform(); | 797 ComputeNonvisibleSurfacesAllocationsNonuniform(); |
| 850 | 798 |
| 851 // Distribute the remaining memory to visible clients. | |
| 852 DistributeRemainingMemoryToVisibleSurfaces(); | |
| 853 | |
| 854 // Send that allocation to the clients. | 799 // Send that allocation to the clients. |
| 855 ClientStateList clients = clients_visible_mru_; | 800 ClientStateList clients = clients_visible_mru_; |
| 856 clients.insert(clients.end(), | 801 clients.insert(clients.end(), |
| 857 clients_nonvisible_mru_.begin(), | 802 clients_nonvisible_mru_.begin(), |
| 858 clients_nonvisible_mru_.end()); | 803 clients_nonvisible_mru_.end()); |
| 859 for (ClientStateList::const_iterator it = clients.begin(); | 804 for (ClientStateList::const_iterator it = clients.begin(); |
| 860 it != clients.end(); | 805 it != clients.end(); |
| 861 ++it) { | 806 ++it) { |
| 862 GpuMemoryManagerClientState* client_state = *it; | 807 GpuMemoryManagerClientState* client_state = *it; |
| 863 | 808 |
| 864 // Re-assign memory limits to this client when its "nice to have" bucket | 809 // Re-assign memory limits to this client when its "nice to have" bucket |
| 865 // grows or shrinks by 1/4. | 810 // grows or shrinks by 1/4. |
| 866 client_state->bytes_nicetohave_limit_high_ = | 811 client_state->bytes_nicetohave_limit_high_ = |
| 867 5 * client_state->managed_memory_stats_.bytes_nice_to_have / 4; | 812 5 * client_state->managed_memory_stats_.bytes_nice_to_have / 4; |
| 868 client_state->bytes_nicetohave_limit_low_ = | 813 client_state->bytes_nicetohave_limit_low_ = |
| 869 3 * client_state->managed_memory_stats_.bytes_nice_to_have / 4; | 814 3 * client_state->managed_memory_stats_.bytes_nice_to_have / 4; |
| 870 | 815 |
| 871 // Populate and send the allocation to the client | 816 // Populate and send the allocation to the client |
| 872 GpuMemoryAllocation allocation; | 817 GpuMemoryAllocation allocation; |
| 873 | 818 |
| 874 allocation.browser_allocation.suggest_have_frontbuffer = | 819 allocation.browser_allocation.suggest_have_frontbuffer = |
| 875 !client_state->hibernated_; | 820 !client_state->hibernated_; |
| 876 | 821 |
| 877 allocation.renderer_allocation.bytes_limit_when_visible = | 822 allocation.renderer_allocation.bytes_limit_when_visible = |
| 878 client_state->bytes_allocation_when_visible_; | 823 client_state->bytes_allocation_when_visible_; |
| 879 allocation.renderer_allocation.priority_cutoff_when_visible = | 824 allocation.renderer_allocation.priority_cutoff_when_visible = |
| 880 #if defined(OS_MACOSX) | |
| 881 GpuMemoryAllocationForRenderer::kPriorityCutoffAllowNiceToHave; | |
| 882 #else | |
| 883 GpuMemoryAllocationForRenderer::kPriorityCutoffAllowEverything; | 825 GpuMemoryAllocationForRenderer::kPriorityCutoffAllowEverything; |
| 884 #endif | |
| 885 | 826 |
| 886 allocation.renderer_allocation.bytes_limit_when_not_visible = | 827 allocation.renderer_allocation.bytes_limit_when_not_visible = |
| 887 client_state->bytes_allocation_when_nonvisible_; | 828 client_state->bytes_allocation_when_nonvisible_; |
| 888 allocation.renderer_allocation.priority_cutoff_when_not_visible = | 829 allocation.renderer_allocation.priority_cutoff_when_not_visible = |
| 889 GpuMemoryAllocationForRenderer::kPriorityCutoffAllowOnlyRequired; | 830 GpuMemoryAllocationForRenderer::kPriorityCutoffAllowOnlyRequired; |
| 890 | 831 |
| 891 client_state->client_->SetMemoryAllocation(allocation); | 832 client_state->client_->SetMemoryAllocation(allocation); |
| 892 } | 833 } |
| 893 } | 834 } |
| 894 | 835 |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1105 | 1046 |
| 1106 void GpuMemoryManager::RemoveClientFromList( | 1047 void GpuMemoryManager::RemoveClientFromList( |
| 1107 GpuMemoryManagerClientState* client_state) { | 1048 GpuMemoryManagerClientState* client_state) { |
| 1108 DCHECK(client_state->list_iterator_valid_); | 1049 DCHECK(client_state->list_iterator_valid_); |
| 1109 ClientStateList* client_list = GetClientList(client_state); | 1050 ClientStateList* client_list = GetClientList(client_state); |
| 1110 client_list->erase(client_state->list_iterator_); | 1051 client_list->erase(client_state->list_iterator_); |
| 1111 client_state->list_iterator_valid_ = false; | 1052 client_state->list_iterator_valid_ = false; |
| 1112 } | 1053 } |
| 1113 | 1054 |
| 1114 } // namespace content | 1055 } // namespace content |
| OLD | NEW |