Handle account removal correctly on all platforms.
[chromium-blink-merge.git] / gpu / command_buffer / client / fenced_allocator.h
blob8e222e135bf6a329988141138a657e87f8be6c79
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 FencedAllocator class.
7 #ifndef GPU_COMMAND_BUFFER_CLIENT_FENCED_ALLOCATOR_H_
8 #define GPU_COMMAND_BUFFER_CLIENT_FENCED_ALLOCATOR_H_
10 #include <stdint.h>
12 #include <vector>
14 #include "base/bind.h"
15 #include "base/logging.h"
16 #include "base/macros.h"
17 #include "gpu/gpu_export.h"
19 namespace gpu {
20 class CommandBufferHelper;
22 // FencedAllocator provides a mechanism to manage allocations within a fixed
23 // block of memory (storing the book-keeping externally). Furthermore this
24 // class allows to free data "pending" the passage of a command buffer token,
25 // that is, the memory won't be reused until the command buffer has processed
26 // that token.
28 // NOTE: Although this class is intended to be used in the command buffer
29 // environment which is multi-process, this class isn't "thread safe", because
30 // it isn't meant to be shared across modules. It is thread-compatible though
31 // (see http://www.corp.google.com/eng/doc/cpp_primer.html#thread_safety).
32 class GPU_EXPORT FencedAllocator {
33 public:
34 typedef unsigned int Offset;
35 // Invalid offset, returned by Alloc in case of failure.
36 static const Offset kInvalidOffset = 0xffffffffU;
38 // Creates a FencedAllocator. Note that the size of the buffer is passed, but
39 // not its base address: everything is handled as offsets into the buffer.
40 FencedAllocator(unsigned int size,
41 CommandBufferHelper *helper,
42 const base::Closure& poll_callback);
44 ~FencedAllocator();
46 // Allocates a block of memory. If the buffer is out of directly available
47 // memory, this function may wait until memory that was freed "pending a
48 // token" can be re-used.
50 // Parameters:
51 // size: the size of the memory block to allocate.
53 // Returns:
54 // the offset of the allocated memory block, or kInvalidOffset if out of
55 // memory.
56 Offset Alloc(unsigned int size);
58 // Frees a block of memory.
60 // Parameters:
61 // offset: the offset of the memory block to free.
62 void Free(Offset offset);
64 // Frees a block of memory, pending the passage of a token. That memory won't
65 // be re-allocated until the token has passed through the command stream.
67 // Parameters:
68 // offset: the offset of the memory block to free.
69 // token: the token value to wait for before re-using the memory.
70 void FreePendingToken(Offset offset, int32 token);
72 // Frees any blocks pending a token for which the token has been read.
73 void FreeUnused();
75 // Gets the size of the largest free block that is available without waiting.
76 unsigned int GetLargestFreeSize();
78 // Gets the size of the largest free block that can be allocated if the
79 // caller can wait. Allocating a block of this size will succeed, but may
80 // block.
81 unsigned int GetLargestFreeOrPendingSize();
83 // Checks for consistency inside the book-keeping structures. Used for
84 // testing.
85 bool CheckConsistency();
87 // True if any memory is allocated.
88 bool InUse();
90 // Return bytes of memory that is IN_USE
91 size_t bytes_in_use() const { return bytes_in_use_; }
93 private:
94 // Status of a block of memory, for book-keeping.
95 enum State {
96 IN_USE,
97 FREE,
98 FREE_PENDING_TOKEN
101 // Book-keeping sturcture that describes a block of memory.
102 struct Block {
103 State state;
104 Offset offset;
105 unsigned int size;
106 int32_t token; // token to wait for in the FREE_PENDING_TOKEN case.
109 // Comparison functor for memory block sorting.
110 class OffsetCmp {
111 public:
112 bool operator() (const Block &left, const Block &right) {
113 return left.offset < right.offset;
117 typedef std::vector<Block> Container;
118 typedef unsigned int BlockIndex;
120 static const int32_t kUnusedToken = 0;
122 // Gets the index of a memory block, given its offset.
123 BlockIndex GetBlockByOffset(Offset offset);
125 // Collapse a free block with its neighbours if they are free. Returns the
126 // index of the collapsed block.
127 // NOTE: this will invalidate block indices.
128 BlockIndex CollapseFreeBlock(BlockIndex index);
130 // Waits for a FREE_PENDING_TOKEN block to be usable, and free it. Returns
131 // the new index of that block (since it may have been collapsed).
132 // NOTE: this will invalidate block indices.
133 BlockIndex WaitForTokenAndFreeBlock(BlockIndex index);
135 // Allocates a block of memory inside a given block, splitting it in two
136 // (unless that block is of the exact requested size).
137 // NOTE: this will invalidate block indices.
138 // Returns the offset of the allocated block (NOTE: this is different from
139 // the other functions that return a block index).
140 Offset AllocInBlock(BlockIndex index, unsigned int size);
142 CommandBufferHelper *helper_;
143 base::Closure poll_callback_;
144 Container blocks_;
145 size_t bytes_in_use_;
147 DISALLOW_IMPLICIT_CONSTRUCTORS(FencedAllocator);
150 // This class functions just like FencedAllocator, but its API uses pointers
151 // instead of offsets.
152 class FencedAllocatorWrapper {
153 public:
154 FencedAllocatorWrapper(unsigned int size,
155 CommandBufferHelper* helper,
156 const base::Closure& poll_callback,
157 void* base)
158 : allocator_(size, helper, poll_callback),
159 base_(base) { }
161 // Allocates a block of memory. If the buffer is out of directly available
162 // memory, this function may wait until memory that was freed "pending a
163 // token" can be re-used.
165 // Parameters:
166 // size: the size of the memory block to allocate.
168 // Returns:
169 // the pointer to the allocated memory block, or NULL if out of
170 // memory.
171 void *Alloc(unsigned int size) {
172 FencedAllocator::Offset offset = allocator_.Alloc(size);
173 return GetPointer(offset);
176 // Allocates a block of memory. If the buffer is out of directly available
177 // memory, this function may wait until memory that was freed "pending a
178 // token" can be re-used.
179 // This is a type-safe version of Alloc, returning a typed pointer.
181 // Parameters:
182 // count: the number of elements to allocate.
184 // Returns:
185 // the pointer to the allocated memory block, or NULL if out of
186 // memory.
187 template <typename T> T *AllocTyped(unsigned int count) {
188 return static_cast<T *>(Alloc(count * sizeof(T)));
191 // Frees a block of memory.
193 // Parameters:
194 // pointer: the pointer to the memory block to free.
195 void Free(void *pointer) {
196 DCHECK(pointer);
197 allocator_.Free(GetOffset(pointer));
200 // Frees a block of memory, pending the passage of a token. That memory won't
201 // be re-allocated until the token has passed through the command stream.
203 // Parameters:
204 // pointer: the pointer to the memory block to free.
205 // token: the token value to wait for before re-using the memory.
206 void FreePendingToken(void *pointer, int32 token) {
207 DCHECK(pointer);
208 allocator_.FreePendingToken(GetOffset(pointer), token);
211 // Frees any blocks pending a token for which the token has been read.
212 void FreeUnused() {
213 allocator_.FreeUnused();
216 // Gets a pointer to a memory block given the base memory and the offset.
217 // It translates FencedAllocator::kInvalidOffset to NULL.
218 void *GetPointer(FencedAllocator::Offset offset) {
219 return (offset == FencedAllocator::kInvalidOffset) ?
220 NULL : static_cast<char *>(base_) + offset;
223 // Gets the offset to a memory block given the base memory and the address.
224 // It translates NULL to FencedAllocator::kInvalidOffset.
225 FencedAllocator::Offset GetOffset(void *pointer) {
226 return pointer ?
227 static_cast<FencedAllocator::Offset>(
228 static_cast<char*>(pointer) - static_cast<char*>(base_)) :
229 FencedAllocator::kInvalidOffset;
232 // Gets the size of the largest free block that is available without waiting.
233 unsigned int GetLargestFreeSize() {
234 return allocator_.GetLargestFreeSize();
237 // Gets the size of the largest free block that can be allocated if the
238 // caller can wait.
239 unsigned int GetLargestFreeOrPendingSize() {
240 return allocator_.GetLargestFreeOrPendingSize();
243 // Checks for consistency inside the book-keeping structures. Used for
244 // testing.
245 bool CheckConsistency() {
246 return allocator_.CheckConsistency();
249 // True if any memory is allocated.
250 bool InUse() {
251 return allocator_.InUse();
254 FencedAllocator &allocator() { return allocator_; }
256 size_t bytes_in_use() const { return allocator_.bytes_in_use(); }
258 private:
259 FencedAllocator allocator_;
260 void* base_;
261 DISALLOW_IMPLICIT_CONSTRUCTORS(FencedAllocatorWrapper);
264 } // namespace gpu
266 #endif // GPU_COMMAND_BUFFER_CLIENT_FENCED_ALLOCATOR_H_