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 |
---|