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