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 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
144 #if defined(OS_ANDROID) || defined(OS_CHROMEOS) | 144 #if defined(OS_ANDROID) || defined(OS_CHROMEOS) |
145 return bytes_available_gpu_memory_; | 145 return bytes_available_gpu_memory_; |
146 #else | 146 #else |
147 // This is to avoid allowing a single page on to use a full 256MB of memory | 147 // This is to avoid allowing a single page on to use a full 256MB of memory |
148 // (the current total limit). Long-scroll pages will hit this limit, | 148 // (the current total limit). Long-scroll pages will hit this limit, |
149 // resulting in instability on some platforms (e.g, issue 141377). | 149 // resulting in instability on some platforms (e.g, issue 141377). |
150 return bytes_available_gpu_memory_ / 2; | 150 return bytes_available_gpu_memory_ / 2; |
151 #endif | 151 #endif |
152 } | 152 } |
153 | 153 |
154 uint64 GpuMemoryManager::CalcAvailableFromViewportArea(int viewport_area) { | 154 uint64 GpuMemoryManager::CalcAvailableFromDalvikHeap() { |
155 // We can't query available GPU memory from the system on Android, but | |
156 // 18X the viewport and 50% of the dalvik heap size give us a good | |
157 // estimate of available GPU memory on a wide range of devices. | |
158 const int kViewportMultiplier = 18; | |
159 const unsigned int kComponentsPerPixel = 4; // GraphicsContext3D::RGBA | |
160 const unsigned int kBytesPerComponent = 1; // sizeof(GC3Dubyte) | |
161 uint64 viewport_limit = viewport_area * kViewportMultiplier * | |
162 kComponentsPerPixel * | |
163 kBytesPerComponent; | |
164 #if !defined(OS_ANDROID) | 155 #if !defined(OS_ANDROID) |
165 return viewport_limit; | 156 CHECK(false); |
157 return 0; | |
166 #else | 158 #else |
159 // We can't query available GPU memory from the system on Android, | |
160 // but the dalvik heap size give us a good estimate of available | |
161 // GPU memory on a wide range of devices. | |
162 | |
163 // The heap size tends to be about 1/4 of total ram on higher end | |
164 // devices, so we use 1/2 of that by default. For example both the | |
165 // Nexus 4/10 have 2GB of ram and 512MB Dalvik heap size. For lower | |
166 // end devices, 1/2 of the heap size can be too high, but this | |
167 // correlates well with having a small heap-growth-limit. So for | |
168 // devices with less ram, we factor in the growth limit. | |
169 | |
170 // This is the result of the calculation below: | |
171 // Droid DNA 1080P 128MB | |
172 // Nexus S 56MB | |
173 // Galaxy Nexus 112MB | |
174 // Nexus 4/10 256MB | |
175 // Xoom 88MB | |
176 | |
167 static uint64 dalvik_limit = 0; | 177 static uint64 dalvik_limit = 0; |
168 if (!dalvik_limit) | 178 if (!dalvik_limit) { |
169 dalvik_limit = (base::SysInfo::DalvikHeapSizeMB() / 2) * 1024 * 1024; | 179 uint64 heap_size = base::SysInfo::DalvikHeapSizeMB(); |
170 return std::min(viewport_limit, dalvik_limit); | 180 uint64 heap_growth = base::SysInfo::DalvikHeapGrowthLimitMB(); |
181 uint64 limit = 0; | |
182 | |
183 if (heap_size >= 350) | |
184 limit = heap_size / 2; | |
185 else | |
186 limit = (heap_size + (heap_growth * 2)) / 4; | |
187 | |
188 dalvik_limit = limit * 1024 * 1024; | |
189 } | |
190 | |
191 return dalvik_limit; | |
171 #endif | 192 #endif |
172 } | 193 } |
173 | 194 |
174 uint64 GpuMemoryManager::CalcAvailableFromGpuTotal(uint64 total_gpu_memory) { | 195 uint64 GpuMemoryManager::CalcAvailableFromGpuTotal(uint64 total_gpu_memory) { |
175 // Allow Chrome to use 75% of total GPU memory, or all-but-64MB of GPU | 196 // Allow Chrome to use 75% of total GPU memory, or all-but-64MB of GPU |
176 // memory, whichever is less. | 197 // memory, whichever is less. |
177 return std::min(3 * total_gpu_memory / 4, total_gpu_memory - 64*1024*1024); | 198 return std::min(3 * total_gpu_memory / 4, total_gpu_memory - 64*1024*1024); |
178 } | 199 } |
179 | 200 |
180 void GpuMemoryManager::UpdateAvailableGpuMemory() { | 201 void GpuMemoryManager::UpdateAvailableGpuMemory() { |
181 // If the amount of video memory to use was specified at the command | 202 // If the amount of video memory to use was specified at the command |
182 // line, never change it. | 203 // line, never change it. |
183 if (bytes_available_gpu_memory_overridden_) | 204 if (bytes_available_gpu_memory_overridden_) |
184 return; | 205 return; |
185 | 206 |
186 #if defined(OS_ANDROID) | 207 #if defined(OS_ANDROID) |
187 // On Android we use the surface size, so this finds the largest visible | 208 // On Android we use the surface size, so this finds the largest visible |
188 // surface size instead of lowest gpu's limit. | 209 // surface size instead of lowest gpu's limit. |
189 int max_surface_area = 0; | 210 int max_surface_area = 0; |
ccameron
2013/02/11 20:05:33
Can kill off max_surface_area here.
| |
190 #else | 211 #else |
191 // On non-Android, we use an operating system query when possible. | 212 // On non-Android, we use an operating system query when possible. |
192 // We do not have a reliable concept of multiple GPUs existing in | 213 // We do not have a reliable concept of multiple GPUs existing in |
193 // a system, so just be safe and go with the minimum encountered. | 214 // a system, so just be safe and go with the minimum encountered. |
194 uint64 bytes_min = 0; | 215 uint64 bytes_min = 0; |
195 #endif | 216 #endif |
196 | 217 |
197 // Only use the clients that are visible, because otherwise the set of clients | 218 // Only use the clients that are visible, because otherwise the set of clients |
198 // we are querying could become extremely large. | 219 // we are querying could become extremely large. |
199 for (ClientStateList::const_iterator it = clients_visible_mru_.begin(); | 220 for (ClientStateList::const_iterator it = clients_visible_mru_.begin(); |
(...skipping 12 matching lines...) Expand all Loading... | |
212 #else | 233 #else |
213 uint64 bytes = 0; | 234 uint64 bytes = 0; |
214 if (client_state->client_->GetTotalGpuMemory(&bytes)) { | 235 if (client_state->client_->GetTotalGpuMemory(&bytes)) { |
215 if (!bytes_min || bytes < bytes_min) | 236 if (!bytes_min || bytes < bytes_min) |
216 bytes_min = bytes; | 237 bytes_min = bytes; |
217 } | 238 } |
218 #endif | 239 #endif |
219 } | 240 } |
220 | 241 |
221 #if defined(OS_ANDROID) | 242 #if defined(OS_ANDROID) |
222 bytes_available_gpu_memory_ = CalcAvailableFromViewportArea(max_surface_area); | 243 bytes_available_gpu_memory_ = CalcAvailableFromDalvikHeap(); |
223 #else | 244 #else |
224 if (!bytes_min) | 245 if (!bytes_min) |
225 return; | 246 return; |
226 | 247 |
227 bytes_available_gpu_memory_ = CalcAvailableFromGpuTotal(bytes_min); | 248 bytes_available_gpu_memory_ = CalcAvailableFromGpuTotal(bytes_min); |
228 #endif | 249 #endif |
229 | 250 |
230 // Never go below the default allocation | 251 // Never go below the default allocation |
231 bytes_available_gpu_memory_ = std::max(bytes_available_gpu_memory_, | 252 bytes_available_gpu_memory_ = std::max(bytes_available_gpu_memory_, |
232 GetDefaultAvailableGpuMemory()); | 253 GetDefaultAvailableGpuMemory()); |
(...skipping 813 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1046 | 1067 |
1047 void GpuMemoryManager::RemoveClientFromList( | 1068 void GpuMemoryManager::RemoveClientFromList( |
1048 GpuMemoryManagerClientState* client_state) { | 1069 GpuMemoryManagerClientState* client_state) { |
1049 DCHECK(client_state->list_iterator_valid_); | 1070 DCHECK(client_state->list_iterator_valid_); |
1050 ClientStateList* client_list = GetClientList(client_state); | 1071 ClientStateList* client_list = GetClientList(client_state); |
1051 client_list->erase(client_state->list_iterator_); | 1072 client_list->erase(client_state->list_iterator_); |
1052 client_state->list_iterator_valid_ = false; | 1073 client_state->list_iterator_valid_ = false; |
1053 } | 1074 } |
1054 | 1075 |
1055 } // namespace content | 1076 } // namespace content |
OLD | NEW |