Home | History | Annotate | Download | only in client
      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.
     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.
     37   unsigned int GetLargestFreeSizeWithWaiting() {
     38     return allocator_.GetLargestFreeOrPendingSize();
     39   }
     40 
     41   // Gets the size of the chunk.
     42   unsigned int GetSize() const {
     43     return static_cast<unsigned int>(shm_->size());
     44   }
     45 
     46   // The shared memory id for this chunk.
     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.
     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.
     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.
     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.
     85   void FreePendingToken(void* pointer, unsigned int token) {
     86     allocator_.FreePendingToken(pointer, token);
     87   }
     88 
     89   // Frees any blocks whose tokens have passed.
     90   void FreeUnused() {
     91     allocator_.FreeUnused();
     92   }
     93 
     94   // Returns true if pointer is in the range of this block.
     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.
    102   bool InUse() {
    103     return allocator_.InUse();
    104   }
    105 
    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 
    133   unsigned int chunk_size_multiple() const {
    134     return chunk_size_multiple_;
    135   }
    136 
    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
    169   size_t num_chunks() const {
    170     return chunks_.size();
    171   }
    172 
    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
    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