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;
94 tbm_bufmgr gBufMgr = NULL;
96 static __thread tbm_error_e tbm_last_error = TBM_ERROR_NONE;
98 static void _tbm_set_last_result(tbm_error_e err)
100 tbm_last_error = err;
103 static void _tbm_util_get_appname_brief(char *brief)
107 char temp[255] = {0,};
108 char *saveptr = NULL;
110 token = strtok_r(brief, delim, &saveptr);
112 while (token != NULL) {
113 memset(temp, 0x00, 255*sizeof(char));
114 strncpy(temp, token, 254*sizeof(char));
115 token = strtok_r(NULL, delim, &saveptr);
118 snprintf(brief, sizeof(temp), "%s", temp);
121 static void _tbm_util_get_appname_from_pid(long pid, char *str)
126 char fn_cmdline[255] = {0,};
127 char cmdline[255] = {0,};
129 snprintf(fn_cmdline, sizeof(fn_cmdline), "/proc/%ld/cmdline", app_pid);
131 fp = fopen(fn_cmdline, "r");
133 fprintf(stderr, "cannot file open /proc/%ld/cmdline", app_pid);
137 if (!fgets(cmdline, 255, fp)) {
138 fprintf(stderr, "fail to get appname for pid(%ld)\n", app_pid);
144 len = strlen(cmdline);
146 memset(cmdline, 0x00, 255);
150 snprintf(str, sizeof(cmdline), "%s", cmdline);
154 /* unneeded version 2.0 */
155 static inline int _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);
165 TBM_LOG("[libtbm:%d] "
166 "error(%s) %s:%d key:%d\n",
167 getpid(), strerror(errno), __FUNCTION__, __LINE__, key);
174 static inline int _tgl_destroy(int fd, unsigned int key)
177 err = ioctl(fd, TGL_IOC_DESTROY_LOCK, key);
179 TBM_LOG("[libtbm:%d] "
180 "error(%s) %s:%d key:%d\n",
181 getpid(), strerror(errno), __FUNCTION__, __LINE__, key);
188 static inline int _tgl_lock(int fd, unsigned int key)
191 err = ioctl(fd, TGL_IOC_LOCK_LOCK, key);
193 TBM_LOG("[libtbm:%d] "
194 "error(%s) %s:%d key:%d\n",
195 getpid(), strerror(errno), __FUNCTION__, __LINE__, key);
202 static inline int _tgl_unlock(int fd, unsigned int key)
205 err = ioctl(fd, TGL_IOC_UNLOCK_LOCK, key);
207 TBM_LOG("[libtbm:%d] "
208 "error(%s) %s:%d key:%d\n",
209 getpid(), strerror(errno), __FUNCTION__, __LINE__, key);
216 static inline int _tgl_set_data(int fd, unsigned int key, unsigned int val)
219 struct tgl_user_data arg;
223 err = ioctl(fd, TGL_IOC_SET_DATA, &arg);
225 TBM_LOG("[libtbm:%d] "
226 "error(%s) %s:%d key:%d\n",
227 getpid(), strerror(errno), __FUNCTION__, __LINE__, key);
234 static inline unsigned int _tgl_get_data(int fd, unsigned int key, unsigned int *locked)
237 struct tgl_user_data arg = { 0, };
240 err = ioctl(fd, TGL_IOC_GET_DATA, &arg);
242 TBM_LOG("[libtbm:%d] "
243 "error(%s) %s:%d key:%d\n",
244 getpid(), strerror(errno), __FUNCTION__, __LINE__, key);
249 *locked = arg.locked;
253 /* unneeded version 2.0 */
255 tbm_user_data *user_data_lookup(struct list_head *user_data_list, unsigned long key)
257 tbm_user_data *user_data = NULL;
258 tbm_user_data *old_data = NULL, *tmp = NULL;
260 if (!LIST_IS_EMPTY(user_data_list)) {
261 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, user_data_list, item_link) {
262 if (old_data->key == key) {
263 user_data = old_data;
272 tbm_user_data *user_data_create(unsigned long key, tbm_data_free data_free_func)
274 tbm_user_data *user_data = NULL;
276 user_data = calloc(1, sizeof(tbm_user_data));
280 user_data->key = key;
281 user_data->free_func = data_free_func;
282 user_data->data = (void *)0;
287 void user_data_delete(tbm_user_data * user_data)
289 if (user_data->data && user_data->free_func)
290 user_data->free_func(user_data->data);
292 LIST_DEL(&user_data->item_link);
297 static int _bo_lock(tbm_bo bo, int device, int opt)
299 tbm_bufmgr bufmgr = bo->bufmgr;
302 if (bufmgr->use_2_0) {
303 if (bufmgr->backend->bo_lock2) {
304 /* use bo_lock2 backend lock */
305 ret = bufmgr->backend->bo_lock2(bo, device, opt);
306 } else if (bufmgr->backend->bo_lock) {
307 /* use bo_lock backend lock */
308 ret = bufmgr->backend->bo_lock(bo);
310 TBM_LOG("[libtbm:%d] "
311 "error %s:%d no backend lock functions\n",
312 getpid(), __FUNCTION__, __LINE__);
315 if (TBM_LOCK_CTRL_BACKEND_VALID(bufmgr->backend->flags)) {
316 if (bufmgr->backend->bo_lock2) {
317 /* use bo_lock2 backend lock */
318 ret = bufmgr->backend->bo_lock2(bo, device, opt);
319 } else if (bufmgr->backend->bo_lock) {
320 /* use bo_lock backend lock */
321 ret = bufmgr->backend->bo_lock(bo);
323 TBM_LOG("[libtbm:%d] "
324 "error %s:%d no backend lock functions\n",
325 getpid(), __FUNCTION__, __LINE__);
328 /* use tizen global lock */
329 ret = _tgl_lock(bufmgr->lock_fd, bo->tgl_key);
336 static void _bo_unlock(tbm_bo bo)
338 tbm_bufmgr bufmgr = bo->bufmgr;
340 if (bufmgr->use_2_0) {
341 if (bufmgr->backend->bo_unlock) {
342 /* use backend unlock */
343 bufmgr->backend->bo_unlock(bo);
345 TBM_LOG("[libtbm:%d] "
346 "error %s:%d no backend unlock functions\n",
347 getpid(), __FUNCTION__, __LINE__);
351 if (TBM_LOCK_CTRL_BACKEND_VALID(bufmgr->backend->flags)) {
352 if (bufmgr->backend->bo_unlock) {
353 /* use backend unlock */
354 bufmgr->backend->bo_unlock(bo);
356 TBM_LOG("[libtbm:%d] "
357 "error %s:%d no backend unlock functions\n",
358 getpid(), __FUNCTION__, __LINE__);
361 /* use tizen global unlock */
362 _tgl_unlock(bufmgr->lock_fd, bo->tgl_key);
367 static int _tbm_bo_init_state(tbm_bo bo, int opt)
369 tbm_bufmgr bufmgr = bo->bufmgr;
370 tbm_bo_cache_state cache_state;
372 if (bo->tgl_key == INITIAL_KEY)
373 bo->tgl_key = bufmgr->backend->bo_get_global_key(bo);
375 if (!bo->default_handle.u32)
376 bo->default_handle = bufmgr->backend->bo_get_handle(bo, TBM_DEVICE_DEFAULT);
378 RETURN_VAL_CHECK_FLAG(TBM_ALL_CTRL_BACKEND_VALID(bufmgr->backend->flags), 1);
382 case CACHE_OP_CREATE: /*Create */
384 _tgl_init(bufmgr->lock_fd, bo->tgl_key);
386 cache_state.data.isCacheable = BO_IS_CACHEABLE(bo);
387 cache_state.data.isDirtied = DEVICE_NONE;
388 cache_state.data.isCached = 0;
389 cache_state.data.cntFlush = 0;
391 _tgl_set_data(bufmgr->lock_fd, bo->tgl_key, cache_state.val);
393 case CACHE_OP_IMPORT: /*Import */
395 _tgl_init(bufmgr->lock_fd, bo->tgl_key);
404 static void _tbm_bo_destroy_state(tbm_bo bo)
406 tbm_bufmgr bufmgr = bo->bufmgr;
408 RETURN_CHECK_FLAG(TBM_ALL_CTRL_BACKEND_VALID(bufmgr->backend->flags));
410 _tgl_destroy(bufmgr->lock_fd, bo->tgl_key);
413 static int _tbm_bo_set_state(tbm_bo bo, int device, int opt)
415 tbm_bufmgr bufmgr = bo->bufmgr;
417 unsigned short cntFlush = 0;
418 unsigned int is_locked;
420 RETURN_VAL_CHECK_FLAG(TBM_CACHE_CTRL_BACKEND_VALID(bufmgr->backend->flags), 1);
422 /* get cache state of a bo */
423 bo->cache_state.val = _tgl_get_data(bufmgr->lock_fd, bo->tgl_key, &is_locked);
425 if (!bo->cache_state.data.isCacheable)
428 /* get global cache flush count */
429 cntFlush = (unsigned short)_tgl_get_data(bufmgr->lock_fd, GLOBAL_KEY, NULL);
431 if (DEVICE_IS_CACHE_AWARE(device)) {
432 if (bo->cache_state.data.isDirtied == DEVICE_CO &&
433 bo->cache_state.data.isCached)
434 need_flush = TBM_CACHE_INV;
436 bo->cache_state.data.isCached = 1;
437 if (opt & TBM_OPTION_WRITE)
438 bo->cache_state.data.isDirtied = DEVICE_CA;
440 if (bo->cache_state.data.isDirtied != DEVICE_CA)
441 bo->cache_state.data.isDirtied = DEVICE_NONE;
444 if (bo->cache_state.data.isDirtied == DEVICE_CA &&
445 bo->cache_state.data.isCached &&
446 bo->cache_state.data.cntFlush == cntFlush)
447 need_flush = TBM_CACHE_CLN | TBM_CACHE_ALL;
449 if (opt & TBM_OPTION_WRITE)
450 bo->cache_state.data.isDirtied = DEVICE_CO;
452 if (bo->cache_state.data.isDirtied != DEVICE_CO)
453 bo->cache_state.data.isDirtied = DEVICE_NONE;
458 /* set global cache flush count */
459 if (need_flush & TBM_CACHE_ALL)
460 _tgl_set_data(bufmgr->lock_fd, GLOBAL_KEY, (unsigned int)(++cntFlush));
462 /* call backend cache flush */
463 bufmgr->backend->bo_cache_flush(bo, need_flush);
465 DBG("[libtbm:%d] \tcache(%d,%d,%d)....flush:0x%x, cntFlush(%d)\n",
467 bo->cache_state.data.isCacheable,
468 bo->cache_state.data.isCached,
469 bo->cache_state.data.isDirtied,
477 static void _tbm_bo_save_state(tbm_bo bo)
479 tbm_bufmgr bufmgr = bo->bufmgr;
480 unsigned short cntFlush = 0;
482 RETURN_CHECK_FLAG(TBM_CACHE_CTRL_BACKEND_VALID(bufmgr->backend->flags));
484 /* get global cache flush count */
485 cntFlush = (unsigned short)_tgl_get_data(bufmgr->lock_fd, GLOBAL_KEY, NULL);
487 /* save global cache flush count */
488 bo->cache_state.data.cntFlush = cntFlush;
489 _tgl_set_data(bufmgr->lock_fd, bo->tgl_key, bo->cache_state.val);
492 static int _tbm_bo_lock(tbm_bo bo, int device, int opt)
494 tbm_bufmgr bufmgr = NULL;
503 /* do not try to lock the bo */
504 if (bufmgr->lock_type == LOCK_TRY_NEVER)
507 if (bo->lock_cnt < 0) {
508 TBM_LOG("[libtbm:%d] "
509 "error %s:%d bo:%p(%d) LOCK_CNT=%d\n",
510 getpid(), __FUNCTION__, __LINE__, bo, bo->tgl_key, bo->lock_cnt);
514 if (bufmgr->lock_type == LOCK_TRY_ONCE) {
515 if (bo->lock_cnt == 0) {
516 pthread_mutex_unlock(&bufmgr->lock);
517 ret = _bo_lock(bo, device, opt);
518 pthread_mutex_lock(&bufmgr->lock);
523 } else if (bufmgr->lock_type == LOCK_TRY_ALWAYS) {
524 pthread_mutex_unlock(&bufmgr->lock);
525 ret = _bo_lock(bo, device, opt);
526 pthread_mutex_lock(&bufmgr->lock);
530 TBM_LOG("[libtbm:%d] "
531 "error %s:%d bo:%p lock_type is wrong.\n",
532 getpid(), __FUNCTION__, __LINE__, bo);
535 DBG_LOCK("[libtbm:%d] >> LOCK bo:%p(%d, %d->%d)\n", getpid(),
536 bo, bo->tgl_key, old, bo->lock_cnt);
541 static void _tbm_bo_unlock(tbm_bo bo)
543 tbm_bufmgr bufmgr = NULL;
552 /* do not try to unlock the bo */
553 if (bufmgr->lock_type == LOCK_TRY_NEVER)
557 if (bufmgr->lock_type == LOCK_TRY_ONCE) {
558 if (bo->lock_cnt > 0) {
560 if (bo->lock_cnt == 0)
563 } else if (bufmgr->lock_type == LOCK_TRY_ALWAYS) {
564 if (bo->lock_cnt > 0) {
569 TBM_LOG("[libtbm:%d] "
570 "error %s:%d bo:%p lock_type is wrong.\n",
571 getpid(), __FUNCTION__, __LINE__, bo);
574 if (bo->lock_cnt < 0)
577 DBG_LOCK("[libtbm:%d] << unlock bo:%p(%d, %d->%d)\n", getpid(),
578 bo, bo->tgl_key, old, bo->lock_cnt);
581 static int _tbm_bo_is_valid(tbm_bo bo)
583 tbm_bo old_data = NULL, tmp = NULL;;
588 if (!LIST_IS_EMPTY(&gBufMgr->bo_list)) {
589 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &gBufMgr->bo_list, item_link) {
598 static void _tbm_bo_ref(tbm_bo bo)
603 static void _tbm_bo_unref(tbm_bo bo)
605 tbm_bufmgr bufmgr = bo->bufmgr;
606 tbm_user_data *old_data = NULL, *tmp = NULL;
608 if (bo->ref_cnt <= 0)
612 if (bo->ref_cnt == 0) {
613 /* destory the user_data_list */
614 if (!LIST_IS_EMPTY(&bo->user_data_list)) {
615 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &bo->user_data_list, item_link) {
616 DBG("[libtbm:%d] free user_data \n",
618 user_data_delete(old_data);
622 if (bo->lock_cnt > 0) {
623 TBM_LOG("[libtbm:%d] "
624 "error %s:%d lock_cnt:%d\n",
625 getpid(), __FUNCTION__, __LINE__, bo->lock_cnt);
629 if (!bufmgr->use_2_0) {
630 /* Destroy Global Lock */
631 _tbm_bo_destroy_state(bo);
634 /* call the bo_free */
635 bufmgr->backend->bo_free(bo);
638 LIST_DEL(&bo->item_link);
645 static int _tbm_bufmgr_init_state(tbm_bufmgr bufmgr)
647 RETURN_VAL_CHECK_FLAG(TBM_ALL_CTRL_BACKEND_VALID(bufmgr->backend->flags), 1);
649 bufmgr->lock_fd = open(tgl_devfile, O_RDWR);
651 if (bufmgr->lock_fd < 0) {
652 bufmgr->lock_fd = open(tgl_devfile1, O_RDWR);
653 if (bufmgr->lock_fd < 0) {
655 TBM_LOG("[libtbm:%d] "
656 "error: Fail to open global_lock:%s\n",
657 getpid(), tgl_devfile);
662 if (!_tgl_init(bufmgr->lock_fd, GLOBAL_KEY)) {
663 TBM_LOG("[libtbm:%d] "
664 "error: Fail to initialize the tgl\n",
672 static void _tbm_bufmgr_destroy_state(tbm_bufmgr bufmgr)
674 RETURN_CHECK_FLAG(TBM_ALL_CTRL_BACKEND_VALID(bufmgr->backend->flags));
676 close(bufmgr->lock_fd);
679 static int _check_version(TBMModuleVersionInfo * data)
684 abimaj = GET_ABI_MAJOR(data->abiversion);
685 abimin = GET_ABI_MINOR(data->abiversion);
688 "TBM module %s: vendor=\"%s\" ABI=%d,%d\n",
689 getpid(), data->modname ? data->modname : "UNKNOWN!",
690 data->vendor ? data->vendor : "UNKNOWN!", abimaj, abimin);
692 vermaj = GET_ABI_MAJOR(TBM_ABI_VERSION);
693 vermin = GET_ABI_MINOR(TBM_ABI_VERSION);
696 "TBM ABI version %d.%d\n",
697 getpid(), vermaj, vermin);
699 if (abimaj != vermaj) {
700 TBM_LOG("[libtbm:%d] "
701 "TBM module ABI major ver(%d) doesn't match the TBM's ver(%d)\n",
702 getpid(), abimaj, vermaj);
704 } else if (abimin > vermin) {
705 TBM_LOG("[libtbm:%d] "
706 "TBM module ABI minor ver(%d) is newer than the TBM's ver(%d)\n",
707 getpid(), abimin, vermin);
713 static int _tbm_bufmgr_load_module(tbm_bufmgr bufmgr, int fd, const char *file)
715 char path[PATH_MAX] = { 0, };
716 TBMModuleData *initdata = NULL;
719 snprintf(path, sizeof(path), BUFMGR_MODULE_DIR "/%s", file);
721 module_data = dlopen(path, RTLD_LAZY);
723 TBM_LOG("[libtbm:%d] "
724 "failed to load module: %s(%s)\n",
725 getpid(), dlerror(), file);
729 initdata = dlsym(module_data, "tbmModuleData");
732 TBMModuleVersionInfo *vers;
734 vers = initdata->vers;
735 init = initdata->init;
738 if (!_check_version(vers)) {
739 dlclose(module_data);
743 TBM_LOG("[libtbm:%d] "
744 "Error: module does not supply version information.\n",
747 dlclose(module_data);
752 if (!init(bufmgr, fd)) {
753 TBM_LOG("[libtbm:%d] "
754 "Fail to init module(%s)\n",
756 dlclose(module_data);
760 if (!bufmgr->backend || !bufmgr->backend->priv) {
761 TBM_LOG("[libtbm:%d] "
762 "Error: module(%s) wrong operation. Check backend or backend's priv.\n",
764 dlclose(module_data);
768 TBM_LOG("[libtbm:%d] "
769 "Error: module does not supply init symbol.\n",
771 dlclose(module_data);
775 TBM_LOG("[libtbm:%d] "
776 "Error: module does not have data object.\n",
778 dlclose(module_data);
782 bufmgr->module_data = module_data;
785 "Success to load module(%s)\n",
791 static int _tbm_load_module(tbm_bufmgr bufmgr, int fd)
793 struct dirent **namelist;
794 const char *p = NULL;
798 /* load bufmgr priv from default lib */
799 ret = _tbm_bufmgr_load_module(bufmgr, fd, DEFAULT_LIB);
801 /* load bufmgr priv from configured path */
803 n = scandir(BUFMGR_MODULE_DIR, &namelist, 0, alphasort);
805 TBM_LOG("[libtbm:%d] "
807 getpid(), BUFMGR_MODULE_DIR);
810 if (!ret && strstr(namelist[n]->d_name, PREFIX_LIB)) {
811 p = strstr(namelist[n]->d_name, SUFFIX_LIB);
813 if (!strcmp(p, SUFFIX_LIB))
814 ret = _tbm_bufmgr_load_module(bufmgr, fd, namelist[n]->d_name);
826 tbm_bufmgr tbm_bufmgr_init(int fd)
830 int backend_flag = 0;
832 pthread_mutex_lock(&gLock);
835 env = getenv("GEM_DEBUG");
838 TBM_LOG("GEM_DEBUG=%s\n", env);
843 /* initialize buffer manager */
845 DBG("[libtbm:%d] use previous gBufMgr\n", getpid());
846 if (!gBufMgr->fd_flag) {
848 if (dup2(gBufMgr->fd, fd) < 0) {
849 _tbm_set_last_result(TBM_BO_ERROR_DUP_FD_FAILED);
850 TBM_LOG("[libtbm:%d] Fail to duplicate(dup2) the drm fd\n",
852 pthread_mutex_unlock(&gLock);
855 DBG("[libtbm:%d] duplicate the drm_fd(%d), new drm_fd(%d).\n",
856 getpid(), gBufMgr->fd, fd);
859 gBufMgr->ref_count++;
861 DBG("[libtbm:%d] bufmgr ref: fd=%d, ref_count:%d\n",
862 getpid(), gBufMgr->fd, gBufMgr->ref_count);
863 pthread_mutex_unlock(&gLock);
871 DBG("[libtbm:%d] bufmgr init: fd=%d\n", getpid(), fd);
873 /* allocate bufmgr */
874 gBufMgr = calloc(1, sizeof(struct _tbm_bufmgr));
876 _tbm_set_last_result(TBM_BO_ERROR_HEAP_ALLOC_FAILED);
877 pthread_mutex_unlock(&gLock);
881 gBufMgr->fd_flag = fd_flag;
886 gBufMgr->fd = dup(fd);
887 if (gBufMgr->fd < 0) {
888 _tbm_set_last_result(TBM_BO_ERROR_DUP_FD_FAILED);
889 TBM_LOG("[libtbm:%d] Fail to duplicate(dup) the drm fd\n",
893 pthread_mutex_unlock(&gLock);
896 DBG("[libtbm:%d] duplicate the drm_fd(%d), bufmgr use fd(%d).\n",
897 getpid(), fd, gBufMgr->fd);
900 /* load bufmgr priv from env */
901 if (!_tbm_load_module(gBufMgr, gBufMgr->fd)) {
902 _tbm_set_last_result(TBM_BO_ERROR_LOAD_MODULE_FAILED);
903 TBM_LOG("[libtbm:%d] " "error : Fail to load bufmgr backend\n", getpid());
910 pthread_mutex_unlock(&gLock);
913 backend_flag = gBufMgr->backend->flags;
914 /* log for tbm backend_flag */
915 DBG("[libtbm:%d] ", getpid());
917 if (backend_flag & TBM_CACHE_CTRL_BACKEND) {
924 if (backend_flag & TBM_LOCK_CTRL_BACKEND) {
930 if (backend_flag & TBM_USE_2_0_BACKEND) {
931 gBufMgr->use_2_0 = 1;
932 DBG("USE 2.0 backend");
938 gBufMgr->ref_count = 1;
940 DBG("[libtbm:%d] create tizen bufmgr: ref_count:%d\n",
941 getpid(), gBufMgr->ref_count);
943 if (pthread_mutex_init(&gBufMgr->lock, NULL) != 0) {
944 _tbm_set_last_result(TBM_BO_ERROR_THREAD_INIT_FAILED);
945 gBufMgr->backend->bufmgr_deinit(gBufMgr->backend->priv);
946 tbm_backend_free(gBufMgr->backend);
947 dlclose(gBufMgr->module_data);
954 pthread_mutex_unlock(&gLock);
958 if (!gBufMgr->use_2_0) {
959 /* intialize the tizen global status */
960 if (!_tbm_bufmgr_init_state(gBufMgr)) {
961 _tbm_set_last_result(TBM_BO_ERROR_INIT_STATE_FAILED);
962 TBM_LOG("[libtbm:%d] " "error: Fail to init state\n", getpid());
963 gBufMgr->backend->bufmgr_deinit(gBufMgr->backend->priv);
964 tbm_backend_free(gBufMgr->backend);
965 pthread_mutex_destroy(&gBufMgr->lock);
966 dlclose(gBufMgr->module_data);
973 pthread_mutex_unlock(&gLock);
977 /* setup the map_cache */
978 env = getenv("BUFMGR_MAP_CACHE");
979 if (env && !strcmp(env, "false"))
980 gBufMgr->use_map_cache = 0;
982 gBufMgr->use_map_cache = 1;
983 DBG("[libtbm:%d] BUFMGR_MAP_CACHE=%s\n",
984 getpid(), env ? env : "default:true");
987 /* setup the lock_type */
988 env = getenv("BUFMGR_LOCK_TYPE");
989 if (env && !strcmp(env, "always"))
990 gBufMgr->lock_type = LOCK_TRY_ALWAYS;
991 else if (env && !strcmp(env, "none"))
992 gBufMgr->lock_type = LOCK_TRY_NEVER;
993 else if (env && !strcmp(env, "once"))
994 gBufMgr->lock_type = LOCK_TRY_ONCE;
996 gBufMgr->lock_type = LOCK_TRY_ALWAYS;
998 DBG("[libtbm:%d] BUFMGR_LOCK_TYPE=%s\n",
999 getpid(), env ? env : "default:once");
1001 /* intialize bo_list */
1002 LIST_INITHEAD(&gBufMgr->bo_list);
1004 /* intialize surf_list */
1005 LIST_INITHEAD(&gBufMgr->surf_list);
1007 pthread_mutex_unlock(&gLock);
1011 void tbm_bufmgr_deinit(tbm_bufmgr bufmgr)
1013 TBM_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
1018 tbm_surface_h surf = NULL;
1019 tbm_surface_h tmp_surf = NULL;
1021 pthread_mutex_lock(&gLock);
1023 bufmgr->ref_count--;
1024 if (bufmgr->ref_count > 0) {
1025 TBM_LOG("[libtbm:%d] "
1026 "tizen bufmgr destroy: bufmgr:%p, ref_count:%d\n",
1027 getpid(), bufmgr, bufmgr->ref_count);
1028 pthread_mutex_unlock(&gLock);
1032 /* destroy bo_list */
1033 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
1034 LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &bufmgr->bo_list, item_link) {
1035 TBM_LOG("[libtbm:%d] "
1036 "Un-freed bo(%p, ref:%d) \n",
1037 getpid(), bo, bo->ref_cnt);
1043 /* destroy surf_list */
1044 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
1045 LIST_FOR_EACH_ENTRY_SAFE(surf, tmp_surf, &bufmgr->surf_list, item_link) {
1046 TBM_LOG("[libtbm:%d] "
1047 "Destroy surf(%p) \n",
1049 tbm_surface_destroy(surf);
1053 if (!bufmgr->use_2_0) {
1054 /* destroy the tizen global status */
1055 _tbm_bufmgr_destroy_state(bufmgr);
1058 /* destroy bufmgr priv */
1059 bufmgr->backend->bufmgr_deinit(bufmgr->backend->priv);
1060 bufmgr->backend->priv = NULL;
1061 tbm_backend_free(bufmgr->backend);
1062 bufmgr->backend = NULL;
1064 pthread_mutex_destroy(&bufmgr->lock);
1067 "tizen bufmgr destroy: bufmgr:%p\n",
1070 dlclose(bufmgr->module_data);
1079 pthread_mutex_unlock(&gLock);
1082 int tbm_bo_size(tbm_bo bo)
1084 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1086 tbm_bufmgr bufmgr = bo->bufmgr;
1089 pthread_mutex_lock(&bufmgr->lock);
1091 size = bufmgr->backend->bo_size(bo);
1093 pthread_mutex_unlock(&bufmgr->lock);
1098 tbm_bo tbm_bo_ref(tbm_bo bo)
1100 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), NULL);
1102 tbm_bufmgr bufmgr = bo->bufmgr;
1104 pthread_mutex_lock(&bufmgr->lock);
1108 pthread_mutex_unlock(&bufmgr->lock);
1113 void tbm_bo_unref(tbm_bo bo)
1115 TBM_RETURN_IF_FAIL(_tbm_bo_is_valid(bo));
1117 tbm_bufmgr bufmgr = bo->bufmgr;
1119 pthread_mutex_lock(&bufmgr->lock);
1123 pthread_mutex_unlock(&bufmgr->lock);
1126 tbm_bo tbm_bo_alloc(tbm_bufmgr bufmgr, int size, int flags)
1128 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr) && (size > 0), NULL);
1131 void *bo_priv = NULL;
1133 bo = calloc(1, sizeof(struct _tbm_bo));
1135 _tbm_set_last_result(TBM_BO_ERROR_HEAP_ALLOC_FAILED);
1139 bo->bufmgr = bufmgr;
1141 pthread_mutex_lock(&bufmgr->lock);
1143 bo_priv = bufmgr->backend->bo_alloc(bo, size, flags);
1145 _tbm_set_last_result(TBM_BO_ERROR_BO_ALLOC_FAILED);
1147 pthread_mutex_unlock(&bufmgr->lock);
1155 if (!bufmgr->use_2_0) {
1156 bo->tgl_key = INITIAL_KEY;
1157 bo->default_handle.u32 = 0;
1160 if (!_tbm_bo_init_state(bo, CACHE_OP_CREATE)) {
1161 _tbm_set_last_result(TBM_BO_ERROR_INIT_STATE_FAILED);
1163 pthread_mutex_unlock(&bufmgr->lock);
1168 LIST_INITHEAD(&bo->user_data_list);
1170 LIST_ADD(&bo->item_link, &bufmgr->bo_list);
1172 pthread_mutex_unlock(&bufmgr->lock);
1177 tbm_bo tbm_bo_import(tbm_bufmgr bufmgr, unsigned int key)
1179 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
1184 void *bo_priv = NULL;
1186 pthread_mutex_lock(&bufmgr->lock);
1188 if (!bufmgr->use_2_0) {
1189 /* find bo in list */
1190 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
1191 LIST_FOR_EACH_ENTRY_SAFE(bo2, tmp, &bufmgr->bo_list, item_link) {
1192 if (bo2->tgl_key == key) {
1194 "find bo(%p, ref:%d key:%d) in list \n",
1195 getpid(), bo2, bo2->ref_cnt, bo2->tgl_key);
1198 pthread_mutex_unlock(&bufmgr->lock);
1205 bo = calloc(1, sizeof(struct _tbm_bo));
1207 pthread_mutex_unlock(&bufmgr->lock);
1211 bo->bufmgr = bufmgr;
1213 bo_priv = bufmgr->backend->bo_import(bo, key);
1215 _tbm_set_last_result(TBM_BO_ERROR_IMPORT_FAILED);
1217 pthread_mutex_unlock(&bufmgr->lock);
1221 if (bufmgr->use_2_0) {
1222 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
1223 LIST_FOR_EACH_ENTRY_SAFE(bo2, tmp, &bufmgr->bo_list, item_link) {
1224 if (bo2->priv == bo_priv) {
1226 "find bo(%p, ref:%d key:%d) in list \n",
1227 getpid(), bo2, bo2->ref_cnt, bo2->tgl_key);
1231 pthread_mutex_unlock(&bufmgr->lock);
1241 if (!bufmgr->use_2_0) {
1242 bo->tgl_key = INITIAL_KEY;
1243 bo->default_handle.u32 = 0;
1246 if (!_tbm_bo_init_state(bo, CACHE_OP_IMPORT)) {
1247 _tbm_set_last_result(TBM_BO_ERROR_INIT_STATE_FAILED);
1249 pthread_mutex_unlock(&bufmgr->lock);
1254 if (bufmgr->backend->bo_get_flags)
1255 bo->flags = bufmgr->backend->bo_get_flags(bo);
1257 bo->flags = TBM_BO_DEFAULT;
1259 LIST_INITHEAD(&bo->user_data_list);
1261 LIST_ADD(&bo->item_link, &bufmgr->bo_list);
1263 pthread_mutex_unlock(&bufmgr->lock);
1268 tbm_bo tbm_bo_import_fd(tbm_bufmgr bufmgr, tbm_fd fd)
1270 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
1275 void *bo_priv = NULL;
1276 tbm_bo_handle default_handle;
1278 pthread_mutex_lock(&bufmgr->lock);
1280 if (!bufmgr->use_2_0) {
1281 default_handle = bufmgr->backend->fd_to_handle(bufmgr, fd, TBM_DEVICE_DEFAULT);
1283 /* find bo in list */
1284 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
1285 LIST_FOR_EACH_ENTRY_SAFE(bo2, tmp, &bufmgr->bo_list, item_link) {
1286 if (bo2->default_handle.u32 == default_handle.u32) {
1288 "find bo(%p, ref:%d handle:%d) in list \n",
1289 getpid(), bo2, bo2->ref_cnt, bo2->default_handle.u32);
1292 pthread_mutex_unlock(&bufmgr->lock);
1299 bo = calloc(1, sizeof(struct _tbm_bo));
1301 pthread_mutex_unlock(&bufmgr->lock);
1305 bo->bufmgr = bufmgr;
1307 bo_priv = bufmgr->backend->bo_import_fd(bo, fd);
1309 _tbm_set_last_result(TBM_BO_ERROR_IMPORT_FD_FAILED);
1311 pthread_mutex_unlock(&bufmgr->lock);
1315 if (bufmgr->use_2_0) {
1316 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
1317 LIST_FOR_EACH_ENTRY_SAFE(bo2, tmp, &bufmgr->bo_list, item_link) {
1318 if (bo2->priv == bo_priv) {
1320 "find bo(%p, ref:%d key:%d) in list \n",
1321 getpid(), bo2, bo2->ref_cnt, bo2->tgl_key);
1325 pthread_mutex_unlock(&bufmgr->lock);
1335 if (!bufmgr->use_2_0) {
1336 bo->tgl_key = INITIAL_KEY;
1337 bo->default_handle.u32 = 0;
1340 if (!_tbm_bo_init_state(bo, CACHE_OP_IMPORT)) {
1341 _tbm_set_last_result(TBM_BO_ERROR_INIT_STATE_FAILED);
1343 pthread_mutex_unlock(&bufmgr->lock);
1348 if (bufmgr->backend->bo_get_flags)
1349 bo->flags = bufmgr->backend->bo_get_flags(bo);
1351 bo->flags = TBM_BO_DEFAULT;
1353 LIST_INITHEAD(&bo->user_data_list);
1355 LIST_ADD(&bo->item_link, &bufmgr->bo_list);
1357 pthread_mutex_unlock(&bufmgr->lock);
1362 tbm_key tbm_bo_export(tbm_bo bo)
1364 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1369 bufmgr = bo->bufmgr;
1371 pthread_mutex_lock(&bufmgr->lock);
1372 ret = bufmgr->backend->bo_export(bo);
1374 _tbm_set_last_result(TBM_BO_ERROR_EXPORT_FAILED);
1375 pthread_mutex_unlock(&bufmgr->lock);
1378 pthread_mutex_unlock(&bufmgr->lock);
1383 tbm_fd tbm_bo_export_fd(tbm_bo bo)
1385 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), -1);
1390 bufmgr = bo->bufmgr;
1392 pthread_mutex_lock(&bufmgr->lock);
1393 ret = bufmgr->backend->bo_export_fd(bo);
1395 _tbm_set_last_result(TBM_BO_ERROR_EXPORT_FD_FAILED);
1396 pthread_mutex_unlock(&bufmgr->lock);
1399 pthread_mutex_unlock(&bufmgr->lock);
1404 tbm_bo_handle tbm_bo_get_handle(tbm_bo bo, int device)
1406 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) 0);
1409 tbm_bo_handle bo_handle;
1411 bufmgr = bo->bufmgr;
1413 pthread_mutex_lock(&bufmgr->lock);
1414 bo_handle = bufmgr->backend->bo_get_handle(bo, device);
1415 if (bo_handle.ptr == NULL) {
1416 _tbm_set_last_result(TBM_BO_ERROR_GET_HANDLE_FAILED);
1417 pthread_mutex_unlock(&bufmgr->lock);
1418 return (tbm_bo_handle) NULL;
1420 pthread_mutex_unlock(&bufmgr->lock);
1425 tbm_bo_handle tbm_bo_map(tbm_bo bo, int device, int opt)
1427 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) 0);
1430 tbm_bo_handle bo_handle;
1432 bufmgr = bo->bufmgr;
1434 pthread_mutex_lock(&bufmgr->lock);
1436 if (!_tbm_bo_lock(bo, device, opt)) {
1437 _tbm_set_last_result(TBM_BO_ERROR_LOCK_FAILED);
1438 TBM_LOG("[libtbm:%d] "
1439 "error %s:%d fail to lock bo:%p)\n",
1440 getpid(), __FUNCTION__, __LINE__, bo);
1441 pthread_mutex_unlock(&bufmgr->lock);
1442 return (tbm_bo_handle) NULL;
1445 bo_handle = bufmgr->backend->bo_map(bo, device, opt);
1446 if (bo_handle.ptr == NULL) {
1447 _tbm_set_last_result(TBM_BO_ERROR_MAP_FAILED);
1448 TBM_LOG("[libtbm:%d] "
1449 "error %s:%d fail to map bo:%p\n",
1450 getpid(), __FUNCTION__, __LINE__, bo);
1453 pthread_mutex_unlock(&bufmgr->lock);
1454 return (tbm_bo_handle) NULL;
1457 if (!bufmgr->use_2_0) {
1458 if (bufmgr->use_map_cache == 1 && bo->map_cnt == 0)
1459 _tbm_bo_set_state(bo, device, opt);
1462 /* increase the map_count */
1465 pthread_mutex_unlock(&bufmgr->lock);
1470 int tbm_bo_unmap(tbm_bo bo)
1472 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1477 bufmgr = bo->bufmgr;
1479 pthread_mutex_lock(&bufmgr->lock);
1481 ret = bufmgr->backend->bo_unmap(bo);
1484 _tbm_set_last_result(TBM_BO_ERROR_UNMAP_FAILED);
1485 pthread_mutex_unlock(&bufmgr->lock);
1489 /* decrease the map_count */
1492 if (!bufmgr->use_2_0) {
1493 if (bo->map_cnt == 0)
1494 _tbm_bo_save_state(bo);
1499 pthread_mutex_unlock(&bufmgr->lock);
1504 int tbm_bo_swap(tbm_bo bo1, tbm_bo bo2)
1506 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo1), 0);
1507 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo2), 0);
1510 unsigned int tmp_key;
1511 tbm_bo_handle tmp_defualt_handle;
1513 pthread_mutex_lock(&bo1->bufmgr->lock);
1515 if (bo1->bufmgr->backend->bo_size(bo1) != bo2->bufmgr->backend->bo_size(bo2)) {
1516 _tbm_set_last_result(TBM_BO_ERROR_SWAP_FAILED);
1517 pthread_mutex_unlock(&bo1->bufmgr->lock);
1521 if (!bo1->bufmgr->use_2_0) {
1522 tmp_key = bo1->tgl_key;
1523 bo1->tgl_key = bo2->tgl_key;
1524 bo2->tgl_key = tmp_key;
1526 tmp_defualt_handle = bo1->default_handle;
1527 bo1->default_handle = bo2->default_handle;
1528 bo2->default_handle = tmp_defualt_handle;
1532 bo1->priv = bo2->priv;
1535 pthread_mutex_unlock(&bo1->bufmgr->lock);
1540 int tbm_bo_locked(tbm_bo bo)
1542 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1546 bufmgr = bo->bufmgr;
1548 if (bufmgr->lock_type == LOCK_TRY_NEVER)
1551 pthread_mutex_lock(&bufmgr->lock);
1553 if (bo->lock_cnt > 0) {
1554 pthread_mutex_unlock(&bufmgr->lock);
1558 pthread_mutex_unlock(&bufmgr->lock);
1563 int tbm_bo_add_user_data(tbm_bo bo, unsigned long key, tbm_data_free data_free_func)
1565 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1567 tbm_user_data *data;
1569 /* check if the data according to the key exist if so, return false. */
1570 data = user_data_lookup(&bo->user_data_list, key);
1572 TBM_LOG("[libtbm:%d] "
1573 "waring: %s:%d user data already exist. key:%ld\n",
1574 getpid(), __FUNCTION__, __LINE__, key);
1578 data = user_data_create(key, data_free_func);
1582 LIST_ADD(&data->item_link, &bo->user_data_list);
1587 int tbm_bo_set_user_data(tbm_bo bo, unsigned long key, void *data)
1589 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1591 tbm_user_data *old_data;
1593 if (LIST_IS_EMPTY(&bo->user_data_list))
1596 old_data = user_data_lookup(&bo->user_data_list, key);
1600 if (old_data->data && old_data->free_func)
1601 old_data->free_func(old_data->data);
1603 old_data->data = data;
1608 int tbm_bo_get_user_data(tbm_bo bo, unsigned long key, void **data)
1610 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1612 tbm_user_data *old_data;
1614 if (!data || LIST_IS_EMPTY(&bo->user_data_list))
1617 old_data = user_data_lookup(&bo->user_data_list, key);
1623 *data = old_data->data;
1628 int tbm_bo_delete_user_data(tbm_bo bo, unsigned long key)
1630 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1632 tbm_user_data *old_data = (void *)0;
1634 if (LIST_IS_EMPTY(&bo->user_data_list))
1637 old_data = user_data_lookup(&bo->user_data_list, key);
1641 user_data_delete(old_data);
1646 tbm_error_e tbm_get_last_error(void)
1648 return tbm_last_error;
1651 unsigned int tbm_bufmgr_get_capability(tbm_bufmgr bufmgr)
1653 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), 0);
1655 unsigned int capability = TBM_BUFMGR_CAPABILITY_NONE;
1657 if (bufmgr->backend->bo_import && bufmgr->backend->bo_export)
1658 capability |= TBM_BUFMGR_CAPABILITY_SHARE_KEY;
1660 if (bufmgr->backend->bo_import_fd && bufmgr->backend->bo_export_fd)
1661 capability |= TBM_BUFMGR_CAPABILITY_SHARE_FD;
1666 int tbm_bo_get_flags(tbm_bo bo)
1668 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1673 void tbm_bufmgr_debug_show(tbm_bufmgr bufmgr)
1675 TBM_RETURN_IF_FAIL(bufmgr != NULL);
1676 tbm_bo bo = NULL, tmp_bo = NULL;
1679 tbm_surface_h surf = NULL, tmp_surf = NULL;
1682 char app_name[255] = {0,};
1683 unsigned int pid = 0;
1685 pthread_mutex_lock(&gLock);
1688 _tbm_util_get_appname_from_pid(getpid(), app_name);
1689 _tbm_util_get_appname_brief(app_name);
1690 TBM_DEBUG("============TBM DEBUG: %s(%d)===========================\n", app_name, getpid());
1691 memset(app_name, 0x0, 255*sizeof(char));
1693 TBM_DEBUG("[tbm_surface information]\n");
1694 TBM_DEBUG("no surface refcnt width height bpp size num_bos num_planes flags format app_name\n");
1695 /* show the tbm_surface information in surf_list */
1696 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
1697 LIST_FOR_EACH_ENTRY_SAFE(surf, tmp_surf, &bufmgr->surf_list, item_link) {
1698 pid = _tbm_surface_internal_get_debug_pid(surf);
1700 /* if pid is null, set the self_pid */
1704 _tbm_util_get_appname_from_pid(pid, app_name);
1705 _tbm_util_get_appname_brief(app_name);
1707 TBM_DEBUG("%-4d%-23p%-6d%-7d%-8d%-5d%-12d%-10d%-9d%-4d%-20s%s\n",
1714 surf->info.size/1024,
1718 _tbm_surface_internal_format_to_str(surf->info.format),
1721 for (i = 0; i < surf->num_bos; i++) {
1722 TBM_DEBUG(" bo:%-12p(key:%2d) %-26d%-10d\n",
1724 surf->bos[i]->tgl_key,
1725 surf->bos[i]->ref_cnt,
1726 tbm_bo_size(surf->bos[i])/1024);
1729 memset(app_name, 0x0, 255*sizeof(char));
1732 TBM_DEBUG("no tbm_surfaces.\n");
1736 TBM_DEBUG("[tbm_bo information]\n");
1737 TBM_DEBUG("no bo refcnt size lock_cnt map_cnt cache_state flags surface\n");
1739 /* show the tbm_bo information in bo_list */
1740 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
1741 LIST_FOR_EACH_ENTRY_SAFE(bo, tmp_bo, &bufmgr->bo_list, item_link) {
1742 TBM_DEBUG("%-4d%-11p(key:%2d) %-6d%-12d%-9d%-9d%-10d%-4d%-11p\n",
1747 tbm_bo_size(bo)/1024,
1750 bo->cache_state.val,
1755 TBM_DEBUG("no tbm_bos.\n");
1759 TBM_DEBUG("===============================================================\n");
1761 pthread_mutex_unlock(&gLock);
1765 void tbm_bufmgr_debug_trace(tbm_bufmgr bufmgr, int onoff)
1767 TBM_LOG("bufmgr=%p onoff=%d\n", bufmgr, onoff);
1768 TBM_LOG("Not implemented yet.\n");
1771 /* internal function */
1772 int _tbm_bo_set_surface(tbm_bo bo, tbm_surface_h surface)
1774 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1776 bo->surface = surface;