aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_memory.h
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_memory.h')
-rw-r--r--libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_memory.h1040
1 files changed, 1040 insertions, 0 deletions
diff --git a/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_memory.h b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_memory.h
new file mode 100644
index 0000000..58661f1
--- /dev/null
+++ b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_memory.h
@@ -0,0 +1,1040 @@
1#ifndef GIM_MEMORY_H_INCLUDED
2#define GIM_MEMORY_H_INCLUDED
3/*! \file gim_memory.h
4\author Francisco León
5*/
6/*
7-----------------------------------------------------------------------------
8This source file is part of GIMPACT Library.
9
10For the latest info, see http://gimpact.sourceforge.net/
11
12Copyright (c) 2006 Francisco Leon. C.C. 80087371.
13email: projectileman@yahoo.com
14
15 This library is free software; you can redistribute it and/or
16 modify it under the terms of EITHER:
17 (1) The GNU Lesser General Public License as published by the Free
18 Software Foundation; either version 2.1 of the License, or (at
19 your option) any later version. The text of the GNU Lesser
20 General Public License is included with this library in the
21 file GIMPACT-LICENSE-LGPL.TXT.
22 (2) The BSD-style license that is included with this library in
23 the file GIMPACT-LICENSE-BSD.TXT.
24
25 This library is distributed in the hope that it will be useful,
26 but WITHOUT ANY WARRANTY; without even the implied warranty of
27 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
28 GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
29
30-----------------------------------------------------------------------------
31*/
32
33
34#include "GIMPACT/gim_math.h"
35#include <memory.h>
36
37//#define PREFETCH 1
38//! \defgroup PREFETCH
39//! @{
40#ifdef PREFETCH
41#include <xmmintrin.h> // for prefetch
42#define pfval 64
43#define pfval2 128
44//! Prefetch 64
45#define pf(_x,_i) _mm_prefetch((void *)(_x + _i + pfval), 0)
46//! Prefetch 128
47#define pf2(_x,_i) _mm_prefetch((void *)(_x + _i + pfval2), 0)
48#else
49//! Prefetch 64
50#define pf(_x,_i)
51//! Prefetch 128
52#define pf2(_x,_i)
53#endif
54//! @}
55
56/*! \defgroup ARRAY_UTILITIES
57\brief
58Functions for manip packed arrays of numbers
59*/
60//! @{
61#define GIM_COPY_ARRAYS(dest_array,source_array,element_count)\
62{\
63 GUINT _i_;\
64 for (_i_=0;_i_<element_count ;_i_++)\
65 {\
66 dest_array[_i_] = source_array[_i_];\
67 }\
68}\
69
70#define GIM_COPY_ARRAYS_1(dest_array,source_array,element_count,copy_macro)\
71{\
72 GUINT _i_;\
73 for (_i_=0;_i_<element_count ;_i_++)\
74 {\
75 copy_macro(dest_array[_i_],source_array[_i_]);\
76 }\
77}\
78
79
80#define GIM_ZERO_ARRAY(array,element_count)\
81{\
82 GUINT _i_;\
83 for (_i_=0;_i_<element_count ;_i_++)\
84 {\
85 array[_i_] = 0;\
86 }\
87}\
88
89#define GIM_CONSTANT_ARRAY(array,element_count,constant)\
90{\
91 GUINT _i_;\
92 for (_i_=0;_i_<element_count ;_i_++)\
93 {\
94 array[_i_] = constant;\
95 }\
96}\
97//! @}
98
99/*! \defgroup MEMORY_FUNCTION_PROTOTYPES
100Function prototypes to allocate and free memory.
101*/
102//! @{
103typedef void * gim_alloc_function (size_t size);
104typedef void * gim_alloca_function (size_t size);//Allocs on the heap
105typedef void * gim_realloc_function (void *ptr, size_t oldsize, size_t newsize);
106typedef void gim_free_function (void *ptr, size_t size);
107//! @}
108
109/*! \defgroup MEMORY_FUNCTION_HANDLERS
110\brief
111Memory Function Handlers
112 set new memory management functions. if fn is 0, the default handlers are
113 used. */
114//! @{
115void gim_set_alloc_handler (gim_alloc_function *fn);
116void gim_set_alloca_handler (gim_alloca_function *fn);
117void gim_set_realloc_handler (gim_realloc_function *fn);
118void gim_set_free_handler (gim_free_function *fn);
119//! @}
120
121/*! \defgroup MEMORY_FUNCTION_GET_HANDLERS
122\brief
123get current memory management functions.
124*/
125//! @{
126gim_alloc_function *gim_get_alloc_handler (void);
127gim_alloca_function *gim_get_alloca_handler(void);
128gim_realloc_function *gim_get_realloc_handler (void);
129gim_free_function *gim_get_free_handler (void);
130//! @}
131
132/*! \defgroup MEMORY_FUNCTIONS
133Standar Memory functions
134*/
135//! @{
136void * gim_alloc(size_t size);
137void * gim_alloca(size_t size);
138void * gim_realloc(void *ptr, size_t oldsize, size_t newsize);
139void gim_free(void *ptr, size_t size);
140//! @}
141
142/*! \defgroup DYNAMIC_ARRAYS
143\brief
144Dynamic Arrays. Allocated from system memory.
145<ul>
146<li> For initializes a dynamic array, use GIM_DYNARRAY_CREATE or GIM_DYNARRAY_CREATE_SIZED.
147<li> When an array is no longer used, must be terminated with the macro GIM_DYNARRAY_DESTROY.
148</ul>
149*/
150//! @{
151#define G_ARRAY_GROW_SIZE 100
152
153//! Dynamic array handle.
154struct GDYNAMIC_ARRAY
155{
156 char * m_pdata;
157 GUINT m_size;
158 GUINT m_reserve_size;
159};
160//typedef struct _GDYNAMIC_ARRAY GDYNAMIC_ARRAY;
161
162//! Creates a dynamic array zero sized
163#define GIM_DYNARRAY_CREATE(type,array_data,reserve_size) \
164{ \
165 array_data.m_pdata = (char *)gim_alloc(reserve_size*sizeof(type)); \
166 array_data.m_size = 0; \
167 array_data.m_reserve_size = reserve_size; \
168}\
169
170//! Creates a dynamic array with n = size elements
171#define GIM_DYNARRAY_CREATE_SIZED(type,array_data,size) \
172{ \
173 array_data.m_pdata = (char *)gim_alloc(size*sizeof(type)); \
174 array_data.m_size = size; \
175 array_data.m_reserve_size = size; \
176}\
177
178//! Reserves memory for a dynamic array.
179#define GIM_DYNARRAY_RESERVE_SIZE(type,array_data,reserve_size) \
180{ \
181 if(reserve_size>array_data.m_reserve_size )\
182 { \
183 array_data.m_pdata = (char *) gim_realloc(array_data.m_pdata,array_data.m_size*sizeof(type),reserve_size*sizeof(type));\
184 array_data.m_reserve_size = reserve_size; \
185 }\
186}\
187
188//! Set the size of the array
189#define GIM_DYNARRAY_SET_SIZE(type,array_data,size) \
190{ \
191 GIM_DYNARRAY_RESERVE_SIZE(type,array_data,size);\
192 array_data.m_size = size;\
193}\
194
195//! Gets a pointer from the beginning of the array
196#define GIM_DYNARRAY_POINTER(type,array_data) (type *)(array_data.m_pdata)
197
198//! Gets a pointer from the last elemento of the array
199#define GIM_DYNARRAY_POINTER_LAST(type,array_data) (((type *)array_data.m_pdata)+array_data.m_size-1)
200
201//! Inserts an element at the last position
202#define GIM_DYNARRAY_PUSH_ITEM(type,array_data,item)\
203{\
204 if(array_data.m_reserve_size<=array_data.m_size)\
205 {\
206 GIM_DYNARRAY_RESERVE_SIZE(type,array_data,(array_data.m_size+G_ARRAY_GROW_SIZE));\
207 }\
208 type * _pt = GIM_DYNARRAY_POINTER(type,array_data);\
209 memcpy(&_pt[array_data.m_size],&item,sizeof(type));\
210 array_data.m_size++; \
211}\
212
213//! Inserts an element at the last position
214#define GIM_DYNARRAY_PUSH_EMPTY(type,array_data)\
215{\
216 if(array_data.m_reserve_size<=array_data.m_size)\
217 {\
218 GIM_DYNARRAY_RESERVE_SIZE(type,array_data,(array_data.m_size+G_ARRAY_GROW_SIZE));\
219 }\
220 array_data.m_size++; \
221}\
222
223//! Inserts an element
224#define GIM_DYNARRAY_INSERT_ITEM(type,array_data,item,index) \
225{ \
226 if(array_data.m_reserve_size<=array_data.m_size)\
227 {\
228 GIM_DYNARRAY_RESERVE_SIZE(type,array_data,(array_data.m_size+G_ARRAY_GROW_SIZE));\
229 }\
230 type * _pt = GIM_DYNARRAY_POINTER(type,array_data);\
231 if(index<array_data.m_size-1) \
232 { \
233 memcpy(&_pt[index+1],&_pt[index],(array_data.m_size-index)*sizeof(type));\
234 } \
235 memcpy(&_pt[index],&item,sizeof(type));\
236 array_data.m_size++; \
237}\
238
239//! Removes an element
240#define GIM_DYNARRAY_DELETE_ITEM(type,array_data,index) \
241{ \
242 if(index<array_data.m_size-1) \
243 { \
244 type * _pt = GIM_DYNARRAY_POINTER(type,array_data);\
245 memcpy(&_pt[index],&_pt[index+1],(array_data.m_size-index-1)*sizeof(type));\
246 } \
247 array_data.m_size--; \
248}\
249
250//! Removes an element at the last position
251#define GIM_DYNARRAY_POP_ITEM(array_data) \
252{ \
253 if(array_data.m_size>0) \
254 { \
255 array_data.m_size--; \
256 } \
257}\
258
259//! Destroys the array
260void GIM_DYNARRAY_DESTROY(GDYNAMIC_ARRAY & array_data);
261//! @}
262
263/*! \defgroup BITSET
264\brief
265Bitsets , based on \ref DYNAMIC_ARRAYS .
266<ul>
267<li> For initializes a bitset array, use \ref GIM_BITSET_CREATE or \ref GIM_BITSET_CREATE_SIZED.
268<li> When the bitset is no longer used, must be terminated with the macro \ref GIM_DYNARRAY_DESTROY.
269<li> For putting a mark on the bitset, call \ref GIM_BITSET_SET
270<li> For clearing a mark on the bitset, call \ref GIM_BITSET_CLEAR
271<li> For retrieving a bit value from a bitset, call \ref GIM_BITSET_GET-
272</ul>
273*/
274//! @{
275
276//! Creates a bitset
277#define GIM_BITSET_CREATE(array_data) GIM_DYNARRAY_CREATE(GUINT,array_data,G_ARRAY_GROW_SIZE)
278
279//! Creates a bitset, with their bits set to 0.
280#define GIM_BITSET_CREATE_SIZED(array_data,bits_count)\
281{\
282 array_data.m_size = bits_count/GUINT_BIT_COUNT + 1;\
283 GIM_DYNARRAY_CREATE(GUINT,array_data,array_data.m_size);\
284 GUINT * _pt = GIM_DYNARRAY_POINTER(GUINT,array_data);\
285 memset(_pt,0,sizeof(GUINT)*(array_data.m_size));\
286}\
287
288//! Gets the bitset bit count.
289#define GIM_BITSET_SIZE(array_data) (array_data.m_size*GUINT_BIT_COUNT)
290
291//! Resizes a bitset, with their bits set to 0.
292#define GIM_BITSET_RESIZE(array_data,new_bits_count)\
293{ \
294 GUINT _oldsize = array_data.m_size;\
295 array_data.m_size = new_bits_count/GUINT_BIT_COUNT + 1; \
296 if(_oldsize<array_data.m_size)\
297 {\
298 if(array_data.m_size > array_data.m_reserve_size)\
299 {\
300 GIM_DYNARRAY_RESERVE_SIZE(GUINT,array_data,array_data.m_size+G_ARRAY_GROW_SIZE);\
301 }\
302 GUINT * _pt = GIM_DYNARRAY_POINTER(GUINT,array_data);\
303 memset(&_pt[_oldsize],0,sizeof(GUINT)*(array_data.m_size-_oldsize));\
304 }\
305}\
306
307//! Sets all bitset bit to 0.
308#define GIM_BITSET_CLEAR_ALL(array_data)\
309{\
310 memset(array_data.m_pdata,0,sizeof(GUINT)*array_data.m_size);\
311}\
312
313//! Sets all bitset bit to 1.
314#define GIM_BITSET_SET_ALL(array_data)\
315{\
316 memset(array_data.m_pdata,0xFF,sizeof(GUINT)*array_data.m_size);\
317}\
318
319///Sets the desired bit to 1
320#define GIM_BITSET_SET(array_data,bit_index)\
321{\
322 if(bit_index>=GIM_BITSET_SIZE(array_data))\
323 {\
324 GIM_BITSET_RESIZE(array_data,bit_index);\
325 }\
326 GUINT * _pt = GIM_DYNARRAY_POINTER(GUINT,array_data);\
327 _pt[bit_index >> GUINT_EXPONENT] |= (1 << (bit_index & (GUINT_BIT_COUNT-1)));\
328}\
329
330///Return 0 or 1
331#define GIM_BITSET_GET(array_data,bit_index,get_value) \
332{\
333 if(bit_index>=GIM_BITSET_SIZE(array_data))\
334 {\
335 get_value = 0;\
336 }\
337 else\
338 {\
339 GUINT * _pt = GIM_DYNARRAY_POINTER(GUINT,array_data);\
340 get_value = _pt[bit_index >> GUINT_EXPONENT] & (1 << (bit_index & (GUINT_BIT_COUNT-1)));\
341 }\
342}\
343
344///Sets the desired bit to 0
345#define GIM_BITSET_CLEAR(array_data,bit_index) \
346{\
347 if(bit_index<GIM_BITSET_SIZE(array_data))\
348 {\
349 GUINT * _pt = GIM_DYNARRAY_POINTER(GUINT,array_data);\
350 _pt[bit_index >> GUINT_EXPONENT] &= ~(1 << (bit_index & (GUINT_BIT_COUNT-1)));\
351 }\
352}\
353//! @}
354
355/*! \defgroup MEMORY_ACCESS_CONSTANTS
356\brief
357Memory Access constants.
358\sa BUFFERS
359*/
360//! @{
361#define G_MA_READ_ONLY 1
362#define G_MA_WRITE_ONLY 2
363#define G_MA_READ_WRITE 3
364//! @}
365
366/*! \defgroup MEMORY_USAGE_CONSTANTS
367\brief
368Memory usage constants.
369\sa BUFFERS
370*/
371//! @{
372/// Don't care how memory is used
373#define G_MU_EITHER 0
374/// specified once, doesn't allow read information
375#define G_MU_STATIC_WRITE 1
376/// specified once, allows to read information from a shadow buffer
377#define G_MU_STATIC_READ 2
378/// write directly on buffer, allows to read information from a shadow buffer
379#define G_MU_STATIC_READ_DYNAMIC_WRITE 3
380/// upload data to buffer from the shadow buffer, allows to read information from a shadow buffer
381#define G_MU_STATIC_READ_DYNAMIC_WRITE_COPY 4
382/// specified once, allows to read information directly from memory
383#define G_MU_STATIC_WRITE_DYNAMIC_READ 5
384/// write directly on buffer, allows to read information directly from memory
385#define G_MU_DYNAMIC_READ_WRITE 6
386//! @}
387
388/*! \defgroup BUFFER_ERRORS
389\brief
390Buffer operation errors
391\sa BUFFERS
392*/
393//! @{
394#define G_BUFFER_OP_SUCCESS 0
395#define G_BUFFER_OP_INVALID 1
396#define G_BUFFER_OP_STILLREFCOUNTED 2
397//! @}
398
399/*! \defgroup BUFFER_MANAGER_IDS
400\brief
401Buffer manager identifiers
402\sa BUFFERS, BUFFER_MANAGERS
403*/
404//! @{
405#define G_BUFFER_MANAGER_SYSTEM 0
406#define G_BUFFER_MANAGER_SHARED 1
407#define G_BUFFER_MANAGER_USER 2
408//! @}
409
410/*! \defgroup BUFFERS
411\brief
412Buffer operations and structs.
413<ul>
414<li> Before using buffers you must initializes GIMPACT buffer managers by calling \ref gimpact_init.
415<li> For initializes a buffer, use \ref gim_create_buffer, \ref gim_create_buffer_from_data , \ref gim_create_common_buffer, \ref gim_create_common_buffer_from_data or \ref gim_create_shared_buffer_from_data.
416<li> For accessing to the buffer memory, you must call \ref gim_lock_buffer, and then \ref gim_unlock_buffer for finish the access.
417<li> When a buffer is no longer needed, you must free it by calling \ref gim_buffer_free.
418<li> You must call \ref gimpact_terminate when finish your application.
419<li> For a safe manipulation of buffers, use \ref BUFFER_ARRAYS
420</ul>
421\sa BUFFER_MANAGERS, BUFFER_ARRAYS
422*/
423//! @{
424
425//! Buffer handle.
426struct GBUFFER_ID
427{
428 GUINT m_buffer_id;
429 GUINT m_buffer_manager_id;
430};
431//typedef struct _GBUFFER_ID GBUFFER_ID;
432
433//! Buffer internal data
434struct GBUFFER_DATA
435{
436 GUINT m_buffer_handle;//!< if 0, buffer doesn't exists
437 GUINT m_size;
438 GUINT m_usage;
439 GINT m_access;
440 GUINT m_lock_count;
441 char * m_mapped_pointer;
442 GBUFFER_ID m_shadow_buffer;
443 GUINT m_refcount;//! Reference counting for safe garbage collection
444};
445//typedef struct _GBUFFER_DATA GBUFFER_DATA;
446//! @}
447
448/*! \defgroup BUFFERS_MANAGER_PROTOTYPES
449\brief
450Function prototypes to allocate and free memory for buffers
451\sa BUFFER_MANAGERS, BUFFERS
452*/
453//! @{
454
455//! Returns a Buffer handle
456typedef GUINT gim_buffer_alloc_function(GUINT size,int usage);
457
458//! Returns a Buffer handle, and copies the pdata to the buffer
459typedef GUINT gim_buffer_alloc_data_function(const void * pdata,GUINT size,int usage);
460
461//! Changes the size of the buffer preserving the content, and returns the new buffer id
462typedef GUINT gim_buffer_realloc_function(GUINT buffer_handle,GUINT oldsize,int old_usage,GUINT newsize,int new_usage);
463
464//! It changes the m_buffer_handle member to 0/0
465typedef void gim_buffer_free_function(GUINT buffer_handle,GUINT size);
466
467//! It maps the m_mapped_pointer. Returns a pointer
468typedef char * gim_lock_buffer_function(GUINT buffer_handle,int access);
469
470//! It sets the m_mapped_pointer to 0
471typedef void gim_unlock_buffer_function(GUINT buffer_handle);
472
473typedef void gim_download_from_buffer_function(
474 GUINT source_buffer_handle,
475 GUINT source_pos,
476 void * destdata,
477 GUINT copysize);
478
479typedef void gim_upload_to_buffer_function(
480 GUINT dest_buffer_handle,
481 GUINT dest_pos,
482 void * sourcedata,
483 GUINT copysize);
484
485typedef void gim_copy_buffers_function(
486 GUINT source_buffer_handle,
487 GUINT source_pos,
488 GUINT dest_buffer_handle,
489 GUINT dest_pos,
490 GUINT copysize);
491//! @}
492
493
494/*! \defgroup BUFFER_MANAGERS
495\brief
496Buffer Manager operations
497*/
498//! @{
499//! Buffer manager prototype
500struct GBUFFER_MANAGER_PROTOTYPE
501{
502 gim_buffer_alloc_function * alloc_fn;
503 gim_buffer_alloc_data_function *alloc_data_fn;
504 gim_buffer_realloc_function * realloc_fn;
505 gim_buffer_free_function * free_fn;
506 gim_lock_buffer_function * lock_buffer_fn;
507 gim_unlock_buffer_function * unlock_buffer_fn;
508 gim_download_from_buffer_function * download_from_buffer_fn;
509 gim_upload_to_buffer_function * upload_to_buffer_fn;
510 gim_copy_buffers_function * copy_buffers_fn;
511};
512//typedef struct _GBUFFER_MANAGER_PROTOTYPE GBUFFER_MANAGER_PROTOTYPE;
513
514//! Buffer manager
515struct GBUFFER_MANAGER_DATA
516{
517 GDYNAMIC_ARRAY m_buffer_array;//!< Array of GBUFFER_DATA objects
518 GDYNAMIC_ARRAY m_free_positions;//!< Array of GUINT elements. Free positions
519 GBUFFER_MANAGER_PROTOTYPE m_prototype;//! Prototype of functions
520 GUINT m_active; //!< 0 or 1
521};
522//typedef struct _GBUFFER_MANAGER_DATA GBUFFER_MANAGER_DATA;
523
524//! Adds a buffer Manager to the Memory Singleton
525void gim_create_buffer_manager(GBUFFER_MANAGER_PROTOTYPE * prototype,GUINT buffer_manager_id);
526//! Gets buffer manager
527GUINT gim_get_buffer_manager_count();
528//! Destroys a buffer manager
529void gim_destroy_buffer_manager(GUINT buffer_manager_id);
530void gim_get_buffer_manager_data(GUINT buffer_manager_id,GBUFFER_MANAGER_DATA ** pbm_data);
531void gim_init_buffer_managers();
532void gim_terminate_buffer_managers();
533
534//! @}
535
536
537/*! \addtogroup BUFFERS
538*/
539//! @{
540
541//!Creates a buffer on the buffer manager specified by buffer_manager_id
542/*!
543\param buffer_manager_id
544\param buffer_size
545\param usage An usage constant. Use G_MU_DYNAMIC_READ_WRITE as default.
546\param buffer_id a pointer for receive the new buffer id
547\return An error code. 0 if success.
548\post m_refcount = 0
549*/
550GUINT gim_create_buffer(
551 GUINT buffer_manager_id,
552 GUINT buffer_size,
553 int usage,
554 GBUFFER_ID * buffer_id);
555
556//!Creates a buffer on the buffer manager specified by buffer_manager_id
557/*!
558\param buffer_manager_id
559\param pdata Data for allocating
560\param buffer_size Size of the data buffer
561\param usage An usage constant. Use G_MU_DYNAMIC_READ_WRITE as default.
562\param buffer_id a pointer for receive the new buffer id
563\return An error code. 0 if success.
564\post m_refcount = 0
565*/
566GUINT gim_create_buffer_from_data(
567 GUINT buffer_manager_id,
568 const void * pdata,
569 GUINT buffer_size,
570 int usage,
571 GBUFFER_ID * buffer_id);
572
573//!Allocates on the G_BUFFER_MANAGER_SYSTEM
574GUINT gim_create_common_buffer(GUINT buffer_size, GBUFFER_ID * buffer_id);
575//!Allocates on the G_BUFFER_MANAGER_SYSTEM, and copies the data
576GUINT gim_create_common_buffer_from_data(
577 const void * pdata, GUINT buffer_size, GBUFFER_ID * buffer_id);
578//!Creates a buffer with shared data
579GUINT gim_create_shared_buffer_from_data(
580 const void * pdata, GUINT buffer_size, GBUFFER_ID * buffer_id);
581
582
583//! Add reference counting to buffer.
584GINT gim_buffer_add_ref(GBUFFER_ID * buffer_id);
585
586//! Function for resize buffer, preserving the content
587/*!
588\param buffer_id
589\param newsize
590\return An error code. 0 if success.
591\post If m_refcount>0 then it decrements it.
592*/
593GINT gim_buffer_realloc(GBUFFER_ID * buffer_id,GUINT newsize);
594
595//! Eliminates the buffer.
596/*!
597If the buffer reference counting is <= 1 and is unlocked, then it eliminates the buffer.
598*/
599GINT gim_buffer_free(GBUFFER_ID * buffer_id);
600
601//! Locks the buffer for memory access.
602/*!
603\param buffer_id Id from buffer.
604\param access Must have the following values: G_MA_READ_ONLY,G_MA_WRITE_ONLY or G_MA_READ_WRITE.
605\param map_pointer Dest Pointer of the memory address from buffer.
606\post m_lock_count increases.
607*/
608GINT gim_lock_buffer(GBUFFER_ID * buffer_id,int access,char ** map_pointer);
609
610//! Unlocks the buffer for memory access.
611GINT gim_unlock_buffer(GBUFFER_ID * buffer_id);
612
613//! Gets the buffer size in bytes
614GINT gim_get_buffer_size(GBUFFER_ID * buffer_id,GUINT * buffer_size);
615
616//! Determines if the buffer is locked
617GINT gim_get_buffer_is_locked(GBUFFER_ID * buffer_id,GUINT * lock_count);
618
619//! Copies the content of the buffer to a dest pointer
620GINT gim_download_from_buffer(
621 GBUFFER_ID * buffer_id,
622 GUINT source_pos,
623 void * destdata,
624 GUINT copysize);
625
626//! Copies the content of a memory pointer to the buffer
627GINT gim_upload_to_buffer(
628 GBUFFER_ID * buffer_id,
629 GUINT dest_pos,
630 void * sourcedata,
631 GUINT copysize);
632
633//! Copies two buffers.
634GINT gim_copy_buffers(
635 GBUFFER_ID * source_buffer_id,
636 GUINT source_pos,
637 GBUFFER_ID * dest_buffer_id,
638 GUINT dest_pos,
639 GUINT copysize);
640//! @}
641
642
643/*! \defgroup BUFFER_ARRAYS
644
645\brief
646Buffered Arrays, for manip elements on a buffer and treat it as an array.
647<ul>
648<li> Before using buffer arrays you must initializes GIMPACT buffer managers by calling gimpact_init.
649<li> Before creating buffer arrays, you must create a buffer. see \ref BUFFERS.
650<li> Create a buffer narray by calling \ref GIM_BUFFER_ARRAY_INIT_TYPE, \ref GIM_BUFFER_ARRAY_INIT_TYPE_OFFSET or \ref GIM_BUFFER_ARRAY_INIT_OFFSET_STRIDE.
651<li> For accessing to the array elements, you must call \ref gim_buffer_array_lock, and then \ref gim_buffer_array_unlock for finish the access.
652<li> When a buffer array is no longer needed, you must free it by calling \ref GIM_BUFFER_ARRAY_DESTROY.
653</ul>
654The following example shows how Buffer arrays can be used:
655
656\code
657int main()
658{
659 //init gimpact
660 gimpact_init();
661
662 //Buffer handle to use
663 GBUFFER_ID bufferhandle;
664
665 //Create a memory buffer of 100 float numbers
666 gim_create_common_buffer(100*sizeof(float), &bufferhandle);
667
668 //Create a buffer array from the bufferhandle
669 GBUFFER_ARRAY buffer_float_array;
670 GIM_BUFFER_ARRAY_INIT_TYPE(float,buffer_float_array,bufferhandle,100);
671
672 ////Access to the buffer data, set all elements of the array
673
674 int i, count;
675 count = buffer_float_array.m_element_count;
676 //Locks the array
677 gim_buffer_array_lock(&buffer_float_array,G_MA_READ_WRITE);
678 float * pelements = GIM_BUFFER_ARRAY_POINTER(float, buffer_float_array, 0); // A pointer to the buffer memory
679
680 //fill the array with random numbers
681 for (i = 0;i < count;i++ )
682 {
683 pelements[i] = gim_unit_random();
684 }
685 //unlock buffer
686 gim_buffer_array_unlock(&buffer_float_array);
687
688 //Program code
689 ....
690 ....
691
692 //Destroy array
693 GIM_BUFFER_ARRAY_DESTROY(buffer_float_array);
694
695 //terminate gimpact
696 gimpact_terminate();
697}
698\endcode
699
700\sa BUFFERS
701*/
702//! @{
703
704//! Buffer managed array struct.
705struct GBUFFER_ARRAY
706{
707 GBUFFER_ID m_buffer_id;
708 char * m_buffer_data;
709 char m_byte_stride;
710 GUINT m_byte_offset;
711 GUINT m_element_count;
712};
713//typedef struct _GBUFFER_ARRAY GBUFFER_ARRAY;
714
715//! Sets offset for a buffered array.
716#define GIM_BUFFER_ARRAY_SET_OFFSET(_array_data,_offset) (_array_data).m_byte_offset = _offset*(_array_data).m_byte_stride;
717
718//! Sets offset for a buffered array.
719#define GIM_BUFFER_ARRAY_GET_OFFSET(_array_data,_offset) _offset = (_array_data).m_byte_offset/(_array_data).m_byte_stride;
720
721//!Return a pointer of the element at the _index
722#define GIM_BUFFER_ARRAY_POINTER(_type,_array_data,_index) (_type *)((_array_data).m_buffer_data + _index*(_array_data).m_byte_stride)
723
724//! Sets stride for a buffered array.
725#define GIM_BUFFER_ARRAY_SET_STRIDE(_type,_array_data) (_array_data).m_byte_stride = sizeof(_type);
726
727//! Is array stride equal to the size of the type ?
728#define GIM_BUFFER_ARRAY_IS_ALIGNED(_type,_array_data) ((_array_data).m_byte_stride == sizeof(_type))
729
730///Verify if two arrays have the same data
731#define GIM_BUFFER_ARRAY_ARE_SAME(_array_data1,_array_data2,aresame)\
732{\
733 aresame = 1;\
734 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)\
735 {\
736 aresame = 0;\
737 }\
738}\
739
740//! Reserve size for a buffered array.
741/*!
742\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
743*/
744#define GIM_BUFFER_ARRAY_RESERVE_SIZE(type,array_data,reserve_size)\
745{ \
746 if(reserve_size>(array_data).m_element_count)\
747 {\
748 GUINT _buffer_size,_newarray_size;\
749 gim_get_buffer_size(&(array_data).m_buffer_id,_buffer_size);\
750 _newarray_size = reserve_size*(array_data).m_byte_stride;\
751 if(_newarray_size>_buffer_size)\
752 { \
753 _newarray_size += G_ARRAY_GROW_SIZE*(array_data).m_byte_stride;\
754 gim_buffer_realloc(&(array_data).m_buffer_id,_newarray_size);\
755 }\
756 }\
757}\
758
759//! Pushes an element at last position
760/*!
761\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
762*/
763#define GIM_BUFFER_ARRAY_PUSH_ITEM(type,array_data,item)\
764{\
765 GIM_BUFFER_ARRAY_RESERVE_SIZE(type,array_data,(array_data).m_element_count+1);\
766 gim_buffer_array_lock(&array_data,G_MA_WRITE_ONLY);\
767 type * _pt = GIM_BUFFER_ARRAY_POINTER(type,array_data,(array_data).m_element_count);\
768 memcpy(_pt,&item,sizeof(type));\
769 gim_buffer_array_unlock(&array_data);\
770 (array_data)->m_element_count++; \
771}\
772
773//! Pushes a new element at last position
774/*!
775\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
776*/
777#define GIM_BUFFER_ARRAY_PUSH_EMPTY(type,array_data)\
778{\
779 GIM_BUFFER_ARRAY_RESERVE_SIZE(type,array_data,(array_data).m_element_count+1);\
780 array_data->m_element_count++; \
781}\
782
783//! Inserts an element
784/*!
785\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
786*/
787#define GIM_BUFFER_ARRAY_INSERT_ITEM(type,array_data,item,index) \
788{ \
789 GIM_BUFFER_ARRAY_RESERVE_SIZE(type,array_data,(array_data).m_element_count+1);\
790 gim_buffer_array_lock(&array_data,G_MA_WRITE_ONLY);\
791 type * _pt = GIM_BUFFER_ARRAY_POINTER(type,array_data,0);\
792 if(index<(array_data)->m_element_count-1) \
793 { \
794 memcpy(&_pt[index+1],&_pt[index],((array_data).m_element_count-index)*sizeof(type));\
795 } \
796 memcpy(&_pt[index],&item,sizeof(type));\
797 gim_buffer_array_unlock(&array_data);\
798 (array_data).m_element_count++; \
799}\
800
801//! Deletes an element
802/*!
803\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
804*/
805#define GIM_BUFFER_ARRAY_DELETE_ITEM(type,array_data,index) \
806{ \
807 if(index<(array_data).m_element_count-1) \
808 { \
809 gim_buffer_array_lock(&array_data,G_MA_WRITE_ONLY);\
810 type * _pt = GIM_BUFFER_ARRAY_POINTER(type,array_data,0);\
811 memcpy(&_pt[index],&_pt[index+1],((array_data).m_element_count-index-1)*sizeof(type));\
812 gim_buffer_array_unlock(&array_data);\
813 } \
814 (array_data).m_element_count--; \
815}\
816
817//! Deletes an element at last position
818/*!
819\pre array_data must be unlocked, and must be the aligned (GIM_BUFFER_ARRAY_IS_ALIGNED )
820*/
821#define GIM_BUFFER_ARRAY_POP_ITEM(array_data) \
822{ \
823 if((array_data).m_element_count>0) \
824 { \
825 (array_data).m_element_count--; \
826 } \
827}\
828
829
830//! Initializes an GBUFFER_ARRAY object from a buffer ID
831/*!
832m_buffer_data will be 0, for acces to the elements, you'd need to call lock_array
833\param array_data Array structure to be filled
834\param buffer_id A GBUFFER_ID structure which this array_daya will refer to
835\param element_count Number of elements
836\param offset element offset, it isn't byte offset. 0 is recomended
837\param byte_stride size of each element. 0 is recomended.
838\post Adds reference to the buffer
839\sa gim_buffer_add_ref
840*/
841#define GIM_BUFFER_ARRAY_INIT_OFFSET_STRIDE(array_data,buffer_id,element_count,offset,byte_stride)\
842{\
843 (array_data).m_buffer_id.m_buffer_id = (buffer_id).m_buffer_id;\
844 (array_data).m_buffer_id.m_buffer_manager_id = (buffer_id).m_buffer_manager_id;\
845 (array_data).m_buffer_data = 0;\
846 (array_data).m_element_count = element_count;\
847 (array_data).m_byte_stride = byte_stride;\
848 GIM_BUFFER_ARRAY_SET_OFFSET(array_data,offset);\
849 gim_buffer_add_ref(&(buffer_id));\
850}\
851
852//! Initializes an GBUFFER_ARRAY object from a buffer ID and a Given type
853/*!
854m_buffer_data will be 0, for acces to the elements, you'd need to call lock_array
855\param type Type of the Array. It determines the stride.
856\param array_data Array structure to be filled
857\param buffer_id A GBUFFER_ID structure which this array_daya will refer to
858\param element_count Number of elements
859\param offset element offset, it isn't byte offset. 0 is recomended
860\post Adds reference to the buffer
861\sa gim_buffer_add_ref
862*/
863#define GIM_BUFFER_ARRAY_INIT_TYPE_OFFSET(type,array_data,buffer_id,element_count,offset)\
864{\
865 (array_data).m_buffer_id.m_buffer_id = (buffer_id).m_buffer_id;\
866 (array_data).m_buffer_id.m_buffer_manager_id = (buffer_id).m_buffer_manager_id;\
867 (array_data).m_buffer_data = 0;\
868 (array_data).m_element_count = element_count;\
869 GIM_BUFFER_ARRAY_SET_STRIDE(type,array_data);\
870 GIM_BUFFER_ARRAY_SET_OFFSET(array_data,offset);\
871 gim_buffer_add_ref(&(buffer_id));\
872}\
873
874//! Initializes a buffer array giving a data type and a buffer id
875/*!
876m_buffer_data will be 0, for acces to the elements, you'd need to call lock_array.
877\param type Type of the Array. It determines the stride.
878\param array_data Array structure to be filled
879\param buffer_id A GBUFFER_ID structure which this array_daya will refer to
880\param element_count Number of elements
881\post Adds reference to the buffer
882\sa gim_buffer_add_ref
883*/
884#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)
885
886//! Gain access to the array buffer through the m_buffer_data element
887/*!
888m_buffer_data pointer will be located at the m_byte_offset position of the buffer m_buffer
889Then, You'd need to call unlock_array when finish to using the array access.
890
891\pre if m_buffer_data != 0, the function returns
892\param array_data Array structure to be locked
893\param access A constant for access to the buffer. can be G_MA_READ_ONLY,G_MA_WRITE_ONLY or G_MA_READ_WRITE
894\return an Buffer error code
895*/
896GINT gim_buffer_array_lock(GBUFFER_ARRAY * array_data, int access);
897
898//! close the access to the array buffer through the m_buffer_data element
899/*!
900\param array_data Array structure to be locked
901\return an Buffer error code
902*/
903GINT gim_buffer_array_unlock(GBUFFER_ARRAY * array_data);
904
905//! Copy an array by reference
906/*!
907\post A reference to the m_buffer_id is increased.
908*/
909void gim_buffer_array_copy_ref(GBUFFER_ARRAY * source_data,GBUFFER_ARRAY * dest_data);
910
911
912//! Copy an array by value
913/*!
914\post A new buffer is created
915*/
916void gim_buffer_array_copy_value(GBUFFER_ARRAY * source_data,GBUFFER_ARRAY * dest_data, GUINT buffer_manager_id,int usage);
917
918//! Destroys an GBUFFER_ARRAY object
919/*!
920\post Attemps to destroy the buffer, decreases reference counting
921*/
922void GIM_BUFFER_ARRAY_DESTROY(GBUFFER_ARRAY & array_data);
923
924//! Copy the content of the array to a pointer
925/*!
926\pre dest_data must have the same size as the array_data
927\param type
928\param array_data A GBUFFERED_ARRAY structure
929\param dest_data A type pointer
930*/
931#define GIM_BUFFER_ARRAY_DOWNLOAD(type,array_data,dest_data)\
932{\
933 if(GIM_BUFFER_ARRAY_IS_ALIGNED(type,array_data))\
934 {\
935 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);\
936 }\
937 else\
938 {\
939 GUINT _k_, _ecount_= (array_data).m_element_count;\
940 type * _source_vert_;\
941 type * _dest_vert_ = dest_data;\
942 gim_buffer_array_lock(&(array_data),G_MA_READ_ONLY);\
943 for (_k_ = 0;_k_< _ecount_; _k_++)\
944 {\
945 _source_vert_ = GIM_BUFFER_ARRAY_POINTER(type,array_data,_k_);\
946 memcpy(_dest_vert_,_source_vert_,sizeof(type));\
947 _dest_vert_++;\
948 }\
949 gim_buffer_array_unlock(&(array_data));\
950 }\
951}\
952
953//! Upload the content of a a pointer to a buffered array
954/*!
955\pre source_data must have the same size as the array_data
956\param type
957\param array_data A GBUFFERED_ARRAY structure
958\param source_data A void pointer
959*/
960#define GIM_BUFFER_ARRAY_UPLOAD(type,array_data,source_data)\
961{\
962 if(GIM_BUFFER_ARRAY_IS_ALIGNED(type,array_data))\
963 {\
964 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);\
965 }\
966 else\
967 {\
968 GUINT _k_, _ecount_= (array_data).m_element_count;\
969 type * _source_vert_ = source_data;\
970 type * _dest_vert_;\
971 gim_buffer_array_lock(&(array_data),G_MA_WRITE_ONLY);\
972 for (_k_ = 0;_k_< _ecount_; _k_++)\
973 {\
974 _dest_vert_ = GIM_BUFFER_ARRAY_POINTER(type,array_data,_k_);\
975 memcpy(_dest_vert_,_source_vert_,sizeof(type));\
976 _source_vert_++;\
977 }\
978 gim_buffer_array_unlock(&(array_data));\
979 }\
980}\
981
982
983//!Kernel function prototype for process streams, given a buffered array as source and
984/*!
985\param 1 the uniform arguments
986\param 2 the source stream
987\param 3 the destination stream
988*/
989typedef void (* gim_kernel_func)(void *,GBUFFER_ARRAY *,GBUFFER_ARRAY *);
990
991//! Generic Stream Processingp loop
992/*!
993
994This macro executes a kernel macro or function for each element of the streams
995\pre _src_array->m_count <= _dst_array->m_count
996
997\param _uniform_data An argument to be passed to the Kernel function
998\param _src_array An GBUFFER_ARRAY structure passed as the source stream
999\param _dst_array An GBUFFER_ARRAY structure passed as the source stream
1000\param _kernel Macro or function of the kernel
1001\param _src_type Required. Type of all elements of the source stream
1002\param _dst_type Required. Type of all elements of the dest stream
1003*/
1004#define GIM_PROCESS_BUFFER_ARRAY(_uniform_data,_src_array,_dst_array,_kernel,_src_type,_dst_type) {\
1005\
1006 gim_buffer_array_lock(&_src_array,G_MA_READ_ONLY);\
1007 gim_buffer_array_lock(&_dst_array,G_MA_WRITE_ONLY);\
1008\
1009 GUINT _i_, _count_=(_src_array).m_element_count;\
1010\
1011 _src_type * _source_vert_;\
1012 _dst_type * _dest_vert_;\
1013 if(GIM_BUFFER_ARRAY_IS_ALIGNED(_src_type,_src_array) && GIM_BUFFER_ARRAY_IS_ALIGNED(_dst_type,_dst_array))\
1014 {\
1015\
1016 _source_vert_ = GIM_BUFFER_ARRAY_POINTER(_src_type,_src_array,0);\
1017 _dest_vert_ = GIM_BUFFER_ARRAY_POINTER(_dst_type,_dst_array,0);\
1018 for (_i_ = 0;_i_< _count_; _i_++)\
1019 {\
1020 _kernel(_uniform_data,(*_source_vert_),(*_dest_vert_));\
1021 _source_vert_++;\
1022 _dest_vert_++;\
1023 }\
1024 }\
1025 else\
1026 {\
1027 for (_i_ = 0;_i_< _count_; _i_++)\
1028 {\
1029 _source_vert_ = GIM_BUFFER_ARRAY_POINTER(_src_type,_src_array,_i_);\
1030 _dest_vert_ = GIM_BUFFER_ARRAY_POINTER(_dst_type,_dst_array,_i_);\
1031 _kernel(_uniform_data,(*_source_vert_),(*_dest_vert_));\
1032 }\
1033 }\
1034 gim_buffer_array_unlock(&_src_array);\
1035 gim_buffer_array_unlock(&_dst_array);\
1036}\
1037
1038//! @}
1039
1040#endif // GIM_MEMORY_H_INCLUDED