diff options
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.h | 1040 |
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 | ----------------------------------------------------------------------------- | ||
8 | This source file is part of GIMPACT Library. | ||
9 | |||
10 | For the latest info, see http://gimpact.sourceforge.net/ | ||
11 | |||
12 | Copyright (c) 2006 Francisco Leon. C.C. 80087371. | ||
13 | email: 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 | ||
58 | Functions 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 | ||
100 | Function prototypes to allocate and free memory. | ||
101 | */ | ||
102 | //! @{ | ||
103 | typedef void * gim_alloc_function (size_t size); | ||
104 | typedef void * gim_alloca_function (size_t size);//Allocs on the heap | ||
105 | typedef void * gim_realloc_function (void *ptr, size_t oldsize, size_t newsize); | ||
106 | typedef void gim_free_function (void *ptr, size_t size); | ||
107 | //! @} | ||
108 | |||
109 | /*! \defgroup MEMORY_FUNCTION_HANDLERS | ||
110 | \brief | ||
111 | Memory Function Handlers | ||
112 | set new memory management functions. if fn is 0, the default handlers are | ||
113 | used. */ | ||
114 | //! @{ | ||
115 | void gim_set_alloc_handler (gim_alloc_function *fn); | ||
116 | void gim_set_alloca_handler (gim_alloca_function *fn); | ||
117 | void gim_set_realloc_handler (gim_realloc_function *fn); | ||
118 | void gim_set_free_handler (gim_free_function *fn); | ||
119 | //! @} | ||
120 | |||
121 | /*! \defgroup MEMORY_FUNCTION_GET_HANDLERS | ||
122 | \brief | ||
123 | get current memory management functions. | ||
124 | */ | ||
125 | //! @{ | ||
126 | gim_alloc_function *gim_get_alloc_handler (void); | ||
127 | gim_alloca_function *gim_get_alloca_handler(void); | ||
128 | gim_realloc_function *gim_get_realloc_handler (void); | ||
129 | gim_free_function *gim_get_free_handler (void); | ||
130 | //! @} | ||
131 | |||
132 | /*! \defgroup MEMORY_FUNCTIONS | ||
133 | Standar Memory functions | ||
134 | */ | ||
135 | //! @{ | ||
136 | void * gim_alloc(size_t size); | ||
137 | void * gim_alloca(size_t size); | ||
138 | void * gim_realloc(void *ptr, size_t oldsize, size_t newsize); | ||
139 | void gim_free(void *ptr, size_t size); | ||
140 | //! @} | ||
141 | |||
142 | /*! \defgroup DYNAMIC_ARRAYS | ||
143 | \brief | ||
144 | Dynamic 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. | ||
154 | struct 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 | ||
260 | void GIM_DYNARRAY_DESTROY(GDYNAMIC_ARRAY & array_data); | ||
261 | //! @} | ||
262 | |||
263 | /*! \defgroup BITSET | ||
264 | \brief | ||
265 | Bitsets , 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 | ||
357 | Memory 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 | ||
368 | Memory 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 | ||
390 | Buffer 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 | ||
401 | Buffer 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 | ||
412 | Buffer 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. | ||
426 | struct 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 | ||
434 | struct 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 | ||
450 | Function prototypes to allocate and free memory for buffers | ||
451 | \sa BUFFER_MANAGERS, BUFFERS | ||
452 | */ | ||
453 | //! @{ | ||
454 | |||
455 | //! Returns a Buffer handle | ||
456 | typedef GUINT gim_buffer_alloc_function(GUINT size,int usage); | ||
457 | |||
458 | //! Returns a Buffer handle, and copies the pdata to the buffer | ||
459 | typedef 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 | ||
462 | typedef 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 | ||
465 | typedef void gim_buffer_free_function(GUINT buffer_handle,GUINT size); | ||
466 | |||
467 | //! It maps the m_mapped_pointer. Returns a pointer | ||
468 | typedef char * gim_lock_buffer_function(GUINT buffer_handle,int access); | ||
469 | |||
470 | //! It sets the m_mapped_pointer to 0 | ||
471 | typedef void gim_unlock_buffer_function(GUINT buffer_handle); | ||
472 | |||
473 | typedef void gim_download_from_buffer_function( | ||
474 | GUINT source_buffer_handle, | ||
475 | GUINT source_pos, | ||
476 | void * destdata, | ||
477 | GUINT copysize); | ||
478 | |||
479 | typedef void gim_upload_to_buffer_function( | ||
480 | GUINT dest_buffer_handle, | ||
481 | GUINT dest_pos, | ||
482 | void * sourcedata, | ||
483 | GUINT copysize); | ||
484 | |||
485 | typedef 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 | ||
496 | Buffer Manager operations | ||
497 | */ | ||
498 | //! @{ | ||
499 | //! Buffer manager prototype | ||
500 | struct 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 | ||
515 | struct 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 | ||
525 | void gim_create_buffer_manager(GBUFFER_MANAGER_PROTOTYPE * prototype,GUINT buffer_manager_id); | ||
526 | //! Gets buffer manager | ||
527 | GUINT gim_get_buffer_manager_count(); | ||
528 | //! Destroys a buffer manager | ||
529 | void gim_destroy_buffer_manager(GUINT buffer_manager_id); | ||
530 | void gim_get_buffer_manager_data(GUINT buffer_manager_id,GBUFFER_MANAGER_DATA ** pbm_data); | ||
531 | void gim_init_buffer_managers(); | ||
532 | void 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 | */ | ||
550 | GUINT 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 | */ | ||
566 | GUINT 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 | ||
574 | GUINT gim_create_common_buffer(GUINT buffer_size, GBUFFER_ID * buffer_id); | ||
575 | //!Allocates on the G_BUFFER_MANAGER_SYSTEM, and copies the data | ||
576 | GUINT gim_create_common_buffer_from_data( | ||
577 | const void * pdata, GUINT buffer_size, GBUFFER_ID * buffer_id); | ||
578 | //!Creates a buffer with shared data | ||
579 | GUINT 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. | ||
584 | GINT 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 | */ | ||
593 | GINT gim_buffer_realloc(GBUFFER_ID * buffer_id,GUINT newsize); | ||
594 | |||
595 | //! Eliminates the buffer. | ||
596 | /*! | ||
597 | If the buffer reference counting is <= 1 and is unlocked, then it eliminates the buffer. | ||
598 | */ | ||
599 | GINT 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 | */ | ||
608 | GINT gim_lock_buffer(GBUFFER_ID * buffer_id,int access,char ** map_pointer); | ||
609 | |||
610 | //! Unlocks the buffer for memory access. | ||
611 | GINT gim_unlock_buffer(GBUFFER_ID * buffer_id); | ||
612 | |||
613 | //! Gets the buffer size in bytes | ||
614 | GINT gim_get_buffer_size(GBUFFER_ID * buffer_id,GUINT * buffer_size); | ||
615 | |||
616 | //! Determines if the buffer is locked | ||
617 | GINT gim_get_buffer_is_locked(GBUFFER_ID * buffer_id,GUINT * lock_count); | ||
618 | |||
619 | //! Copies the content of the buffer to a dest pointer | ||
620 | GINT 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 | ||
627 | GINT gim_upload_to_buffer( | ||
628 | GBUFFER_ID * buffer_id, | ||
629 | GUINT dest_pos, | ||
630 | void * sourcedata, | ||
631 | GUINT copysize); | ||
632 | |||
633 | //! Copies two buffers. | ||
634 | GINT 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 | ||
646 | Buffered 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> | ||
654 | The following example shows how Buffer arrays can be used: | ||
655 | |||
656 | \code | ||
657 | int 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. | ||
705 | struct 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 | /*! | ||
832 | m_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 | /*! | ||
854 | m_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 | /*! | ||
876 | m_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 | /*! | ||
888 | m_buffer_data pointer will be located at the m_byte_offset position of the buffer m_buffer | ||
889 | Then, 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 | */ | ||
896 | GINT 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 | */ | ||
903 | GINT 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 | */ | ||
909 | void 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 | */ | ||
916 | void 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 | */ | ||
922 | void 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 | */ | ||
989 | typedef void (* gim_kernel_func)(void *,GBUFFER_ARRAY *,GBUFFER_ARRAY *); | ||
990 | |||
991 | //! Generic Stream Processingp loop | ||
992 | /*! | ||
993 | |||
994 | This 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 | ||