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

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

Issue 11293194: ui: Prefer +/- operators to apply offsets. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: floats Created 8 years, 1 month 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 #if defined(ENABLE_GPU) 7 #if defined(ENABLE_GPU)
8 8
9 #include <algorithm> 9 #include <algorithm>
10 10
(...skipping 20 matching lines...) Expand all
31 31
32 } 32 }
33 33
34 GpuMemoryManager::GpuMemoryManager( 34 GpuMemoryManager::GpuMemoryManager(
35 size_t max_surfaces_with_frontbuffer_soft_limit) 35 size_t max_surfaces_with_frontbuffer_soft_limit)
36 : manage_immediate_scheduled_(false), 36 : manage_immediate_scheduled_(false),
37 max_surfaces_with_frontbuffer_soft_limit_( 37 max_surfaces_with_frontbuffer_soft_limit_(
38 max_surfaces_with_frontbuffer_soft_limit), 38 max_surfaces_with_frontbuffer_soft_limit),
39 bytes_available_gpu_memory_(0), 39 bytes_available_gpu_memory_(0),
40 bytes_available_gpu_memory_overridden_(false), 40 bytes_available_gpu_memory_overridden_(false),
41 bytes_backgrounded_available_gpu_memory_(0),
41 bytes_allocated_current_(0), 42 bytes_allocated_current_(0),
42 bytes_allocated_managed_visible_(0), 43 bytes_allocated_managed_visible_(0),
43 bytes_allocated_managed_backgrounded_(0), 44 bytes_allocated_managed_backgrounded_(0),
44 window_count_has_been_received_(false), 45 window_count_has_been_received_(false),
45 window_count_(0), 46 window_count_(0),
46 disable_schedule_manage_(false) 47 disable_schedule_manage_(false)
47 { 48 {
48 CommandLine* command_line = CommandLine::ForCurrentProcess(); 49 CommandLine* command_line = CommandLine::ForCurrentProcess();
49 if (command_line->HasSwitch(switches::kForceGpuMemAvailableMb)) { 50 if (command_line->HasSwitch(switches::kForceGpuMemAvailableMb)) {
50 base::StringToSizeT( 51 base::StringToSizeT(
51 command_line->GetSwitchValueASCII(switches::kForceGpuMemAvailableMb), 52 command_line->GetSwitchValueASCII(switches::kForceGpuMemAvailableMb),
52 &bytes_available_gpu_memory_); 53 &bytes_available_gpu_memory_);
53 bytes_available_gpu_memory_ *= 1024 * 1024; 54 bytes_available_gpu_memory_ *= 1024 * 1024;
54 bytes_available_gpu_memory_overridden_ = true; 55 bytes_available_gpu_memory_overridden_ = true;
55 } else 56 } else
56 bytes_available_gpu_memory_ = GetDefaultAvailableGpuMemory(); 57 bytes_available_gpu_memory_ = GetDefaultAvailableGpuMemory();
58 UpdateBackgroundedAvailableGpuMemory();
57 } 59 }
58 60
59 GpuMemoryManager::~GpuMemoryManager() { 61 GpuMemoryManager::~GpuMemoryManager() {
60 DCHECK(tracking_groups_.empty()); 62 DCHECK(tracking_groups_.empty());
61 DCHECK(clients_.empty()); 63 DCHECK(clients_.empty());
62 DCHECK(!bytes_allocated_current_); 64 DCHECK(!bytes_allocated_current_);
63 DCHECK(!bytes_allocated_managed_visible_); 65 DCHECK(!bytes_allocated_managed_visible_);
64 DCHECK(!bytes_allocated_managed_backgrounded_); 66 DCHECK(!bytes_allocated_managed_backgrounded_);
65 } 67 }
66 68
67 size_t GpuMemoryManager::GetAvailableGpuMemory() const { 69 size_t GpuMemoryManager::GetAvailableGpuMemory() const {
68 return bytes_available_gpu_memory_; 70 return bytes_available_gpu_memory_;
69 } 71 }
70 72
73 size_t GpuMemoryManager::GetCurrentBackgroundedAvailableGpuMemory() const {
74 if (bytes_allocated_managed_visible_ < GetAvailableGpuMemory()) {
75 return std::min(bytes_backgrounded_available_gpu_memory_,
76 GetAvailableGpuMemory() - bytes_allocated_managed_visible_);
77 }
78 return 0;
79 }
80
71 size_t GpuMemoryManager::GetDefaultAvailableGpuMemory() const { 81 size_t GpuMemoryManager::GetDefaultAvailableGpuMemory() const {
72 #if defined(OS_ANDROID) 82 #if defined(OS_ANDROID)
73 return 32 * 1024 * 1024; 83 return 32 * 1024 * 1024;
74 #elif defined(OS_CHROMEOS) 84 #elif defined(OS_CHROMEOS)
75 return 1024 * 1024 * 1024; 85 return 1024 * 1024 * 1024;
76 #else 86 #else
77 return 256 * 1024 * 1024; 87 return 256 * 1024 * 1024;
78 #endif 88 #endif
79 } 89 }
80 90
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 bytes_available_gpu_memory_ = CalcAvailableFromGpuTotal(bytes_min); 193 bytes_available_gpu_memory_ = CalcAvailableFromGpuTotal(bytes_min);
184 #endif 194 #endif
185 195
186 // Never go below the default allocation 196 // Never go below the default allocation
187 bytes_available_gpu_memory_ = std::max(bytes_available_gpu_memory_, 197 bytes_available_gpu_memory_ = std::max(bytes_available_gpu_memory_,
188 GetDefaultAvailableGpuMemory()); 198 GetDefaultAvailableGpuMemory());
189 199
190 // Never go above the maximum. 200 // Never go above the maximum.
191 bytes_available_gpu_memory_ = std::min(bytes_available_gpu_memory_, 201 bytes_available_gpu_memory_ = std::min(bytes_available_gpu_memory_,
192 GetMaximumTotalGpuMemory()); 202 GetMaximumTotalGpuMemory());
203
204 // Update the backgrounded available gpu memory because it depends on
205 // the available GPU memory.
206 UpdateBackgroundedAvailableGpuMemory();
207 }
208
209 void GpuMemoryManager::UpdateBackgroundedAvailableGpuMemory() {
210 // Be conservative and disable saving backgrounded tabs' textures on Android
211 // for the moment
212 #if defined(OS_ANDROID)
213 bytes_backgrounded_available_gpu_memory_ = 0;
214 #else
215 bytes_backgrounded_available_gpu_memory_ = bytes_available_gpu_memory_ / 4;
216 #endif
193 } 217 }
194 218
195 bool GpuMemoryManager::ClientsComparator::operator()( 219 bool GpuMemoryManager::ClientsComparator::operator()(
196 ClientState* lhs, 220 ClientState* lhs,
197 ClientState* rhs) { 221 ClientState* rhs) {
198 if (lhs->has_surface != rhs->has_surface) 222 if (lhs->has_surface != rhs->has_surface)
199 return lhs->has_surface > rhs->has_surface; 223 return lhs->has_surface > rhs->has_surface;
200 if (lhs->visible != rhs->visible) 224 if (lhs->visible != rhs->visible)
201 return lhs->visible > rhs->visible; 225 return lhs->visible > rhs->visible;
202 if (lhs->last_used_time != rhs->last_used_time) 226 if (lhs->last_used_time != rhs->last_used_time)
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
271 void GpuMemoryManager::SetClientVisible(GpuMemoryManagerClient* client, 295 void GpuMemoryManager::SetClientVisible(GpuMemoryManagerClient* client,
272 bool visible) 296 bool visible)
273 { 297 {
274 ClientMap::const_iterator it = clients_.find(client); 298 ClientMap::const_iterator it = clients_.find(client);
275 if (it == clients_.end()) 299 if (it == clients_.end())
276 return; 300 return;
277 ClientState* client_state = it->second; 301 ClientState* client_state = it->second;
278 if (client_state->visible == visible) 302 if (client_state->visible == visible)
279 return; 303 return;
280 client_state->visible = visible; 304 client_state->visible = visible;
305 client_state->last_used_time = base::TimeTicks::Now();
281 TrackValueChanged(client_state->managed_memory_stats.bytes_allocated, 0, 306 TrackValueChanged(client_state->managed_memory_stats.bytes_allocated, 0,
282 client_state->visible ? 307 client_state->visible ?
283 &bytes_allocated_managed_backgrounded_ : 308 &bytes_allocated_managed_backgrounded_ :
284 &bytes_allocated_managed_visible_); 309 &bytes_allocated_managed_visible_);
285 TrackValueChanged(0, client_state->managed_memory_stats.bytes_allocated, 310 TrackValueChanged(0, client_state->managed_memory_stats.bytes_allocated,
286 client_state->visible ? 311 client_state->visible ?
287 &bytes_allocated_managed_visible_ : 312 &bytes_allocated_managed_visible_ :
288 &bytes_allocated_managed_backgrounded_); 313 &bytes_allocated_managed_backgrounded_);
289 ScheduleManage(visible); 314 ScheduleManage(visible);
290 } 315 }
291 316
292 void GpuMemoryManager::SetClientManagedMemoryStats( 317 void GpuMemoryManager::SetClientManagedMemoryStats(
293 GpuMemoryManagerClient* client, 318 GpuMemoryManagerClient* client,
294 const GpuManagedMemoryStats& stats) 319 const GpuManagedMemoryStats& stats)
295 { 320 {
296 ClientMap::const_iterator it = clients_.find(client); 321 ClientMap::const_iterator it = clients_.find(client);
297 if (it == clients_.end()) 322 if (it == clients_.end())
298 return; 323 return;
299 ClientState* client_state = it->second; 324 ClientState* client_state = it->second;
300 TrackValueChanged(client_state->managed_memory_stats.bytes_allocated, 325 TrackValueChanged(client_state->managed_memory_stats.bytes_allocated,
301 stats.bytes_allocated, 326 stats.bytes_allocated,
302 client_state->visible ? 327 client_state->visible ?
303 &bytes_allocated_managed_visible_ : 328 &bytes_allocated_managed_visible_ :
304 &bytes_allocated_managed_backgrounded_); 329 &bytes_allocated_managed_backgrounded_);
305 client_state->managed_memory_stats = stats; 330 client_state->managed_memory_stats = stats;
331
332 // If this allocation pushed our usage of backgrounded tabs memory over the
333 // limit, then schedule a drop of backgrounded memory.
334 if (bytes_allocated_managed_backgrounded_ >
335 GetCurrentBackgroundedAvailableGpuMemory())
336 ScheduleManage(false);
306 } 337 }
307 338
308 void GpuMemoryManager::TestingSetClientVisible( 339 void GpuMemoryManager::TestingSetClientVisible(
309 GpuMemoryManagerClient* client, bool visible) { 340 GpuMemoryManagerClient* client, bool visible) {
310 DCHECK(clients_.count(client)); 341 DCHECK(clients_.count(client));
311 clients_[client]->visible = visible; 342 clients_[client]->visible = visible;
312 } 343 }
313 344
314 void GpuMemoryManager::TestingSetClientLastUsedTime( 345 void GpuMemoryManager::TestingSetClientLastUsedTime(
315 GpuMemoryManagerClient* client, base::TimeTicks last_used_time) { 346 GpuMemoryManagerClient* client, base::TimeTicks last_used_time) {
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
415 DCHECK(std::unique(clients.begin(), clients.end()) == clients.end()); 446 DCHECK(std::unique(clients.begin(), clients.end()) == clients.end());
416 447
417 // Update the amount of GPU memory available on the system. 448 // Update the amount of GPU memory available on the system.
418 UpdateAvailableGpuMemory(clients); 449 UpdateAvailableGpuMemory(clients);
419 450
420 // Determine which clients are "hibernated" (which determines the 451 // Determine which clients are "hibernated" (which determines the
421 // distribution of frontbuffers and memory among clients that don't have 452 // distribution of frontbuffers and memory among clients that don't have
422 // surfaces). 453 // surfaces).
423 SetClientsHibernatedState(clients); 454 SetClientsHibernatedState(clients);
424 455
425 // Determine how much memory to assign to give to visible clients 456 // Determine how much memory to assign to give to visible and backgrounded
457 // clients.
426 size_t bytes_limit_when_visible = GetVisibleClientAllocation(clients); 458 size_t bytes_limit_when_visible = GetVisibleClientAllocation(clients);
427 459
428 // Now give out allocations to everyone. 460 // Now give out allocations to everyone.
461 size_t bytes_allocated_backgrounded = 0;
429 for (ClientStateVector::iterator it = clients.begin(); 462 for (ClientStateVector::iterator it = clients.begin();
430 it != clients.end(); 463 it != clients.end();
431 ++it) { 464 ++it) {
432 ClientState* client_state = *it; 465 ClientState* client_state = *it;
433
434 GpuMemoryAllocation allocation; 466 GpuMemoryAllocation allocation;
435 if (client_state->has_surface) { 467 if (client_state->has_surface) {
436 allocation.browser_allocation.suggest_have_frontbuffer = 468 allocation.browser_allocation.suggest_have_frontbuffer =
437 !client_state->hibernated; 469 !client_state->hibernated;
470
471 // Set the state when visible.
438 allocation.renderer_allocation.bytes_limit_when_visible = 472 allocation.renderer_allocation.bytes_limit_when_visible =
439 bytes_limit_when_visible; 473 bytes_limit_when_visible;
440 allocation.renderer_allocation.priority_cutoff_when_visible = 474 allocation.renderer_allocation.priority_cutoff_when_visible =
441 GpuMemoryAllocationForRenderer::kPriorityCutoffAllowEverything; 475 GpuMemoryAllocationForRenderer::kPriorityCutoffAllowEverything;
442 allocation.renderer_allocation.bytes_limit_when_not_visible = 476
443 0; 477 // Set the state when backgrounded.
444 allocation.renderer_allocation.priority_cutoff_when_not_visible = 478 bool allow_allocation_when_backgrounded = false;
445 GpuMemoryAllocationForRenderer::kPriorityCutoffAllowNothing; 479 if (client_state->visible) {
480 // If the client is visible, then allow it to keep its textures, should
481 // it be backgrounded, but only if all textures required to draw will
482 // fit in total backgrounded memory limit.
483 allow_allocation_when_backgrounded =
484 client_state->managed_memory_stats.bytes_required <
485 bytes_backgrounded_available_gpu_memory_;
486 } else {
487 // If the client is backgrounded, then allow it to keep its textures
488 // if everything required to draw fits in-budget.
489 allow_allocation_when_backgrounded =
490 client_state->managed_memory_stats.bytes_required +
491 bytes_allocated_backgrounded <
492 GetCurrentBackgroundedAvailableGpuMemory();
493 if (allow_allocation_when_backgrounded) {
494 bytes_allocated_backgrounded +=
495 client_state->managed_memory_stats.bytes_allocated;
496 }
497 }
498 if (allow_allocation_when_backgrounded) {
499 allocation.renderer_allocation.bytes_limit_when_not_visible =
500 GetCurrentBackgroundedAvailableGpuMemory();
501 allocation.renderer_allocation.priority_cutoff_when_not_visible =
502 GpuMemoryAllocationForRenderer::kPriorityCutoffAllowOnlyRequired;
503 } else {
504 allocation.renderer_allocation.bytes_limit_when_not_visible = 0;
505 allocation.renderer_allocation.priority_cutoff_when_not_visible =
506 GpuMemoryAllocationForRenderer::kPriorityCutoffAllowNothing;
507 }
446 } else { 508 } else {
447 if (!client_state->hibernated) { 509 if (!client_state->hibernated) {
448 allocation.renderer_allocation.bytes_limit_when_visible = 510 allocation.renderer_allocation.bytes_limit_when_visible =
449 GetMinimumTabAllocation(); 511 GetMinimumTabAllocation();
450 allocation.renderer_allocation.priority_cutoff_when_visible = 512 allocation.renderer_allocation.priority_cutoff_when_visible =
451 GpuMemoryAllocationForRenderer::kPriorityCutoffAllowEverything; 513 GpuMemoryAllocationForRenderer::kPriorityCutoffAllowEverything;
452 } 514 }
453 } 515 }
454 client_state->client->SetMemoryAllocation(allocation); 516 client_state->client->SetMemoryAllocation(allocation);
455 } 517 }
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 : client(client), 604 : client(client),
543 has_surface(has_surface), 605 has_surface(has_surface),
544 visible(visible), 606 visible(visible),
545 last_used_time(last_used_time), 607 last_used_time(last_used_time),
546 hibernated(false) { 608 hibernated(false) {
547 } 609 }
548 610
549 } // namespace content 611 } // namespace content
550 612
551 #endif 613 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698