📄 gim_memory.h
字号:
//terminate gimpact
gimpact_terminate();
}
\endcode
\sa BUFFERS
*/
//! @{
//! Buffer managed array struct.
struct GBUFFER_ARRAY
{
GBUFFER_ID m_buffer_id;
char * m_buffer_data;
char m_byte_stride;
GUINT m_byte_offset;
GUINT m_element_count;
};
//typedef struct _GBUFFER_ARRAY GBUFFER_ARRAY;
//! Sets offset for a buffered array.
#define GIM_BUFFER_ARRAY_SET_OFFSET(_array_data,_offset) (_array_data).m_byte_offset = _offset*(_array_data).m_byte_stride;
//! Sets offset for a buffered array.
#define GIM_BUFFER_ARRAY_GET_OFFSET(_array_data,_offset) _offset = (_array_data).m_byte_offset/(_array_data).m_byte_stride;
//!Return a pointer of the element at the _index
#define GIM_BUFFER_ARRAY_POINTER(_type,_array_data,_index) (_type *)((_array_data).m_buffer_data + _index*(_array_data).m_byte_stride)
//! Sets stride for a buffered array.
#define GIM_BUFFER_ARRAY_SET_STRIDE(_type,_array_data) (_array_data).m_byte_stride = sizeof(_type);
//! Is array stride equal to the size of the type ?
#define GIM_BUFFER_ARRAY_IS_ALIGNED(_type,_array_data) ((_array_data).m_byte_stride == sizeof(_type))
///Verify if two arrays have the same data
#define GIM_BUFFER_ARRAY_ARE_SAME(_array_data1,_array_data2,aresame)\
{\
aresame = 1;\
if((_array_data1).m_buffer_id.m_buffer_id != (_array_data2).m_buffer_id.m_buffer_id || (_array_data1).m_buffer_id.m_buffer_manager_id != (_array_data2).m_buffer_id.m_buffer_manager_id || (_array_data1).m_byte_offset != (_array_data2).m_byte_offset)\
{\
aresame = 0;\
}\
}\
//! Reserve size for a buffered array.
/*!
\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
*/
#define GIM_BUFFER_ARRAY_RESERVE_SIZE(type,array_data,reserve_size)\
{ \
if(reserve_size>(array_data).m_element_count)\
{\
GUINT _buffer_size,_newarray_size;\
gim_get_buffer_size(&(array_data).m_buffer_id,_buffer_size);\
_newarray_size = reserve_size*(array_data).m_byte_stride;\
if(_newarray_size>_buffer_size)\
{ \
_newarray_size += G_ARRAY_GROW_SIZE*(array_data).m_byte_stride;\
gim_buffer_realloc(&(array_data).m_buffer_id,_newarray_size);\
}\
}\
}\
//! Pushes an element at last position
/*!
\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
*/
#define GIM_BUFFER_ARRAY_PUSH_ITEM(type,array_data,item)\
{\
GIM_BUFFER_ARRAY_RESERVE_SIZE(type,array_data,(array_data).m_element_count+1);\
gim_buffer_array_lock(&array_data,G_MA_WRITE_ONLY);\
type * _pt = GIM_BUFFER_ARRAY_POINTER(type,array_data,(array_data).m_element_count);\
memcpy(_pt,&item,sizeof(type));\
gim_buffer_array_unlock(&array_data);\
(array_data)->m_element_count++; \
}\
//! Pushes a new element at last position
/*!
\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
*/
#define GIM_BUFFER_ARRAY_PUSH_EMPTY(type,array_data)\
{\
GIM_BUFFER_ARRAY_RESERVE_SIZE(type,array_data,(array_data).m_element_count+1);\
array_data->m_element_count++; \
}\
//! Inserts an element
/*!
\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
*/
#define GIM_BUFFER_ARRAY_INSERT_ITEM(type,array_data,item,index) \
{ \
GIM_BUFFER_ARRAY_RESERVE_SIZE(type,array_data,(array_data).m_element_count+1);\
gim_buffer_array_lock(&array_data,G_MA_WRITE_ONLY);\
type * _pt = GIM_BUFFER_ARRAY_POINTER(type,array_data,0);\
if(index<(array_data)->m_element_count-1) \
{ \
memcpy(&_pt[index+1],&_pt[index],((array_data).m_element_count-index)*sizeof(type));\
} \
memcpy(&_pt[index],&item,sizeof(type));\
gim_buffer_array_unlock(&array_data);\
(array_data).m_element_count++; \
}\
//! Deletes an element
/*!
\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
*/
#define GIM_BUFFER_ARRAY_DELETE_ITEM(type,array_data,index) \
{ \
if(index<(array_data).m_element_count-1) \
{ \
gim_buffer_array_lock(&array_data,G_MA_WRITE_ONLY);\
type * _pt = GIM_BUFFER_ARRAY_POINTER(type,array_data,0);\
memcpy(&_pt[index],&_pt[index+1],((array_data).m_element_count-index-1)*sizeof(type));\
gim_buffer_array_unlock(&array_data);\
} \
(array_data).m_element_count--; \
}\
//! Deletes an element at last position
/*!
\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
*/
#define GIM_BUFFER_ARRAY_POP_ITEM(array_data) \
{ \
if((array_data).m_element_count>0) \
{ \
(array_data).m_element_count--; \
} \
}\
//! Initializes an GBUFFER_ARRAY object from a buffer ID
/*!
m_buffer_data will be 0, for acces to the elements, you'd need to call lock_array
\param array_data Array structure to be filled
\param buffer_id A GBUFFER_ID structure which this array_daya will refer to
\param element_count Number of elements
\param offset element offset, it isn't byte offset. 0 is recomended
\param byte_stride size of each element. 0 is recomended.
\post Adds reference to the buffer
\sa gim_buffer_add_ref
*/
#define GIM_BUFFER_ARRAY_INIT_OFFSET_STRIDE(array_data,buffer_id,element_count,offset,byte_stride)\
{\
(array_data).m_buffer_id.m_buffer_id = (buffer_id).m_buffer_id;\
(array_data).m_buffer_id.m_buffer_manager_id = (buffer_id).m_buffer_manager_id;\
(array_data).m_buffer_data = 0;\
(array_data).m_element_count = element_count;\
(array_data).m_byte_stride = byte_stride;\
GIM_BUFFER_ARRAY_SET_OFFSET(array_data,offset);\
gim_buffer_add_ref(&(buffer_id));\
}\
//! Initializes an GBUFFER_ARRAY object from a buffer ID and a Given type
/*!
m_buffer_data will be 0, for acces to the elements, you'd need to call lock_array
\param type Type of the Array. It determines the stride.
\param array_data Array structure to be filled
\param buffer_id A GBUFFER_ID structure which this array_daya will refer to
\param element_count Number of elements
\param offset element offset, it isn't byte offset. 0 is recomended
\post Adds reference to the buffer
\sa gim_buffer_add_ref
*/
#define GIM_BUFFER_ARRAY_INIT_TYPE_OFFSET(type,array_data,buffer_id,element_count,offset)\
{\
(array_data).m_buffer_id.m_buffer_id = (buffer_id).m_buffer_id;\
(array_data).m_buffer_id.m_buffer_manager_id = (buffer_id).m_buffer_manager_id;\
(array_data).m_buffer_data = 0;\
(array_data).m_element_count = element_count;\
GIM_BUFFER_ARRAY_SET_STRIDE(type,array_data);\
GIM_BUFFER_ARRAY_SET_OFFSET(array_data,offset);\
gim_buffer_add_ref(&(buffer_id));\
}\
//! Initializes a buffer array giving a data type and a buffer id
/*!
m_buffer_data will be 0, for acces to the elements, you'd need to call lock_array.
\param type Type of the Array. It determines the stride.
\param array_data Array structure to be filled
\param buffer_id A GBUFFER_ID structure which this array_daya will refer to
\param element_count Number of elements
\post Adds reference to the buffer
\sa gim_buffer_add_ref
*/
#define GIM_BUFFER_ARRAY_INIT_TYPE(type,array_data,buffer_id,element_count) GIM_BUFFER_ARRAY_INIT_TYPE_OFFSET(type,array_data,buffer_id,element_count,0)
//! Gain access to the array buffer through the m_buffer_data element
/*!
m_buffer_data pointer will be located at the m_byte_offset position of the buffer m_buffer
Then, You'd need to call unlock_array when finish to using the array access.
\pre if m_buffer_data != 0, the function returns
\param array_data Array structure to be locked
\param access A constant for access to the buffer. can be G_MA_READ_ONLY,G_MA_WRITE_ONLY or G_MA_READ_WRITE
\return an Buffer error code
*/
GINT gim_buffer_array_lock(GBUFFER_ARRAY * array_data, int access);
//! close the access to the array buffer through the m_buffer_data element
/*!
\param array_data Array structure to be locked
\return an Buffer error code
*/
GINT gim_buffer_array_unlock(GBUFFER_ARRAY * array_data);
//! Copy an array by reference
/*!
\post A reference to the m_buffer_id is increased.
*/
void gim_buffer_array_copy_ref(GBUFFER_ARRAY * source_data,GBUFFER_ARRAY * dest_data);
//! Copy an array by value
/*!
\post A new buffer is created
*/
void gim_buffer_array_copy_value(GBUFFER_ARRAY * source_data,GBUFFER_ARRAY * dest_data, GUINT buffer_manager_id,int usage);
//! Destroys an GBUFFER_ARRAY object
/*!
\post Attemps to destroy the buffer, decreases reference counting
*/
void GIM_BUFFER_ARRAY_DESTROY(GBUFFER_ARRAY & array_data);
//! Copy the content of the array to a pointer
/*!
\pre dest_data must have the same size as the array_data
\param type
\param array_data A GBUFFERED_ARRAY structure
\param dest_data A type pointer
*/
#define GIM_BUFFER_ARRAY_DOWNLOAD(type,array_data,dest_data)\
{\
if(GIM_BUFFER_ARRAY_IS_ALIGNED(type,array_data))\
{\
gim_download_from_buffer(&(array_data).m_buffer_id, (array_data).m_byte_offset,(void *) dest_data, (array_data).m_element_count*(array_data).m_byte_stride);\
}\
else\
{\
GUINT _k_, _ecount_= (array_data).m_element_count;\
type * _source_vert_;\
type * _dest_vert_ = dest_data;\
gim_buffer_array_lock(&(array_data),G_MA_READ_ONLY);\
for (_k_ = 0;_k_< _ecount_; _k_++)\
{\
_source_vert_ = GIM_BUFFER_ARRAY_POINTER(type,array_data,_k_);\
memcpy(_dest_vert_,_source_vert_,sizeof(type));\
_dest_vert_++;\
}\
gim_buffer_array_unlock(&(array_data));\
}\
}\
//! Upload the content of a a pointer to a buffered array
/*!
\pre source_data must have the same size as the array_data
\param type
\param array_data A GBUFFERED_ARRAY structure
\param source_data A void pointer
*/
#define GIM_BUFFER_ARRAY_UPLOAD(type,array_data,source_data)\
{\
if(GIM_BUFFER_ARRAY_IS_ALIGNED(type,array_data))\
{\
gim_upload_to_buffer(&(array_data).m_buffer_id, (array_data).m_byte_offset,(void *) source_data, (array_data).m_element_count*(array_data).m_byte_stride);\
}\
else\
{\
GUINT _k_, _ecount_= (array_data).m_element_count;\
type * _source_vert_ = source_data;\
type * _dest_vert_;\
gim_buffer_array_lock(&(array_data),G_MA_WRITE_ONLY);\
for (_k_ = 0;_k_< _ecount_; _k_++)\
{\
_dest_vert_ = GIM_BUFFER_ARRAY_POINTER(type,array_data,_k_);\
memcpy(_dest_vert_,_source_vert_,sizeof(type));\
_source_vert_++;\
}\
gim_buffer_array_unlock(&(array_data));\
}\
}\
//!Kernel function prototype for process streams, given a buffered array as source and
/*!
\param 1 the uniform arguments
\param 2 the source stream
\param 3 the destination stream
*/
typedef void (* gim_kernel_func)(void *,GBUFFER_ARRAY *,GBUFFER_ARRAY *);
//! Generic Stream Processingp loop
/*!
This macro executes a kernel macro or function for each element of the streams
\pre _src_array->m_count <= _dst_array->m_count
\param _uniform_data An argument to be passed to the Kernel function
\param _src_array An GBUFFER_ARRAY structure passed as the source stream
\param _dst_array An GBUFFER_ARRAY structure passed as the source stream
\param _kernel Macro or function of the kernel
\param _src_type Required. Type of all elements of the source stream
\param _dst_type Required. Type of all elements of the dest stream
*/
#define GIM_PROCESS_BUFFER_ARRAY(_uniform_data,_src_array,_dst_array,_kernel,_src_type,_dst_type) {\
\
gim_buffer_array_lock(&_src_array,G_MA_READ_ONLY);\
gim_buffer_array_lock(&_dst_array,G_MA_WRITE_ONLY);\
\
GUINT _i_, _count_=(_src_array).m_element_count;\
\
_src_type * _source_vert_;\
_dst_type * _dest_vert_;\
if(GIM_BUFFER_ARRAY_IS_ALIGNED(_src_type,_src_array) && GIM_BUFFER_ARRAY_IS_ALIGNED(_dst_type,_dst_array))\
{\
\
_source_vert_ = GIM_BUFFER_ARRAY_POINTER(_src_type,_src_array,0);\
_dest_vert_ = GIM_BUFFER_ARRAY_POINTER(_dst_type,_dst_array,0);\
for (_i_ = 0;_i_< _count_; _i_++)\
{\
_kernel(_uniform_data,(*_source_vert_),(*_dest_vert_));\
_source_vert_++;\
_dest_vert_++;\
}\
}\
else\
{\
for (_i_ = 0;_i_< _count_; _i_++)\
{\
_source_vert_ = GIM_BUFFER_ARRAY_POINTER(_src_type,_src_array,_i_);\
_dest_vert_ = GIM_BUFFER_ARRAY_POINTER(_dst_type,_dst_array,_i_);\
_kernel(_uniform_data,(*_source_vert_),(*_dest_vert_));\
}\
}\
gim_buffer_array_unlock(&_src_array);\
gim_buffer_array_unlock(&_dst_array);\
}\
//! @}
#endif // GIM_MEMORY_H_INCLUDED
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -