• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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;
GetMaximumClientAllocation()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.
GetCurrentUsage()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
TestingDisableScheduleManage()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