gpu_memory_manager.h revision 6d86b77056ed63eb6871182f42a9fd5f07550f90
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  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