Home | History | Annotate | Download | only in gpu
      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