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_TRANSFER_BUFFER_H_
      6 #define GPU_COMMAND_BUFFER_CLIENT_TRANSFER_BUFFER_H_
      7 
      8 #include "base/compiler_specific.h"
      9 #include "base/memory/scoped_ptr.h"
     10 #include "gpu/command_buffer/client/ring_buffer.h"
     11 #include "gpu/command_buffer/common/buffer.h"
     12 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
     13 #include "gpu/gpu_export.h"
     14 
     15 namespace gpu {
     16 
     17 class CommandBufferHelper;
     18 
     19 // Interface for managing the transfer buffer.
     20 class GPU_EXPORT TransferBufferInterface {
     21  public:
     22   TransferBufferInterface() { }
     23   virtual ~TransferBufferInterface() { }
     24 
     25   virtual bool Initialize(
     26       unsigned int buffer_size,
     27       unsigned int result_size,
     28       unsigned int min_buffer_size,
     29       unsigned int max_buffer_size,
     30       unsigned int alignment,
     31       unsigned int size_to_flush) = 0;
     32 
     33   virtual int GetShmId() = 0;
     34   virtual void* GetResultBuffer() = 0;
     35   virtual int GetResultOffset() = 0;
     36 
     37   virtual void Free() = 0;
     38 
     39   virtual bool HaveBuffer() const = 0;
     40 
     41   // Allocates up to size bytes.
     42   virtual void* AllocUpTo(unsigned int size, unsigned int* size_allocated) = 0;
     43 
     44   // Allocates size bytes.
     45   // Note: Alloc will fail if it can not return size bytes.
     46   virtual void* Alloc(unsigned int size) = 0;
     47 
     48   virtual RingBuffer::Offset GetOffset(void* pointer) const = 0;
     49 
     50   virtual void FreePendingToken(void* p, unsigned int token) = 0;
     51 };
     52 
     53 // Class that manages the transfer buffer.
     54 class GPU_EXPORT TransferBuffer : public TransferBufferInterface {
     55  public:
     56   TransferBuffer(CommandBufferHelper* helper);
     57   virtual ~TransferBuffer();
     58 
     59   // Overridden from TransferBufferInterface.
     60   virtual bool Initialize(
     61       unsigned int default_buffer_size,
     62       unsigned int result_size,
     63       unsigned int min_buffer_size,
     64       unsigned int max_buffer_size,
     65       unsigned int alignment,
     66       unsigned int size_to_flush) OVERRIDE;
     67   virtual int GetShmId() OVERRIDE;
     68   virtual void* GetResultBuffer() OVERRIDE;
     69   virtual int GetResultOffset() OVERRIDE;
     70   virtual void Free() OVERRIDE;
     71   virtual bool HaveBuffer() const OVERRIDE;
     72   virtual void* AllocUpTo(
     73       unsigned int size, unsigned int* size_allocated) OVERRIDE;
     74   virtual void* Alloc(unsigned int size) OVERRIDE;
     75   virtual RingBuffer::Offset GetOffset(void* pointer) const OVERRIDE;
     76   virtual void FreePendingToken(void* p, unsigned int token) OVERRIDE;
     77 
     78   // These are for testing.
     79   unsigned int GetCurrentMaxAllocationWithoutRealloc() const;
     80   unsigned int GetMaxAllocation() const;
     81 
     82  private:
     83   // Tries to reallocate the ring buffer if it's not large enough for size.
     84   void ReallocateRingBuffer(unsigned int size);
     85 
     86   void AllocateRingBuffer(unsigned int size);
     87 
     88   CommandBufferHelper* helper_;
     89   scoped_ptr<RingBuffer> ring_buffer_;
     90 
     91   // size reserved for results
     92   unsigned int result_size_;
     93 
     94   // default size. Size we want when starting or re-allocating
     95   unsigned int default_buffer_size_;
     96 
     97   // min size we'll consider successful
     98   unsigned int min_buffer_size_;
     99 
    100   // max size we'll let the buffer grow
    101   unsigned int max_buffer_size_;
    102 
    103   // alignment for allocations
    104   unsigned int alignment_;
    105 
    106   // Size at which to do an async flush. 0 = never.
    107   unsigned int size_to_flush_;
    108 
    109   // Number of bytes since we last flushed.
    110   unsigned int bytes_since_last_flush_;
    111 
    112   // the current buffer.
    113   scoped_refptr<gpu::Buffer> buffer_;
    114 
    115   // id of buffer. -1 = no buffer
    116   int32 buffer_id_;
    117 
    118   // address of result area
    119   void* result_buffer_;
    120 
    121   // offset to result area
    122   uint32 result_shm_offset_;
    123 
    124   // false if we failed to allocate min_buffer_size
    125   bool usable_;
    126 };
    127 
    128 // A class that will manage the lifetime of a transferbuffer allocation.
    129 class GPU_EXPORT ScopedTransferBufferPtr {
    130  public:
    131   ScopedTransferBufferPtr(
    132       unsigned int size,
    133       CommandBufferHelper* helper,
    134       TransferBufferInterface* transfer_buffer)
    135       : buffer_(NULL),
    136         size_(0),
    137         helper_(helper),
    138         transfer_buffer_(transfer_buffer) {
    139     Reset(size);
    140   }
    141 
    142   ~ScopedTransferBufferPtr() {
    143     Release();
    144   }
    145 
    146   bool valid() const {
    147     return buffer_ != NULL;
    148   }
    149 
    150   unsigned int size() const {
    151     return size_;
    152   }
    153 
    154   int shm_id() const {
    155     return transfer_buffer_->GetShmId();
    156   }
    157 
    158   RingBuffer::Offset offset() const {
    159     return transfer_buffer_->GetOffset(buffer_);
    160   }
    161 
    162   void* address() const {
    163     return buffer_;
    164   }
    165 
    166   void Release();
    167 
    168   void Reset(unsigned int new_size);
    169 
    170  private:
    171   void* buffer_;
    172   unsigned int size_;
    173   CommandBufferHelper* helper_;
    174   TransferBufferInterface* transfer_buffer_;
    175   DISALLOW_COPY_AND_ASSIGN(ScopedTransferBufferPtr);
    176 };
    177 
    178 template <typename T>
    179 class ScopedTransferBufferArray : public ScopedTransferBufferPtr {
    180  public:
    181   ScopedTransferBufferArray(
    182       unsigned int num_elements,
    183       CommandBufferHelper* helper, TransferBufferInterface* transfer_buffer)
    184       : ScopedTransferBufferPtr(
    185           num_elements * sizeof(T), helper, transfer_buffer) {
    186   }
    187 
    188   T* elements() {
    189     return static_cast<T*>(address());
    190   }
    191 
    192   unsigned int num_elements() const {
    193     return size() / sizeof(T);
    194   }
    195 };
    196 
    197 }  // namespace gpu
    198 
    199 #endif  // GPU_COMMAND_BUFFER_CLIENT_TRANSFER_BUFFER_H_
    200