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_
12 #include "gpu/command_buffer/common/logging.h"
13 #include "gpu/command_buffer/common/types.h"
14 #include "gpu/gpu_export.h"
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
{
24 typedef unsigned int Offset
;
26 // Creates a RingBuffer.
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.
32 Offset base_offset
, unsigned int size
, CommandBufferHelper
* helper
);
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.
41 // size: the size of the memory block to allocate.
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.
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
61 unsigned int GetLargestFreeOrPendingSize() {
71 // Book-keeping sturcture that describes a block of memory.
73 Block(Offset _offset
, unsigned int _size
, State _state
)
81 unsigned int token
; // token to wait for.
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.
95 // The base offset of the ring buffer.
98 // The size of the ring buffer.
101 // Offset of first free byte.
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
{
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
,
122 CommandBufferHelper
* helper
,
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.
133 // size: the size of the memory block to allocate.
136 // the pointer to the allocated memory block, or NULL if out of
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.
149 // count: the number of elements to allocate.
152 // the pointer to the allocated memory block, or NULL if out of
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.
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
) {
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
186 unsigned int GetLargestFreeOrPendingSize() {
187 return allocator_
.GetLargestFreeOrPendingSize();
191 RingBuffer allocator_
;
193 DISALLOW_IMPLICIT_CONSTRUCTORS(RingBufferWrapper
);
198 #endif // GPU_COMMAND_BUFFER_CLIENT_RING_BUFFER_H_