gpu_memory_manager.h revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
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
21namespace content {
22
23class GpuChannelManager;
24class GpuMemoryManagerClient;
25class GpuMemoryManagerClientState;
26class GpuMemoryTrackingGroup;
27
28class 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
67 private:
68  friend class GpuMemoryManagerTest;
69  friend class GpuMemoryTrackingGroup;
70  friend class GpuMemoryManagerClientState;
71
72  FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest,
73                           TestManageBasicFunctionality);
74  FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest,
75                           TestManageChangingVisibility);
76  FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest,
77                           TestManageManyVisibleStubs);
78  FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest,
79                           TestManageManyNotVisibleStubs);
80  FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest,
81                           TestManageChangingLastUsedTime);
82  FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest,
83                           TestManageChangingImportanceShareGroup);
84  FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest,
85                           TestForegroundStubsGetBonusAllocation);
86  FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest,
87                           TestUpdateAvailableGpuMemory);
88  FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest,
89                           GpuMemoryAllocationCompareTests);
90  FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest,
91                           StubMemoryStatsForLastManageTests);
92  FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest,
93                           TestManagedUsageTracking);
94  FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest,
95                           BackgroundMru);
96  FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest,
97                           AllowNonvisibleMemory);
98  FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest,
99                           BackgroundDiscardPersistent);
100  FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest,
101                           UnmanagedTracking);
102  FRIEND_TEST_ALL_PREFIXES(GpuMemoryManagerTest,
103                           DefaultAllocation);
104
105  typedef std::map<gpu::gles2::MemoryTracker*, GpuMemoryTrackingGroup*>
106      TrackingGroupMap;
107
108  typedef std::list<GpuMemoryManagerClientState*> ClientStateList;
109
110  void Manage();
111  void SetClientsHibernatedState() const;
112  void AssignSurfacesAllocations();
113  void AssignNonSurfacesAllocations();
114
115  // Math helper function to compute the maximum value of cap such that
116  // sum_i min(bytes[i], cap) <= bytes_sum_limit
117  static uint64 ComputeCap(std::vector<uint64> bytes, uint64 bytes_sum_limit);
118
119  // Compute the allocation for clients when visible and not visible.
120  void ComputeVisibleSurfacesAllocations();
121  void DistributeRemainingMemoryToVisibleSurfaces();
122
123  // Compute the budget for a client. Allow at most bytes_above_required_cap
124  // bytes above client_state's required level. Allow at most
125  // bytes_above_minimum_cap bytes above client_state's minimum level. Allow
126  // at most bytes_overall_cap bytes total.
127  uint64 ComputeClientAllocationWhenVisible(
128      GpuMemoryManagerClientState* client_state,
129      uint64 bytes_above_required_cap,
130      uint64 bytes_above_minimum_cap,
131      uint64 bytes_overall_cap);
132
133  // Update the amount of GPU memory we think we have in the system, based
134  // on what the stubs' contexts report.
135  void UpdateAvailableGpuMemory();
136  void UpdateUnmanagedMemoryLimits();
137
138  // The amount of video memory which is available for allocation.
139  uint64 GetAvailableGpuMemory() const;
140
141  // Minimum value of available GPU memory, no matter how little the GPU
142  // reports. This is the default value.
143  uint64 GetDefaultAvailableGpuMemory() const;
144
145  // Maximum cap on total GPU memory, no matter how much the GPU reports.
146  uint64 GetMaximumTotalGpuMemory() const;
147
148  // The maximum and minimum amount of memory that a client may be assigned.
149  uint64 GetMaximumClientAllocation() const;
150  uint64 GetMinimumClientAllocation() const {
151    return bytes_minimum_per_client_;
152  }
153  // The default amount of memory that a client is assigned, if it has not
154  // reported any memory usage stats yet.
155  uint64 GetDefaultClientAllocation() const {
156    return bytes_default_per_client_;
157  }
158
159  static uint64 CalcAvailableFromGpuTotal(uint64 total_gpu_memory);
160
161  // Send memory usage stats to the browser process.
162  void SendUmaStatsToBrowser();
163
164  // Get the current number of bytes allocated.
165  uint64 GetCurrentUsage() const {
166    return bytes_allocated_managed_current_ +
167        bytes_allocated_unmanaged_current_;
168  }
169
170  // GpuMemoryTrackingGroup interface
171  void TrackMemoryAllocatedChange(
172      GpuMemoryTrackingGroup* tracking_group,
173      uint64 old_size,
174      uint64 new_size,
175      gpu::gles2::MemoryTracker::Pool tracking_pool);
176  void OnDestroyTrackingGroup(GpuMemoryTrackingGroup* tracking_group);
177  bool EnsureGPUMemoryAvailable(uint64 size_needed);
178
179  // GpuMemoryManagerClientState interface
180  void SetClientStateVisible(
181      GpuMemoryManagerClientState* client_state, bool visible);
182  void SetClientStateManagedMemoryStats(
183      GpuMemoryManagerClientState* client_state,
184      const gpu::ManagedMemoryStats& stats);
185  void OnDestroyClientState(GpuMemoryManagerClientState* client);
186
187  // Add or remove a client from its clients list (visible, nonvisible, or
188  // nonsurface). When adding the client, add it to the front of the list.
189  void AddClientToList(GpuMemoryManagerClientState* client_state);
190  void RemoveClientFromList(GpuMemoryManagerClientState* client_state);
191  ClientStateList* GetClientList(GpuMemoryManagerClientState* client_state);
192
193  // Interfaces for testing
194  void TestingDisableScheduleManage() { disable_schedule_manage_ = true; }
195  void TestingSetAvailableGpuMemory(uint64 bytes) {
196    bytes_available_gpu_memory_ = bytes;
197    bytes_available_gpu_memory_overridden_ = true;
198  }
199
200  void TestingSetMinimumClientAllocation(uint64 bytes) {
201    bytes_minimum_per_client_ = bytes;
202  }
203
204  void TestingSetDefaultClientAllocation(uint64 bytes) {
205    bytes_default_per_client_ = bytes;
206  }
207
208  void TestingSetUnmanagedLimitStep(uint64 bytes) {
209    bytes_unmanaged_limit_step_ = bytes;
210  }
211
212  GpuChannelManager* channel_manager_;
213
214  // A list of all visible and nonvisible clients, in most-recently-used
215  // order (most recently used is first).
216  ClientStateList clients_visible_mru_;
217  ClientStateList clients_nonvisible_mru_;
218
219  // A list of all clients that don't have a surface.
220  ClientStateList clients_nonsurface_;
221
222  // All context groups' tracking structures
223  TrackingGroupMap tracking_groups_;
224
225  base::CancelableClosure delayed_manage_callback_;
226  bool manage_immediate_scheduled_;
227
228  uint64 max_surfaces_with_frontbuffer_soft_limit_;
229
230  // The maximum amount of memory that may be allocated for GPU resources
231  uint64 bytes_available_gpu_memory_;
232  bool bytes_available_gpu_memory_overridden_;
233
234  // The minimum and default allocations for a single client.
235  uint64 bytes_minimum_per_client_;
236  uint64 bytes_default_per_client_;
237
238  // The current total memory usage, and historical maximum memory usage
239  uint64 bytes_allocated_managed_current_;
240  uint64 bytes_allocated_unmanaged_current_;
241  uint64 bytes_allocated_historical_max_;
242
243  // If bytes_allocated_unmanaged_current_ leaves the interval [low_, high_),
244  // then ScheduleManage to take the change into account.
245  uint64 bytes_allocated_unmanaged_high_;
246  uint64 bytes_allocated_unmanaged_low_;
247
248  // Update bytes_allocated_unmanaged_low/high_ in intervals of step_.
249  uint64 bytes_unmanaged_limit_step_;
250
251  // Used to disable automatic changes to Manage() in testing.
252  bool disable_schedule_manage_;
253
254  DISALLOW_COPY_AND_ASSIGN(GpuMemoryManager);
255};
256
257}  // namespace content
258
259#endif // CONTENT_COMMON_GPU_GPU_MEMORY_MANAGER_H_
260