• 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 GPU_COMMAND_BUFFER_CLIENT_MAPPED_MEMORY_H_
6 #define GPU_COMMAND_BUFFER_CLIENT_MAPPED_MEMORY_H_
7 
8 #include <stdint.h>
9 
10 #include "base/bind.h"
11 #include "base/macros.h"
12 #include "base/memory/scoped_vector.h"
13 #include "gpu/command_buffer/client/fenced_allocator.h"
14 #include "gpu/command_buffer/common/buffer.h"
15 #include "gpu/gpu_export.h"
16 
17 namespace gpu {
18 
19 class CommandBufferHelper;
20 
21 // Manages a shared memory segment.
22 class GPU_EXPORT MemoryChunk {
23  public:
24   MemoryChunk(int32_t shm_id,
25               scoped_refptr<gpu::Buffer> shm,
26               CommandBufferHelper* helper,
27               const base::Closure& poll_callback);
28   ~MemoryChunk();
29 
30   // Gets the size of the largest free block that is available without waiting.
GetLargestFreeSizeWithoutWaiting()31   unsigned int GetLargestFreeSizeWithoutWaiting() {
32     return allocator_.GetLargestFreeSize();
33   }
34 
35   // Gets the size of the largest free block that can be allocated if the
36   // caller can wait.
GetLargestFreeSizeWithWaiting()37   unsigned int GetLargestFreeSizeWithWaiting() {
38     return allocator_.GetLargestFreeOrPendingSize();
39   }
40 
41   // Gets the size of the chunk.
GetSize()42   unsigned int GetSize() const {
43     return static_cast<unsigned int>(shm_->size());
44   }
45 
46   // The shared memory id for this chunk.
shm_id()47   int32_t shm_id() const {
48     return shm_id_;
49   }
50 
51   // Allocates a block of memory. If the buffer is out of directly available
52   // memory, this function may wait until memory that was freed "pending a
53   // token" can be re-used.
54   //
55   // Parameters:
56   //   size: the size of the memory block to allocate.
57   //
58   // Returns:
59   //   the pointer to the allocated memory block, or NULL if out of
60   //   memory.
Alloc(unsigned int size)61   void* Alloc(unsigned int size) {
62     return allocator_.Alloc(size);
63   }
64 
65   // Gets the offset to a memory block given the base memory and the address.
66   // It translates NULL to FencedAllocator::kInvalidOffset.
GetOffset(void * pointer)67   unsigned int GetOffset(void* pointer) {
68     return allocator_.GetOffset(pointer);
69   }
70 
71   // Frees a block of memory.
72   //
73   // Parameters:
74   //   pointer: the pointer to the memory block to free.
Free(void * pointer)75   void Free(void* pointer) {
76     allocator_.Free(pointer);
77   }
78 
79   // Frees a block of memory, pending the passage of a token. That memory won't
80   // be re-allocated until the token has passed through the command stream.
81   //
82   // Parameters:
83   //   pointer: the pointer to the memory block to free.
84   //   token: the token value to wait for before re-using the memory.
FreePendingToken(void * pointer,unsigned int token)85   void FreePendingToken(void* pointer, unsigned int token) {
86     allocator_.FreePendingToken(pointer, token);
87   }
88 
89   // Frees any blocks whose tokens have passed.
FreeUnused()90   void FreeUnused() {
91     allocator_.FreeUnused();
92   }
93 
94   // Returns true if pointer is in the range of this block.
IsInChunk(void * pointer)95   bool IsInChunk(void* pointer) const {
96     return pointer >= shm_->memory() &&
97            pointer <
98                reinterpret_cast<const int8_t*>(shm_->memory()) + shm_->size();
99   }
100 
101   // Returns true of any memory in this chunk is in use.
InUse()102   bool InUse() {
103     return allocator_.InUse();
104   }
105 
bytes_in_use()106   size_t bytes_in_use() const {
107     return allocator_.bytes_in_use();
108   }
109 
110  private:
111   int32_t shm_id_;
112   scoped_refptr<gpu::Buffer> shm_;
113   FencedAllocatorWrapper allocator_;
114 
115   DISALLOW_COPY_AND_ASSIGN(MemoryChunk);
116 };
117 
118 // Manages MemoryChunks.
119 class GPU_EXPORT MappedMemoryManager {
120  public:
121   enum MemoryLimit {
122     kNoLimit = 0,
123   };
124 
125   // |unused_memory_reclaim_limit|: When exceeded this causes pending memory
126   // to be reclaimed before allocating more memory.
127   MappedMemoryManager(CommandBufferHelper* helper,
128                       const base::Closure& poll_callback,
129                       size_t unused_memory_reclaim_limit);
130 
131   ~MappedMemoryManager();
132 
chunk_size_multiple()133   unsigned int chunk_size_multiple() const {
134     return chunk_size_multiple_;
135   }
136 
set_chunk_size_multiple(unsigned int multiple)137   void set_chunk_size_multiple(unsigned int multiple) {
138     chunk_size_multiple_ = multiple;
139   }
140 
141   // Allocates a block of memory
142   // Parameters:
143   //   size: size of memory to allocate.
144   //   shm_id: pointer to variable to receive the shared memory id.
145   //   shm_offset: pointer to variable to receive the shared memory offset.
146   // Returns:
147   //   pointer to allocated block of memory. NULL if failure.
148   void* Alloc(
149       unsigned int size, int32_t* shm_id, unsigned int* shm_offset);
150 
151   // Frees a block of memory.
152   //
153   // Parameters:
154   //   pointer: the pointer to the memory block to free.
155   void Free(void* pointer);
156 
157   // Frees a block of memory, pending the passage of a token. That memory won't
158   // be re-allocated until the token has passed through the command stream.
159   //
160   // Parameters:
161   //   pointer: the pointer to the memory block to free.
162   //   token: the token value to wait for before re-using the memory.
163   void FreePendingToken(void* pointer, int32_t token);
164 
165   // Free Any Shared memory that is not in use.
166   void FreeUnused();
167 
168   // Used for testing
num_chunks()169   size_t num_chunks() const {
170     return chunks_.size();
171   }
172 
bytes_in_use()173   size_t bytes_in_use() const {
174     size_t bytes_in_use = 0;
175     for (size_t ii = 0; ii < chunks_.size(); ++ii) {
176       MemoryChunk* chunk = chunks_[ii];
177       bytes_in_use += chunk->bytes_in_use();
178     }
179     return bytes_in_use;
180   }
181 
182   // Used for testing
allocated_memory()183   size_t allocated_memory() const {
184     return allocated_memory_;
185   }
186 
187  private:
188   typedef ScopedVector<MemoryChunk> MemoryChunkVector;
189 
190   // size a chunk is rounded up to.
191   unsigned int chunk_size_multiple_;
192   CommandBufferHelper* helper_;
193   base::Closure poll_callback_;
194   MemoryChunkVector chunks_;
195   size_t allocated_memory_;
196   size_t max_free_bytes_;
197 
198   DISALLOW_COPY_AND_ASSIGN(MappedMemoryManager);
199 };
200 
201 }  // namespace gpu
202 
203 #endif  // GPU_COMMAND_BUFFER_CLIENT_MAPPED_MEMORY_H_
204 
205