gpu_memory_manager.h revision 5821806d5e7f356e8fa4b058a389a808ea183019
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 3// found in the LICENSE file. 4 5#ifndef CONTENT_COMMON_GPU_GPU_MEMORY_MANAGER_H_ 6#define CONTENT_COMMON_GPU_GPU_MEMORY_MANAGER_H_ 7 8#if defined(ENABLE_GPU) 9 10#include <set> 11#include <vector> 12 13#include "base/basictypes.h" 14#include "base/cancelable_callback.h" 15#include "base/gtest_prod_util.h" 16#include "base/hash_tables.h" 17#include "base/memory/weak_ptr.h" 18#include "content/common/content_export.h" 19#include "content/common/gpu/gpu_memory_allocation.h" 20#include "content/public/common/gpu_memory_stats.h" 21#include "gpu/command_buffer/service/memory_tracking.h" 22#include "ui/gfx/size.h" 23 24namespace content { 25class GpuMemoryManagerClient; 26} 27 28#if defined(COMPILER_GCC) 29namespace BASE_HASH_NAMESPACE { 30template<> 31struct hash<content::GpuMemoryManagerClient*> { 32 size_t operator()(content::GpuMemoryManagerClient* ptr) const { 33 return hash<size_t>()(reinterpret_cast<size_t>(ptr)); 34 } 35}; 36} // namespace BASE_HASH_NAMESPACE 37#endif // COMPILER 38 39namespace content { 40class GpuMemoryManagerClient; 41class GpuMemoryTrackingGroup; 42 43class CONTENT_EXPORT GpuMemoryManager : 44 public base::SupportsWeakPtr<GpuMemoryManager> { 45 public: 46 enum { kDefaultMaxSurfacesWithFrontbufferSoftLimit = 8 }; 47 48 explicit GpuMemoryManager(size_t max_surfaces_with_frontbuffer_soft_limit); 49 ~GpuMemoryManager(); 50 51 // Schedule a Manage() call. If immediate is true, we PostTask without delay. 52 // Otherwise PostDelayedTask using a CancelableClosure and allow multiple 53 // delayed calls to "queue" up. This way, we do not spam clients in certain 54 // lower priority situations. An immediate schedule manage will cancel any 55 // queued delayed manage. 56 void ScheduleManage(bool immediate); 57 58 // Retrieve GPU Resource consumption statistics for the task manager 59 void GetVideoMemoryUsageStats( 60 content::GPUVideoMemoryUsageStats& video_memory_usage_stats) const; 61 void SetWindowCount(uint32 count); 62 63 // Add and remove clients 64 void AddClient(GpuMemoryManagerClient* client, 65 bool has_surface, 66 bool visible, 67 base::TimeTicks last_used_time); 68 void RemoveClient(GpuMemoryManagerClient* client); 69 void SetClientVisible(GpuMemoryManagerClient* client, bool visible); 70 void SetClientManagedMemoryStats(GpuMemoryManagerClient* client, 71 const GpuManagedMemoryStats& stats); 72 73 // Add and remove structures to track context groups' memory consumption 74 void AddTrackingGroup(GpuMemoryTrackingGroup* tracking_group); 75 void RemoveTrackingGroup(GpuMemoryTrackingGroup* tracking_group); 76 77 // Track a change in memory allocated by any context 78 void TrackMemoryAllocatedChange(size_t old_size, size_t new_size); 79 80 private: 81 friend class GpuMemoryManagerTest; 82 FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest, 83 ComparatorTests); 84 FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest, 85 TestManageBasicFunctionality); 86 FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest, 87 TestManageChangingVisibility); 88 FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest, 89 TestManageManyVisibleStubs); 90 FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest, 91 TestManageManyNotVisibleStubs); 92 FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest, 93 TestManageChangingLastUsedTime); 94 FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest, 95 TestManageChangingImportanceShareGroup); 96 FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest, 97 TestForegroundStubsGetBonusAllocation); 98 FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest, 99 TestUpdateAvailableGpuMemory); 100 FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest, 101 GpuMemoryAllocationCompareTests); 102 FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest, 103 StubMemoryStatsForLastManageTests); 104 FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest, 105 TestManagedUsageTracking); 106 FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest, 107 TestBackgroundCutoff); 108 FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest, 109 TestBackgroundMru); 110 111 struct ClientState { 112 ClientState(GpuMemoryManagerClient* client, 113 bool has_surface, 114 bool visible, 115 base::TimeTicks last_used_time); 116 // The client to send allocations to. 117 GpuMemoryManagerClient* client; 118 119 // Offscreen commandbuffers will not have a surface. 120 bool has_surface; 121 122 // The last used time is determined by the last time that visibility 123 // was changed. 124 bool visible; 125 base::TimeTicks last_used_time; 126 127 // Statistics about memory usage. 128 GpuManagedMemoryStats managed_memory_stats; 129 130 // Set to disable allocating a frontbuffer or to disable allocations 131 // for clients that don't have surfaces. 132 bool hibernated; 133 }; 134 135 class CONTENT_EXPORT ClientsComparator { 136 public: 137 bool operator()(ClientState* lhs, 138 ClientState* rhs); 139 }; 140 141 typedef std::map<GpuMemoryManagerClient*, ClientState*> ClientMap; 142 143 typedef std::vector<ClientState*> ClientStateVector; 144 145 void Manage(); 146 void SetClientsHibernatedState(const ClientStateVector& clients) const; 147 size_t GetVisibleClientAllocation(const ClientStateVector& clients) const; 148 size_t GetCurrentBackgroundedAvailableGpuMemory() const; 149 150 // Update the amount of GPU memory we think we have in the system, based 151 // on what the stubs' contexts report. 152 void UpdateAvailableGpuMemory(const ClientStateVector& clients); 153 void UpdateBackgroundedAvailableGpuMemory(); 154 155 // The amount of video memory which is available for allocation. 156 size_t GetAvailableGpuMemory() const; 157 158 // Minimum value of available GPU memory, no matter how little the GPU 159 // reports. This is the default value. 160 size_t GetDefaultAvailableGpuMemory() const; 161 162 // Maximum cap on total GPU memory, no matter how much the GPU reports. 163 size_t GetMaximumTotalGpuMemory() const; 164 165 // The maximum and minimum amount of memory that a tab may be assigned. 166 size_t GetMaximumTabAllocation() const; 167 size_t GetMinimumTabAllocation() const; 168 169 // Get a reasonable memory limit from a viewport's surface area. 170 static size_t CalcAvailableFromViewportArea(int viewport_area); 171 static size_t CalcAvailableFromGpuTotal(size_t total_gpu_memory); 172 173 // Interfaces for testing 174 void TestingSetClientVisible(GpuMemoryManagerClient* client, bool visible); 175 void TestingSetClientLastUsedTime(GpuMemoryManagerClient* client, 176 base::TimeTicks last_used_time); 177 void TestingSetClientHasSurface(GpuMemoryManagerClient* client, 178 bool has_surface); 179 bool TestingCompareClients(GpuMemoryManagerClient* lhs, 180 GpuMemoryManagerClient* rhs) const; 181 void TestingDisableScheduleManage() { disable_schedule_manage_ = true; } 182 void TestingSetAvailableGpuMemory(size_t bytes) { 183 bytes_available_gpu_memory_ = bytes; 184 bytes_available_gpu_memory_overridden_ = true; 185 } 186 187 void TestingSetBackgroundedAvailableGpuMemory(size_t bytes) { 188 bytes_backgrounded_available_gpu_memory_ = bytes; 189 } 190 191 // All clients of this memory manager which have callbacks we 192 // can use to adjust memory usage 193 ClientMap clients_; 194 195 // All context groups' tracking structures 196 std::set<GpuMemoryTrackingGroup*> tracking_groups_; 197 198 base::CancelableClosure delayed_manage_callback_; 199 bool manage_immediate_scheduled_; 200 201 size_t max_surfaces_with_frontbuffer_soft_limit_; 202 203 // The maximum amount of memory that may be allocated for GPU resources 204 size_t bytes_available_gpu_memory_; 205 bool bytes_available_gpu_memory_overridden_; 206 207 // The maximum amount of memory that can be allocated for GPU resources 208 // in backgrounded renderers. 209 size_t bytes_backgrounded_available_gpu_memory_; 210 211 // The current total memory usage, and historical maximum memory usage 212 size_t bytes_allocated_current_; 213 size_t bytes_allocated_managed_visible_; 214 size_t bytes_allocated_managed_backgrounded_; 215 216 // The number of browser windows that exist. If we ever receive a 217 // GpuMsg_SetVideoMemoryWindowCount, then we use this to compute memory 218 // budgets, instead of doing more complicated stub-based calculations. 219 bool window_count_has_been_received_; 220 uint32 window_count_; 221 222 // Used to disable automatic changes to Manage() in testing. 223 bool disable_schedule_manage_; 224 225 DISALLOW_COPY_AND_ASSIGN(GpuMemoryManager); 226}; 227 228class CONTENT_EXPORT GpuMemoryManagerClient { 229 public: 230 virtual ~GpuMemoryManagerClient() {} 231 232 // Returns surface size. 233 virtual gfx::Size GetSurfaceSize() const = 0; 234 235 // Returns the memory tracker for this stub. 236 virtual gpu::gles2::MemoryTracker* GetMemoryTracker() const = 0; 237 238 // Sets buffer usage depending on Memory Allocation 239 virtual void SetMemoryAllocation( 240 const GpuMemoryAllocation& allocation) = 0; 241 242 // Returns in bytes the total amount of GPU memory for the GPU which this 243 // context is currently rendering on. Returns false if no extension exists 244 // to get the exact amount of GPU memory. 245 virtual bool GetTotalGpuMemory(size_t* bytes) = 0; 246}; 247 248} // namespace content 249 250#endif 251 252#endif // CONTENT_COMMON_GPU_GPU_MEMORY_MANAGER_H_ 253