Added grv@ and dvh@ as owners of developer private API.
[chromium-blink-merge.git] / gpu / command_buffer / client / ring_buffer.h
blob81f1cddafa52babad1ebbb1cb4f062ba37128152
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.
5 // This file contains the definition of the RingBuffer class.
7 #ifndef GPU_COMMAND_BUFFER_CLIENT_RING_BUFFER_H_
8 #define GPU_COMMAND_BUFFER_CLIENT_RING_BUFFER_H_
10 #include <deque>
12 #include "base/logging.h"
13 #include "gpu/command_buffer/common/types.h"
14 #include "gpu/gpu_export.h"
16 namespace gpu {
17 class CommandBufferHelper;
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;
26 // Creates a RingBuffer.
27 // Parameters:
28 // base_offset: The offset of the start of the buffer.
29 // size: The size of the buffer in bytes.
30 // helper: A CommandBufferHelper for dealing with tokens.
31 RingBuffer(
32 Offset base_offset, unsigned int size, CommandBufferHelper* helper);
34 ~RingBuffer();
36 // Allocates a block of memory. If the buffer is out of directly available
37 // memory, this function may wait until memory that was freed "pending a
38 // token" can be re-used.
40 // Parameters:
41 // size: the size of the memory block to allocate.
43 // Returns:
44 // the offset of the allocated memory block.
45 Offset Alloc(unsigned int size);
47 // Frees a block of memory, pending the passage of a token. That memory won't
48 // be re-allocated until the token has passed through the command stream.
50 // Parameters:
51 // offset: the offset of the memory block to free.
52 // token: the token value to wait for before re-using the memory.
53 void FreePendingToken(Offset offset, unsigned int token);
55 // Gets the size of the largest free block that is available without waiting.
56 unsigned int GetLargestFreeSizeNoWaiting();
58 // Gets the size of the largest free block that can be allocated if the
59 // caller can wait. Allocating a block of this size will succeed, but may
60 // block.
61 unsigned int GetLargestFreeOrPendingSize() {
62 return size_;
65 private:
66 enum State {
67 IN_USE,
68 PADDING,
69 FREE_PENDING_TOKEN
71 // Book-keeping sturcture that describes a block of memory.
72 struct Block {
73 Block(Offset _offset, unsigned int _size, State _state)
74 : offset(_offset),
75 size(_size),
76 token(0),
77 state(_state) {
79 Offset offset;
80 unsigned int size;
81 unsigned int token; // token to wait for.
82 State state;
85 typedef std::deque<Block> Container;
86 typedef unsigned int BlockIndex;
88 void FreeOldestBlock();
90 CommandBufferHelper* helper_;
92 // Used blocks are added to the end, blocks are freed from the beginning.
93 Container blocks_;
95 // The base offset of the ring buffer.
96 Offset base_offset_;
98 // The size of the ring buffer.
99 Offset size_;
101 // Offset of first free byte.
102 Offset free_offset_;
104 // Offset of first used byte.
105 // Range between in_use_mark and free_mark is in use.
106 Offset in_use_offset_;
108 DISALLOW_IMPLICIT_CONSTRUCTORS(RingBuffer);
111 // This class functions just like RingBuffer, but its API uses pointers
112 // instead of offsets.
113 class RingBufferWrapper {
114 public:
115 // Parameters:
116 // base_offset: The offset to the start of the buffer
117 // size: The size of the buffer in bytes.
118 // helper: A CommandBufferHelper for dealing with tokens.
119 // base: The physical address that corresponds to base_offset.
120 RingBufferWrapper(RingBuffer::Offset base_offset,
121 unsigned int size,
122 CommandBufferHelper* helper,
123 void* base)
124 : allocator_(base_offset, size, helper),
125 base_(static_cast<int8*>(base) - base_offset) {
128 // Allocates a block of memory. If the buffer is out of directly available
129 // memory, this function may wait until memory that was freed "pending a
130 // token" can be re-used.
132 // Parameters:
133 // size: the size of the memory block to allocate.
135 // Returns:
136 // the pointer to the allocated memory block, or NULL if out of
137 // memory.
138 void* Alloc(unsigned int size) {
139 RingBuffer::Offset offset = allocator_.Alloc(size);
140 return GetPointer(offset);
143 // Allocates a block of memory. If the buffer is out of directly available
144 // memory, this function may wait until memory that was freed "pending a
145 // token" can be re-used.
146 // This is a type-safe version of Alloc, returning a typed pointer.
148 // Parameters:
149 // count: the number of elements to allocate.
151 // Returns:
152 // the pointer to the allocated memory block, or NULL if out of
153 // memory.
154 template <typename T> T* AllocTyped(unsigned int count) {
155 return static_cast<T*>(Alloc(count * sizeof(T)));
158 // Frees a block of memory, pending the passage of a token. That memory won't
159 // be re-allocated until the token has passed through the command stream.
161 // Parameters:
162 // pointer: the pointer to the memory block to free.
163 // token: the token value to wait for before re-using the memory.
164 void FreePendingToken(void* pointer, unsigned int token) {
165 DCHECK(pointer);
166 allocator_.FreePendingToken(GetOffset(pointer), token);
169 // Gets a pointer to a memory block given the base memory and the offset.
170 void* GetPointer(RingBuffer::Offset offset) const {
171 return static_cast<int8*>(base_) + offset;
174 // Gets the offset to a memory block given the base memory and the address.
175 RingBuffer::Offset GetOffset(void* pointer) const {
176 return static_cast<int8*>(pointer) - static_cast<int8*>(base_);
179 // Gets the size of the largest free block that is available without waiting.
180 unsigned int GetLargestFreeSizeNoWaiting() {
181 return allocator_.GetLargestFreeSizeNoWaiting();
184 // Gets the size of the largest free block that can be allocated if the
185 // caller can wait.
186 unsigned int GetLargestFreeOrPendingSize() {
187 return allocator_.GetLargestFreeOrPendingSize();
190 private:
191 RingBuffer allocator_;
192 void* base_;
193 DISALLOW_IMPLICIT_CONSTRUCTORS(RingBufferWrapper);
196 } // namespace gpu
198 #endif // GPU_COMMAND_BUFFER_CLIENT_RING_BUFFER_H_