15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_memory_manager.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/debug/trace_event.h" 129ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 1358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch#include "base/process/process_handle.h" 147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/string_number_conversions.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/common/gpu/gpu_channel_manager.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/common/gpu/gpu_memory_manager_client.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_memory_tracking.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/common/gpu/gpu_memory_uma_stats.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/common/gpu/gpu_messages.h" 201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "gpu/command_buffer/common/gpu_memory_allocation.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/gpu_switches.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)using gpu::MemoryAllocation; 241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kDelayedScheduleManageTimeoutMs = 67; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const uint64 kBytesAllocatedUnmanagedStep = 16 * 1024 * 1024; 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TrackValueChanged(uint64 old_size, uint64 new_size, uint64* total_size) { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(new_size > old_size || *total_size >= (old_size - new_size)); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *total_size += (new_size - old_size); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuMemoryManager::GpuMemoryManager( 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GpuChannelManager* channel_manager, 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint64 max_surfaces_with_frontbuffer_soft_limit) 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : channel_manager_(channel_manager), 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) manage_immediate_scheduled_(false), 44f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) disable_schedule_manage_(false), 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_surfaces_with_frontbuffer_soft_limit_( 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_surfaces_with_frontbuffer_soft_limit), 47f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) client_hard_limit_bytes_(0), 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bytes_allocated_managed_current_(0), 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bytes_allocated_unmanaged_current_(0), 50f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bytes_allocated_historical_max_(0) 51f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles){ } 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuMemoryManager::~GpuMemoryManager() { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(tracking_groups_.empty()); 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(clients_visible_mru_.empty()); 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(clients_nonvisible_mru_.empty()); 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(clients_nonsurface_.empty()); 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!bytes_allocated_managed_current_); 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!bytes_allocated_unmanaged_current_); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GpuMemoryManager::UpdateAvailableGpuMemory() { 63f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // If the value was overridden on the command line, use the specified value. 64f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) static bool client_hard_limit_bytes_overridden = 656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::CommandLine::ForCurrentProcess()->HasSwitch( 66f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) switches::kForceGpuMemAvailableMb); 67f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (client_hard_limit_bytes_overridden) { 68f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::StringToUint64( 696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( 70f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) switches::kForceGpuMemAvailableMb), 71f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) &client_hard_limit_bytes_); 72f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) client_hard_limit_bytes_ *= 1024 * 1024; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 74f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 76f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#if defined(OS_ANDROID) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // On non-Android, we use an operating system query when possible. 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We do not have a reliable concept of multiple GPUs existing in 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a system, so just be safe and go with the minimum encountered. 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint64 bytes_min = 0; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only use the clients that are visible, because otherwise the set of clients 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we are querying could become extremely large. 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (ClientStateList::const_iterator it = clients_visible_mru_.begin(); 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != clients_visible_mru_.end(); 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++it) { 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GpuMemoryManagerClientState* client_state = *it; 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!client_state->has_surface_) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!client_state->visible_) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint64 bytes = 0; 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (client_state->client_->GetTotalGpuMemory(&bytes)) { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!bytes_min || bytes < bytes_min) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_min = bytes; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 100f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) client_hard_limit_bytes_ = bytes_min; 101f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Clamp the observed value to a specific range on Android. 102f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) client_hard_limit_bytes_ = std::max(client_hard_limit_bytes_, 103f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) static_cast<uint64>(16 * 1024 * 1024)); 104f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) client_hard_limit_bytes_ = std::min(client_hard_limit_bytes_, 105f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) static_cast<uint64>(256 * 1024 * 1024)); 106f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#else 107f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Ignore what the system said and give all clients the same maximum 108f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // allocation on desktop platforms. 1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci client_hard_limit_bytes_ = 512 * 1024 * 1024; 110f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GpuMemoryManager::ScheduleManage( 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScheduleManageTime schedule_manage_time) { 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (disable_schedule_manage_) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (manage_immediate_scheduled_) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (schedule_manage_time == kScheduleManageNow) { 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::current()->PostTask( 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, base::Bind(&GpuMemoryManager::Manage, AsWeakPtr())); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manage_immediate_scheduled_ = true; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!delayed_manage_callback_.IsCancelled()) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delayed_manage_callback_.Cancel(); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!delayed_manage_callback_.IsCancelled()) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delayed_manage_callback_.Reset(base::Bind(&GpuMemoryManager::Manage, 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AsWeakPtr())); 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) delayed_manage_callback_.callback(), 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::TimeDelta::FromMilliseconds(kDelayedScheduleManageTimeoutMs)); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GpuMemoryManager::TrackMemoryAllocatedChange( 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GpuMemoryTrackingGroup* tracking_group, 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint64 old_size, 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint64 new_size, 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gpu::gles2::MemoryTracker::Pool tracking_pool) { 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TrackValueChanged(old_size, new_size, &tracking_group->size_); 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (tracking_pool) { 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case gpu::gles2::MemoryTracker::kManaged: 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TrackValueChanged(old_size, new_size, &bytes_allocated_managed_current_); 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case gpu::gles2::MemoryTracker::kUnmanaged: 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TrackValueChanged(old_size, 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new_size, 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &bytes_allocated_unmanaged_current_); 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED(); 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (new_size != old_size) { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_COUNTER1("gpu", 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "GpuMemoryUsage", 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetCurrentUsage()); 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 162f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (GetCurrentUsage() > bytes_allocated_historical_max_ + 163f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) kBytesAllocatedUnmanagedStep) { 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bytes_allocated_historical_max_ = GetCurrentUsage(); 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If we're blowing into new memory usage territory, spam the browser 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // process with the most up-to-date information about our memory usage. 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendUmaStatsToBrowser(); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuMemoryManager::EnsureGPUMemoryAvailable(uint64 /* size_needed */) { 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO: Check if there is enough space. Lose contexts until there is. 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuMemoryManagerClientState* GpuMemoryManager::CreateClientState( 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GpuMemoryManagerClient* client, 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool has_surface, 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool visible) { 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TrackingGroupMap::iterator tracking_group_it = 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tracking_groups_.find(client->GetMemoryTracker()); 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(tracking_group_it != tracking_groups_.end()); 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GpuMemoryTrackingGroup* tracking_group = tracking_group_it->second; 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GpuMemoryManagerClientState* client_state = new GpuMemoryManagerClientState( 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, client, tracking_group, has_surface, visible); 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AddClientToList(client_state); 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScheduleManage(kScheduleManageNow); 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return client_state; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GpuMemoryManager::OnDestroyClientState( 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GpuMemoryManagerClientState* client_state) { 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RemoveClientFromList(client_state); 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScheduleManage(kScheduleManageLater); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GpuMemoryManager::SetClientStateVisible( 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GpuMemoryManagerClientState* client_state, bool visible) { 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(client_state->has_surface_); 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (client_state->visible_ == visible) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RemoveClientFromList(client_state); 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_state->visible_ = visible; 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AddClientToList(client_state); 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScheduleManage(visible ? kScheduleManageNow : kScheduleManageLater); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 210a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)uint64 GpuMemoryManager::GetClientMemoryUsage( 211effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const GpuMemoryManagerClient* client) const { 212a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) TrackingGroupMap::const_iterator tracking_group_it = 213a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) tracking_groups_.find(client->GetMemoryTracker()); 214a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(tracking_group_it != tracking_groups_.end()); 215a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return tracking_group_it->second->GetSize(); 216a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 217a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuMemoryTrackingGroup* GpuMemoryManager::CreateTrackingGroup( 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ProcessId pid, gpu::gles2::MemoryTracker* memory_tracker) { 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GpuMemoryTrackingGroup* tracking_group = new GpuMemoryTrackingGroup( 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pid, memory_tracker, this); 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!tracking_groups_.count(tracking_group->GetMemoryTracker())); 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tracking_groups_.insert(std::make_pair(tracking_group->GetMemoryTracker(), 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tracking_group)); 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return tracking_group; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GpuMemoryManager::OnDestroyTrackingGroup( 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuMemoryTrackingGroup* tracking_group) { 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(tracking_groups_.count(tracking_group->GetMemoryTracker())); 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tracking_groups_.erase(tracking_group->GetMemoryTracker()); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuMemoryManager::GetVideoMemoryUsageStats( 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GPUVideoMemoryUsageStats* video_memory_usage_stats) const { 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For each context group, assign its memory usage to its PID 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) video_memory_usage_stats->process_map.clear(); 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (TrackingGroupMap::const_iterator i = 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tracking_groups_.begin(); i != tracking_groups_.end(); ++i) { 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GpuMemoryTrackingGroup* tracking_group = i->second; 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) video_memory_usage_stats->process_map[ 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tracking_group->GetPid()].video_memory += tracking_group->GetSize(); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Assign the total across all processes in the GPU process 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) video_memory_usage_stats->process_map[ 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::GetCurrentProcId()].video_memory = GetCurrentUsage(); 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) video_memory_usage_stats->process_map[ 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::GetCurrentProcId()].has_duplicates = true; 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) video_memory_usage_stats->bytes_allocated = GetCurrentUsage(); 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) video_memory_usage_stats->bytes_allocated_historical_max = 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bytes_allocated_historical_max_; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuMemoryManager::Manage() { 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manage_immediate_scheduled_ = false; 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delayed_manage_callback_.Cancel(); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Update the amount of GPU memory available on the system. 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateAvailableGpuMemory(); 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Determine which clients are "hibernated" (which determines the 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // distribution of frontbuffers and memory among clients that don't have 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // surfaces). 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetClientsHibernatedState(); 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Assign memory allocations to clients that have surfaces. 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AssignSurfacesAllocations(); 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Assign memory allocations to clients that don't have surfaces. 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AssignNonSurfacesAllocations(); 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendUmaStatsToBrowser(); 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GpuMemoryManager::AssignSurfacesAllocations() { 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Send that allocation to the clients. 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClientStateList clients = clients_visible_mru_; 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) clients.insert(clients.end(), 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) clients_nonvisible_mru_.begin(), 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) clients_nonvisible_mru_.end()); 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (ClientStateList::const_iterator it = clients.begin(); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != clients.end(); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++it) { 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GpuMemoryManagerClientState* client_state = *it; 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Populate and send the allocation to the client 2891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) MemoryAllocation allocation; 290f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) allocation.bytes_limit_when_visible = client_hard_limit_bytes_; 291f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#if defined(OS_ANDROID) 292f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // On Android, because there is only one visible tab at any time, allow 293f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // that renderer to cache as much as it can. 294f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) allocation.priority_cutoff_when_visible = 295f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MemoryAllocation::CUTOFF_ALLOW_EVERYTHING; 296f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#else 297f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // On desktop platforms, instruct the renderers to cache only a smaller 298f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // set, to play nice with other renderers and other applications. If this 299f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // if not done, then the system can become unstable. 300f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // http://crbug.com/145600 (Linux) 301f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // http://crbug.com/141377 (Mac) 302f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) allocation.priority_cutoff_when_visible = 303f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE; 304f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_state->client_->SetMemoryAllocation(allocation); 3071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) client_state->client_->SuggestHaveFrontBuffer(!client_state->hibernated_); 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GpuMemoryManager::AssignNonSurfacesAllocations() { 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (ClientStateList::const_iterator it = clients_nonsurface_.begin(); 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != clients_nonsurface_.end(); 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++it) { 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GpuMemoryManagerClientState* client_state = *it; 3161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) MemoryAllocation allocation; 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!client_state->hibernated_) { 319f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) allocation.bytes_limit_when_visible = client_hard_limit_bytes_; 3201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) allocation.priority_cutoff_when_visible = 3211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) MemoryAllocation::CUTOFF_ALLOW_EVERYTHING; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_state->client_->SetMemoryAllocation(allocation); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GpuMemoryManager::SetClientsHibernatedState() const { 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Re-set all tracking groups as being hibernated. 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (TrackingGroupMap::const_iterator it = tracking_groups_.begin(); 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != tracking_groups_.end(); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++it) { 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GpuMemoryTrackingGroup* tracking_group = it->second; 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tracking_group->hibernated_ = true; 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // All clients with surfaces that are visible are non-hibernated. 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint64 non_hibernated_clients = 0; 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (ClientStateList::const_iterator it = clients_visible_mru_.begin(); 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != clients_visible_mru_.end(); 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++it) { 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GpuMemoryManagerClientState* client_state = *it; 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_state->hibernated_ = false; 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_state->tracking_group_->hibernated_ = false; 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) non_hibernated_clients++; 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Then an additional few clients with surfaces are non-hibernated too, up to 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // a fixed limit. 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (ClientStateList::const_iterator it = clients_nonvisible_mru_.begin(); 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != clients_nonvisible_mru_.end(); 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++it) { 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GpuMemoryManagerClientState* client_state = *it; 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (non_hibernated_clients < max_surfaces_with_frontbuffer_soft_limit_) { 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_state->hibernated_ = false; 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_state->tracking_group_->hibernated_ = false; 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) non_hibernated_clients++; 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_state->hibernated_ = true; 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Clients that don't have surfaces are non-hibernated if they are 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // in a GL share group with a non-hibernated surface. 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (ClientStateList::const_iterator it = clients_nonsurface_.begin(); 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != clients_nonsurface_.end(); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++it) { 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GpuMemoryManagerClientState* client_state = *it; 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_state->hibernated_ = client_state->tracking_group_->hibernated_; 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GpuMemoryManager::SendUmaStatsToBrowser() { 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!channel_manager_) 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GPUMemoryUmaStats params; 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.bytes_allocated_current = GetCurrentUsage(); 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.bytes_allocated_max = bytes_allocated_historical_max_; 376f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) params.bytes_limit = client_hard_limit_bytes_; 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.client_count = clients_visible_mru_.size() + 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) clients_nonvisible_mru_.size() + 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) clients_nonsurface_.size(); 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.context_group_count = tracking_groups_.size(); 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) channel_manager_->Send(new GpuHostMsg_GpuMemoryUmaStats(params)); 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuMemoryManager::ClientStateList* GpuMemoryManager::GetClientList( 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GpuMemoryManagerClientState* client_state) { 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (client_state->has_surface_) { 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (client_state->visible_) 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return &clients_visible_mru_; 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return &clients_nonvisible_mru_; 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return &clients_nonsurface_; 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GpuMemoryManager::AddClientToList( 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GpuMemoryManagerClientState* client_state) { 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!client_state->list_iterator_valid_); 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClientStateList* client_list = GetClientList(client_state); 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_state->list_iterator_ = client_list->insert( 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_list->begin(), client_state); 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_state->list_iterator_valid_ = true; 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GpuMemoryManager::RemoveClientFromList( 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GpuMemoryManagerClientState* client_state) { 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(client_state->list_iterator_valid_); 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClientStateList* client_list = GetClientList(client_state); 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_list->erase(client_state->list_iterator_); 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_state->list_iterator_valid_ = false; 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 413