1 /**************************************************************************
5 Copyright 2012 Samsung Electronics co., Ltd. All Rights Reserved.
7 Contact: SooChan Lim <sc1.lim@samsung.com>, Sangjin Lee <lsj119@samsung.com>
8 Boram Park <boram1288.park@samsung.com>, Changyeon Lee <cyeon.lee@samsung.com>
10 Permission is hereby granted, free of charge, to any person obtaining a
11 copy of this software and associated documentation files (the
12 "Software"), to deal in the Software without restriction, including
13 without limitation the rights to use, copy, modify, merge, publish,
14 distribute, sub license, and/or sell copies of the Software, and to
15 permit persons to whom the Software is furnished to do so, subject to
16 the following conditions:
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial portions
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
25 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 **************************************************************************/
34 #include "tbm_bufmgr.h"
35 #include "tbm_bufmgr_int.h"
36 #include "tbm_bufmgr_backend.h"
37 #include "tbm_bufmgr_tgl.h"
43 #define DBG(...) {if (bDebug&0x1) TBM_LOG(__VA_ARGS__);}
44 #define DBG_LOCK(...) {if (bDebug&0x2) TBM_LOG(__VA_ARGS__);}
50 #define PREFIX_LIB "libtbm_"
51 #define SUFFIX_LIB ".so"
52 #define DEFAULT_LIB PREFIX_LIB"default"SUFFIX_LIB
54 /* unneeded version 2.0 */
55 #define BO_IS_CACHEABLE(bo) ((bo->flags & TBM_BO_NONCACHABLE) ? 0 : 1)
56 #define DEVICE_IS_CACHE_AWARE(device) ((device == TBM_DEVICE_CPU) ? (1) : (0))
59 #define GLOBAL_KEY ((unsigned int)(-1))
60 #define INITIAL_KEY ((unsigned int)(-2))
62 #define CACHE_OP_CREATE (-1)
63 #define CACHE_OP_ATTACH (-2)
64 #define CACHE_OP_IMPORT (-3)
65 /* unneeded version 2.0 */
67 /* values to indicate unspecified fields in XF86ModReqInfo. */
68 #define MAJOR_UNSPEC 0xFF
69 #define MINOR_UNSPEC 0xFF
70 #define PATCH_UNSPEC 0xFFFF
71 #define ABI_VERS_UNSPEC 0xFFFFFFFF
73 #define MODULE_VERSION_NUMERIC(maj, min, patch) \
74 ((((maj) & 0xFF) << 24) | (((min) & 0xFF) << 16) | (patch & 0xFFFF))
75 #define GET_MODULE_MAJOR_VERSION(vers) (((vers) >> 24) & 0xFF)
76 #define GET_MODULE_MINOR_VERSION(vers) (((vers) >> 16) & 0xFF)
77 #define GET_MODULE_PATCHLEVEL(vers) ((vers) & 0xFFFF)
85 /* unneeded version 2.0 */
88 DEVICE_CA, /* cache aware device */
89 DEVICE_CO /* cache oblivious device */
91 /* unneeded version 2.0 */
93 pthread_mutex_t gLock = PTHREAD_MUTEX_INITIALIZER;
96 static __thread tbm_error_e tbm_last_error = TBM_ERROR_NONE;
99 _tbm_set_last_result(tbm_error_e err)
101 tbm_last_error = err;
105 _tbm_util_get_appname_brief(char *brief)
109 char temp[255] = {0,};
110 char *saveptr = NULL;
112 token = strtok_r(brief, delim, &saveptr);
114 while (token != NULL) {
115 memset(temp, 0x00, 255 * sizeof(char));
116 strncpy(temp, token, 254 * sizeof(char));
117 token = strtok_r(NULL, delim, &saveptr);
120 snprintf(brief, sizeof(temp), "%s", temp);
124 _tbm_util_get_appname_from_pid(long pid, char *str)
129 char fn_cmdline[255] = {0,};
130 char cmdline[255] = {0,};
132 snprintf(fn_cmdline, sizeof(fn_cmdline), "/proc/%ld/cmdline", app_pid);
134 fp = fopen(fn_cmdline, "r");
136 fprintf(stderr, "cannot file open /proc/%ld/cmdline", app_pid);
140 if (!fgets(cmdline, 255, fp)) {
141 fprintf(stderr, "fail to get appname for pid(%ld)\n", app_pid);
147 len = strlen(cmdline);
149 memset(cmdline, 0x00, 255);
153 snprintf(str, sizeof(cmdline), "%s", cmdline);
157 /* unneeded version 2.0 */
159 _tgl_init(int fd, unsigned int key)
161 struct tgl_attribute attr;
165 attr.timeout_ms = 1000;
167 err = ioctl(fd, TGL_IOC_INIT_LOCK, &attr);
169 TBM_LOG("[libtbm:%d] error(%s) %s:%d key:%d\n",
170 getpid(), strerror(errno), __func__, __LINE__, key);
178 _tgl_destroy(int fd, unsigned int key)
182 err = ioctl(fd, TGL_IOC_DESTROY_LOCK, key);
184 TBM_LOG("[libtbm:%d] "
185 "error(%s) %s:%d key:%d\n",
186 getpid(), strerror(errno), __func__, __LINE__, key);
194 _tgl_lock(int fd, unsigned int key)
198 err = ioctl(fd, TGL_IOC_LOCK_LOCK, key);
200 TBM_LOG("[libtbm:%d] "
201 "error(%s) %s:%d key:%d\n",
202 getpid(), strerror(errno), __func__, __LINE__, key);
210 _tgl_unlock(int fd, unsigned int key)
214 err = ioctl(fd, TGL_IOC_UNLOCK_LOCK, key);
216 TBM_LOG("[libtbm:%d] "
217 "error(%s) %s:%d key:%d\n",
218 getpid(), strerror(errno), __func__, __LINE__, key);
226 _tgl_set_data(int fd, unsigned int key, unsigned int val)
229 struct tgl_user_data arg;
233 err = ioctl(fd, TGL_IOC_SET_DATA, &arg);
235 TBM_LOG("[libtbm:%d] "
236 "error(%s) %s:%d key:%d\n",
237 getpid(), strerror(errno), __func__, __LINE__, key);
244 static inline unsigned int
245 _tgl_get_data(int fd, unsigned int key, unsigned int *locked)
248 struct tgl_user_data arg = { 0, };
251 err = ioctl(fd, TGL_IOC_GET_DATA, &arg);
253 TBM_LOG("[libtbm:%d] "
254 "error(%s) %s:%d key:%d\n",
255 getpid(), strerror(errno), __func__, __LINE__, key);
260 *locked = arg.locked;
264 /* unneeded version 2.0 */
267 *user_data_lookup(struct list_head *user_data_list, unsigned long key)
269 tbm_user_data *user_data = NULL;
270 tbm_user_data *old_data = NULL, *tmp = NULL;
272 if (!LIST_IS_EMPTY(user_data_list)) {
273 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, user_data_list, item_link) {
274 if (old_data->key == key) {
275 user_data = old_data;
285 *user_data_create(unsigned long key, tbm_data_free data_free_func)
287 tbm_user_data *user_data = NULL;
289 user_data = calloc(1, sizeof(tbm_user_data));
293 user_data->key = key;
294 user_data->free_func = data_free_func;
295 user_data->data = (void *)0;
301 user_data_delete(tbm_user_data *user_data)
303 if (user_data->data && user_data->free_func)
304 user_data->free_func(user_data->data);
306 LIST_DEL(&user_data->item_link);
312 _bo_lock(tbm_bo bo, int device, int opt)
314 tbm_bufmgr bufmgr = bo->bufmgr;
317 if (bufmgr->use_2_0) {
318 if (bufmgr->backend->bo_lock2) {
319 /* use bo_lock2 backend lock */
320 ret = bufmgr->backend->bo_lock2(bo, device, opt);
321 } else if (bufmgr->backend->bo_lock) {
322 /* use bo_lock backend lock */
323 ret = bufmgr->backend->bo_lock(bo);
325 TBM_LOG("[libtbm:%d] "
326 "error %s:%d no backend lock functions\n",
327 getpid(), __func__, __LINE__);
330 if (TBM_LOCK_CTRL_BACKEND_VALID(bufmgr->backend->flags)) {
331 if (bufmgr->backend->bo_lock2) {
332 /* use bo_lock2 backend lock */
333 ret = bufmgr->backend->bo_lock2(bo, device, opt);
334 } else if (bufmgr->backend->bo_lock) {
335 /* use bo_lock backend lock */
336 ret = bufmgr->backend->bo_lock(bo);
338 TBM_LOG("[libtbm:%d] "
339 "error %s:%d no backend lock functions\n",
340 getpid(), __func__, __LINE__);
343 /* use tizen global lock */
344 ret = _tgl_lock(bufmgr->lock_fd, bo->tgl_key);
352 _bo_unlock(tbm_bo bo)
354 tbm_bufmgr bufmgr = bo->bufmgr;
356 if (bufmgr->use_2_0) {
357 if (bufmgr->backend->bo_unlock) {
358 /* use backend unlock */
359 bufmgr->backend->bo_unlock(bo);
361 TBM_LOG("[libtbm:%d] "
362 "error %s:%d no backend unlock functions\n",
363 getpid(), __func__, __LINE__);
366 if (TBM_LOCK_CTRL_BACKEND_VALID(bufmgr->backend->flags)) {
367 if (bufmgr->backend->bo_unlock) {
368 /* use backend unlock */
369 bufmgr->backend->bo_unlock(bo);
371 TBM_LOG("[libtbm:%d] "
372 "error %s:%d no backend unlock functions\n",
373 getpid(), __func__, __LINE__);
376 /* use tizen global unlock */
377 _tgl_unlock(bufmgr->lock_fd, bo->tgl_key);
383 _tbm_bo_init_state(tbm_bo bo, int opt)
385 tbm_bufmgr bufmgr = bo->bufmgr;
386 tbm_bo_cache_state cache_state;
388 if (bo->tgl_key == INITIAL_KEY)
389 bo->tgl_key = bufmgr->backend->bo_get_global_key(bo);
391 if (!bo->default_handle.u32)
392 bo->default_handle = bufmgr->backend->bo_get_handle(bo, TBM_DEVICE_DEFAULT);
394 RETURN_VAL_CHECK_FLAG(TBM_ALL_CTRL_BACKEND_VALID(bufmgr->backend->flags), 1);
398 case CACHE_OP_CREATE: /*Create */
400 _tgl_init(bufmgr->lock_fd, bo->tgl_key);
402 cache_state.data.isCacheable = BO_IS_CACHEABLE(bo);
403 cache_state.data.isDirtied = DEVICE_NONE;
404 cache_state.data.isCached = 0;
405 cache_state.data.cntFlush = 0;
407 _tgl_set_data(bufmgr->lock_fd, bo->tgl_key, cache_state.val);
409 case CACHE_OP_IMPORT: /*Import */
411 _tgl_init(bufmgr->lock_fd, bo->tgl_key);
421 _tbm_bo_destroy_state(tbm_bo bo)
423 tbm_bufmgr bufmgr = bo->bufmgr;
425 RETURN_CHECK_FLAG(TBM_ALL_CTRL_BACKEND_VALID(bufmgr->backend->flags));
427 _tgl_destroy(bufmgr->lock_fd, bo->tgl_key);
431 _tbm_bo_set_state(tbm_bo bo, int device, int opt)
433 tbm_bufmgr bufmgr = bo->bufmgr;
435 unsigned short cntFlush = 0;
436 unsigned int is_locked;
438 RETURN_VAL_CHECK_FLAG(TBM_CACHE_CTRL_BACKEND_VALID(bufmgr->backend->flags), 1);
440 /* get cache state of a bo */
441 bo->cache_state.val = _tgl_get_data(bufmgr->lock_fd, bo->tgl_key, &is_locked);
443 if (!bo->cache_state.data.isCacheable)
446 /* get global cache flush count */
447 cntFlush = (unsigned short)_tgl_get_data(bufmgr->lock_fd, GLOBAL_KEY, NULL);
449 if (DEVICE_IS_CACHE_AWARE(device)) {
450 if (bo->cache_state.data.isDirtied == DEVICE_CO &&
451 bo->cache_state.data.isCached)
452 need_flush = TBM_CACHE_INV;
454 bo->cache_state.data.isCached = 1;
455 if (opt & TBM_OPTION_WRITE)
456 bo->cache_state.data.isDirtied = DEVICE_CA;
458 if (bo->cache_state.data.isDirtied != DEVICE_CA)
459 bo->cache_state.data.isDirtied = DEVICE_NONE;
462 if (bo->cache_state.data.isDirtied == DEVICE_CA &&
463 bo->cache_state.data.isCached &&
464 bo->cache_state.data.cntFlush == cntFlush)
465 need_flush = TBM_CACHE_CLN | TBM_CACHE_ALL;
467 if (opt & TBM_OPTION_WRITE)
468 bo->cache_state.data.isDirtied = DEVICE_CO;
470 if (bo->cache_state.data.isDirtied != DEVICE_CO)
471 bo->cache_state.data.isDirtied = DEVICE_NONE;
476 /* set global cache flush count */
477 if (need_flush & TBM_CACHE_ALL)
478 _tgl_set_data(bufmgr->lock_fd, GLOBAL_KEY, (unsigned int)(++cntFlush));
480 /* call backend cache flush */
481 bufmgr->backend->bo_cache_flush(bo, need_flush);
483 DBG("[libtbm:%d] \tcache(%d,%d,%d)....flush:0x%x, cntFlush(%d)\n",
485 bo->cache_state.data.isCacheable,
486 bo->cache_state.data.isCached,
487 bo->cache_state.data.isDirtied,
496 _tbm_bo_save_state(tbm_bo bo)
498 tbm_bufmgr bufmgr = bo->bufmgr;
499 unsigned short cntFlush = 0;
501 RETURN_CHECK_FLAG(TBM_CACHE_CTRL_BACKEND_VALID(bufmgr->backend->flags));
503 /* get global cache flush count */
504 cntFlush = (unsigned short)_tgl_get_data(bufmgr->lock_fd, GLOBAL_KEY, NULL);
506 /* save global cache flush count */
507 bo->cache_state.data.cntFlush = cntFlush;
508 _tgl_set_data(bufmgr->lock_fd, bo->tgl_key, bo->cache_state.val);
512 _tbm_bo_lock(tbm_bo bo, int device, int opt)
514 tbm_bufmgr bufmgr = NULL;
523 /* do not try to lock the bo */
524 if (bufmgr->lock_type == LOCK_TRY_NEVER)
527 if (bo->lock_cnt < 0) {
528 TBM_LOG("[libtbm:%d] "
529 "error %s:%d bo:%p(%d) LOCK_CNT=%d\n",
530 getpid(), __func__, __LINE__, bo, bo->tgl_key, bo->lock_cnt);
534 if (bufmgr->lock_type == LOCK_TRY_ONCE) {
535 if (bo->lock_cnt == 0) {
536 pthread_mutex_unlock(&bufmgr->lock);
537 ret = _bo_lock(bo, device, opt);
538 pthread_mutex_lock(&bufmgr->lock);
543 } else if (bufmgr->lock_type == LOCK_TRY_ALWAYS) {
544 pthread_mutex_unlock(&bufmgr->lock);
545 ret = _bo_lock(bo, device, opt);
546 pthread_mutex_lock(&bufmgr->lock);
550 TBM_LOG("[libtbm:%d] "
551 "error %s:%d bo:%p lock_type is wrong.\n",
552 getpid(), __func__, __LINE__, bo);
555 DBG_LOCK("[libtbm:%d] >> LOCK bo:%p(%d, %d->%d)\n", getpid(),
556 bo, bo->tgl_key, old, bo->lock_cnt);
562 _tbm_bo_unlock(tbm_bo bo)
564 tbm_bufmgr bufmgr = NULL;
573 /* do not try to unlock the bo */
574 if (bufmgr->lock_type == LOCK_TRY_NEVER)
578 if (bufmgr->lock_type == LOCK_TRY_ONCE) {
579 if (bo->lock_cnt > 0) {
581 if (bo->lock_cnt == 0)
584 } else if (bufmgr->lock_type == LOCK_TRY_ALWAYS) {
585 if (bo->lock_cnt > 0) {
590 TBM_LOG("[libtbm:%d] "
591 "error %s:%d bo:%p lock_type is wrong.\n",
592 getpid(), __func__, __LINE__, bo);
595 if (bo->lock_cnt < 0)
598 DBG_LOCK("[libtbm:%d] << unlock bo:%p(%d, %d->%d)\n", getpid(),
599 bo, bo->tgl_key, old, bo->lock_cnt);
603 _tbm_bo_is_valid(tbm_bo bo)
605 tbm_bo old_data = NULL, tmp = NULL;
610 if (!LIST_IS_EMPTY(&gBufMgr->bo_list)) {
611 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &gBufMgr->bo_list, item_link) {
621 _tbm_bo_ref(tbm_bo bo)
627 _tbm_bo_unref(tbm_bo bo)
629 tbm_bufmgr bufmgr = bo->bufmgr;
630 tbm_user_data *old_data = NULL, *tmp = NULL;
632 if (bo->ref_cnt <= 0)
636 if (bo->ref_cnt == 0) {
637 /* destory the user_data_list */
638 if (!LIST_IS_EMPTY(&bo->user_data_list)) {
639 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &bo->user_data_list, item_link) {
640 DBG("[libtbm:%d] free user_data\n",
642 user_data_delete(old_data);
646 if (bo->lock_cnt > 0) {
647 TBM_LOG("[libtbm:%d] "
648 "error %s:%d lock_cnt:%d\n",
649 getpid(), __func__, __LINE__, bo->lock_cnt);
653 if (!bufmgr->use_2_0) {
654 /* Destroy Global Lock */
655 _tbm_bo_destroy_state(bo);
658 /* call the bo_free */
659 bufmgr->backend->bo_free(bo);
662 LIST_DEL(&bo->item_link);
670 _tbm_bufmgr_init_state(tbm_bufmgr bufmgr)
672 RETURN_VAL_CHECK_FLAG(TBM_ALL_CTRL_BACKEND_VALID(bufmgr->backend->flags), 1);
674 bufmgr->lock_fd = open(tgl_devfile, O_RDWR);
676 if (bufmgr->lock_fd < 0) {
677 bufmgr->lock_fd = open(tgl_devfile1, O_RDWR);
678 if (bufmgr->lock_fd < 0) {
680 TBM_LOG("[libtbm:%d] "
681 "error: Fail to open global_lock:%s\n",
682 getpid(), tgl_devfile);
687 if (!_tgl_init(bufmgr->lock_fd, GLOBAL_KEY)) {
688 TBM_LOG("[libtbm:%d] "
689 "error: Fail to initialize the tgl\n",
698 _tbm_bufmgr_destroy_state(tbm_bufmgr bufmgr)
700 RETURN_CHECK_FLAG(TBM_ALL_CTRL_BACKEND_VALID(bufmgr->backend->flags));
702 close(bufmgr->lock_fd);
706 _check_version(TBMModuleVersionInfo *data)
711 abimaj = GET_ABI_MAJOR(data->abiversion);
712 abimin = GET_ABI_MINOR(data->abiversion);
715 "TBM module %s: vendor=\"%s\" ABI=%d,%d\n",
716 getpid(), data->modname ? data->modname : "UNKNOWN!",
717 data->vendor ? data->vendor : "UNKNOWN!", abimaj, abimin);
719 vermaj = GET_ABI_MAJOR(TBM_ABI_VERSION);
720 vermin = GET_ABI_MINOR(TBM_ABI_VERSION);
723 "TBM ABI version %d.%d\n",
724 getpid(), vermaj, vermin);
726 if (abimaj != vermaj) {
727 TBM_LOG("[libtbm:%d] "
728 "TBM module ABI major ver(%d) doesn't match the TBM's ver(%d)\n",
729 getpid(), abimaj, vermaj);
731 } else if (abimin > vermin) {
732 TBM_LOG("[libtbm:%d] "
733 "TBM module ABI minor ver(%d) is newer than the TBM's ver(%d)\n",
734 getpid(), abimin, vermin);
741 _tbm_bufmgr_load_module(tbm_bufmgr bufmgr, int fd, const char *file)
743 char path[PATH_MAX] = { 0, };
744 TBMModuleData *initdata = NULL;
747 snprintf(path, sizeof(path), BUFMGR_MODULE_DIR "/%s", file);
749 module_data = dlopen(path, RTLD_LAZY);
751 TBM_LOG("[libtbm:%d] "
752 "failed to load module: %s(%s)\n",
753 getpid(), dlerror(), file);
757 initdata = dlsym(module_data, "tbmModuleData");
760 TBMModuleVersionInfo *vers;
762 vers = initdata->vers;
763 init = initdata->init;
766 if (!_check_version(vers)) {
767 dlclose(module_data);
771 TBM_LOG("[libtbm:%d] "
772 "Error: module does not supply version information.\n",
775 dlclose(module_data);
780 if (!init(bufmgr, fd)) {
781 TBM_LOG("[libtbm:%d] "
782 "Fail to init module(%s)\n",
784 dlclose(module_data);
788 if (!bufmgr->backend || !bufmgr->backend->priv) {
789 TBM_LOG("[libtbm:%d] "
790 "Error: module(%s) wrong operation. Check backend or backend's priv.\n",
792 dlclose(module_data);
796 TBM_LOG("[libtbm:%d] "
797 "Error: module does not supply init symbol.\n",
799 dlclose(module_data);
803 TBM_LOG("[libtbm:%d] "
804 "Error: module does not have data object.\n",
806 dlclose(module_data);
810 bufmgr->module_data = module_data;
813 "Success to load module(%s)\n",
820 _tbm_load_module(tbm_bufmgr bufmgr, int fd)
822 struct dirent **namelist;
823 const char *p = NULL;
827 /* load bufmgr priv from default lib */
828 ret = _tbm_bufmgr_load_module(bufmgr, fd, DEFAULT_LIB);
830 /* load bufmgr priv from configured path */
832 n = scandir(BUFMGR_MODULE_DIR, &namelist, 0, alphasort);
834 TBM_LOG("[libtbm:%d] "
836 getpid(), BUFMGR_MODULE_DIR);
839 if (!ret && strstr(namelist[n]->d_name, PREFIX_LIB)) {
840 p = strstr(namelist[n]->d_name, SUFFIX_LIB);
841 if (p && !strcmp(p, SUFFIX_LIB))
842 ret = _tbm_bufmgr_load_module(bufmgr, fd, namelist[n]->d_name);
854 tbm_bufmgr_init(int fd)
858 int backend_flag = 0;
860 pthread_mutex_lock(&gLock);
863 env = getenv("GEM_DEBUG");
866 TBM_LOG("GEM_DEBUG=%s\n", env);
872 /* initialize buffer manager */
874 DBG("[libtbm:%d] use previous gBufMgr\n", getpid());
875 if (!gBufMgr->fd_flag) {
877 if (dup2(gBufMgr->fd, fd) < 0) {
878 _tbm_set_last_result(TBM_BO_ERROR_DUP_FD_FAILED);
879 TBM_LOG("[libtbm:%d] Fail to duplicate(dup2) the drm fd\n",
881 pthread_mutex_unlock(&gLock);
884 DBG("[libtbm:%d] duplicate the drm_fd(%d), new drm_fd(%d).\n",
885 getpid(), gBufMgr->fd, fd);
888 gBufMgr->ref_count++;
890 DBG("[libtbm:%d] bufmgr ref: fd=%d, ref_count:%d\n",
891 getpid(), gBufMgr->fd, gBufMgr->ref_count);
892 pthread_mutex_unlock(&gLock);
899 DBG("[libtbm:%d] bufmgr init: fd=%d\n", getpid(), fd);
901 /* allocate bufmgr */
902 gBufMgr = calloc(1, sizeof(struct _tbm_bufmgr));
904 _tbm_set_last_result(TBM_BO_ERROR_HEAP_ALLOC_FAILED);
905 pthread_mutex_unlock(&gLock);
909 gBufMgr->fd_flag = fd_flag;
914 gBufMgr->fd = dup(fd);
915 if (gBufMgr->fd < 0) {
916 _tbm_set_last_result(TBM_BO_ERROR_DUP_FD_FAILED);
917 TBM_LOG("[libtbm:%d] Fail to duplicate(dup) the drm fd\n",
921 pthread_mutex_unlock(&gLock);
924 DBG("[libtbm:%d] duplicate the drm_fd(%d), bufmgr use fd(%d).\n",
925 getpid(), fd, gBufMgr->fd);
928 /* load bufmgr priv from env */
929 if (!_tbm_load_module(gBufMgr, gBufMgr->fd)) {
930 _tbm_set_last_result(TBM_BO_ERROR_LOAD_MODULE_FAILED);
931 TBM_LOG("[libtbm:%d] error : Fail to load bufmgr backend\n", getpid());
938 pthread_mutex_unlock(&gLock);
942 backend_flag = gBufMgr->backend->flags;
943 /* log for tbm backend_flag */
944 DBG("[libtbm:%d] ", getpid());
946 if (backend_flag & TBM_CACHE_CTRL_BACKEND) {
953 if (backend_flag & TBM_LOCK_CTRL_BACKEND) {
959 if (backend_flag & TBM_USE_2_0_BACKEND) {
960 gBufMgr->use_2_0 = 1;
961 DBG("USE 2.0 backend");
966 gBufMgr->ref_count = 1;
968 DBG("[libtbm:%d] create tizen bufmgr: ref_count:%d\n",
969 getpid(), gBufMgr->ref_count);
971 if (pthread_mutex_init(&gBufMgr->lock, NULL) != 0) {
972 _tbm_set_last_result(TBM_BO_ERROR_THREAD_INIT_FAILED);
973 gBufMgr->backend->bufmgr_deinit(gBufMgr->backend->priv);
974 tbm_backend_free(gBufMgr->backend);
975 dlclose(gBufMgr->module_data);
982 pthread_mutex_unlock(&gLock);
986 if (!gBufMgr->use_2_0) {
987 /* intialize the tizen global status */
988 if (!_tbm_bufmgr_init_state(gBufMgr)) {
989 _tbm_set_last_result(TBM_BO_ERROR_INIT_STATE_FAILED);
990 TBM_LOG("[libtbm:%d] error: Fail to init state\n", getpid());
991 gBufMgr->backend->bufmgr_deinit(gBufMgr->backend->priv);
992 tbm_backend_free(gBufMgr->backend);
993 pthread_mutex_destroy(&gBufMgr->lock);
994 dlclose(gBufMgr->module_data);
1001 pthread_mutex_unlock(&gLock);
1005 /* setup the map_cache */
1006 env = getenv("BUFMGR_MAP_CACHE");
1007 if (env && !strcmp(env, "false"))
1008 gBufMgr->use_map_cache = 0;
1010 gBufMgr->use_map_cache = 1;
1011 DBG("[libtbm:%d] BUFMGR_MAP_CACHE=%s\n",
1012 getpid(), env ? env : "default:true");
1015 /* setup the lock_type */
1016 env = getenv("BUFMGR_LOCK_TYPE");
1017 if (env && !strcmp(env, "always"))
1018 gBufMgr->lock_type = LOCK_TRY_ALWAYS;
1019 else if (env && !strcmp(env, "none"))
1020 gBufMgr->lock_type = LOCK_TRY_NEVER;
1021 else if (env && !strcmp(env, "once"))
1022 gBufMgr->lock_type = LOCK_TRY_ONCE;
1024 gBufMgr->lock_type = LOCK_TRY_ALWAYS;
1026 DBG("[libtbm:%d] BUFMGR_LOCK_TYPE=%s\n",
1027 getpid(), env ? env : "default:once");
1029 /* intialize bo_list */
1030 LIST_INITHEAD(&gBufMgr->bo_list);
1032 /* intialize surf_list */
1033 LIST_INITHEAD(&gBufMgr->surf_list);
1035 pthread_mutex_unlock(&gLock);
1040 tbm_bufmgr_deinit(tbm_bufmgr bufmgr)
1042 TBM_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
1047 tbm_surface_h surf = NULL;
1048 tbm_surface_h tmp_surf = NULL;
1050 pthread_mutex_lock(&gLock);
1052 bufmgr->ref_count--;
1053 if (bufmgr->ref_count > 0) {
1054 TBM_LOG("[libtbm:%d] "
1055 "tizen bufmgr destroy: bufmgr:%p, ref_count:%d\n",
1056 getpid(), bufmgr, bufmgr->ref_count);
1057 pthread_mutex_unlock(&gLock);
1061 /* destroy bo_list */
1062 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
1063 LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &bufmgr->bo_list, item_link) {
1064 TBM_LOG("[libtbm:%d] "
1065 "Un-freed bo(%p, ref:%d)\n",
1066 getpid(), bo, bo->ref_cnt);
1072 /* destroy surf_list */
1073 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
1074 LIST_FOR_EACH_ENTRY_SAFE(surf, tmp_surf, &bufmgr->surf_list, item_link) {
1075 TBM_LOG("[libtbm:%d] "
1076 "Destroy surf(%p)\n",
1078 tbm_surface_destroy(surf);
1082 if (!bufmgr->use_2_0) {
1083 /* destroy the tizen global status */
1084 _tbm_bufmgr_destroy_state(bufmgr);
1087 /* destroy bufmgr priv */
1088 bufmgr->backend->bufmgr_deinit(bufmgr->backend->priv);
1089 bufmgr->backend->priv = NULL;
1090 tbm_backend_free(bufmgr->backend);
1091 bufmgr->backend = NULL;
1093 pthread_mutex_destroy(&bufmgr->lock);
1096 "tizen bufmgr destroy: bufmgr:%p\n",
1099 dlclose(bufmgr->module_data);
1108 pthread_mutex_unlock(&gLock);
1112 tbm_bo_size(tbm_bo bo)
1114 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1116 tbm_bufmgr bufmgr = bo->bufmgr;
1119 pthread_mutex_lock(&bufmgr->lock);
1121 size = bufmgr->backend->bo_size(bo);
1123 pthread_mutex_unlock(&bufmgr->lock);
1129 tbm_bo_ref(tbm_bo bo)
1131 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), NULL);
1133 tbm_bufmgr bufmgr = bo->bufmgr;
1135 pthread_mutex_lock(&bufmgr->lock);
1139 pthread_mutex_unlock(&bufmgr->lock);
1145 tbm_bo_unref(tbm_bo bo)
1147 TBM_RETURN_IF_FAIL(_tbm_bo_is_valid(bo));
1149 tbm_bufmgr bufmgr = bo->bufmgr;
1151 pthread_mutex_lock(&bufmgr->lock);
1155 pthread_mutex_unlock(&bufmgr->lock);
1159 tbm_bo_alloc(tbm_bufmgr bufmgr, int size, int flags)
1161 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr) && (size > 0), NULL);
1164 void *bo_priv = NULL;
1166 bo = calloc(1, sizeof(struct _tbm_bo));
1168 _tbm_set_last_result(TBM_BO_ERROR_HEAP_ALLOC_FAILED);
1172 bo->bufmgr = bufmgr;
1174 pthread_mutex_lock(&bufmgr->lock);
1176 bo_priv = bufmgr->backend->bo_alloc(bo, size, flags);
1178 _tbm_set_last_result(TBM_BO_ERROR_BO_ALLOC_FAILED);
1180 pthread_mutex_unlock(&bufmgr->lock);
1188 if (!bufmgr->use_2_0) {
1189 bo->tgl_key = INITIAL_KEY;
1190 bo->default_handle.u32 = 0;
1193 if (!_tbm_bo_init_state(bo, CACHE_OP_CREATE)) {
1194 _tbm_set_last_result(TBM_BO_ERROR_INIT_STATE_FAILED);
1196 pthread_mutex_unlock(&bufmgr->lock);
1201 LIST_INITHEAD(&bo->user_data_list);
1203 LIST_ADD(&bo->item_link, &bufmgr->bo_list);
1205 pthread_mutex_unlock(&bufmgr->lock);
1211 tbm_bo_import(tbm_bufmgr bufmgr, unsigned int key)
1213 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
1218 void *bo_priv = NULL;
1220 pthread_mutex_lock(&bufmgr->lock);
1222 if (!bufmgr->use_2_0) {
1223 /* find bo in list */
1224 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
1225 LIST_FOR_EACH_ENTRY_SAFE(bo2, tmp, &bufmgr->bo_list, item_link) {
1226 if (bo2->tgl_key == key) {
1228 "find bo(%p, ref:%d key:%d) in list\n",
1229 getpid(), bo2, bo2->ref_cnt, bo2->tgl_key);
1232 pthread_mutex_unlock(&bufmgr->lock);
1239 bo = calloc(1, sizeof(struct _tbm_bo));
1241 pthread_mutex_unlock(&bufmgr->lock);
1245 bo->bufmgr = bufmgr;
1247 bo_priv = bufmgr->backend->bo_import(bo, key);
1249 _tbm_set_last_result(TBM_BO_ERROR_IMPORT_FAILED);
1251 pthread_mutex_unlock(&bufmgr->lock);
1255 if (bufmgr->use_2_0) {
1256 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
1257 LIST_FOR_EACH_ENTRY_SAFE(bo2, tmp, &bufmgr->bo_list, item_link) {
1258 if (bo2->priv == bo_priv) {
1260 "find bo(%p, ref:%d key:%d) in list\n",
1261 getpid(), bo2, bo2->ref_cnt, bo2->tgl_key);
1265 pthread_mutex_unlock(&bufmgr->lock);
1275 if (!bufmgr->use_2_0) {
1276 bo->tgl_key = INITIAL_KEY;
1277 bo->default_handle.u32 = 0;
1280 if (!_tbm_bo_init_state(bo, CACHE_OP_IMPORT)) {
1281 _tbm_set_last_result(TBM_BO_ERROR_INIT_STATE_FAILED);
1283 pthread_mutex_unlock(&bufmgr->lock);
1288 if (bufmgr->backend->bo_get_flags)
1289 bo->flags = bufmgr->backend->bo_get_flags(bo);
1291 bo->flags = TBM_BO_DEFAULT;
1293 LIST_INITHEAD(&bo->user_data_list);
1295 LIST_ADD(&bo->item_link, &bufmgr->bo_list);
1297 pthread_mutex_unlock(&bufmgr->lock);
1303 tbm_bo_import_fd(tbm_bufmgr bufmgr, tbm_fd fd)
1305 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
1310 void *bo_priv = NULL;
1311 tbm_bo_handle default_handle;
1313 pthread_mutex_lock(&bufmgr->lock);
1315 if (!bufmgr->use_2_0) {
1316 default_handle = bufmgr->backend->fd_to_handle(bufmgr, fd, TBM_DEVICE_DEFAULT);
1318 /* find bo in list */
1319 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
1320 LIST_FOR_EACH_ENTRY_SAFE(bo2, tmp, &bufmgr->bo_list, item_link) {
1321 if (bo2->default_handle.u32 == default_handle.u32) {
1323 "find bo(%p, ref:%d handle:%d) in list\n",
1324 getpid(), bo2, bo2->ref_cnt, bo2->default_handle.u32);
1327 pthread_mutex_unlock(&bufmgr->lock);
1334 bo = calloc(1, sizeof(struct _tbm_bo));
1336 pthread_mutex_unlock(&bufmgr->lock);
1340 bo->bufmgr = bufmgr;
1342 bo_priv = bufmgr->backend->bo_import_fd(bo, fd);
1344 _tbm_set_last_result(TBM_BO_ERROR_IMPORT_FD_FAILED);
1346 pthread_mutex_unlock(&bufmgr->lock);
1350 if (bufmgr->use_2_0) {
1351 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
1352 LIST_FOR_EACH_ENTRY_SAFE(bo2, tmp, &bufmgr->bo_list, item_link) {
1353 if (bo2->priv == bo_priv) {
1355 "find bo(%p, ref:%d key:%d) in list\n",
1356 getpid(), bo2, bo2->ref_cnt, bo2->tgl_key);
1360 pthread_mutex_unlock(&bufmgr->lock);
1370 if (!bufmgr->use_2_0) {
1371 bo->tgl_key = INITIAL_KEY;
1372 bo->default_handle.u32 = 0;
1375 if (!_tbm_bo_init_state(bo, CACHE_OP_IMPORT)) {
1376 _tbm_set_last_result(TBM_BO_ERROR_INIT_STATE_FAILED);
1378 pthread_mutex_unlock(&bufmgr->lock);
1383 if (bufmgr->backend->bo_get_flags)
1384 bo->flags = bufmgr->backend->bo_get_flags(bo);
1386 bo->flags = TBM_BO_DEFAULT;
1388 LIST_INITHEAD(&bo->user_data_list);
1390 LIST_ADD(&bo->item_link, &bufmgr->bo_list);
1392 pthread_mutex_unlock(&bufmgr->lock);
1398 tbm_bo_export(tbm_bo bo)
1400 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1405 bufmgr = bo->bufmgr;
1407 pthread_mutex_lock(&bufmgr->lock);
1408 ret = bufmgr->backend->bo_export(bo);
1410 _tbm_set_last_result(TBM_BO_ERROR_EXPORT_FAILED);
1411 pthread_mutex_unlock(&bufmgr->lock);
1414 pthread_mutex_unlock(&bufmgr->lock);
1420 tbm_bo_export_fd(tbm_bo bo)
1422 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), -1);
1427 bufmgr = bo->bufmgr;
1429 pthread_mutex_lock(&bufmgr->lock);
1430 ret = bufmgr->backend->bo_export_fd(bo);
1432 _tbm_set_last_result(TBM_BO_ERROR_EXPORT_FD_FAILED);
1433 pthread_mutex_unlock(&bufmgr->lock);
1436 pthread_mutex_unlock(&bufmgr->lock);
1442 tbm_bo_get_handle(tbm_bo bo, int device)
1444 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) 0);
1447 tbm_bo_handle bo_handle;
1449 bufmgr = bo->bufmgr;
1451 pthread_mutex_lock(&bufmgr->lock);
1452 bo_handle = bufmgr->backend->bo_get_handle(bo, device);
1453 if (bo_handle.ptr == NULL) {
1454 _tbm_set_last_result(TBM_BO_ERROR_GET_HANDLE_FAILED);
1455 pthread_mutex_unlock(&bufmgr->lock);
1456 return (tbm_bo_handle) NULL;
1458 pthread_mutex_unlock(&bufmgr->lock);
1464 tbm_bo_map(tbm_bo bo, int device, int opt)
1466 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) 0);
1469 tbm_bo_handle bo_handle;
1471 bufmgr = bo->bufmgr;
1473 pthread_mutex_lock(&bufmgr->lock);
1475 if (!_tbm_bo_lock(bo, device, opt)) {
1476 _tbm_set_last_result(TBM_BO_ERROR_LOCK_FAILED);
1477 TBM_LOG("[libtbm:%d] "
1478 "error %s:%d fail to lock bo:%p)\n",
1479 getpid(), __func__, __LINE__, bo);
1480 pthread_mutex_unlock(&bufmgr->lock);
1481 return (tbm_bo_handle) NULL;
1484 bo_handle = bufmgr->backend->bo_map(bo, device, opt);
1485 if (bo_handle.ptr == NULL) {
1486 _tbm_set_last_result(TBM_BO_ERROR_MAP_FAILED);
1487 TBM_LOG("[libtbm:%d] "
1488 "error %s:%d fail to map bo:%p\n",
1489 getpid(), __func__, __LINE__, bo);
1492 pthread_mutex_unlock(&bufmgr->lock);
1493 return (tbm_bo_handle) NULL;
1496 if (!bufmgr->use_2_0) {
1497 if (bufmgr->use_map_cache == 1 && bo->map_cnt == 0)
1498 _tbm_bo_set_state(bo, device, opt);
1501 /* increase the map_count */
1504 pthread_mutex_unlock(&bufmgr->lock);
1510 tbm_bo_unmap(tbm_bo bo)
1512 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1517 bufmgr = bo->bufmgr;
1519 pthread_mutex_lock(&bufmgr->lock);
1521 ret = bufmgr->backend->bo_unmap(bo);
1524 _tbm_set_last_result(TBM_BO_ERROR_UNMAP_FAILED);
1525 pthread_mutex_unlock(&bufmgr->lock);
1529 /* decrease the map_count */
1532 if (!bufmgr->use_2_0) {
1533 if (bo->map_cnt == 0)
1534 _tbm_bo_save_state(bo);
1539 pthread_mutex_unlock(&bufmgr->lock);
1545 tbm_bo_swap(tbm_bo bo1, tbm_bo bo2)
1547 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo1), 0);
1548 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo2), 0);
1551 unsigned int tmp_key;
1552 tbm_bo_handle tmp_defualt_handle;
1554 pthread_mutex_lock(&bo1->bufmgr->lock);
1556 if (bo1->bufmgr->backend->bo_size(bo1) != bo2->bufmgr->backend->bo_size(bo2)) {
1557 _tbm_set_last_result(TBM_BO_ERROR_SWAP_FAILED);
1558 pthread_mutex_unlock(&bo1->bufmgr->lock);
1562 if (!bo1->bufmgr->use_2_0) {
1563 tmp_key = bo1->tgl_key;
1564 bo1->tgl_key = bo2->tgl_key;
1565 bo2->tgl_key = tmp_key;
1567 tmp_defualt_handle = bo1->default_handle;
1568 bo1->default_handle = bo2->default_handle;
1569 bo2->default_handle = tmp_defualt_handle;
1573 bo1->priv = bo2->priv;
1576 pthread_mutex_unlock(&bo1->bufmgr->lock);
1582 tbm_bo_locked(tbm_bo bo)
1584 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1588 bufmgr = bo->bufmgr;
1590 if (bufmgr->lock_type == LOCK_TRY_NEVER)
1593 pthread_mutex_lock(&bufmgr->lock);
1595 if (bo->lock_cnt > 0) {
1596 pthread_mutex_unlock(&bufmgr->lock);
1600 pthread_mutex_unlock(&bufmgr->lock);
1606 tbm_bo_add_user_data(tbm_bo bo, unsigned long key,
1607 tbm_data_free data_free_func)
1609 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1611 tbm_user_data *data;
1613 /* check if the data according to the key exist if so, return false. */
1614 data = user_data_lookup(&bo->user_data_list, key);
1616 TBM_LOG("[libtbm:%d] "
1617 "waring: %s:%d user data already exist. key:%ld\n",
1618 getpid(), __func__, __LINE__, key);
1622 data = user_data_create(key, data_free_func);
1626 LIST_ADD(&data->item_link, &bo->user_data_list);
1632 tbm_bo_set_user_data(tbm_bo bo, unsigned long key, void *data)
1634 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1636 tbm_user_data *old_data;
1638 if (LIST_IS_EMPTY(&bo->user_data_list))
1641 old_data = user_data_lookup(&bo->user_data_list, key);
1645 if (old_data->data && old_data->free_func)
1646 old_data->free_func(old_data->data);
1648 old_data->data = data;
1654 tbm_bo_get_user_data(tbm_bo bo, unsigned long key, void **data)
1656 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1658 tbm_user_data *old_data;
1660 if (!data || LIST_IS_EMPTY(&bo->user_data_list))
1663 old_data = user_data_lookup(&bo->user_data_list, key);
1669 *data = old_data->data;
1675 tbm_bo_delete_user_data(tbm_bo bo, unsigned long key)
1677 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1679 tbm_user_data *old_data = (void *)0;
1681 if (LIST_IS_EMPTY(&bo->user_data_list))
1684 old_data = user_data_lookup(&bo->user_data_list, key);
1688 user_data_delete(old_data);
1694 tbm_get_last_error(void)
1696 return tbm_last_error;
1700 tbm_bufmgr_get_capability(tbm_bufmgr bufmgr)
1702 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), 0);
1704 unsigned int capability = TBM_BUFMGR_CAPABILITY_NONE;
1706 if (bufmgr->backend->bo_import && bufmgr->backend->bo_export)
1707 capability |= TBM_BUFMGR_CAPABILITY_SHARE_KEY;
1709 if (bufmgr->backend->bo_import_fd && bufmgr->backend->bo_export_fd)
1710 capability |= TBM_BUFMGR_CAPABILITY_SHARE_FD;
1716 tbm_bo_get_flags(tbm_bo bo)
1718 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1724 tbm_bufmgr_debug_show(tbm_bufmgr bufmgr)
1726 TBM_RETURN_IF_FAIL(bufmgr != NULL);
1727 tbm_bo bo = NULL, tmp_bo = NULL;
1730 tbm_surface_h surf = NULL, tmp_surf = NULL;
1733 char app_name[255] = {0,};
1734 unsigned int pid = 0;
1736 pthread_mutex_lock(&gLock);
1739 _tbm_util_get_appname_from_pid(getpid(), app_name);
1740 _tbm_util_get_appname_brief(app_name);
1741 TBM_DEBUG("============TBM DEBUG: %s(%d)===========================\n",
1742 app_name, getpid());
1743 memset(app_name, 0x0, 255 * sizeof(char));
1745 TBM_DEBUG("[tbm_surface information]\n");
1746 TBM_DEBUG("no surface refcnt width height bpp size num_bos num_planes flags format app_name\n");
1747 /* show the tbm_surface information in surf_list */
1748 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
1749 LIST_FOR_EACH_ENTRY_SAFE(surf, tmp_surf, &bufmgr->surf_list, item_link) {
1750 pid = _tbm_surface_internal_get_debug_pid(surf);
1752 /* if pid is null, set the self_pid */
1756 _tbm_util_get_appname_from_pid(pid, app_name);
1757 _tbm_util_get_appname_brief(app_name);
1759 TBM_DEBUG("%-4d%-23p%-6d%-7d%-8d%-5d%-12d%-10d%-9d%-4d%-20s%s\n",
1766 surf->info.size / 1024,
1770 _tbm_surface_internal_format_to_str(surf->info.format),
1773 for (i = 0; i < surf->num_bos; i++) {
1774 TBM_DEBUG(" bo:%-12p(key:%2d) %-26d%-10d\n",
1776 surf->bos[i]->tgl_key,
1777 surf->bos[i]->ref_cnt,
1778 tbm_bo_size(surf->bos[i]) / 1024);
1781 memset(app_name, 0x0, 255 * sizeof(char));
1784 TBM_DEBUG("no tbm_surfaces.\n");
1788 TBM_DEBUG("[tbm_bo information]\n");
1789 TBM_DEBUG("no bo refcnt size lock_cnt map_cnt cache_state flags surface\n");
1791 /* show the tbm_bo information in bo_list */
1792 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
1793 LIST_FOR_EACH_ENTRY_SAFE(bo, tmp_bo, &bufmgr->bo_list, item_link) {
1794 TBM_DEBUG("%-4d%-11p(key:%2d) %-6d%-12d%-9d%-9d%-10d%-4d%-11p\n",
1799 tbm_bo_size(bo) / 1024,
1802 bo->cache_state.val,
1807 TBM_DEBUG("no tbm_bos.\n");
1811 TBM_DEBUG("===============================================================\n");
1813 pthread_mutex_unlock(&gLock);
1818 tbm_bufmgr_debug_trace(tbm_bufmgr bufmgr, int onoff)
1820 TBM_LOG("bufmgr=%p onoff=%d\n", bufmgr, onoff);
1821 TBM_LOG("Not implemented yet.\n");
1824 /* internal function */
1826 _tbm_bo_set_surface(tbm_bo bo, tbm_surface_h surface)
1828 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1830 bo->surface = surface;
1836 tbm_bufmgr_bind_native_display(tbm_bufmgr bufmgr, void *NativeDisplay)
1838 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), 0);
1842 pthread_mutex_lock(&bufmgr->lock);
1844 ret = bufmgr->backend->bufmgr_bind_native_display(bufmgr, NativeDisplay);
1846 pthread_mutex_unlock(&bufmgr->lock);
1850 pthread_mutex_unlock(&bufmgr->lock);