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 16namespace gpu { 17class 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. 22class 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