Gamp v0.0.7-54-gccdc599
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 GLArrayDataProxyRef = 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_ref;
47
49 typedef std::unique_ptr<buffer_t> buffer_ref;
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 The custom name for the GL attribute, maybe null if gpuBufferTarget is {@link GL#GL_ELEMENT_ARRAY_BUFFER}
61 * @param componentsPerElement The array component number
62 * @param normalized Whether the data shall be normalized
63 * @param stride
64 * @param buffer the user define data, passed through by reference
65 * @param vboName
66 * @param vboOffset
67 * @param vboUsage GL_STREAM_DRAW, GL_STATIC_DRAW or GL_DYNAMIC_DRAW
68 * @param vboTarget GL_ARRAY_BUFFER or GL_ELEMENT_ARRAY_BUFFER
69 * @return the new create instance
70 * @throws GLException
71 */
72 static proxy_ref createGLSL(std::string_view name, GLsizei componentsPerElement, bool normalized, GLsizei stride,
73 buffer_t& buffer, GLuint vboName, uintptr_t vboOffset, GLenum vboUsage, GLenum vboTarget) {
74 return std::make_shared<GLArrayDataProxy>(Private(),
75 name, componentsPerElement, normalized, stride, buffer,
76 /*isVertexAttribute=*/true, vboName, vboOffset, vboUsage, vboTarget);
77 }
78
79 /**
80 * Create a VBO, using a custom GLSL array attribute name, proxying the mapped data characteristics.
81 *
82 * The GL data type is determined via template type glType<Value_type>().
83 *
84 * This buffer is always {@link #sealed()}.
85 *
86 * @param name The custom name for the GL attribute, maybe null if gpuBufferTarget is {@link GL#GL_ELEMENT_ARRAY_BUFFER}
87 * @param componentsPerElement The array component number
88 * @param normalized Whether the data shall be normalized
89 * @param stride
90 * @param mappedElementCount
91 * @param vboName
92 * @param vboOffset
93 * @param vboUsage GL_STREAM_DRAW, GL_STATIC_DRAW or GL_DYNAMIC_DRAW
94 * @param vboTarget GL_ARRAY_BUFFER or GL_ELEMENT_ARRAY_BUFFER
95 * @return the new create instance
96 * @throws GLException
97 */
98 static proxy_ref createGLSL(std::string_view name, GLsizei componentsPerElement, bool normalized, GLsizei stride,
99 GLsizei mappedElementCount, GLuint vboName, uintptr_t vboOffset, GLenum vboUsage, GLenum vboTarget) {
100 return std::make_shared<GLArrayDataProxy>(Private(),
101 name, componentsPerElement, normalized, stride, mappedElementCount,
102 /*isVertexAttribute=*/true, vboName, vboOffset, vboUsage, vboTarget);
103 }
104
105 /** Returns true if using mapped memory, otherwise false for client-data */
106 constexpr bool usesMappedMem() const noexcept { return !m_bufferptr; }
107 /** Returns true if using client-data, otherwise false for mapped memory */
108 constexpr bool usesClientMem() const noexcept { return m_bufferptr; }
109
110 std::string_view className() const noexcept override { return "GLArrayDataProxy"; }
111
112 const jau::type_info& classSignature() const noexcept override {
114 }
115
117
118 /** Returns client-data pointer at current position if usesClientMem(), otherwise nullptr */
119 const void* data() const noexcept override { return usesClientMem() ? reinterpret_cast<const void*>(m_bufferptr->position_ptr()) : nullptr; }
120
121 GLsizei elemCount() const noexcept override {
122 if( usesClientMem() ) {
123 if( m_sealed ) {
124 return static_cast<GLsizei>( (m_bufferptr->limit() * m_bytesPerComp) / m_strideB );
125 } else {
126 return static_cast<GLsizei>( (m_bufferptr->position() * m_bytesPerComp) / m_strideB );
127 }
128 } else {
129 return m_mappedElemCount;
130 }
131 }
132
133 glmemsize_t byteCount() const noexcept override {
134 if( usesClientMem() ) {
135 if( m_sealed ) {
136 return m_bufferptr->limit() * m_bytesPerComp ;
137 } else {
138 return m_bufferptr->position() * m_bytesPerComp ;
139 }
140 } else {
142 }
143 }
144
145 glmemsize_t byteCapacity() const noexcept override {
146 if( usesClientMem() ) {
147 return m_bufferptr->capacity() * m_bytesPerComp;
148 } else {
149 return 0;
150 }
151 }
152
153 std::string elemStatsToString() const noexcept override {
154 const size_t elem_limit = ( (usesClientMem() ? m_bufferptr->limit() : 0) * m_bytesPerComp ) / m_strideB;
155 try {
156 return jau::format_string("sealed %d, elements %s cnt, [%s pos .. %s rem .. %s lim .. %s cap]",
157 sealed(),
158 jau::to_decstring(elemCount()).c_str(),
161 jau::to_decstring(elem_limit).c_str(),
163 } catch (const std::exception &e) {
164 ERR_PRINT2("Caught exception %s", e.what());
165 return "";
166 }
167 }
168
169 void destroy(GL& gl) override {
171 if( usesClientMem() ) {
172 m_bufferptr->clear();
173 }
174 }
175
176 std::string toString() const noexcept override { return toString(false); }
177 virtual std::string toString(bool withData) const noexcept {
178 std::string r(className());
179 r.append("[").append(m_name)
180 .append(", location ").append(std::to_string(m_location))
181 .append(", isVertexAttribute ").append(std::to_string(m_isVertexAttr))
182 .append(", dataType ").append(jau::toHexString(m_compType))
183 .append(", compsPerElem ").append(std::to_string(m_compsPerElement))
184 .append(", stride ").append(std::to_string(m_strideB)).append("b ").append(std::to_string(m_strideL)).append("c")
185 .append(", mappedElemCount ").append(std::to_string(m_mappedElemCount))
186 .append(", ").append(elemStatsToString());
187 if( withData ) {
188 r.append(", buffer ").append(usesClientMem()?m_bufferptr->toString():"nil");
189 }
190 r.append(", vboEnabled ").append(std::to_string(m_vboEnabled))
191 .append(", vboName ").append(std::to_string(m_vboName))
192 .append(", vboUsage ").append(jau::toHexString(m_vboUsage))
193 .append(", vboTarget ").append(jau::toHexString(m_vboTarget))
194 .append(", vboOffset ").append(std::to_string(m_vboOffset))
195 .append(", alive ").append(std::to_string(m_alive)).append("]");
196 return r;
197 }
198
199 /** The Buffer holding the data, nullptr if !usesClientMem() */
200 const buffer_t* buffer_ptr() const noexcept { return m_bufferptr; }
201 /** The Buffer holding the data, nullptr if !usesClientMem() */
202 buffer_t* buffer_ptr() noexcept { return m_bufferptr; }
203
204 /**
205 * Returns the element position.
206 * <p>
207 * On element consist out of {@link #getCompsPerElem()} components.
208 * </p>
209 * @see bytePosition()
210 * @see getElemCount()
211 * @see remainingElems()
212 * @see getElemCapacity()
213 */
214 glmemsize_t elemPosition() const noexcept {
215 if( usesClientMem() ) {
216 return ( m_bufferptr->position() * m_bytesPerComp ) / m_strideB ;
217 } else {
218 return m_mappedElemCount;
219 }
220 }
221
222 /**
223 * The current number of remaining elements.
224 * <p>
225 * On element consist out of {@link #getCompsPerElem()} components.
226 * </p>
227 * Returns the number of elements between the current position and the limit, i.e. remaining elements to write in this buffer.
228 * @see remainingBytes()
229 * @see getElemCount()
230 * @see elemPosition()
231 * @see getElemCapacity()
232 */
233 glmemsize_t remainingElems() const noexcept {
234 if( usesClientMem() ) {
235 return (m_bufferptr->remaining() * m_bytesPerComp) / m_strideB;
236 } else {
237 return 0;
238 }
239 }
240
241 /**
242 * Return the element capacity.
243 * <p>
244 * On element consist out of {@link #getCompsPerElem()} components.
245 * </p>
246 * @see getByteCapacity()
247 * @see getElemCount()
248 * @see elemPosition()
249 * @see remainingElems()
250 */
251 glmemsize_t elemCapacity() const noexcept {
252 if( usesClientMem() ) {
253 return ( m_bufferptr->capacity() * m_bytesPerComp ) / m_strideB ;
254 } else {
255 return 0;
256 }
257 }
258
259 /**
260 * Returns the bytes position.
261 * @see elemPosition
262 * @see getByteCount
263 * @see remainingElems
264 * @see getElemCapacity
265 */
266 glmemsize_t bytePosition() const noexcept {
267 if( usesClientMem() ) {
268 return m_bufferptr->position() * m_bytesPerComp;
269 } else {
271 }
272 }
273
274 /**
275 * The current number of remaining bytes.
276 * <p>
277 * Returns the number of bytes between the current position and the limit, i.e. remaining bytes to write in this buffer.
278 * </p>
279 * @see remainingElems
280 * @see getByteCount
281 * @see bytePosition
282 * @see getByteCapacity
283 */
284 glmemsize_t remainingBytes() const noexcept {
285 if( usesClientMem() ) {
286 return m_bufferptr->remaining() * m_bytesPerComp;
287 } else {
288 return 0;
289 }
290 }
291
292 /**
293 * Returns a string with detailed buffer fill stats.
294 */
295 std::string fillStatsToString() const noexcept {
296 const size_t cnt_bytes = byteCount();
297 const size_t cap_bytes = byteCapacity();
298 const float filled = (float)cnt_bytes / (float)cap_bytes;
299 return jau::format_string("elements %s cnt / %s cap, bytes %s cnt / %s cap, filled %.1f%%, left %.1f%%",
300 jau::to_decstring(elemCount()).c_str(),
302 jau::to_decstring(cnt_bytes).c_str(),
303 jau::to_decstring(cap_bytes).c_str(),
304 filled * 100.0f, (1.0f - filled) * 100.0f);
305 }
306
307 //
308 // OpenGL pass through funcs
309 //
310
311 void glBufferData(const GL& gl) const noexcept {
313 }
314
315 protected:
316 struct Private{ explicit Private() = default; };
317
318 public:
319 // using passing through client buffer_t
321 std::string_view name, GLsizei componentsPerElement,
322 bool normalized, GLsizei stride, buffer_t& buffer,
323 bool isVertexAttribute, GLuint vboName, uintptr_t vboOffset, GLenum vboUsage, GLenum vboTarget)
324 : GLArrayData(GLArrayData::Private(), name, componentsPerElement, glType<value_type>(), jau::make_ctti<value_type>(),
325 normalized, stride, /*mappedElementCount=*/0, isVertexAttribute, vboName, vboOffset, vboUsage, vboTarget),
326 m_bufferptr( &buffer )
327 { }
328
329 // using memory mapped elements
331 std::string_view name, GLsizei componentsPerElement,
332 bool normalized, GLsizei stride, GLsizei mappedElementCount,
333 bool isVertexAttribute, GLuint vboName, uintptr_t vboOffset, GLenum vboUsage, GLenum vboTarget)
334 : GLArrayData(GLArrayData::Private(), name, componentsPerElement, glType<value_type>(), jau::make_ctti<value_type>(),
336 m_bufferptr(nullptr)
337 {
338 if( 0 == mappedElementCount ) {
339 throw jau::IllegalArgumentError("mappedElementCount:=" + std::to_string(mappedElementCount)
340 + " specified for memory map:\n\t" + toStringImpl(), E_FILE_LINE);
341 }
342 }
343
344 protected:
345 // mutable
347 };
348
349 /**@}*/
350
351} // namespace gamp::render::gl
352
353#endif /* GAMP_GLARRAYDATAPROXY_HPP_ */
#define E_FILE_LINE
Proxying a data buffer for GLArrayData usage of given template-type Value_type.
glmemsize_t elemCapacity() const noexcept
Return the element capacity.
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.
const GLArrayDataProxyRef< value_type > shared()
virtual std::string toString(bool withData) const noexcept
buffer_t * buffer_ptr() noexcept
The Buffer holding the data, nullptr if !usesClientMem()
std::string fillStatsToString() const noexcept
Returns a string with detailed buffer fill stats.
static proxy_ref createGLSL(std::string_view name, GLsizei componentsPerElement, bool normalized, GLsizei stride, buffer_t &buffer, GLuint vboName, uintptr_t vboOffset, GLenum vboUsage, GLenum vboTarget)
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
glmemsize_t elemPosition() const noexcept
Returns the element position.
static proxy_ref 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.
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 const std::string & name() const noexcept
The name of the reflecting shader array attribute.
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.
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 ERR_PRINT2(...)
Use for unconditional error messages, prefix '[elapsed_time] Error @ FILE:LINE FUNC: '.
Definition debug.hpp:125
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 > > GLArrayDataProxyRef
constexpr GLenum glType() noexcept
Definition GLTypes.hpp:46
constexpr std::string format_string(const std::string_view format, const Args &...args)
Safely returns a (non-truncated) string according to snprintf() formatting rules using an initially s...
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.
std::string to_decstring(const value_type &v, const char separator=',', const nsize_t width=0) noexcept
Produce a decimal string representation of an integral integer value.
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
Definition backtrace.hpp:32
STL namespace.
uint8_t Value_type