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" |
11 #include "base/debug/trace_event.h" | 11 #include "base/debug/trace_event.h" |
12 #include "base/message_loop.h" | 12 #include "base/message_loop.h" |
13 #include "base/process_util.h" | 13 #include "base/process_util.h" |
14 #include "base/string_number_conversions.h" | 14 #include "base/string_number_conversions.h" |
15 #include "base/sys_info.h" | |
16 #include "content/common/gpu/gpu_channel_manager.h" | 15 #include "content/common/gpu/gpu_channel_manager.h" |
17 #include "content/common/gpu/gpu_memory_allocation.h" | 16 #include "content/common/gpu/gpu_memory_allocation.h" |
18 #include "content/common/gpu/gpu_memory_manager_client.h" | 17 #include "content/common/gpu/gpu_memory_manager_client.h" |
19 #include "content/common/gpu/gpu_memory_tracking.h" | 18 #include "content/common/gpu/gpu_memory_tracking.h" |
20 #include "content/common/gpu/gpu_memory_uma_stats.h" | 19 #include "content/common/gpu/gpu_memory_uma_stats.h" |
21 #include "content/common/gpu/gpu_messages.h" | 20 #include "content/common/gpu/gpu_messages.h" |
22 #include "gpu/command_buffer/service/gpu_switches.h" | 21 #include "gpu/command_buffer/service/gpu_switches.h" |
23 | 22 |
24 namespace content { | 23 namespace content { |
25 namespace { | 24 namespace { |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
144 #if defined(OS_ANDROID) || defined(OS_CHROMEOS) | 143 #if defined(OS_ANDROID) || defined(OS_CHROMEOS) |
145 return bytes_available_gpu_memory_; | 144 return bytes_available_gpu_memory_; |
146 #else | 145 #else |
147 // This is to avoid allowing a single page on to use a full 256MB of memory | 146 // 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, | 147 // (the current total limit). Long-scroll pages will hit this limit, |
149 // resulting in instability on some platforms (e.g, issue 141377). | 148 // resulting in instability on some platforms (e.g, issue 141377). |
150 return bytes_available_gpu_memory_ / 2; | 149 return bytes_available_gpu_memory_ / 2; |
151 #endif | 150 #endif |
152 } | 151 } |
153 | 152 |
154 uint64 GpuMemoryManager::CalcAvailableFromViewportArea(int viewport_area) { | |
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) | |
165 return viewport_limit; | |
166 #else | |
167 static uint64 dalvik_limit = 0; | |
168 if (!dalvik_limit) | |
169 dalvik_limit = (base::SysInfo::DalvikHeapSizeMB() / 2) * 1024 * 1024; | |
170 return std::min(viewport_limit, dalvik_limit); | |
171 #endif | |
172 } | |
173 | |
174 uint64 GpuMemoryManager::CalcAvailableFromGpuTotal(uint64 total_gpu_memory) { | 153 uint64 GpuMemoryManager::CalcAvailableFromGpuTotal(uint64 total_gpu_memory) { |
175 // Allow Chrome to use 75% of total GPU memory, or all-but-64MB of GPU | 154 // Allow Chrome to use 75% of total GPU memory, or all-but-64MB of GPU |
176 // memory, whichever is less. | 155 // memory, whichever is less. |
177 return std::min(3 * total_gpu_memory / 4, total_gpu_memory - 64*1024*1024); | 156 return std::min(3 * total_gpu_memory / 4, total_gpu_memory - 64*1024*1024); |
178 } | 157 } |
179 | 158 |
180 void GpuMemoryManager::UpdateAvailableGpuMemory() { | 159 void GpuMemoryManager::UpdateAvailableGpuMemory() { |
181 // If the amount of video memory to use was specified at the command | 160 // If the amount of video memory to use was specified at the command |
182 // line, never change it. | 161 // line, never change it. |
183 if (bytes_available_gpu_memory_overridden_) | 162 if (bytes_available_gpu_memory_overridden_) |
184 return; | 163 return; |
185 | 164 |
186 #if defined(OS_ANDROID) | |
187 // On Android we use the surface size, so this finds the largest visible | |
188 // surface size instead of lowest gpu's limit. | |
189 int max_surface_area = 0; | |
190 #else | |
191 // On non-Android, we use an operating system query when possible. | 165 // On non-Android, we use an operating system query when possible. |
192 // We do not have a reliable concept of multiple GPUs existing in | 166 // 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. | 167 // a system, so just be safe and go with the minimum encountered. |
194 uint64 bytes_min = 0; | 168 uint64 bytes_min = 0; |
195 #endif | |
196 | 169 |
197 // Only use the clients that are visible, because otherwise the set of clients | 170 // Only use the clients that are visible, because otherwise the set of clients |
198 // we are querying could become extremely large. | 171 // we are querying could become extremely large. |
199 for (ClientStateList::const_iterator it = clients_visible_mru_.begin(); | 172 for (ClientStateList::const_iterator it = clients_visible_mru_.begin(); |
200 it != clients_visible_mru_.end(); | 173 it != clients_visible_mru_.end(); |
201 ++it) { | 174 ++it) { |
202 const GpuMemoryManagerClientState* client_state = *it; | 175 const GpuMemoryManagerClientState* client_state = *it; |
203 if (!client_state->has_surface_) | 176 if (!client_state->has_surface_) |
204 continue; | 177 continue; |
205 if (!client_state->visible_) | 178 if (!client_state->visible_) |
206 continue; | 179 continue; |
207 | 180 |
208 #if defined(OS_ANDROID) | |
209 gfx::Size surface_size = client_state->client_->GetSurfaceSize(); | |
210 max_surface_area = std::max(max_surface_area, surface_size.width() * | |
211 surface_size.height()); | |
212 #else | |
213 uint64 bytes = 0; | 181 uint64 bytes = 0; |
214 if (client_state->client_->GetTotalGpuMemory(&bytes)) { | 182 if (client_state->client_->GetTotalGpuMemory(&bytes)) { |
215 if (!bytes_min || bytes < bytes_min) | 183 if (!bytes_min || bytes < bytes_min) |
216 bytes_min = bytes; | 184 bytes_min = bytes; |
217 } | 185 } |
218 #endif | |
219 } | 186 } |
220 | 187 |
221 #if defined(OS_ANDROID) | |
222 bytes_available_gpu_memory_ = CalcAvailableFromViewportArea(max_surface_area); | |
223 #else | |
224 if (!bytes_min) | 188 if (!bytes_min) |
225 return; | 189 return; |
226 | 190 |
191 #if defined(OS_ANDROID) | |
192 // We don't need to reduce the total on Android, since | |
ccameron
2013/02/12 01:56:23
Nit: can you put this #if inside CalcAvialbleFromG
| |
193 // the total is an estimate to begin with. | |
194 bytes_available_gpu_memory_ = bytes_min; | |
195 #else | |
227 bytes_available_gpu_memory_ = CalcAvailableFromGpuTotal(bytes_min); | 196 bytes_available_gpu_memory_ = CalcAvailableFromGpuTotal(bytes_min); |
228 #endif | 197 #endif |
229 | 198 |
230 // Never go below the default allocation | 199 // Never go below the default allocation |
231 bytes_available_gpu_memory_ = std::max(bytes_available_gpu_memory_, | 200 bytes_available_gpu_memory_ = std::max(bytes_available_gpu_memory_, |
232 GetDefaultAvailableGpuMemory()); | 201 GetDefaultAvailableGpuMemory()); |
233 | 202 |
234 // Never go above the maximum. | 203 // Never go above the maximum. |
235 bytes_available_gpu_memory_ = std::min(bytes_available_gpu_memory_, | 204 bytes_available_gpu_memory_ = std::min(bytes_available_gpu_memory_, |
236 GetMaximumTotalGpuMemory()); | 205 GetMaximumTotalGpuMemory()); |
(...skipping 809 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1046 | 1015 |
1047 void GpuMemoryManager::RemoveClientFromList( | 1016 void GpuMemoryManager::RemoveClientFromList( |
1048 GpuMemoryManagerClientState* client_state) { | 1017 GpuMemoryManagerClientState* client_state) { |
1049 DCHECK(client_state->list_iterator_valid_); | 1018 DCHECK(client_state->list_iterator_valid_); |
1050 ClientStateList* client_list = GetClientList(client_state); | 1019 ClientStateList* client_list = GetClientList(client_state); |
1051 client_list->erase(client_state->list_iterator_); | 1020 client_list->erase(client_state->list_iterator_); |
1052 client_state->list_iterator_valid_ = false; | 1021 client_state->list_iterator_valid_ = false; |
1053 } | 1022 } |
1054 | 1023 |
1055 } // namespace content | 1024 } // namespace content |
OLD | NEW |