Gamp v0.0.8
Gamp: Graphics, Audio, Multimedia and Processing
Loading...
Searching...
No Matches
GLArrayDataProxy.hpp
Go to the documentation of this file.
1/*
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright Gothel Software e.K.
4 *
5 * SPDX-License-Identifier: MIT
6 *
7 * This Source Code Form is subject to the terms of the MIT License
8 * If a copy of the MIT was not distributed with this file,
9 * you can obtain one at https://opensource.org/license/mit/.
10 */
11
12#ifndef GAMP_GLARRAYDATAPROXY_HPP_
13#define GAMP_GLARRAYDATAPROXY_HPP_
14
15#include <memory>
16
17#include <jau/darray.hpp>
18
21
22namespace gamp::render::gl::data {
23 using namespace gamp::render::gl;
24
25 /** \addtogroup Gamp_GLData
26 *
27 * @{
28 */
29
30 template<typename Value_type>
31 class GLArrayDataProxy;
32
33 template<typename Value_type>
34 using GLArrayDataProxySRef = std::shared_ptr<GLArrayDataProxy<Value_type>>;
35
36 /**
37 * Proxying a data buffer for GLArrayData usage of given template-type Value_type.
38 *
39 * The GL data type is determined via template type glType<Value_type>().
40 */
41 template<typename Value_type>
43 public:
46 typedef std::shared_ptr<proxy_t> proxy_sref;
47
49 typedef std::unique_ptr<buffer_t> buffer_sref;
50
51 ~GLArrayDataProxy() noexcept override = default;
52
53 /**
54 * Create a VBO, using a custom GLSL array attribute name, proxying the given data.
55 *
56 * The GL data type is determined via template type glType<Value_type>().
57 *
58 * This buffer is always {@link #sealed()}.
59 *
60 * @param name Persistent custom name for the GL attribute, maybe empty if gpuBufferTarget is {@link GL#GL_ELEMENT_ARRAY_BUFFER}.
61 * Must be valid through the lifecycle of this instance
62 * @param componentsPerElement The array component number
63 * @param normalized Whether the data shall be normalized
64 * @param stride
65 * @param buffer the user define data, passed through by reference
66 * @param vboName
67 * @param vboOffset
68 * @param vboUsage GL_STREAM_DRAW, GL_STATIC_DRAW or GL_DYNAMIC_DRAW
69 * @param vboTarget GL_ARRAY_BUFFER or GL_ELEMENT_ARRAY_BUFFER
70 * @return the new create instance
71 * @throws GLException
72 */
73 static proxy_sref createGLSL(std::string_view name, GLsizei componentsPerElement, bool normalized, GLsizei stride,
74 buffer_t& buffer, GLuint vboName, uintptr_t vboOffset, GLenum vboUsage, GLenum vboTarget) {
75 return std::make_shared<GLArrayDataProxy>(Private(),
76 name, componentsPerElement, normalized, stride, buffer,
77 /*isVertexAttribute=*/true, vboName, vboOffset, vboUsage, vboTarget);
78 }
79
80 /**
81 * Create a VBO, using a custom GLSL array attribute name, proxying the mapped data characteristics.
82 *
83 * The GL data type is determined via template type glType<Value_type>().
84 *
85 * This buffer is always {@link #sealed()}.
86 *
87 * @param name Persistent custom name for the GL attribute, maybe empty if gpuBufferTarget is {@link GL#GL_ELEMENT_ARRAY_BUFFER}.
88 * Must be valid through the lifecycle of this instance
89 * @param componentsPerElement The array component number
90 * @param normalized Whether the data shall be normalized
91 * @param stride
92 * @param mappedElementCount
93 * @param vboName
94 * @param vboOffset
95 * @param vboUsage GL_STREAM_DRAW, GL_STATIC_DRAW or GL_DYNAMIC_DRAW
96 * @param vboTarget GL_ARRAY_BUFFER or GL_ELEMENT_ARRAY_BUFFER
97 * @return the new create instance
98 * @throws GLException
99 */
100 static proxy_sref createGLSL(std::string_view name, GLsizei componentsPerElement, bool normalized, GLsizei stride,
101 GLsizei mappedElementCount, GLuint vboName, uintptr_t vboOffset, GLenum vboUsage, GLenum vboTarget) {
102 return std::make_shared<GLArrayDataProxy>(Private(),
103 name, componentsPerElement, normalized, stride, mappedElementCount,
104 /*isVertexAttribute=*/true, vboName, vboOffset, vboUsage, vboTarget);
105 }
106
107 /** Returns true if using mapped memory, otherwise false for client-data */
108 constexpr bool usesMappedMem() const noexcept { return !m_bufferptr; }
109 /** Returns true if using client-data, otherwise false for mapped memory */
110 constexpr bool usesClientMem() const noexcept { return m_bufferptr; }
111
112 std::string_view className() const noexcept override { return "GLArrayDataProxy"; }
113
114 const jau::type_info& classSignature() const noexcept override {
116 }
117
119
120 /** Returns client-data pointer at current position if usesClientMem(), otherwise nullptr */
121 const void* data() const noexcept override { return usesClientMem() ? reinterpret_cast<const void*>(m_bufferptr->position_ptr()) : nullptr; }
122
123 GLsizei elemCount() const noexcept override {
124 if( usesClientMem() ) {
125 if( m_sealed ) {
126 return static_cast<GLsizei>( (m_bufferptr->limit() * m_bytesPerComp) / m_strideB );
127 } else {
128 return static_cast<GLsizei>( (m_bufferptr->position() * m_bytesPerComp) / m_strideB );
129 }
130 } else {
131 return m_mappedElemCount;
132 }
133 }
134
135 glmemsize_t byteCount() const noexcept override {
136 if( usesClientMem() ) {
137 if( m_sealed ) {
138 return m_bufferptr->limit() * m_bytesPerComp ;
139 } else {
140 return m_bufferptr->position() * m_bytesPerComp ;
141 }
142 } else {
144 }
145 }
146
147 glmemsize_t byteCapacity() const noexcept override {
148 if( usesClientMem() ) {
149 return m_bufferptr->capacity() * m_bytesPerComp;
150 } else {
151 return 0;
152 }
153 }
154
155 std::string elemStatsToString() const noexcept override {
156 const size_t elem_limit = ( (usesClientMem() ? m_bufferptr->limit() : 0) * m_bytesPerComp ) / m_strideB;
157 try {
158 return jau_format_string("sealed %s, elements %'d cnt, [%'zd pos .. %'zd rem .. %'zu lim .. %'zd cap]",
159 sealed(), elemCount(), elemPosition(), remainingElems(), elem_limit, elemCapacity());
160 } catch (const std::exception &e) {
161 jau_ERR_PRINT2("Caught exception %s", e.what());
162 return "";
163 }
164 }
165
166 void destroy(GL& gl) override {
168 if( usesClientMem() ) {
169 m_bufferptr->clear();
170 }
171 }
172
173 std::string toString() const noexcept override { return toString(false); }
174 virtual std::string toString(bool withData) const noexcept {
175 std::string r(className());
176 r.append("[").append(m_name)
177 .append(", location ").append(std::to_string(m_location))
178 .append(", isVertexAttribute ").append(std::to_string(m_isVertexAttr))
179 .append(", dataType ").append(jau::toHexString(m_compType))
180 .append(", compsPerElem ").append(std::to_string(m_compsPerElement))
181 .append(", stride ").append(std::to_string(m_strideB)).append("b ").append(std::to_string(m_strideL)).append("c")
182 .append(", mappedElemCount ").append(std::to_string(m_mappedElemCount))
183 .append(", ").append(elemStatsToString());
184 if( withData ) {
185 r.append(", buffer ").append(usesClientMem()?m_bufferptr->toString():"nil");
186 }
187 r.append(", vboEnabled ").append(std::to_string(m_vboEnabled))
188 .append(", vboName ").append(std::to_string(m_vboName))
189 .append(", vboUsage ").append(jau::toHexString(m_vboUsage))
190 .append(", vboTarget ").append(jau::toHexString(m_vboTarget))
191 .append(", vboOffset ").append(std::to_string(m_vboOffset))
192 .append(", alive ").append(std::to_string(m_alive)).append("]");
193 return r;
194 }
195
196 /** The Buffer holding the data, nullptr if !usesClientMem() */
197 const buffer_t* buffer_ptr() const noexcept { return m_bufferptr; }
198 /** The Buffer holding the data, nullptr if !usesClientMem() */
199 buffer_t* buffer_ptr() noexcept { return m_bufferptr; }
200
201 /**
202 * Returns the element position.
203 * <p>
204 * On element consist out of {@link #getCompsPerElem()} components.
205 * </p>
206 * @see bytePosition()
207 * @see getElemCount()
208 * @see remainingElems()
209 * @see getElemCapacity()
210 */
211 glmemsize_t elemPosition() const noexcept {
212 if( usesClientMem() ) {
213 return ( m_bufferptr->position() * m_bytesPerComp ) / m_strideB ;
214 } else {
215 return m_mappedElemCount;
216 }
217 }
218
219 /**
220 * The current number of remaining elements.
221 * <p>
222 * On element consist out of {@link #getCompsPerElem()} components.
223 * </p>
224 * Returns the number of elements between the current position and the limit, i.e. remaining elements to write in this buffer.
225 * @see remainingBytes()
226 * @see getElemCount()
227 * @see elemPosition()
228 * @see getElemCapacity()
229 */
230 glmemsize_t remainingElems() const noexcept {
231 if( usesClientMem() ) {
232 return (m_bufferptr->remaining() * m_bytesPerComp) / m_strideB;
233 } else {
234 return 0;
235 }
236 }
237
238 /**
239 * Return the element capacity.
240 * <p>
241 * On element consist out of {@link #getCompsPerElem()} components.
242 * </p>
243 * @see getByteCapacity()
244 * @see getElemCount()
245 * @see elemPosition()
246 * @see remainingElems()
247 */
248 glmemsize_t elemCapacity() const noexcept {
249 if( usesClientMem() ) {
250 return ( m_bufferptr->capacity() * m_bytesPerComp ) / m_strideB ;
251 } else {
252 return 0;
253 }
254 }
255
256 /**
257 * Returns the bytes position.
258 * @see elemPosition
259 * @see getByteCount
260 * @see remainingElems
261 * @see getElemCapacity
262 */
263 glmemsize_t bytePosition() const noexcept {
264 if( usesClientMem() ) {
265 return m_bufferptr->position() * m_bytesPerComp;
266 } else {
268 }
269 }
270
271 /**
272 * The current number of remaining bytes.
273 * <p>
274 * Returns the number of bytes between the current position and the limit, i.e. remaining bytes to write in this buffer.
275 * </p>
276 * @see remainingElems
277 * @see getByteCount
278 * @see bytePosition
279 * @see getByteCapacity
280 */
281 glmemsize_t remainingBytes() const noexcept {
282 if( usesClientMem() ) {
283 return m_bufferptr->remaining() * m_bytesPerComp;
284 } else {
285 return 0;
286 }
287 }
288
289 /**
290 * Returns a string with detailed buffer fill stats.
291 */
292 std::string fillStatsToString() const noexcept {
293 const size_t cnt_bytes = byteCount();
294 const size_t cap_bytes = byteCapacity();
295 const float filled = (float)cnt_bytes / (float)cap_bytes;
296 return jau::format_string("elements %'d cnt / %'zd cap, bytes %'zu cnt / %'zu cap, filled %.1f%%, left %.1f%%",
297 elemCount(), elemCapacity(), cnt_bytes, cap_bytes, filled * 100.0f, (1.0f - filled) * 100.0f);
298 }
299
300 //
301 // OpenGL pass through funcs
302 //
303
304 void glBufferData(const GL& gl) const noexcept {
306 }
307
308 protected:
309 struct Private{ explicit Private() = default; };
310
311 public:
312 // using passing through client buffer_t
314 std::string_view name, GLsizei componentsPerElement,
315 bool normalized, GLsizei stride, buffer_t& buffer,
316 bool isVertexAttribute, GLuint vboName, uintptr_t vboOffset, GLenum vboUsage, GLenum vboTarget)
317 : GLArrayData(GLArrayData::Private(), name, componentsPerElement, glType<value_type>(), jau::make_ctti<value_type>(),
318 normalized, stride, /*mappedElementCount=*/0, isVertexAttribute, vboName, vboOffset, vboUsage, vboTarget),
319 m_bufferptr( &buffer )
320 { }
321
322 // using memory mapped elements
324 std::string_view name, GLsizei componentsPerElement,
325 bool normalized, GLsizei stride, GLsizei mappedElementCount,
326 bool isVertexAttribute, GLuint vboName, uintptr_t vboOffset, GLenum vboUsage, GLenum vboTarget)
327 : GLArrayData(GLArrayData::Private(), name, componentsPerElement, glType<value_type>(), jau::make_ctti<value_type>(),
329 m_bufferptr(nullptr)
330 {
331 if( 0 == mappedElementCount ) {
332 throw jau::IllegalArgumentError("mappedElementCount:=" + std::to_string(mappedElementCount)
333 + " specified for memory map:\n\t" + toStringImpl(), E_FILE_LINE);
334 }
335 }
336
337 protected:
338 // mutable
340 };
341
342 /**@}*/
343
344} // namespace gamp::render::gl
345
346#endif /* GAMP_GLARRAYDATAPROXY_HPP_ */
Proxying a data buffer for GLArrayData usage of given template-type Value_type.
glmemsize_t elemCapacity() const noexcept
Return the element capacity.
static proxy_sref createGLSL(std::string_view name, GLsizei componentsPerElement, bool normalized, GLsizei stride, GLsizei mappedElementCount, GLuint vboName, uintptr_t vboOffset, GLenum vboUsage, GLenum vboTarget)
Create a VBO, using a custom GLSL array attribute name, proxying the mapped data characteristics.
constexpr bool usesMappedMem() const noexcept
Returns true if using mapped memory, otherwise false for client-data.
const buffer_t * buffer_ptr() const noexcept
The Buffer holding the data, nullptr if !usesClientMem()
glmemsize_t byteCount() const noexcept override
Returns the byte position (written elements) if not sealed() or the byte limit (available to read) af...
std::string_view className() const noexcept override
Returns class name of implementing class.
glmemsize_t remainingElems() const noexcept
The current number of remaining elements.
glmemsize_t bytePosition() const noexcept
Returns the bytes position.
virtual std::string toString(bool withData) const noexcept
buffer_t * buffer_ptr() noexcept
The Buffer holding the data, nullptr if !usesClientMem()
const GLArrayDataProxySRef< value_type > shared()
std::string fillStatsToString() const noexcept
Returns a string with detailed buffer fill stats.
std::string elemStatsToString() const noexcept override
Returns a string with detailed buffer element stats, i.e.
GLsizei elemCount() const noexcept override
Returns the element position (written elements) if not sealed() or the element limit (available to re...
GLArrayDataProxy(Private, std::string_view name, GLsizei componentsPerElement, bool normalized, GLsizei stride, GLsizei mappedElementCount, bool isVertexAttribute, GLuint vboName, uintptr_t vboOffset, GLenum vboUsage, GLenum vboTarget)
GLArrayDataProxy(Private, std::string_view name, GLsizei componentsPerElement, bool normalized, GLsizei stride, buffer_t &buffer, bool isVertexAttribute, GLuint vboName, uintptr_t vboOffset, GLenum vboUsage, GLenum vboTarget)
jau::darray< value_type, glmemsize_t > buffer_t
std::string toString() const noexcept override
static proxy_sref createGLSL(std::string_view name, GLsizei componentsPerElement, bool normalized, GLsizei stride, buffer_t &buffer, GLuint vboName, uintptr_t vboOffset, GLenum vboUsage, GLenum vboTarget)
glmemsize_t elemPosition() const noexcept
Returns the element position.
glmemsize_t remainingBytes() const noexcept
The current number of remaining bytes.
const void * data() const noexcept override
Returns client-data pointer at current position if usesClientMem(), otherwise nullptr.
~GLArrayDataProxy() noexcept override=default
const jau::type_info & classSignature() const noexcept override
Returns type signature of implementing class.
void glBufferData(const GL &gl) const noexcept
constexpr bool usesClientMem() const noexcept
Returns true if using client-data, otherwise false for mapped memory.
glmemsize_t byteCapacity() const noexcept override
Return the capacity in bytes.
constexpr bool sealed() const noexcept
Returns true if data has been sealed (flipped to read), otherwise false (writing mode).
void glBufferData(const GL &, glmemsize_t size) const noexcept
Sends (creates, updates) the data to the bound vboName buffer, see glBindBuffer().
constexpr uintptr_t vboOffset() const noexcept
The VBO buffer offset if isVBO()
constexpr GLuint vboName() const noexcept
The VBO name or 0 if not a VBO.
constexpr bool isVertexAttribute() const noexcept
Returns true if this data set is intended for a GLSL vertex shader attribute, otherwise false,...
GLsizei m_strideB
stride in bytes; strideB >= compsPerElement * bytesPerComp
constexpr GLenum vboUsage() const noexcept
The VBO usage or 0 if not a VBO.
std::string toStringImpl() const noexcept
GLsizei stride() const noexcept
constexpr bool normalized() const noexcept
True, if GL shall normalize fixed point data while converting them into float.
GLsizei m_strideL
stride in logical components
GLArrayData(Private, std::string_view name, GLsizei componentsPerElement, GLenum componentType, jau::type_info compTypeSignature, bool normalized, GLsizei stride, GLsizei mappedElementCount, bool isVertexAttribute, GLuint vboName, uintptr_t vboOffset, GLenum vboUsage, GLenum vboTarget)
Private ctor for shared_ptr.
std::shared_ptr< ChildT > shared_from_base()
constexpr GLenum vboTarget() const noexcept
The VBO target or 0 if not a VBO.
constexpr const std::string_view name() const noexcept
The name of the reflecting shader array attribute.
Implementation of a dynamic linear array storage, aka vector, including relative positional access.
Definition darray.hpp:154
Generic type information using either Runtime type information (RTTI) or Compile time type informatio...
#define jau_ERR_PRINT2(...)
Use for unconditional error messages, prefix '[elapsed_time] Error @ FILE:LINE FUNC: '.
Definition debug.hpp:155
#define E_FILE_LINE
const jau::type_info & static_ctti() noexcept
Returns a static global reference of make_ctti<T>(true) w/ identity instance.
GLsizeiptr glmemsize_t
Compatible with ssize_t.
Definition GLBuffers.hpp:26
std::shared_ptr< GLArrayDataProxy< Value_type > > GLArrayDataProxySRef
constexpr GLenum glType() noexcept
Definition GLTypes.hpp:46
#define jau_format_string(fmt,...)
Macro, safely returns a (non-truncated) string according to snprintf() formatting rules using a reser...
std::string toHexString(const void *data, const nsize_t length, const lb_endian_t byteOrder=lb_endian_t::big, const LoUpCase capitalization=LoUpCase::lower, const PrefixOpt prefix=PrefixOpt::prefix) noexcept
Produce a hexadecimal string representation of the given lsb-first byte values.
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
Definition backtrace.hpp:32
std::string format_string(std::string_view fmt, const Args &...args) noexcept
Safely returns a (non-truncated) string according to snprintf() formatting rules using a reserved str...
STL namespace.
uint8_t Value_type