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 #include <list> 9 #include <map> 10 11 #include "base/basictypes.h" 12 #include "base/cancelable_callback.h" 13 #include "base/containers/hash_tables.h" 14 #include "base/gtest_prod_util.h" 15 #include "base/memory/weak_ptr.h" 16 #include "content/common/content_export.h" 17 #include "content/public/common/gpu_memory_stats.h" 18 #include "gpu/command_buffer/common/gpu_memory_allocation.h" 19 #include "gpu/command_buffer/service/memory_tracking.h" 20 21 namespace content { 22 23 class GpuChannelManager; 24 class GpuMemoryManagerClient; 25 class GpuMemoryManagerClientState; 26 class GpuMemoryTrackingGroup; 27 28 class CONTENT_EXPORT GpuMemoryManager : 29 public base::SupportsWeakPtr<GpuMemoryManager> { 30 public: 31 #if defined(OS_ANDROID) || (defined(OS_LINUX) && !defined(OS_CHROMEOS)) 32 enum { kDefaultMaxSurfacesWithFrontbufferSoftLimit = 1 }; 33 #else 34 enum { kDefaultMaxSurfacesWithFrontbufferSoftLimit = 8 }; 35 #endif 36 enum ScheduleManageTime { 37 // Add a call to Manage to the thread's message loop immediately. 38 kScheduleManageNow, 39 // Add a Manage call to the thread's message loop for execution 1/60th of 40 // of a second from now. 41 kScheduleManageLater, 42 }; 43 44 GpuMemoryManager(GpuChannelManager* channel_manager, 45 uint64 max_surfaces_with_frontbuffer_soft_limit); 46 ~GpuMemoryManager(); 47 48 // Schedule a Manage() call. If immediate is true, we PostTask without delay. 49 // Otherwise PostDelayedTask using a CancelableClosure and allow multiple 50 // delayed calls to "queue" up. This way, we do not spam clients in certain 51 // lower priority situations. An immediate schedule manage will cancel any 52 // queued delayed manage. 53 void ScheduleManage(ScheduleManageTime schedule_manage_time); 54 55 // Retrieve GPU Resource consumption statistics for the task manager 56 void GetVideoMemoryUsageStats( 57 content::GPUVideoMemoryUsageStats* video_memory_usage_stats) const; 58 59 GpuMemoryManagerClientState* CreateClientState( 60 GpuMemoryManagerClient* client, bool has_surface, bool visible); 61 62 GpuMemoryTrackingGroup* CreateTrackingGroup( 63 base::ProcessId pid, gpu::gles2::MemoryTracker* memory_tracker); 64 65 uint64 GetClientMemoryUsage(const GpuMemoryManagerClient* client) const; 66 uint64 GetMaximumClientAllocation() const { 67 return client_hard_limit_bytes_; 68 } 69 70 private: 71 friend class GpuMemoryManagerTest; 72 friend class GpuMemoryTrackingGroup; 73 friend class GpuMemoryManagerClientState; 74 75 FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest, 76 TestManageBasicFunctionality); 77 FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest, 78 TestManageChangingVisibility); 79 FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest, 80 TestManageManyVisibleStubs); 81 FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest, 82 TestManageManyNotVisibleStubs); 83 FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest, 84 TestManageChangingLastUsedTime); 85 FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest, 86 TestManageChangingImportanceShareGroup); 87 FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest, 88 TestForegroundStubsGetBonusAllocation); 89 FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest, 90 TestUpdateAvailableGpuMemory); 91 FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest, 92 GpuMemoryAllocationCompareTests); 93 FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest, 94 StubMemoryStatsForLastManageTests); 95 FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest, 96 TestManagedUsageTracking); 97 FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest, 98 BackgroundMru); 99 FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest, 100 AllowNonvisibleMemory); 101 FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest, 102 BackgroundDiscardPersistent); 103 FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest, 104 UnmanagedTracking); 105 FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest, 106 DefaultAllocation); 107 108 typedef std::map<gpu::gles2::MemoryTracker*, GpuMemoryTrackingGroup*> 109 TrackingGroupMap; 110 111 typedef std::list<GpuMemoryManagerClientState*> ClientStateList; 112 113 void Manage(); 114 void SetClientsHibernatedState() const; 115 void AssignSurfacesAllocations(); 116 void AssignNonSurfacesAllocations(); 117 118 // Update the amount of GPU memory we think we have in the system, based 119 // on what the stubs' contexts report. 120 void UpdateAvailableGpuMemory(); 121 122 // Send memory usage stats to the browser process. 123 void SendUmaStatsToBrowser(); 124 125 // Get the current number of bytes allocated. 126 uint64 GetCurrentUsage() const { 127 return bytes_allocated_managed_current_ + 128 bytes_allocated_unmanaged_current_; 129 } 130 131 // GpuMemoryTrackingGroup interface 132 void TrackMemoryAllocatedChange( 133 GpuMemoryTrackingGroup* tracking_group, 134 uint64 old_size, 135 uint64 new_size, 136 gpu::gles2::MemoryTracker::Pool tracking_pool); 137 void OnDestroyTrackingGroup(GpuMemoryTrackingGroup* tracking_group); 138 bool EnsureGPUMemoryAvailable(uint64 size_needed); 139 140 // GpuMemoryManagerClientState interface 141 void SetClientStateVisible( 142 GpuMemoryManagerClientState* client_state, bool visible); 143 void OnDestroyClientState(GpuMemoryManagerClientState* client); 144 145 // Add or remove a client from its clients list (visible, nonvisible, or 146 // nonsurface). When adding the client, add it to the front of the list. 147 void AddClientToList(GpuMemoryManagerClientState* client_state); 148 void RemoveClientFromList(GpuMemoryManagerClientState* client_state); 149 ClientStateList* GetClientList(GpuMemoryManagerClientState* client_state); 150 151 // Interfaces for testing 152 void TestingDisableScheduleManage() { disable_schedule_manage_ = true; } 153 154 GpuChannelManager* channel_manager_; 155 156 // A list of all visible and nonvisible clients, in most-recently-used 157 // order (most recently used is first). 158 ClientStateList clients_visible_mru_; 159 ClientStateList clients_nonvisible_mru_; 160 161 // A list of all clients that don't have a surface. 162 ClientStateList clients_nonsurface_; 163 164 // All context groups' tracking structures 165 TrackingGroupMap tracking_groups_; 166 167 base::CancelableClosure delayed_manage_callback_; 168 bool manage_immediate_scheduled_; 169 bool disable_schedule_manage_; 170 171 uint64 max_surfaces_with_frontbuffer_soft_limit_; 172 173 // The maximum amount of memory that may be allocated for a single client. 174 uint64 client_hard_limit_bytes_; 175 176 // The current total memory usage, and historical maximum memory usage 177 uint64 bytes_allocated_managed_current_; 178 uint64 bytes_allocated_unmanaged_current_; 179 uint64 bytes_allocated_historical_max_; 180 181 DISALLOW_COPY_AND_ASSIGN(GpuMemoryManager); 182 }; 183 184 } // namespace content 185 186 #endif // CONTENT_COMMON_GPU_GPU_MEMORY_MANAGER_H_ 187