Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(236)

Side by Side Diff: content/common/gpu/gpu_memory_manager.cc

Issue 12212143: Distribute extra memory evenly among visible clients (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: One more missed test Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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 =
880 #if defined(OS_MACOSX)
881 GpuMemoryAllocationForRenderer::kPriorityCutoffAllowNiceToHave;
882 #else
825 GpuMemoryAllocationForRenderer::kPriorityCutoffAllowEverything; 883 GpuMemoryAllocationForRenderer::kPriorityCutoffAllowEverything;
884 #endif
826 885
827 allocation.renderer_allocation.bytes_limit_when_not_visible = 886 allocation.renderer_allocation.bytes_limit_when_not_visible =
828 client_state->bytes_allocation_when_nonvisible_; 887 client_state->bytes_allocation_when_nonvisible_;
829 allocation.renderer_allocation.priority_cutoff_when_not_visible = 888 allocation.renderer_allocation.priority_cutoff_when_not_visible =
830 GpuMemoryAllocationForRenderer::kPriorityCutoffAllowOnlyRequired; 889 GpuMemoryAllocationForRenderer::kPriorityCutoffAllowOnlyRequired;
831 890
832 client_state->client_->SetMemoryAllocation(allocation); 891 client_state->client_->SetMemoryAllocation(allocation);
833 } 892 }
834 } 893 }
835 894
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
1046 1105
1047 void GpuMemoryManager::RemoveClientFromList( 1106 void GpuMemoryManager::RemoveClientFromList(
1048 GpuMemoryManagerClientState* client_state) { 1107 GpuMemoryManagerClientState* client_state) {
1049 DCHECK(client_state->list_iterator_valid_); 1108 DCHECK(client_state->list_iterator_valid_);
1050 ClientStateList* client_list = GetClientList(client_state); 1109 ClientStateList* client_list = GetClientList(client_state);
1051 client_list->erase(client_state->list_iterator_); 1110 client_list->erase(client_state->list_iterator_);
1052 client_state->list_iterator_valid_ = false; 1111 client_state->list_iterator_valid_ = false;
1053 } 1112 }
1054 1113
1055 } // namespace content 1114 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/gpu_memory_manager.h ('k') | content/common/gpu/gpu_memory_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698