Chromium Code Reviews| 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 #if defined(ENABLE_GPU) | 7 #if defined(ENABLE_GPU) |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 | 10 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/message_loop.h" | 12 #include "base/message_loop.h" |
| 13 #include "content/common/gpu/gpu_command_buffer_stub.h" | 13 #include "content/common/gpu/gpu_command_buffer_stub.h" |
| 14 #include "content/common/gpu/gpu_memory_allocation.h" | 14 #include "content/common/gpu/gpu_memory_allocation.h" |
| 15 | 15 |
| 16 namespace { | 16 namespace { |
| 17 | 17 |
| 18 // These are predefined values (in bytes) for | 18 // These are predefined values (in bytes) for |
| 19 // GpuMemoryAllocation::gpuResourceSizeInBytes. Currently, the value is only | 19 // GpuMemoryAllocation::gpuResourceSizeInBytes. |
| 20 // used to check if it is 0 or non-0. In the future, these values will not | |
| 21 // come from constants, but rather will be distributed dynamically. | |
| 22 enum { | 20 enum { |
| 21 kResourceSizeMinimumForVisibleTab = 64 * 1024 * 1024, | |
| 22 kResourceSizeSumOfAllVisibleTabs = | |
| 23 512 * 1024 * 1024 - kResourceSizeMinimumForVisibleTab, | |
|
mmocny
2012/04/18 20:43:11
I subtract kResourceSizeMinumumForVisibleTab from
nduca
2012/04/18 23:16:28
~shrug~ no strong opinions here. Put a rough expla
| |
| 24 kResourceSizeNonVisibleTab = 0, | |
| 25 | |
| 23 kResourceSizeNonHibernatedTab = 1, | 26 kResourceSizeNonHibernatedTab = 1, |
|
nduca
2012/04/18 23:16:28
are we still using these?
| |
| 24 kResourceSizeHibernatedTab = 0 | 27 kResourceSizeHibernatedTab = 0 |
| 25 }; | 28 }; |
| 26 | 29 |
| 27 bool IsInSameContextShareGroupAsAnyOf( | 30 bool IsInSameContextShareGroupAsAnyOf( |
| 28 const GpuCommandBufferStubBase* stub, | 31 const GpuCommandBufferStubBase* stub, |
| 29 const std::vector<GpuCommandBufferStubBase*>& stubs) { | 32 const std::vector<GpuCommandBufferStubBase*>& stubs) { |
| 30 for (std::vector<GpuCommandBufferStubBase*>::const_iterator it = | 33 for (std::vector<GpuCommandBufferStubBase*>::const_iterator it = |
| 31 stubs.begin(); it != stubs.end(); ++it) { | 34 stubs.begin(); it != stubs.end(); ++it) { |
| 32 if (stub->IsInSameContextShareGroup(**it)) | 35 if (stub->IsInSameContextShareGroup(**it)) |
| 33 return true; | 36 return true; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 92 // The considerations for categorizing contexts without a surface are: | 95 // The considerations for categorizing contexts without a surface are: |
| 93 // 1. These contexts do not track {visibility,last_used_time}, so cannot | 96 // 1. These contexts do not track {visibility,last_used_time}, so cannot |
| 94 // sort them directly. | 97 // sort them directly. |
| 95 // 2. These contexts may be used by, and thus affect, other contexts, and so | 98 // 2. These contexts may be used by, and thus affect, other contexts, and so |
| 96 // cannot be less visible than any affected context. | 99 // cannot be less visible than any affected context. |
| 97 // 3. Contexts belong to share groups within which resources can be shared. | 100 // 3. Contexts belong to share groups within which resources can be shared. |
| 98 // | 101 // |
| 99 // As such, the rule for categorizing contexts without a surface is: | 102 // As such, the rule for categorizing contexts without a surface is: |
| 100 // 1. Find the most visible context-with-a-surface within each | 103 // 1. Find the most visible context-with-a-surface within each |
| 101 // context-without-a-surface's share group, and inherit its visibilty. | 104 // context-without-a-surface's share group, and inherit its visibilty. |
| 102 void GpuMemoryManager::Manage() { | 105 void GpuMemoryManager::Manage() { |
|
nduca
2012/04/18 23:16:28
im having a really hard time reading these allocat
mmocny
2012/04/20 18:37:55
done.
On 2012/04/18 23:16:28, nduca wrote:
| |
| 103 // Set up three allocation values for the three possible stub states | |
| 104 const GpuMemoryAllocation all_buffers_allocation( | |
| 105 kResourceSizeNonHibernatedTab, true, true); | |
| 106 const GpuMemoryAllocation front_buffers_allocation( | |
| 107 kResourceSizeNonHibernatedTab, false, true); | |
| 108 const GpuMemoryAllocation no_buffers_allocation( | |
| 109 kResourceSizeHibernatedTab, false, false); | |
| 110 | |
| 111 manage_scheduled_ = false; | 106 manage_scheduled_ = false; |
| 112 | 107 |
| 113 // Create stub lists by separating out the two types received from client | 108 // Create stub lists by separating out the two types received from client |
| 114 std::vector<GpuCommandBufferStubBase*> stubs_with_surface; | 109 std::vector<GpuCommandBufferStubBase*> stubs_with_surface; |
| 115 std::vector<GpuCommandBufferStubBase*> stubs_without_surface; | 110 std::vector<GpuCommandBufferStubBase*> stubs_without_surface; |
| 111 size_t num_visible_stubs_with_surface = 0; | |
| 116 { | 112 { |
| 117 std::vector<GpuCommandBufferStubBase*> stubs; | 113 std::vector<GpuCommandBufferStubBase*> stubs; |
| 118 client_->AppendAllCommandBufferStubs(stubs); | 114 client_->AppendAllCommandBufferStubs(stubs); |
| 119 | 115 |
| 120 for (std::vector<GpuCommandBufferStubBase*>::iterator it = stubs.begin(); | 116 for (std::vector<GpuCommandBufferStubBase*>::iterator it = stubs.begin(); |
| 121 it != stubs.end(); ++it) { | 117 it != stubs.end(); ++it) { |
| 122 GpuCommandBufferStubBase* stub = *it; | 118 GpuCommandBufferStubBase* stub = *it; |
| 123 if (stub->has_surface_state()) | 119 if (stub->has_surface_state()) { |
| 124 stubs_with_surface.push_back(stub); | 120 stubs_with_surface.push_back(stub); |
| 125 else | 121 if (stub->surface_state().visible) |
| 122 ++num_visible_stubs_with_surface; | |
| 123 } else { | |
| 126 stubs_without_surface.push_back(stub); | 124 stubs_without_surface.push_back(stub); |
| 125 } | |
| 127 } | 126 } |
| 128 } | 127 } |
| 129 | 128 |
| 130 // Sort stubs with surface into {visibility,last_used_time} order using | 129 // Sort stubs with surface into {visibility,last_used_time} order using |
| 131 // custom comparator | 130 // custom comparator |
| 132 std::sort(stubs_with_surface.begin(), | 131 std::sort(stubs_with_surface.begin(), |
| 133 stubs_with_surface.end(), | 132 stubs_with_surface.end(), |
| 134 StubWithSurfaceComparator()); | 133 StubWithSurfaceComparator()); |
| 135 DCHECK(std::unique(stubs_with_surface.begin(), stubs_with_surface.end()) == | 134 DCHECK(std::unique(stubs_with_surface.begin(), stubs_with_surface.end()) == |
| 136 stubs_with_surface.end()); | 135 stubs_with_surface.end()); |
| 137 | 136 |
| 137 // Set up allocation values for possible states for stubs with surfaces. | |
|
mmocny
2012/04/18 20:43:11
We divide the total desired global limit by the nu
| |
| 138 size_t allocation_for_visible_tabs = | |
| 139 num_visible_stubs_with_surface == 0 ? 0 : | |
| 140 std::max(kResourceSizeSumOfAllVisibleTabs/num_visible_stubs_with_surface, | |
| 141 (size_t)kResourceSizeMinimumForVisibleTab); | |
| 142 const GpuMemoryAllocation all_buffers_allocation( | |
| 143 allocation_for_visible_tabs, true, true); | |
| 144 const GpuMemoryAllocation front_buffers_allocation( | |
| 145 kResourceSizeNonVisibleTab, false, true); | |
| 146 const GpuMemoryAllocation no_buffers_allocation( | |
| 147 kResourceSizeNonVisibleTab, false, false); | |
| 148 | |
| 138 // Separate stubs into memory allocation sets. | 149 // Separate stubs into memory allocation sets. |
| 139 std::vector<GpuCommandBufferStubBase*> all_buffers, front_buffers, no_buffers; | 150 std::vector<GpuCommandBufferStubBase*> all_buffers, front_buffers, no_buffers; |
| 140 | 151 |
| 141 for (size_t i = 0; i < stubs_with_surface.size(); ++i) { | 152 for (size_t i = 0; i < stubs_with_surface.size(); ++i) { |
| 142 GpuCommandBufferStubBase* stub = stubs_with_surface[i]; | 153 GpuCommandBufferStubBase* stub = stubs_with_surface[i]; |
| 143 DCHECK(stub->has_surface_state()); | 154 DCHECK(stub->has_surface_state()); |
| 144 if (stub->surface_state().visible) { | 155 if (stub->surface_state().visible) { |
| 145 all_buffers.push_back(stub); | 156 all_buffers.push_back(stub); |
| 146 stub->SetMemoryAllocation(all_buffers_allocation); | 157 stub->SetMemoryAllocation(all_buffers_allocation); |
| 147 } else if (i < max_surfaces_with_frontbuffer_soft_limit_) { | 158 } else if (i < max_surfaces_with_frontbuffer_soft_limit_) { |
| 148 front_buffers.push_back(stub); | 159 front_buffers.push_back(stub); |
| 149 stub->SetMemoryAllocation(front_buffers_allocation); | 160 stub->SetMemoryAllocation(front_buffers_allocation); |
| 150 } else { | 161 } else { |
| 151 no_buffers.push_back(stub); | 162 no_buffers.push_back(stub); |
| 152 stub->SetMemoryAllocation(no_buffers_allocation); | 163 stub->SetMemoryAllocation(no_buffers_allocation); |
| 153 } | 164 } |
| 154 } | 165 } |
| 155 | 166 |
| 167 // Set up allocation values for possible states for stubs without surfaces. | |
|
mmocny
2012/04/18 20:43:11
Stubs without surfaces do not receive memory alloc
| |
| 168 const GpuMemoryAllocation non_hibernated_allocation( | |
| 169 kResourceSizeNonHibernatedTab, true, true); | |
| 170 const GpuMemoryAllocation hibernated_allocation( | |
| 171 kResourceSizeHibernatedTab, false, false); | |
|
nduca
2012/04/18 23:16:28
I'm not loving that this causes us to give "1" to
mmocny
2012/04/20 18:37:55
Did a big re-factoring here to make it all clearer
| |
| 172 | |
| 156 // Now, go through the stubs without surfaces and deduce visibility using the | 173 // Now, go through the stubs without surfaces and deduce visibility using the |
| 157 // visibility of stubs which are in the same context share group. | 174 // visibility of stubs which are in the same context share group. |
| 158 for (std::vector<GpuCommandBufferStubBase*>::const_iterator it = | 175 for (std::vector<GpuCommandBufferStubBase*>::const_iterator it = |
| 159 stubs_without_surface.begin(); it != stubs_without_surface.end(); ++it) { | 176 stubs_without_surface.begin(); it != stubs_without_surface.end(); ++it) { |
| 160 GpuCommandBufferStubBase* stub = *it; | 177 GpuCommandBufferStubBase* stub = *it; |
| 161 DCHECK(!stub->has_surface_state()); | 178 DCHECK(!stub->has_surface_state()); |
| 162 if (IsInSameContextShareGroupAsAnyOf(stub, all_buffers)) { | 179 if (IsInSameContextShareGroupAsAnyOf(stub, all_buffers) || |
| 163 stub->SetMemoryAllocation(all_buffers_allocation); | 180 IsInSameContextShareGroupAsAnyOf(stub, front_buffers)) |
| 164 } else if (IsInSameContextShareGroupAsAnyOf(stub, front_buffers)) { | 181 stub->SetMemoryAllocation(non_hibernated_allocation); |
| 165 stub->SetMemoryAllocation(front_buffers_allocation); | 182 else |
| 166 } else { | 183 stub->SetMemoryAllocation(hibernated_allocation); |
| 167 stub->SetMemoryAllocation(no_buffers_allocation); | |
| 168 } | |
| 169 } | 184 } |
| 170 } | 185 } |
| 171 | 186 |
| 172 #endif | 187 #endif |
| OLD | NEW |