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 #ifndef GPU_COMMAND_BUFFER_CLIENT_TRANSFER_BUFFER_H_
6 #define GPU_COMMAND_BUFFER_CLIENT_TRANSFER_BUFFER_H_
8 #include "base/memory/scoped_ptr.h"
9 #include "gpu/command_buffer/client/ring_buffer.h"
10 #include "gpu/command_buffer/common/buffer.h"
11 #include "gpu/command_buffer/common/compiler_specific.h"
12 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
13 #include "gpu/gpu_export.h"
17 class CommandBufferHelper
;
19 // Wraps RingBufferWrapper to provide aligned allocations.
20 class AlignedRingBuffer
: public RingBufferWrapper
{
23 unsigned int alignment
,
25 RingBuffer::Offset base_offset
,
27 CommandBufferHelper
* helper
,
29 : RingBufferWrapper(base_offset
, size
, helper
, base
),
30 alignment_(alignment
),
35 // Hiding Alloc from RingBufferWrapper
36 void* Alloc(unsigned int size
) {
37 return RingBufferWrapper::Alloc(RoundToAlignment(size
));
40 int32
GetShmId() const {
45 unsigned int RoundToAlignment(unsigned int size
) {
46 return (size
+ alignment_
- 1) & ~(alignment_
- 1);
49 unsigned int alignment_
;
53 // Interface for managing the transfer buffer.
54 class GPU_EXPORT TransferBufferInterface
{
56 TransferBufferInterface() { }
57 virtual ~TransferBufferInterface() { }
59 virtual bool Initialize(
60 unsigned int buffer_size
,
61 unsigned int result_size
,
62 unsigned int min_buffer_size
,
63 unsigned int max_buffer_size
,
64 unsigned int alignment
,
65 unsigned int size_to_flush
) = 0;
67 virtual int GetShmId() = 0;
68 virtual void* GetResultBuffer() = 0;
69 virtual int GetResultOffset() = 0;
71 virtual void Free() = 0;
73 virtual bool HaveBuffer() const = 0;
75 // Allocates up to size bytes.
76 virtual void* AllocUpTo(unsigned int size
, unsigned int* size_allocated
) = 0;
78 // Allocates size bytes.
79 // Note: Alloc will fail if it can not return size bytes.
80 virtual void* Alloc(unsigned int size
) = 0;
82 virtual RingBuffer::Offset
GetOffset(void* pointer
) const = 0;
84 virtual void FreePendingToken(void* p
, unsigned int token
) = 0;
87 // Class that manages the transfer buffer.
88 class GPU_EXPORT TransferBuffer
: public TransferBufferInterface
{
90 TransferBuffer(CommandBufferHelper
* helper
);
91 virtual ~TransferBuffer();
93 // Overridden from TransferBufferInterface.
94 virtual bool Initialize(
95 unsigned int default_buffer_size
,
96 unsigned int result_size
,
97 unsigned int min_buffer_size
,
98 unsigned int max_buffer_size
,
99 unsigned int alignment
,
100 unsigned int size_to_flush
) OVERRIDE
;
101 virtual int GetShmId() OVERRIDE
;
102 virtual void* GetResultBuffer() OVERRIDE
;
103 virtual int GetResultOffset() OVERRIDE
;
104 virtual void Free() OVERRIDE
;
105 virtual bool HaveBuffer() const OVERRIDE
;
106 virtual void* AllocUpTo(
107 unsigned int size
, unsigned int* size_allocated
) OVERRIDE
;
108 virtual void* Alloc(unsigned int size
) OVERRIDE
;
109 virtual RingBuffer::Offset
GetOffset(void* pointer
) const OVERRIDE
;
110 virtual void FreePendingToken(void* p
, unsigned int token
) OVERRIDE
;
112 // These are for testing.
113 unsigned int GetCurrentMaxAllocationWithoutRealloc() const;
114 unsigned int GetMaxAllocation() const;
117 // Tries to reallocate the ring buffer if it's not large enough for size.
118 void ReallocateRingBuffer(unsigned int size
);
120 void AllocateRingBuffer(unsigned int size
);
122 CommandBufferHelper
* helper_
;
123 scoped_ptr
<AlignedRingBuffer
> ring_buffer_
;
125 // size reserved for results
126 unsigned int result_size_
;
128 // default size. Size we want when starting or re-allocating
129 unsigned int default_buffer_size_
;
131 // min size we'll consider successful
132 unsigned int min_buffer_size_
;
134 // max size we'll let the buffer grow
135 unsigned int max_buffer_size_
;
137 // alignment for allocations
138 unsigned int alignment_
;
140 // Size at which to do an async flush. 0 = never.
141 unsigned int size_to_flush_
;
143 // Number of bytes since we last flushed.
144 unsigned int bytes_since_last_flush_
;
146 // the current buffer.
149 // id of buffer. -1 = no buffer
152 // address of result area
153 void* result_buffer_
;
155 // offset to result area
156 uint32 result_shm_offset_
;
158 // false if we failed to allocate min_buffer_size
162 // A class that will manage the lifetime of a transferbuffer allocation.
163 class GPU_EXPORT ScopedTransferBufferPtr
{
165 ScopedTransferBufferPtr(
167 CommandBufferHelper
* helper
,
168 TransferBufferInterface
* transfer_buffer
)
172 transfer_buffer_(transfer_buffer
) {
176 ~ScopedTransferBufferPtr() {
181 return buffer_
!= NULL
;
184 unsigned int size() const {
189 return transfer_buffer_
->GetShmId();
192 RingBuffer::Offset
offset() const {
193 return transfer_buffer_
->GetOffset(buffer_
);
196 void* address() const {
202 void Reset(unsigned int new_size
);
207 CommandBufferHelper
* helper_
;
208 TransferBufferInterface
* transfer_buffer_
;
209 DISALLOW_COPY_AND_ASSIGN(ScopedTransferBufferPtr
);
212 template <typename T
>
213 class ScopedTransferBufferArray
: public ScopedTransferBufferPtr
{
215 ScopedTransferBufferArray(
216 unsigned int num_elements
,
217 CommandBufferHelper
* helper
, TransferBufferInterface
* transfer_buffer
)
218 : ScopedTransferBufferPtr(
219 num_elements
* sizeof(T
), helper
, transfer_buffer
) {
223 return static_cast<T
*>(address());
226 unsigned int num_elements() const {
227 return size() / sizeof(T
);
233 #endif // GPU_COMMAND_BUFFER_CLIENT_TRANSFER_BUFFER_H_