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 #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 |