1 /**************************************************************************
5 Copyright 2012 Samsung Electronics co., Ltd. All Rights Reserved.
7 Contact: SooChan Lim <sc1.lim@samsung.com>, Sangjin Lee <lsj119@samsung.com>
9 Permission is hereby granted, free of charge, to any person obtaining a
10 copy of this software and associated documentation files (the
11 "Software"), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sub license, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
17 The above copyright notice and this permission notice (including the
18 next paragraph) shall be included in all copies or substantial portions
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
24 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
25 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
26 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 **************************************************************************/
37 #include <sys/ioctl.h>
38 #include <sys/types.h>
46 #include "tbm_bufmgr.h"
47 #include "tbm_bufmgr_glock.h"
48 #include "tbm_bufmgr_backend.h"
49 #include "tbm_bufmgr_int.h"
54 static int bDebug = 0;
55 #define DBG(...) if(bDebug&0x1) fprintf(stderr, __VA_ARGS__)
56 #define DBG_LOCK(...) if(bDebug&0x2) fprintf(stderr, __VA_ARGS__)
63 #define TBM_RETURN_IF_FAIL(cond) {\
65 fprintf (stderr, "[%s] : '%s' failed.\n", __FUNCTION__, #cond);\
69 #define TBM_RETURN_VAL_IF_FAIL(cond, val) {\
71 fprintf (stderr, "[%s] : '%s' failed.\n", __FUNCTION__, #cond);\
77 #define RETURN_CHECK_FLAG(cond) {\
82 #define RETURN_VAL_CHECK_FLAG(cond, val) {\
89 /* check validation */
90 #define TBM_BUFMGR_IS_VALID(mgr) (mgr && \
92 mgr->link.next->prev == &mgr->link)
93 #define TBM_BO_IS_VALID(bo) (bo && \
94 TBM_BUFMGR_IS_VALID(bo->bufmgr) && \
95 bo->item_link.next && \
96 bo->item_link.next->prev == &bo->item_link)
98 #define CTRL_BACKEND_VALID(flags) ((flags&TBM_CACHE_CTRL_BACKEND) && \
99 (flags&TBM_LOCK_CTRL_BACKEND))
101 #define PREFIX_LIB "libtbm_"
102 #define SUFFIX_LIB ".so"
103 #define DEFAULT_LIB PREFIX_LIB"default"SUFFIX_LIB
105 #define BO_IS_CACHEABLE(bo) ((bo->flags & TBM_BO_NONCACHABLE)?0:1)
106 #define DEVICE_IS_CACHE_AWARE(device) ((device == TBM_DEVICE_CPU)?(1):(0))
109 #define GLOBAL_KEY ((unsigned int)(-1))
110 #define INITIAL_KEY ((unsigned int)(-2))
112 #define CACHE_OP_CREATE (-1)
113 #define CACHE_OP_ATTACH (-2)
114 #define CACHE_OP_IMPORT (-3)
116 /* values to indicate unspecified fields in XF86ModReqInfo. */
117 #define MAJOR_UNSPEC 0xFF
118 #define MINOR_UNSPEC 0xFF
119 #define PATCH_UNSPEC 0xFFFF
120 #define ABI_VERS_UNSPEC 0xFFFFFFFF
122 #define MODULE_VERSION_NUMERIC(maj, min, patch) \
123 ((((maj) & 0xFF) << 24) | (((min) & 0xFF) << 16) | (patch & 0xFFFF))
124 #define GET_MODULE_MAJOR_VERSION(vers) (((vers) >> 24) & 0xFF)
125 #define GET_MODULE_MINOR_VERSION(vers) (((vers) >> 16) & 0xFF)
126 #define GET_MODULE_PATCHLEVEL(vers) ((vers) & 0xFFFF)
136 DEVICE_CA, /* cache aware device */
137 DEVICE_CO /* cache oblivious device */
144 tbm_data_free free_func ;
146 /* link of user_data */
147 struct list_head item_link;
151 static struct list_head *gBufMgrs = NULL;
155 _tgl_init (int fd, unsigned int key)
157 struct tgl_attribute attr;
161 attr.timeout_ms = 1000;
163 err = ioctl (fd, TGL_IOC_INIT_LOCK, &attr);
166 fprintf (stderr, "[libtbm:%d] "
167 "error(%s) %s:%d key:%d\n",
168 getpid(), strerror(errno), __FUNCTION__, __LINE__, key);
176 _tgl_destroy (int fd, unsigned int key)
179 err = ioctl (fd, TGL_IOC_DESTROY_LOCK, key);
182 fprintf (stderr, "[libtbm:%d] "
183 "error(%s) %s:%d key:%d\n",
184 getpid(), strerror(errno), __FUNCTION__, __LINE__, key);
192 _tgl_lock (int fd, unsigned int key)
195 err = ioctl (fd, TGL_IOC_LOCK_LOCK, key);
198 fprintf (stderr, "[libtbm:%d] "
199 "error(%s) %s:%d key:%d\n",
200 getpid(), strerror(errno), __FUNCTION__, __LINE__, key);
208 _tgl_unlock (int fd, unsigned int key)
211 err = ioctl (fd, TGL_IOC_UNLOCK_LOCK, key);
214 fprintf (stderr, "[libtbm:%d] "
215 "error(%s) %s:%d key:%d\n",
216 getpid(), strerror(errno), __FUNCTION__, __LINE__, key);
224 _tgl_set_data (int fd, unsigned int key, unsigned int val)
227 struct tgl_user_data arg;
231 err = ioctl (fd, TGL_IOC_SET_DATA, &arg);
234 fprintf (stderr, "[libtbm:%d] "
235 "error(%s) %s:%d key:%d\n",
236 getpid(), strerror(errno), __FUNCTION__, __LINE__, key);
243 static inline unsigned int
244 _tgl_get_data (int fd, unsigned int key, unsigned int *locked)
247 struct tgl_user_data arg = {0,};
250 err = ioctl (fd, TGL_IOC_GET_DATA, &arg);
253 fprintf (stderr, "[libtbm:%d] "
254 "error(%s) %s:%d key:%d\n",
255 getpid(), strerror(errno), __FUNCTION__, __LINE__, key);
260 *locked = arg.locked;
265 static tbm_user_data *
266 _user_data_lookup (struct list_head *user_data_list, unsigned long key)
268 tbm_user_data *user_data = NULL;
269 tbm_user_data *old_data = NULL, *tmp = NULL;
271 if (!LIST_IS_EMPTY (user_data_list))
273 LIST_FOR_EACH_ENTRY_SAFE (old_data, tmp, user_data_list, item_link)
275 if (old_data->key == key)
277 user_data = old_data;
286 static tbm_user_data *
287 _user_data_create (unsigned long key, tbm_data_free data_free_func)
289 tbm_user_data * user_data = NULL;
291 user_data = calloc (1, sizeof (tbm_user_data));
295 user_data->key = key;
296 user_data->free_func = data_free_func;
297 user_data->data = (void *)0;
303 _user_data_delete (tbm_user_data *user_data)
305 if (user_data->data && user_data->free_func)
306 user_data->free_func(user_data->data);
308 LIST_DEL (&user_data->item_link);
316 tbm_bufmgr bufmgr = bo->bufmgr;
319 if (bufmgr->backend->flags&TBM_LOCK_CTRL_BACKEND &&
320 bufmgr->backend->bo_lock)
322 /* use backend lock */
323 ret = bufmgr->backend->bo_lock (bo);
327 /* use tizen global lock */
328 ret = _tgl_lock (bufmgr->lock_fd, bo->tgl_key);
335 _bo_unlock (tbm_bo bo)
337 tbm_bufmgr bufmgr = bo->bufmgr;
339 if (bufmgr->backend->flags&TBM_LOCK_CTRL_BACKEND &&
340 bufmgr->backend->bo_unlock)
342 /* use backend unlock */
343 bufmgr->backend->bo_unlock (bo);
347 /* use tizen global unlock */
348 _tgl_unlock (bufmgr->lock_fd, bo->tgl_key);
353 _tbm_bo_lock (tbm_bo bo)
355 tbm_bufmgr bufmgr = NULL;
364 RETURN_VAL_CHECK_FLAG (CTRL_BACKEND_VALID(bufmgr->backend->flags), 1);
366 if (bo->lock_cnt < 0)
368 fprintf (stderr, "[libtbm:%d] "
369 "error %s:%d bo:%p(%d) LOCK_CNT=%d\n",
370 getpid(), __FUNCTION__, __LINE__, bo, bo->tgl_key, bo->lock_cnt);
374 switch (bufmgr->lock_type)
376 case LOCK_TRY_ALWAYS: /* LOCK_TRY_ALWAYS */
377 pthread_mutex_unlock (&bufmgr->lock);
379 pthread_mutex_lock (&bufmgr->lock);
383 case LOCK_TRY_NEVER: /* LOCK_TRY_NEVER */
387 if (bo->lock_cnt == 0)
389 pthread_mutex_unlock (&bufmgr->lock);
391 pthread_mutex_lock (&bufmgr->lock);
399 DBG_LOCK ("[libtbm:%d] >> LOCK bo:%p(%d, %d->%d)\n", getpid(),
400 bo, bo->tgl_key, old, bo->lock_cnt);
406 _tbm_bo_unlock (tbm_bo bo)
408 tbm_bufmgr bufmgr = NULL;
417 RETURN_CHECK_FLAG (CTRL_BACKEND_VALID(bufmgr->backend->flags));
420 if (bo->lock_cnt > 0)
423 if (bo->lock_cnt == 0)
426 else if (bo->lock_cnt < 0)
431 DBG_LOCK ("[libtbm:%d] << unlock bo:%p(%d, %d->%d)\n", getpid(),
432 bo, bo->tgl_key, old, bo->lock_cnt);
437 _tbm_bo_set_state (tbm_bo bo, int device, int opt)
439 tbm_bufmgr bufmgr = bo->bufmgr;
441 unsigned short cntFlush = 0;
442 unsigned int is_locked;
444 RETURN_VAL_CHECK_FLAG (CTRL_BACKEND_VALID(bufmgr->backend->flags), 1);
446 /* get cache state of a bo */
447 bo->cache_state.val = _tgl_get_data (bufmgr->lock_fd, bo->tgl_key, &is_locked);
449 if (!bo->cache_state.data.isCacheable)
452 /* get global cache flush count */
453 cntFlush = (unsigned short)_tgl_get_data (bufmgr->lock_fd, GLOBAL_KEY, NULL);
455 if (DEVICE_IS_CACHE_AWARE (device))
457 if (bo->cache_state.data.isDirtied == DEVICE_CO &&
458 bo->cache_state.data.isCached)
460 need_flush = TBM_CACHE_INV;
463 bo->cache_state.data.isCached = 1;
464 if (opt & TBM_OPTION_WRITE)
465 bo->cache_state.data.isDirtied = DEVICE_CA;
467 bo->cache_state.data.isDirtied = DEVICE_NONE;
471 if (bo->cache_state.data.isDirtied == DEVICE_CA &&
472 bo->cache_state.data.isCached &&
473 bo->cache_state.data.cntFlush == cntFlush)
475 need_flush = TBM_CACHE_CLN | TBM_CACHE_ALL;
478 if (opt & TBM_OPTION_WRITE)
479 bo->cache_state.data.isDirtied = DEVICE_CO;
481 bo->cache_state.data.isDirtied = DEVICE_NONE;
486 /* call backend cache flush */
487 bufmgr->backend->bo_cache_flush (bo, need_flush);
489 /* set global cache flush count */
490 if (need_flush & TBM_CACHE_ALL)
491 _tgl_set_data (bufmgr->lock_fd, GLOBAL_KEY, (unsigned int)(++cntFlush));
493 DBG ("[libtbm:%d] \tcache(%d,%d,%d)....flush:0x%x, cntFlush(%d)\n", getpid(),
494 bo->cache_state.data.isCacheable,
495 bo->cache_state.data.isCached,
496 bo->cache_state.data.isDirtied,
497 need_flush, cntFlush);
504 _tbm_bo_save_state (tbm_bo bo)
506 tbm_bufmgr bufmgr = bo->bufmgr;
507 unsigned short cntFlush = 0;
509 RETURN_CHECK_FLAG (CTRL_BACKEND_VALID(bufmgr->backend->flags));
511 /* get global cache flush count */
512 cntFlush = (unsigned short)_tgl_get_data (bufmgr->lock_fd, GLOBAL_KEY, NULL);
514 /* save global cache flush count */
515 bo->cache_state.data.cntFlush = cntFlush;
516 _tgl_set_data(bufmgr->lock_fd, bo->tgl_key, bo->cache_state.val);
520 _tbm_bo_init_state (tbm_bo bo, int opt)
522 tbm_bufmgr bufmgr = bo->bufmgr;
523 tbm_bo_cache_state cache_state;
525 RETURN_VAL_CHECK_FLAG (CTRL_BACKEND_VALID(bufmgr->backend->flags), 1);
530 case CACHE_OP_CREATE: /*Create*/
531 if (bo->tgl_key == INITIAL_KEY)
532 bo->tgl_key = bufmgr->backend->bo_get_global_key (bo);
534 _tgl_init (bufmgr->lock_fd, bo->tgl_key);
536 cache_state.data.isCacheable = BO_IS_CACHEABLE(bo);
537 cache_state.data.isDirtied = DEVICE_NONE;
538 cache_state.data.isCached = 0;
539 cache_state.data.cntFlush = 0;
541 _tgl_set_data (bufmgr->lock_fd, bo->tgl_key, cache_state.val);
543 case CACHE_OP_IMPORT: /*Import*/
544 if (bo->tgl_key == INITIAL_KEY)
545 bo->tgl_key = bufmgr->backend->bo_get_global_key (bo);
547 _tgl_init (bufmgr->lock_fd, bo->tgl_key);
557 _tbm_bo_destroy_state (tbm_bo bo)
559 tbm_bufmgr bufmgr = bo->bufmgr;
561 RETURN_CHECK_FLAG (CTRL_BACKEND_VALID(bufmgr->backend->flags));
563 _tgl_destroy (bufmgr->lock_fd, bo->tgl_key);
567 _tbm_bo_ref (tbm_bo bo)
573 _tbm_bo_unref (tbm_bo bo)
575 tbm_bufmgr bufmgr = bo->bufmgr;
576 tbm_user_data *old_data = NULL, *tmp = NULL;
578 if (bo->ref_cnt <= 0)
582 if (bo->ref_cnt == 0)
584 /* destory the user_data_list */
585 if (!LIST_IS_EMPTY (&bo->user_data_list))
587 LIST_FOR_EACH_ENTRY_SAFE (old_data, tmp, &bo->user_data_list, item_link)
589 DBG ("[libtbm:%d] free user_data \n", getpid());
590 _user_data_delete (old_data);
594 if (bo->lock_cnt > 0)
596 fprintf (stderr, "[libtbm:%d] "
597 "error %s:%d lock_cnt:%d\n",
598 getpid(), __FUNCTION__, __LINE__, bo->lock_cnt);
602 /* Destroy Global Lock */
603 _tbm_bo_destroy_state (bo);
605 /* call the bo_free */
606 bufmgr->backend->bo_free (bo);
609 LIST_DEL (&bo->item_link);
617 _tbm_bufmgr_init_state (tbm_bufmgr bufmgr)
619 RETURN_VAL_CHECK_FLAG (CTRL_BACKEND_VALID(bufmgr->backend->flags), 1);
621 bufmgr->lock_fd = open(tgl_devfile, O_RDWR);
623 if(bufmgr->lock_fd < 0)
625 fprintf (stderr, "[libtbm:%d] "
626 "error: Fail to open global_lock:%s\n",
627 getpid(), tgl_devfile);
631 if (!_tgl_init(bufmgr->lock_fd, GLOBAL_KEY))
633 fprintf (stderr, "[libtbm:%d] "
634 "error: Fail to initialize the tgl\n",
643 _tbm_bufmgr_destroy_state (tbm_bufmgr bufmgr)
645 RETURN_CHECK_FLAG (CTRL_BACKEND_VALID(bufmgr->backend->flags));
647 close (bufmgr->lock_fd);
651 _check_version (TBMModuleVersionInfo *data)
656 abimaj = GET_ABI_MAJOR (data->abiversion);
657 abimin = GET_ABI_MINOR (data->abiversion);
659 fprintf (stderr, "[libtbm:%d] "
660 "TBM module %s: vendor=\"%s\" ABI=%d,%d\n",
661 getpid(), data->modname ? data->modname : "UNKNOWN!",
662 data->vendor ? data->vendor : "UNKNOWN!", abimaj, abimin);
664 vermaj = GET_ABI_MAJOR (TBM_ABI_VERSION);
665 vermin = GET_ABI_MINOR (TBM_ABI_VERSION);
667 DBG ("[libtbm:%d] " "TBM ABI version %d.%d\n", getpid(), vermaj, vermin);
669 if (abimaj != vermaj)
671 fprintf (stderr, "[libtbm:%d] "
672 "TBM module ABI major ver(%d) doesn't match the TBM's ver(%d)\n",
673 getpid(), abimaj, vermaj);
676 else if (abimin > vermin)
678 fprintf (stderr, "[libtbm:%d] "
679 "TBM module ABI minor ver(%d) is newer than the TBM's ver(%d)\n",
680 getpid(), abimin, vermin);
687 _tbm_bufmgr_load_module (tbm_bufmgr bufmgr, int fd, const char *file)
689 char path[PATH_MAX] = {0,};
690 TBMModuleData *initdata = NULL;
693 snprintf(path, sizeof(path), BUFMGR_MODULE_DIR "/%s", file);
695 module_data = dlopen (path, RTLD_LAZY);
698 fprintf (stderr, "[libtbm:%d] "
699 "failed to load module: %s(%s)\n",
700 getpid(), dlerror(), file);
704 initdata = dlsym (module_data, "tbmModuleData");
708 TBMModuleVersionInfo *vers;
710 vers = initdata->vers;
711 init = initdata->init;
715 if (!_check_version (vers))
717 dlclose (module_data);
723 fprintf (stderr, "[libtbm:%d] "
724 "Error: module does not supply version information.\n",
727 dlclose (module_data);
733 if(!init (bufmgr, fd))
735 fprintf (stderr, "[libtbm:%d] "
736 "Fail to init module(%s)\n",
738 dlclose (module_data);
744 fprintf (stderr, "[libtbm:%d] "
745 "Error: module does not supply init symbol.\n", getpid());
746 dlclose (module_data);
752 fprintf (stderr, "[libtbm:%d] "
753 "Error: module does not have data object.\n", getpid());
754 dlclose (module_data);
758 bufmgr->module_data = module_data;
760 fprintf (stderr,"[libtbm:%d] "
761 "Success to load module(%s)\n", getpid(), file);
766 static int _tbm_load_module (tbm_bufmgr bufmgr, int fd)
768 struct dirent **namelist;
769 const char *p = NULL;
773 /* load bufmgr priv from default lib */
774 ret = _tbm_bufmgr_load_module (bufmgr, fd, DEFAULT_LIB);
776 /* load bufmgr priv from configured path */
779 n = scandir (BUFMGR_MODULE_DIR, &namelist, 0, alphasort);
781 fprintf (stderr,"[libtbm:%d] "
782 "no files : %s\n", getpid(), BUFMGR_MODULE_DIR);
787 if (!ret && strstr (namelist[n]->d_name, PREFIX_LIB))
789 p = strstr (namelist[n]->d_name, SUFFIX_LIB);
790 if (!strcmp (p, SUFFIX_LIB))
792 ret = _tbm_bufmgr_load_module (bufmgr, fd, namelist[n]->d_name);
805 tbm_bufmgr_init (int fd)
811 env = getenv("GEM_DEBUG");
815 fprintf(stderr, "GEM_DEBUG=%s\n", env);
821 /* initialize buffer manager */
827 gBufMgrs = malloc(sizeof(struct list_head));
828 LIST_INITHEAD(gBufMgrs);
832 LIST_FOR_EACH_ENTRY(bufmgr, gBufMgrs, link)
837 fprintf (stderr, "[libtbm:%d] bufmgr ref: fd=%d, ref_count:%d\n",
838 getpid(), fd, bufmgr->ref_count);
844 fprintf(stderr, "[libtbm:%d] bufmgr init: fd=%d\n", getpid(), fd);
846 /* allocate bufmgr */
847 bufmgr = calloc (1, sizeof(struct _tbm_bufmgr));
851 /* load bufmgr priv from env */
852 if (!_tbm_load_module(bufmgr, fd))
854 fprintf (stderr,"[libtbm:%d] "
855 "error : Fail to load bufmgr backend\n",
862 bufmgr->ref_count = 1;
865 fprintf(stderr, "[libtbm:%d] create tizen bufmgr: ref_count:%d\n",
866 getpid(), bufmgr->ref_count);
868 if (pthread_mutex_init (&bufmgr->lock, NULL) != 0)
870 bufmgr->backend->bufmgr_deinit (bufmgr);
876 /* intialize the tizen global status */
877 if (!_tbm_bufmgr_init_state (bufmgr))
879 fprintf (stderr, "[libtbm:%d] "
880 "error: Fail to init state\n",
882 bufmgr->backend->bufmgr_deinit (bufmgr);
888 /* setup the lock_type */
889 env = getenv ("BUFMGR_LOCK_TYPE");
890 if (env && !strcmp (env, "always"))
891 bufmgr->lock_type = LOCK_TRY_ALWAYS;
892 else if(env && !strcmp(env, "none"))
893 bufmgr->lock_type = LOCK_TRY_NEVER;
895 bufmgr->lock_type = LOCK_TRY_ONCE;
896 DBG ("[libtbm:%d] BUFMGR_LOCK_TYPE=%s\n", getpid(), env?env:"default:once");
898 /* setup the map_cache */
899 env = getenv ("BUFMGR_MAP_CACHE");
900 if (env && !strcmp (env, "false"))
901 bufmgr->use_map_cache = 0;
903 bufmgr->use_map_cache = 1;
904 DBG ("[libtbm:%d] BUFMGR_MAP_CACHE=%s\n", getpid(), env?env:"default:true");
906 /* intialize bo_list */
907 LIST_INITHEAD (&bufmgr->bo_list);
909 /* add bufmgr to the gBufMgrs */
910 LIST_ADD(&bufmgr->link, gBufMgrs);
916 tbm_bufmgr_deinit (tbm_bufmgr bufmgr)
918 TBM_RETURN_IF_FAIL (TBM_BUFMGR_IS_VALID(bufmgr));
924 if (bufmgr->ref_count > 0)
926 fprintf (stderr, "[libtbm:%d] "
927 "tizen bufmgr destroy: bufmgr:%p, ref_cnt:%d\n",
928 getpid(), bufmgr, bufmgr->ref_count);
932 /* destroy bo_list */
933 if(!LIST_IS_EMPTY (&bufmgr->bo_list))
935 LIST_FOR_EACH_ENTRY_SAFE (bo, tmp, &bufmgr->bo_list, item_link)
937 fprintf (stderr, "[libtbm:%d] "
938 "Un-freed bo(%p, ref:%d) \n",
939 getpid(), bo, bo->ref_cnt);
945 /* destroy the tizen global status */
946 _tbm_bufmgr_destroy_state (bufmgr);
948 /* destroy bufmgr priv */
949 bufmgr->backend->bufmgr_deinit (bufmgr->backend->priv);
950 bufmgr->backend->priv = NULL;
951 tbm_backend_free (bufmgr->backend);
952 bufmgr->backend = NULL;
954 pthread_mutex_destroy (&bufmgr->lock);
956 fprintf (stderr, "[libtbm:%d] "
957 "tizen bufmgr destroy: bufmgr:%p, ref_cnt:%d\n",
958 getpid(), bufmgr, bufmgr->ref_count);
960 dlclose (bufmgr->module_data);
968 tbm_bo_size (tbm_bo bo)
970 TBM_RETURN_VAL_IF_FAIL (TBM_BO_IS_VALID(bo), 0);
972 tbm_bufmgr bufmgr = bo->bufmgr;
975 pthread_mutex_lock(&bufmgr->lock);
976 size = bufmgr->backend->bo_size(bo);
977 pthread_mutex_unlock(&bufmgr->lock);
983 tbm_bo_ref (tbm_bo bo)
985 TBM_RETURN_VAL_IF_FAIL(TBM_BO_IS_VALID(bo), NULL);
987 tbm_bufmgr bufmgr = bo->bufmgr;
989 pthread_mutex_lock(&bufmgr->lock);
993 pthread_mutex_unlock(&bufmgr->lock);
999 tbm_bo_unref (tbm_bo bo)
1001 TBM_RETURN_IF_FAIL(TBM_BO_IS_VALID(bo));
1003 tbm_bufmgr bufmgr = bo->bufmgr;
1005 pthread_mutex_lock (&bufmgr->lock);
1009 pthread_mutex_unlock(&bufmgr->lock);
1013 tbm_bo_alloc (tbm_bufmgr bufmgr, int size, int flags)
1015 TBM_RETURN_VAL_IF_FAIL (TBM_BUFMGR_IS_VALID(bufmgr) && (size > 0), NULL);
1018 void * bo_priv = NULL;
1020 bo = calloc (1, sizeof(struct _tbm_bo));
1024 bo->bufmgr = bufmgr;
1026 pthread_mutex_lock (&bufmgr->lock);
1028 bo_priv = bufmgr->backend->bo_alloc (bo, size, flags);
1032 pthread_mutex_unlock (&bufmgr->lock);
1038 bo->tgl_key = INITIAL_KEY;
1042 if (!_tbm_bo_init_state (bo, CACHE_OP_CREATE))
1045 pthread_mutex_unlock (&bufmgr->lock);
1049 LIST_INITHEAD (&bo->user_data_list);
1051 LIST_ADD (&bo->item_link, &bufmgr->bo_list);
1053 pthread_mutex_unlock(&bufmgr->lock);
1059 tbm_bo_import (tbm_bufmgr bufmgr, unsigned int key)
1061 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
1064 void * bo_priv = NULL;
1066 bo = calloc (1, sizeof(struct _tbm_bo));
1070 bo->bufmgr = bufmgr;
1072 pthread_mutex_lock (&bufmgr->lock);
1074 bo_priv = bufmgr->backend->bo_import (bo, key);
1078 pthread_mutex_unlock (&bufmgr->lock);
1083 bo->tgl_key = INITIAL_KEY;
1087 if (!_tbm_bo_init_state (bo, CACHE_OP_IMPORT))
1090 pthread_mutex_unlock (&bufmgr->lock);
1094 LIST_INITHEAD (&bo->user_data_list);
1096 LIST_ADD (&bo->item_link, &bufmgr->bo_list);
1098 pthread_mutex_unlock (&bufmgr->lock);
1104 tbm_bo_export (tbm_bo bo)
1106 TBM_RETURN_VAL_IF_FAIL (TBM_BO_IS_VALID(bo), 0);
1111 bufmgr = bo->bufmgr;
1113 pthread_mutex_lock (&bufmgr->lock);
1114 ret = bufmgr->backend->bo_export (bo);
1115 pthread_mutex_unlock (&bufmgr->lock);
1121 tbm_bo_get_handle (tbm_bo bo, int device)
1123 TBM_RETURN_VAL_IF_FAIL (TBM_BO_IS_VALID(bo), (tbm_bo_handle)0);
1126 tbm_bo_handle bo_handle;
1128 bufmgr = bo->bufmgr;
1130 pthread_mutex_lock (&bufmgr->lock);
1131 bo_handle = bufmgr->backend->bo_get_handle (bo, device);
1132 pthread_mutex_unlock (&bufmgr->lock);
1138 tbm_bo_map (tbm_bo bo, int device, int opt)
1140 TBM_RETURN_VAL_IF_FAIL (TBM_BO_IS_VALID(bo), (tbm_bo_handle)0);
1143 tbm_bo_handle bo_handle;
1145 bufmgr = bo->bufmgr;
1147 pthread_mutex_lock (&bufmgr->lock);
1150 bo_handle = bufmgr->backend->bo_map (bo, device, opt);
1152 /* increase the ref_count */
1153 // _tbm_bo_ref (bo);
1155 if (bufmgr->use_map_cache == 1 && bo->map_cnt == 0)
1156 _tbm_bo_set_state (bo, device, opt);
1158 /* increase the map_count */
1161 pthread_mutex_unlock (&bufmgr->lock);
1167 tbm_bo_unmap (tbm_bo bo)
1169 TBM_RETURN_VAL_IF_FAIL (TBM_BO_IS_VALID(bo), 0);
1174 bufmgr = bo->bufmgr;
1176 pthread_mutex_lock (&bufmgr->lock);
1178 ret = bufmgr->backend->bo_unmap (bo);
1180 /* decrease the map_count */
1183 if (bo->map_cnt == 0)
1184 _tbm_bo_save_state (bo);
1186 _tbm_bo_unlock (bo);
1188 /* decrease the ref_count */
1189 // _tbm_bo_unref (bo);
1191 pthread_mutex_unlock (&bufmgr->lock);
1197 tbm_bo_swap (tbm_bo bo1, tbm_bo bo2)
1199 TBM_RETURN_VAL_IF_FAIL (TBM_BO_IS_VALID(bo1), 0);
1200 TBM_RETURN_VAL_IF_FAIL (TBM_BO_IS_VALID(bo2), 0);
1203 unsigned int tmp_key;
1205 if (bo1->bufmgr->backend->bo_size (bo1) != bo2->bufmgr->backend->bo_size (bo2))
1208 pthread_mutex_lock (&bo1->bufmgr->lock);
1210 tmp_key = bo1->tgl_key;
1211 bo1->tgl_key = bo2->tgl_key;
1212 bo2->tgl_key = tmp_key;
1215 bo1->priv = bo2->priv;
1218 pthread_mutex_unlock (&bo1->bufmgr->lock);
1224 tbm_bo_locked (tbm_bo bo)
1226 TBM_RETURN_VAL_IF_FAIL (TBM_BO_IS_VALID(bo), 0);
1230 bufmgr = bo->bufmgr;
1232 if (bufmgr->lock_type == LOCK_TRY_NEVER)
1235 pthread_mutex_lock (&bufmgr->lock);
1237 if (bo->lock_cnt > 0)
1239 pthread_mutex_unlock (&bufmgr->lock);
1243 pthread_mutex_unlock (&bufmgr->lock);
1250 tbm_bo_add_user_data (tbm_bo bo, unsigned long key, tbm_data_free data_free_func)
1252 TBM_RETURN_VAL_IF_FAIL(TBM_BO_IS_VALID(bo), 0);
1254 tbm_user_data *data;
1256 /* check if the data according to the key exist if so, return false.*/
1257 data = _user_data_lookup (&bo->user_data_list, key);
1260 fprintf (stderr, "[libtbm:%d] "
1261 "waring: %s:%d user data already exist. key:%ld\n",
1262 getpid(), __FUNCTION__, __LINE__, key);
1266 data = _user_data_create (key, data_free_func);
1270 LIST_ADD (&data->item_link, &bo->user_data_list);
1276 tbm_bo_set_user_data (tbm_bo bo, unsigned long key, void* data)
1278 TBM_RETURN_VAL_IF_FAIL(TBM_BO_IS_VALID(bo), 0);
1280 tbm_user_data *old_data;
1282 if (LIST_IS_EMPTY (&bo->user_data_list))
1285 old_data = _user_data_lookup (&bo->user_data_list, key);
1289 if (old_data->data && old_data->free_func)
1290 old_data->free_func(old_data->data);
1292 old_data->data = data;
1298 tbm_bo_get_user_data (tbm_bo bo, unsigned long key, void** data)
1300 TBM_RETURN_VAL_IF_FAIL(TBM_BO_IS_VALID(bo), 0);
1302 tbm_user_data* old_data;
1304 if (!data || LIST_IS_EMPTY (&bo->user_data_list))
1307 old_data = _user_data_lookup (&bo->user_data_list, key);
1314 *data = old_data->data;
1320 tbm_bo_delete_user_data (tbm_bo bo, unsigned long key)
1322 TBM_RETURN_VAL_IF_FAIL(TBM_BO_IS_VALID(bo), 0);
1324 tbm_user_data *old_data = (void *)0;
1326 if (LIST_IS_EMPTY (&bo->user_data_list))
1329 old_data = _user_data_lookup (&bo->user_data_list, key);
1333 _user_data_delete (old_data);