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 // This file contains the definition of the RingBuffer class.
      6 
      7 #ifndef GPU_COMMAND_BUFFER_CLIENT_RING_BUFFER_H_
      8 #define GPU_COMMAND_BUFFER_CLIENT_RING_BUFFER_H_
      9 
     10 #include <deque>
     11 
     12 #include "base/logging.h"
     13 #include "base/macros.h"
     14 #include "gpu/gpu_export.h"
     15 
     16 namespace gpu {
     17 class CommandBufferHelper;
     18 
     19 // RingBuffer manages a piece of memory as a ring buffer. Memory is allocated
     20 // with Alloc and then a is freed pending a token with FreePendingToken.  Old
     21 // allocations must not be kept past new allocations.
     22 class GPU_EXPORT RingBuffer {
     23  public:
     24   typedef unsigned int Offset;
     25 
     26   // Creates a RingBuffer.
     27   // Parameters:
     28   //   alignment: Alignment for allocations.
     29   //   base_offset: The offset of the start of the buffer.
     30   //   size: The size of the buffer in bytes.
     31   //   helper: A CommandBufferHelper for dealing with tokens.
     32   //   base: The physical address that corresponds to base_offset.
     33   RingBuffer(unsigned int alignment, Offset base_offset,
     34              unsigned int size, CommandBufferHelper* helper, void* base);
     35 
     36   ~RingBuffer();
     37 
     38   // Allocates a block of memory. If the buffer is out of directly available
     39   // memory, this function may wait until memory that was freed "pending a
     40   // token" can be re-used.
     41   //
     42   // Parameters:
     43   //   size: the size of the memory block to allocate.
     44   //
     45   // Returns:
     46   //   the pointer to the allocated memory block.
     47   void* Alloc(unsigned int size);
     48 
     49   // Frees a block of memory, pending the passage of a token. That memory won't
     50   // be re-allocated until the token has passed through the command stream.
     51   //
     52   // Parameters:
     53   //   pointer: the pointer to the memory block to free.
     54   //   token: the token value to wait for before re-using the memory.
     55   void FreePendingToken(void* pointer, unsigned int token);
     56 
     57   // Gets the size of the largest free block that is available without waiting.
     58   unsigned int GetLargestFreeSizeNoWaiting();
     59 
     60   // Gets the size of the largest free block that can be allocated if the
     61   // caller can wait. Allocating a block of this size will succeed, but may
     62   // block.
     63   unsigned int GetLargestFreeOrPendingSize() {
     64     return size_;
     65   }
     66 
     67   // Gets a pointer to a memory block given the base memory and the offset.
     68   void* GetPointer(RingBuffer::Offset offset) const {
     69     return static_cast<int8*>(base_) + offset;
     70   }
     71 
     72   // Gets the offset to a memory block given the base memory and the address.
     73   RingBuffer::Offset GetOffset(void* pointer) const {
     74     return static_cast<int8*>(pointer) - static_cast<int8*>(base_);
     75   }
     76 
     77   // Rounds the given size to the alignment in use.
     78   unsigned int RoundToAlignment(unsigned int size) {
     79     return (size + alignment_ - 1) & ~(alignment_ - 1);
     80   }
     81 
     82 
     83  private:
     84   enum State {
     85     IN_USE,
     86     PADDING,
     87     FREE_PENDING_TOKEN
     88   };
     89   // Book-keeping sturcture that describes a block of memory.
     90   struct Block {
     91     Block(Offset _offset, unsigned int _size, State _state)
     92         : offset(_offset),
     93           size(_size),
     94           token(0),
     95           state(_state) {
     96     }
     97     Offset offset;
     98     unsigned int size;
     99     unsigned int token;  // token to wait for.
    100     State state;
    101   };
    102 
    103   typedef std::deque<Block> Container;
    104   typedef unsigned int BlockIndex;
    105 
    106   void FreeOldestBlock();
    107 
    108   CommandBufferHelper* helper_;
    109 
    110   // Used blocks are added to the end, blocks are freed from the beginning.
    111   Container blocks_;
    112 
    113   // The base offset of the ring buffer.
    114   Offset base_offset_;
    115 
    116   // The size of the ring buffer.
    117   Offset size_;
    118 
    119   // Offset of first free byte.
    120   Offset free_offset_;
    121 
    122   // Offset of first used byte.
    123   // Range between in_use_mark and free_mark is in use.
    124   Offset in_use_offset_;
    125 
    126   // Alignment for allocations.
    127   unsigned int alignment_;
    128 
    129   // The physical address that corresponds to base_offset.
    130   void* base_;
    131 
    132   DISALLOW_IMPLICIT_CONSTRUCTORS(RingBuffer);
    133 };
    134 
    135 }  // namespace gpu
    136 
    137 #endif  // GPU_COMMAND_BUFFER_CLIENT_RING_BUFFER_H_
    138