- add sources.
[platform/framework/web/crosswalk.git] / src / gpu / command_buffer / client / ring_buffer.h
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 "gpu/command_buffer/common/logging.h"
13 #include "gpu/command_buffer/common/types.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   //   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);
33
34   ~RingBuffer();
35
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.
39   //
40   // Parameters:
41   //   size: the size of the memory block to allocate.
42   //
43   // Returns:
44   //   the offset of the allocated memory block.
45   Offset Alloc(unsigned int size);
46
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.
49   //
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);
54
55   // Gets the size of the largest free block that is available without waiting.
56   unsigned int GetLargestFreeSizeNoWaiting();
57
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_;
63   }
64
65  private:
66   enum State {
67     IN_USE,
68     PADDING,
69     FREE_PENDING_TOKEN
70   };
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) {
78     }
79     Offset offset;
80     unsigned int size;
81     unsigned int token;  // token to wait for.
82     State state;
83   };
84
85   typedef std::deque<Block> Container;
86   typedef unsigned int BlockIndex;
87
88   void FreeOldestBlock();
89
90   CommandBufferHelper* helper_;
91
92   // Used blocks are added to the end, blocks are freed from the beginning.
93   Container blocks_;
94
95   // The base offset of the ring buffer.
96   Offset base_offset_;
97
98   // The size of the ring buffer.
99   Offset size_;
100
101   // Offset of first free byte.
102   Offset free_offset_;
103
104   // Offset of first used byte.
105   // Range between in_use_mark and free_mark is in use.
106   Offset in_use_offset_;
107
108   DISALLOW_IMPLICIT_CONSTRUCTORS(RingBuffer);
109 };
110
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) {
126   }
127
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.
131   //
132   // Parameters:
133   //   size: the size of the memory block to allocate.
134   //
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);
141   }
142
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.
147   //
148   // Parameters:
149   //   count: the number of elements to allocate.
150   //
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)));
156   }
157
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.
160   //
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     GPU_DCHECK(pointer);
166     allocator_.FreePendingToken(GetOffset(pointer), token);
167   }
168
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;
172   }
173
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_);
177   }
178
179   // Gets the size of the largest free block that is available without waiting.
180   unsigned int GetLargestFreeSizeNoWaiting() {
181     return allocator_.GetLargestFreeSizeNoWaiting();
182   }
183
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();
188   }
189
190  private:
191   RingBuffer allocator_;
192   void* base_;
193   DISALLOW_IMPLICIT_CONSTRUCTORS(RingBufferWrapper);
194 };
195
196 }  // namespace gpu
197
198 #endif  // GPU_COMMAND_BUFFER_CLIENT_RING_BUFFER_H_