Changed: HAVE_PTHREAD_ATTR_SETINHERITSCHED and HAVE_PTHREAD_ATTR_SETSTACKLAZY defines...
[ode.git] / GIMPACT / src / gim_memory.cpp
blobcc5188d1722178a3842b0ce130a149e411529122
2 /*
3 -----------------------------------------------------------------------------
4 This source file is part of GIMPACT Library.
6 For the latest info, see http://gimpact.sourceforge.net/
8 Copyright (c) 2006 Francisco Leon. C.C. 80087371.
9 email: projectileman@yahoo.com
11 This library is free software; you can redistribute it and/or
12 modify it under the terms of EITHER:
13 (1) The GNU Lesser General Public License as published by the Free
14 Software Foundation; either version 2.1 of the License, or (at
15 your option) any later version. The text of the GNU Lesser
16 General Public License is included with this library in the
17 file GIMPACT-LICENSE-LGPL.TXT.
18 (2) The BSD-style license that is included with this library in
19 the file GIMPACT-LICENSE-BSD.TXT.
21 This library is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
24 GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
26 -----------------------------------------------------------------------------
30 #include <assert.h>
31 #include <stdlib.h>
32 #include "GIMPACT/gim_memory.h"
33 #include <ode/odeconfig.h>
34 #include "config.h"
35 //#include "malloc.h"
36 //#include "mm_malloc.h"
38 static gim_alloc_function *g_allocfn = 0;
39 // static gim_alloca_function *g_allocafn = 0; -- a nonsense
40 static gim_realloc_function *g_reallocfn = 0;
41 static gim_free_function *g_freefn = 0;
44 #define VALIDATE_BUFFER_MANAGER(buffer_managers,buffer_manager_id)\
45 if(buffer_manager_id>=G_BUFFER_MANAGER__MAX) return G_BUFFER_OP_INVALID;\
46 GBUFFER_MANAGER_DATA * bm_data;\
47 gim_get_buffer_manager_data(buffer_managers,buffer_manager_id,&bm_data);\
48 if(bm_data == 0) return G_BUFFER_OP_INVALID;\
50 #define VALIDATE_BUFFER_ID_PT(buffer_id)\
51 GBUFFER_MANAGER_DATA * bm_data = buffer_id->m_bm_data;\
52 if(bm_data == 0) return G_BUFFER_OP_INVALID;\
53 if(buffer_id->m_buffer_id>=bm_data->m_buffer_array.m_size) return G_BUFFER_OP_INVALID;\
54 GBUFFER_DATA * pbuffer = GIM_DYNARRAY_POINTER(GBUFFER_DATA,bm_data->m_buffer_array);\
55 pbuffer += buffer_id->m_buffer_id;\
56 if(pbuffer->m_buffer_handle==0) return G_BUFFER_OP_INVALID;\
59 void GIM_BUFFER_ARRAY_DESTROY(GBUFFER_ARRAY & array_data)
61 gim_buffer_array_unlock(&array_data);
62 gim_buffer_free(&(array_data).m_buffer_id);
65 void GIM_DYNARRAY_DESTROY(GDYNAMIC_ARRAY & array_data)
67 if(array_data.m_pdata != 0)
69 gim_free(array_data.m_pdata,0);
70 array_data.m_reserve_size = 0;
71 array_data.m_size = 0;
72 array_data.m_pdata = 0;
76 void gim_set_alloc_handler (gim_alloc_function *fn)
78 g_allocfn = fn;
81 /* -- a nonsense
82 void gim_set_alloca_handler (gim_alloca_function *fn)
84 g_allocafn = fn;
88 void gim_set_realloc_handler (gim_realloc_function *fn)
90 g_reallocfn = fn;
93 void gim_set_free_handler (gim_free_function *fn)
95 g_freefn = fn;
98 gim_alloc_function *gim_get_alloc_handler()
100 return g_allocfn;
103 /* -- a nonsense
104 gim_alloca_function *gim_get_alloca_handler()
106 return g_allocafn;
110 gim_realloc_function *gim_get_realloc_handler ()
112 return g_reallocfn;
116 gim_free_function *gim_get_free_handler ()
118 return g_freefn;
122 void * gim_alloc(size_t size)
124 void * ptr;
126 if (g_allocfn)
128 ptr = g_allocfn(size);
130 else
133 ptr = malloc(size);//_mm_malloc(size,0);*/
135 assert(ptr);
136 return ptr;
139 /* -- a nonsense
140 void * gim_alloca(size_t size)
142 if (g_allocafn) return g_allocafn(size); else return alloca(size);
146 void * gim_realloc(void *ptr, size_t oldsize, size_t newsize)
148 /*if (g_reallocfn) return g_reallocfn(ptr,oldsize,newsize);
149 else return realloc(ptr,newsize);*/
150 //return realloc(ptr,newsize);
151 void * newptr = gim_alloc(newsize);
152 size_t copysize = newsize> oldsize? oldsize: newsize;
153 memcpy(newptr,ptr,copysize);
154 gim_free(ptr,oldsize);
155 return newptr;
158 void gim_free(void *ptr, size_t size)
160 if (!ptr) return;
161 /* -- if custom allocation function is not used, custom free must not be used too
162 if (g_freefn)
164 g_freefn(ptr,size);
166 else
169 free(ptr);//_mm_free(ptr);
173 ///******************************* BUFFER MANAGERS ******************************///
175 //!** Basic buffer prototype functions
177 static GPTR _system_buffer_alloc_function(GUINT32 size,int usage)
179 void * newdata = gim_alloc(size);
180 memset(newdata,0,size);
181 return (GPTR)newdata;
184 static GPTR _system_buffer_alloc_data_function(const void * pdata,GUINT32 size,int usage)
186 void * newdata = gim_alloc(size);
187 memcpy(newdata,pdata,size);
188 return (GPTR)(newdata);
191 static GPTR _system_buffer_realloc_function(GPTR buffer_handle,GUINT32 oldsize,int old_usage,GUINT32 newsize,int new_usage)
193 void * newdata = gim_realloc(buffer_handle,oldsize,newsize);
194 return (GPTR)(newdata);
197 static void _system_buffer_free_function(GPTR buffer_handle,GUINT32 size)
199 gim_free(buffer_handle,size);
202 static char * _system_lock_buffer_function(GPTR buffer_handle,int access)
204 return (char * )(buffer_handle);
208 static void _system_unlock_buffer_function(GPTR buffer_handle)
212 static void _system_download_from_buffer_function(
213 GPTR source_buffer_handle,
214 GUINT32 source_pos,
215 void * destdata,
216 GUINT32 copysize)
218 char * pdata;
219 pdata = (char *)source_buffer_handle;
220 memcpy(destdata,pdata+source_pos,copysize);
223 static void _system_upload_to_buffer_function(
224 GPTR dest_buffer_handle,
225 GUINT32 dest_pos,
226 void * sourcedata,
227 GUINT32 copysize)
229 char * pdata;
230 pdata = (char * )dest_buffer_handle;
231 memcpy(pdata+dest_pos,sourcedata,copysize);
234 static void _system_copy_buffers_function(
235 GPTR source_buffer_handle,
236 GUINT32 source_pos,
237 GPTR dest_buffer_handle,
238 GUINT32 dest_pos,
239 GUINT32 copysize)
241 char * pdata1,*pdata2;
242 pdata1 = (char *)source_buffer_handle;
243 pdata2 = (char *)dest_buffer_handle;
244 memcpy(pdata2+dest_pos,pdata1+source_pos,copysize);
247 static GPTR _shared_buffer_alloc_function(GUINT32 size,int usage)
249 return 0;
252 static GPTR _shared_buffer_alloc_data_function(const void * pdata,GUINT32 size,int usage)
254 return (GPTR)pdata;
257 #if 0
258 static GPTR _shared_buffer_realloc_function(GPTR buffer_handle,GUINT32 oldsize,int old_usage,GUINT32 newsize,int new_usage)
260 return 0;
262 #endif
264 static void _shared_buffer_free_function(GPTR buffer_handle,GUINT32 size)
268 static inline int _is_buffer_manager_data_active(GBUFFER_MANAGER_DATA * bm_data)
270 return bm_data->m_buffer_array.m_pdata != 0;
273 static inline void _init_buffer_manager_data(GBUFFER_MANAGER_DATA * bm_data)
275 bm_data->m_buffer_array.m_pdata = 0;
278 static const GBUFFER_MANAGER_PROTOTYPE g_bm_prototypes[G_BUFFER_MANAGER__MAX] =
281 &_system_buffer_alloc_function, // alloc_fn;
282 &_system_buffer_alloc_data_function, // alloc_data_fn;
283 &_system_buffer_realloc_function, // realloc_fn;
284 &_system_buffer_free_function, // free_fn;
285 &_system_lock_buffer_function, // lock_buffer_fn;
286 &_system_unlock_buffer_function, // unlock_buffer_fn;
287 &_system_download_from_buffer_function, // download_from_buffer_fn;
288 &_system_upload_to_buffer_function, // upload_to_buffer_fn;
289 &_system_copy_buffers_function, // copy_buffers_fn;
290 }, // G_BUFFER_MANAGER_SYSTEM
293 &_shared_buffer_alloc_function, // alloc_fn;
294 &_shared_buffer_alloc_data_function, // alloc_data_fn;
295 &_system_buffer_realloc_function, // realloc_fn;
296 &_shared_buffer_free_function, // free_fn;
297 &_system_lock_buffer_function, // lock_buffer_fn;
298 &_system_unlock_buffer_function, // unlock_buffer_fn;
299 &_system_download_from_buffer_function, // download_from_buffer_fn;
300 &_system_upload_to_buffer_function, // upload_to_buffer_fn;
301 &_system_copy_buffers_function, // copy_buffers_fn;
302 }, // G_BUFFER_MANAGER_SHARED
305 int gim_is_buffer_manager_active(GBUFFER_MANAGER_DATA buffer_managers[],
306 GUINT32 buffer_manager_id)
308 GBUFFER_MANAGER_DATA * bm_data;
309 bm_data = &buffer_managers[buffer_manager_id];
310 return _is_buffer_manager_data_active(bm_data);
313 //!** Buffer manager operations
314 void gim_create_buffer_manager(GBUFFER_MANAGER_DATA buffer_managers[],
315 GUINT32 buffer_manager_id)
317 GBUFFER_MANAGER_DATA * bm_data;
318 bm_data = &buffer_managers[buffer_manager_id];
320 if (_is_buffer_manager_data_active(bm_data))
322 gim_destroy_buffer_manager(buffer_managers, buffer_manager_id);
325 //CREATE ARRAYS
326 GIM_DYNARRAY_CREATE(GBUFFER_DATA,bm_data->m_buffer_array,G_ARRAY_BUFFERMANAGER_INIT_SIZE);
327 GIM_DYNARRAY_CREATE(GUINT32,bm_data->m_free_positions,G_ARRAY_BUFFERMANAGER_INIT_SIZE);
328 bm_data->m_prototype = g_bm_prototypes + buffer_manager_id;
329 bm_data->m_buffer_manager_id = buffer_manager_id;
332 void gim_destroy_buffer_manager(GBUFFER_MANAGER_DATA buffer_managers[], GUINT32 buffer_manager_id)
334 GBUFFER_MANAGER_DATA * bm_data;
335 gim_get_buffer_manager_data(buffer_managers,buffer_manager_id,&bm_data);
336 if(bm_data == 0) return;
337 //Destroy all buffers
339 GBUFFER_DATA * buffers = GIM_DYNARRAY_POINTER(GBUFFER_DATA,bm_data->m_buffer_array);
340 GUINT32 i, buffer_count = bm_data->m_buffer_array.m_size;
341 for (i=0;i<buffer_count ;i++ )
343 GBUFFER_DATA * current_buffer = buffers + i;
344 if(current_buffer->m_buffer_handle!=0) //Is active
346 // free handle
347 bm_data->m_prototype->free_fn(current_buffer->m_buffer_handle,current_buffer->m_size);
351 //destroy buffer array
352 GIM_DYNARRAY_DESTROY(bm_data->m_buffer_array);
353 //destroy free positions
354 GIM_DYNARRAY_DESTROY(bm_data->m_free_positions);
356 void gim_get_buffer_manager_data(GBUFFER_MANAGER_DATA buffer_managers[],
357 GUINT32 buffer_manager_id,GBUFFER_MANAGER_DATA ** pbm_data)
359 GBUFFER_MANAGER_DATA * bm_data;
360 bm_data = &buffer_managers[buffer_manager_id];
362 if (_is_buffer_manager_data_active(bm_data))
364 *pbm_data = bm_data;
366 else
368 *pbm_data = 0;
372 void gim_init_buffer_managers(GBUFFER_MANAGER_DATA buffer_managers[])
374 GUINT32 i;
375 for (i=0;i<G_BUFFER_MANAGER__MAX;i++)
377 _init_buffer_manager_data(buffer_managers + i);
380 // Add the two most important buffer managers
382 //add system buffer manager
383 gim_create_buffer_manager(buffer_managers,G_BUFFER_MANAGER_SYSTEM );
385 //add shared buffer manager
386 gim_create_buffer_manager(buffer_managers,G_BUFFER_MANAGER_SHARED);
389 void gim_terminate_buffer_managers(GBUFFER_MANAGER_DATA buffer_managers[])
391 GUINT32 i;
392 for (i=0;i<G_BUFFER_MANAGER__MAX;i++)
394 gim_destroy_buffer_manager(buffer_managers,i);
398 //!** Buffer operations
400 void GET_AVALIABLE_BUFFER_ID(GBUFFER_MANAGER_DATA * buffer_manager, GUINT32 & buffer_id)
402 if(buffer_manager->m_free_positions.m_size>0)\
404 GUINT32 * _pointer = GIM_DYNARRAY_POINTER(GUINT32,buffer_manager->m_free_positions);
405 buffer_id = _pointer[buffer_manager->m_free_positions.m_size-1];
406 GIM_DYNARRAY_POP_ITEM(buffer_manager->m_free_positions);
408 else
410 buffer_id = buffer_manager->m_buffer_array.m_size;
411 GIM_DYNARRAY_PUSH_EMPTY(GBUFFER_DATA,buffer_manager->m_buffer_array);
415 GINT32 _validate_buffer_id(GBUFFER_ID * buffer_id,GBUFFER_DATA ** ppbuffer,GBUFFER_MANAGER_DATA ** pbm_data)
417 VALIDATE_BUFFER_ID_PT(buffer_id)
418 *ppbuffer = pbuffer;
419 *pbm_data = bm_data;
420 return G_BUFFER_OP_SUCCESS;
423 GUINT32 gim_create_buffer(
424 GBUFFER_MANAGER_DATA buffer_managers[],
425 GUINT32 buffer_manager_id,
426 GUINT32 buffer_size,
427 int usage,
428 GBUFFER_ID * buffer_id)
430 VALIDATE_BUFFER_MANAGER(buffer_managers,buffer_manager_id)
432 GPTR newbufferhandle = bm_data->m_prototype->alloc_fn(buffer_size,usage);
433 if(newbufferhandle==0) return G_BUFFER_OP_INVALID;
435 GET_AVALIABLE_BUFFER_ID(bm_data,buffer_id->m_buffer_id);
436 buffer_id->m_bm_data = bm_data;
438 GBUFFER_DATA * pbuffer = GIM_DYNARRAY_POINTER(GBUFFER_DATA,bm_data->m_buffer_array);
439 pbuffer += buffer_id->m_buffer_id ;
440 pbuffer->m_buffer_handle = newbufferhandle;
441 pbuffer->m_size = buffer_size;
442 pbuffer->m_usage = usage;
443 pbuffer->m_lock_count = 0;
444 pbuffer->m_refcount = 0;
445 pbuffer->m_mapped_pointer = 0;
447 //set shadow buffer if needed
449 if(usage == G_MU_STATIC_READ ||
450 usage == G_MU_STATIC_READ_DYNAMIC_WRITE||
451 usage == G_MU_STATIC_READ_DYNAMIC_WRITE_COPY)
453 gim_create_common_buffer(buffer_managers,buffer_size,&pbuffer->m_shadow_buffer);
455 else
457 pbuffer->m_shadow_buffer.m_bm_data = 0;
458 pbuffer->m_shadow_buffer.m_buffer_id = G_UINT_INFINITY;
460 return G_BUFFER_OP_SUCCESS;
464 GUINT32 gim_create_buffer_from_data(
465 GBUFFER_MANAGER_DATA buffer_managers[],
466 GUINT32 buffer_manager_id,
467 const void * pdata,
468 GUINT32 buffer_size,
469 int usage,
470 GBUFFER_ID * buffer_id)
472 VALIDATE_BUFFER_MANAGER(buffer_managers,buffer_manager_id)
474 GPTR newbufferhandle = bm_data->m_prototype->alloc_data_fn(pdata,buffer_size,usage);
475 if(newbufferhandle==0) return G_BUFFER_OP_INVALID;
477 GET_AVALIABLE_BUFFER_ID(bm_data,buffer_id->m_buffer_id);
478 buffer_id->m_bm_data = bm_data;
480 GBUFFER_DATA * pbuffer = GIM_DYNARRAY_POINTER(GBUFFER_DATA,bm_data->m_buffer_array);
481 pbuffer += buffer_id->m_buffer_id ;
482 pbuffer->m_buffer_handle = newbufferhandle;
483 pbuffer->m_size = buffer_size;
484 pbuffer->m_usage = usage;
485 pbuffer->m_lock_count = 0;
486 pbuffer->m_mapped_pointer = 0;
487 pbuffer->m_refcount = 0;
489 //set shadow buffer if needed
491 if(usage == G_MU_STATIC_READ ||
492 usage == G_MU_STATIC_READ_DYNAMIC_WRITE||
493 usage == G_MU_STATIC_READ_DYNAMIC_WRITE_COPY)
495 gim_create_common_buffer_from_data(buffer_managers,pdata,buffer_size,&pbuffer->m_shadow_buffer);
497 else
499 pbuffer->m_shadow_buffer.m_bm_data = 0;
500 pbuffer->m_shadow_buffer.m_buffer_id = G_UINT_INFINITY;
502 return G_BUFFER_OP_SUCCESS;
505 GUINT32 gim_create_common_buffer(GBUFFER_MANAGER_DATA buffer_managers[],
506 GUINT32 buffer_size, GBUFFER_ID * buffer_id)
508 return gim_create_buffer(buffer_managers,G_BUFFER_MANAGER_SYSTEM,buffer_size,G_MU_DYNAMIC_READ_WRITE,buffer_id);
511 GUINT32 gim_create_common_buffer_from_data(GBUFFER_MANAGER_DATA buffer_managers[],
512 const void * pdata, GUINT32 buffer_size, GBUFFER_ID * buffer_id)
514 return gim_create_buffer_from_data(buffer_managers,G_BUFFER_MANAGER_SYSTEM,pdata,buffer_size,G_MU_DYNAMIC_READ_WRITE,buffer_id);
517 GUINT32 gim_create_shared_buffer_from_data(GBUFFER_MANAGER_DATA buffer_managers[],
518 const void * pdata, GUINT32 buffer_size, GBUFFER_ID * buffer_id)
520 return gim_create_buffer_from_data(buffer_managers,G_BUFFER_MANAGER_SHARED,pdata,buffer_size,G_MU_DYNAMIC_READ_WRITE,buffer_id);
523 GINT32 gim_buffer_realloc(GBUFFER_ID * buffer_id,GUINT32 newsize)
525 VALIDATE_BUFFER_ID_PT(buffer_id)
526 if(pbuffer->m_lock_count>0) return G_BUFFER_OP_INVALID;
527 GPTR newhandle = buffer_id->m_bm_data->m_prototype->realloc_fn(
528 pbuffer->m_buffer_handle,pbuffer->m_size,pbuffer->m_usage,newsize,pbuffer->m_usage);
529 if(newhandle==0) return G_BUFFER_OP_INVALID;
530 pbuffer->m_buffer_handle = newhandle;
531 //realloc shadow buffer if any
532 gim_buffer_realloc(&pbuffer->m_shadow_buffer,newsize);
533 return G_BUFFER_OP_SUCCESS;
536 GINT32 gim_buffer_add_ref(GBUFFER_ID * buffer_id)
538 VALIDATE_BUFFER_ID_PT(buffer_id)
539 pbuffer->m_refcount++;
540 return G_BUFFER_OP_SUCCESS;
543 GINT32 gim_buffer_free(GBUFFER_ID * buffer_id)
545 VALIDATE_BUFFER_ID_PT(buffer_id)
546 if(pbuffer->m_lock_count>0) return G_BUFFER_OP_INVALID;
547 if(pbuffer->m_refcount>0) pbuffer->m_refcount--;
548 if(pbuffer->m_refcount>0) return G_BUFFER_OP_STILLREFCOUNTED;
550 buffer_id->m_bm_data->m_prototype->free_fn(
551 pbuffer->m_buffer_handle,pbuffer->m_size);
552 //destroy shadow buffer if needed
553 gim_buffer_free(&pbuffer->m_shadow_buffer);
554 // Obtain a free slot index for a new buffer
555 GIM_DYNARRAY_PUSH_ITEM(GUINT32,bm_data->m_free_positions,buffer_id->m_buffer_id);
556 pbuffer->m_buffer_handle = 0;
557 pbuffer->m_size = 0;
558 pbuffer->m_shadow_buffer.m_bm_data = 0;
559 pbuffer->m_shadow_buffer.m_buffer_id = G_UINT_INFINITY;
560 return G_BUFFER_OP_SUCCESS;
563 GINT32 gim_lock_buffer(GBUFFER_ID * buffer_id,int access,char ** map_pointer)
565 VALIDATE_BUFFER_ID_PT(buffer_id)
566 if(pbuffer->m_lock_count>0)
568 if(pbuffer->m_access!=access) return G_BUFFER_OP_INVALID;
569 pbuffer->m_lock_count++;
570 *map_pointer = pbuffer->m_mapped_pointer;
571 return G_BUFFER_OP_SUCCESS;
574 pbuffer->m_access = access;
576 GUINT32 result;
577 if(pbuffer->m_usage==G_MU_STATIC_WRITE)
579 *map_pointer = 0;///no access
580 return G_BUFFER_OP_INVALID;
582 else if(pbuffer->m_usage==G_MU_STATIC_READ)
584 if(pbuffer->m_access == G_MA_READ_ONLY)
586 result = gim_lock_buffer(&pbuffer->m_shadow_buffer,access,map_pointer);
587 if(result!= G_BUFFER_OP_SUCCESS) return G_BUFFER_OP_INVALID;
588 pbuffer->m_mapped_pointer = *map_pointer;
589 pbuffer->m_lock_count++;
591 else
593 *map_pointer = 0;
594 return G_BUFFER_OP_INVALID;
597 else if(pbuffer->m_usage==G_MU_STATIC_READ_DYNAMIC_WRITE)
599 if(pbuffer->m_access == G_MA_READ_ONLY)
601 result = gim_lock_buffer(&pbuffer->m_shadow_buffer,access,map_pointer);
602 if(result!= G_BUFFER_OP_SUCCESS) return G_BUFFER_OP_INVALID;
603 pbuffer->m_mapped_pointer = *map_pointer;
604 pbuffer->m_lock_count++;
606 else if(pbuffer->m_access == G_MA_WRITE_ONLY)
608 pbuffer->m_mapped_pointer = buffer_id->m_bm_data->m_prototype->lock_buffer_fn(
609 pbuffer->m_buffer_handle,access);
610 *map_pointer = pbuffer->m_mapped_pointer;
611 pbuffer->m_lock_count++;
613 else if(pbuffer->m_access == G_MA_READ_WRITE)
615 *map_pointer = 0;
616 return G_BUFFER_OP_INVALID;
619 else if(pbuffer->m_usage==G_MU_STATIC_READ_DYNAMIC_WRITE_COPY)
621 result = gim_lock_buffer(&pbuffer->m_shadow_buffer,access,map_pointer);
622 if(result!= G_BUFFER_OP_SUCCESS) return G_BUFFER_OP_INVALID;
623 pbuffer->m_mapped_pointer = *map_pointer;
624 pbuffer->m_lock_count++;
626 else if(pbuffer->m_usage==G_MU_STATIC_WRITE_DYNAMIC_READ)
628 if(pbuffer->m_access == G_MA_READ_ONLY)
630 pbuffer->m_mapped_pointer = buffer_id->m_bm_data->m_prototype->lock_buffer_fn(
631 pbuffer->m_buffer_handle,access);
632 *map_pointer = pbuffer->m_mapped_pointer;
633 pbuffer->m_lock_count++;
635 else
637 *map_pointer = 0;
638 return G_BUFFER_OP_INVALID;
641 else if(pbuffer->m_usage==G_MU_DYNAMIC_READ_WRITE)
643 pbuffer->m_mapped_pointer = buffer_id->m_bm_data->m_prototype->lock_buffer_fn(
644 pbuffer->m_buffer_handle,access);
645 *map_pointer = pbuffer->m_mapped_pointer;
646 pbuffer->m_lock_count++;
648 return G_BUFFER_OP_SUCCESS;
651 GINT32 gim_unlock_buffer(GBUFFER_ID * buffer_id)
653 VALIDATE_BUFFER_ID_PT(buffer_id)
654 if(pbuffer->m_lock_count==0) return G_BUFFER_OP_INVALID;
656 if(pbuffer->m_lock_count>1)
658 pbuffer->m_lock_count--;
659 return G_BUFFER_OP_SUCCESS;
663 GUINT32 result;
664 if(pbuffer->m_usage==G_MU_STATIC_WRITE)
666 pbuffer->m_mapped_pointer = 0;
667 pbuffer->m_lock_count=0;
668 return G_BUFFER_OP_INVALID;
670 else if(pbuffer->m_usage==G_MU_STATIC_READ)
672 if(pbuffer->m_access == G_MA_READ_ONLY)
674 result = gim_unlock_buffer(&pbuffer->m_shadow_buffer);
675 if(result!= G_BUFFER_OP_SUCCESS) return G_BUFFER_OP_INVALID;
676 pbuffer->m_mapped_pointer = 0;
677 pbuffer->m_lock_count=0;
679 else
681 pbuffer->m_mapped_pointer = 0;
682 pbuffer->m_lock_count=0;
683 return G_BUFFER_OP_INVALID;
686 else if(pbuffer->m_usage==G_MU_STATIC_READ_DYNAMIC_WRITE)
688 if(pbuffer->m_access == G_MA_READ_ONLY)
690 result = gim_unlock_buffer(&pbuffer->m_shadow_buffer);
691 if(result!= G_BUFFER_OP_SUCCESS) return G_BUFFER_OP_INVALID;
692 pbuffer->m_mapped_pointer = 0;
693 pbuffer->m_lock_count=0;
695 else if(pbuffer->m_access == G_MA_WRITE_ONLY)
697 buffer_id->m_bm_data->m_prototype->unlock_buffer_fn(
698 pbuffer->m_buffer_handle);
699 pbuffer->m_mapped_pointer = 0;
700 pbuffer->m_lock_count=0;
702 else if(pbuffer->m_access == G_MA_READ_WRITE)
704 pbuffer->m_mapped_pointer = 0;
705 pbuffer->m_lock_count=0;
706 return G_BUFFER_OP_INVALID;
709 else if(pbuffer->m_usage==G_MU_STATIC_READ_DYNAMIC_WRITE_COPY)
711 result = gim_unlock_buffer(&pbuffer->m_shadow_buffer);
712 if(result!= G_BUFFER_OP_SUCCESS) return G_BUFFER_OP_INVALID;
713 pbuffer->m_mapped_pointer = 0;
714 pbuffer->m_lock_count=0;
715 if(pbuffer->m_access == G_MA_WRITE_ONLY||pbuffer->m_access == G_MA_READ_WRITE)
717 gim_copy_buffers(&pbuffer->m_shadow_buffer,0,buffer_id,0,pbuffer->m_size);
720 else if(pbuffer->m_usage==G_MU_STATIC_WRITE_DYNAMIC_READ)
722 if(pbuffer->m_access == G_MA_READ_ONLY)
724 buffer_id->m_bm_data->m_prototype->unlock_buffer_fn(
725 pbuffer->m_buffer_handle);
726 pbuffer->m_mapped_pointer = 0;
727 pbuffer->m_lock_count=0;
729 else
731 pbuffer->m_mapped_pointer = 0;
732 pbuffer->m_lock_count=0;
733 return G_BUFFER_OP_INVALID;
736 else if(pbuffer->m_usage==G_MU_DYNAMIC_READ_WRITE)
738 buffer_id->m_bm_data->m_prototype->unlock_buffer_fn(
739 pbuffer->m_buffer_handle);
740 pbuffer->m_mapped_pointer = 0;
741 pbuffer->m_lock_count=0;
743 return G_BUFFER_OP_SUCCESS;
746 GINT32 gim_get_buffer_size(GBUFFER_ID * buffer_id,GUINT32 * buffer_size)
748 VALIDATE_BUFFER_ID_PT(buffer_id)
749 *buffer_size = pbuffer->m_size;
750 return G_BUFFER_OP_SUCCESS;
753 GINT32 gim_get_buffer_is_locked(GBUFFER_ID * buffer_id,GUINT32 * lock_count)
755 VALIDATE_BUFFER_ID_PT(buffer_id)
756 *lock_count = pbuffer->m_lock_count;
757 return G_BUFFER_OP_SUCCESS;
761 GINT32 gim_download_from_buffer(
762 GBUFFER_ID * buffer_id,
763 GUINT32 source_pos,
764 void * destdata,
765 GUINT32 copysize)
767 VALIDATE_BUFFER_ID_PT(buffer_id)
768 buffer_id->m_bm_data->m_prototype->download_from_buffer_fn(
769 pbuffer->m_buffer_handle,source_pos,destdata,copysize);
770 return G_BUFFER_OP_SUCCESS;
773 GINT32 gim_upload_to_buffer(
774 GBUFFER_ID * buffer_id,
775 GUINT32 dest_pos,
776 void * sourcedata,
777 GUINT32 copysize)
779 VALIDATE_BUFFER_ID_PT(buffer_id)
780 buffer_id->m_bm_data->m_prototype->upload_to_buffer_fn(
781 pbuffer->m_buffer_handle,dest_pos,sourcedata,copysize);
782 return G_BUFFER_OP_SUCCESS;
785 GINT32 gim_copy_buffers(
786 GBUFFER_ID * source_buffer_id,
787 GUINT32 source_pos,
788 GBUFFER_ID * dest_buffer_id,
789 GUINT32 dest_pos,
790 GUINT32 copysize)
792 GBUFFER_MANAGER_DATA * bm_data1,* bm_data2;
793 GBUFFER_DATA * pbuffer1, * pbuffer2;
794 void * tempdata;
795 if(_validate_buffer_id(source_buffer_id,&pbuffer1,&bm_data1)!= G_BUFFER_OP_SUCCESS) return G_BUFFER_OP_INVALID;
797 if(_validate_buffer_id(dest_buffer_id,&pbuffer2,&bm_data2)!= G_BUFFER_OP_SUCCESS) return G_BUFFER_OP_INVALID;
799 if((bm_data1->m_buffer_manager_id == bm_data2->m_buffer_manager_id)||
800 (bm_data1->m_buffer_manager_id == G_BUFFER_MANAGER_SYSTEM && bm_data2->m_buffer_manager_id == G_BUFFER_MANAGER_SHARED)||
801 (bm_data1->m_buffer_manager_id == G_BUFFER_MANAGER_SHARED && bm_data2->m_buffer_manager_id == G_BUFFER_MANAGER_SYSTEM)
803 {//smooth copy
804 bm_data1->m_prototype->copy_buffers_fn(
805 pbuffer1->m_buffer_handle,source_pos,pbuffer2->m_buffer_handle,dest_pos,copysize);
807 else if(bm_data1->m_buffer_manager_id == G_BUFFER_MANAGER_SYSTEM ||
808 bm_data1->m_buffer_manager_id == G_BUFFER_MANAGER_SHARED)
810 //hard copy
811 tempdata = (void *)pbuffer1->m_buffer_handle;
812 //upload data
813 bm_data2->m_prototype->upload_to_buffer_fn(
814 pbuffer2->m_buffer_handle,dest_pos,tempdata,copysize);
816 else
818 //very hard copy
819 void * tempdata = gim_alloc(copysize);
820 //download data
821 bm_data1->m_prototype->download_from_buffer_fn(
822 pbuffer1->m_buffer_handle,source_pos,tempdata,copysize);
824 //upload data
825 bm_data2->m_prototype->upload_to_buffer_fn(
826 pbuffer2->m_buffer_handle,dest_pos,tempdata,copysize);
827 //delete temp buffer
828 gim_free(tempdata,copysize);
830 return G_BUFFER_OP_SUCCESS;
833 GINT32 gim_buffer_array_lock(GBUFFER_ARRAY * array_data, int access)
835 if(array_data->m_buffer_data != 0) return G_BUFFER_OP_SUCCESS;
836 GINT32 result = gim_lock_buffer(&array_data->m_buffer_id,access,&array_data->m_buffer_data);
837 if(result!= G_BUFFER_OP_SUCCESS) return result;
838 array_data->m_buffer_data += array_data->m_byte_offset;
839 return result;
842 GINT32 gim_buffer_array_unlock(GBUFFER_ARRAY * array_data)
844 if(array_data->m_buffer_data == 0) return G_BUFFER_OP_SUCCESS;
845 GINT32 result = gim_unlock_buffer(&array_data->m_buffer_id);
846 if(result!= G_BUFFER_OP_SUCCESS) return result;
847 array_data->m_buffer_data = 0;
848 return result;
851 void gim_buffer_array_copy_ref(GBUFFER_ARRAY * source_data,GBUFFER_ARRAY * dest_data)
853 dest_data->m_buffer_id.m_buffer_id = source_data->m_buffer_id.m_buffer_id;
854 dest_data->m_buffer_id.m_bm_data = source_data->m_buffer_id.m_bm_data;
855 dest_data->m_buffer_data = 0;
856 dest_data->m_byte_stride = source_data->m_byte_stride;
857 dest_data->m_byte_offset = source_data->m_byte_offset;
858 dest_data->m_element_count = source_data->m_element_count;
859 gim_buffer_add_ref(&dest_data->m_buffer_id);
862 void gim_buffer_array_copy_value(GBUFFER_ARRAY * source_data,
863 GBUFFER_MANAGER_DATA dest_buffer_managers[],GBUFFER_ARRAY * dest_data,
864 GUINT32 buffer_manager_id,int usage)
866 //Create new buffer
867 GUINT32 buffsize = source_data->m_element_count*source_data->m_byte_stride;
868 gim_create_buffer(dest_buffer_managers,buffer_manager_id,buffsize,usage,&dest_data->m_buffer_id);
870 //copy ref data
871 dest_data->m_buffer_data = 0;
872 dest_data->m_byte_stride = source_data->m_byte_stride;
873 dest_data->m_byte_offset = 0;
874 dest_data->m_element_count = source_data->m_element_count;
875 gim_buffer_add_ref(&dest_data->m_buffer_id);
876 //copy buffers
877 gim_copy_buffers(&source_data->m_buffer_id,source_data->m_byte_offset,&dest_data->m_buffer_id,0,buffsize);