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"
39 #include <sys/resource.h>
56 static pthread_mutex_t gLock = PTHREAD_MUTEX_INITIALIZER;
57 static pthread_mutex_t tbm_bufmgr_lock = PTHREAD_MUTEX_INITIALIZER;
58 static __thread tbm_error_e tbm_last_error = TBM_ERROR_NONE;
60 static void _tbm_bufmgr_mutex_unlock(void);
62 //#define TBM_BUFMGR_INIT_TIME
64 #define PREFIX_LIB "libtbm_"
65 #define SUFFIX_LIB ".so"
66 #define DEFAULT_LIB PREFIX_LIB"default"SUFFIX_LIB
68 /* values to indicate unspecified fields in XF86ModReqInfo. */
69 #define MAJOR_UNSPEC 0xFF
70 #define MINOR_UNSPEC 0xFF
71 #define PATCH_UNSPEC 0xFFFF
72 #define ABI_VERS_UNSPEC 0xFFFFFFFF
74 #define MODULE_VERSION_NUMERIC(maj, min, patch) \
75 ((((maj) & 0xFF) << 24) | (((min) & 0xFF) << 16) | (patch & 0xFFFF))
76 #define GET_MODULE_MAJOR_VERSION(vers) (((vers) >> 24) & 0xFF)
77 #define GET_MODULE_MINOR_VERSION(vers) (((vers) >> 16) & 0xFF)
78 #define GET_MODULE_PATCHLEVEL(vers) ((vers) & 0xFFFF)
81 #define TBM_BUFMGR_RETURN_IF_FAIL(cond) {\
83 TBM_LOG_E("'%s' failed.\n", #cond);\
84 _tbm_bufmgr_mutex_unlock();\
89 #define TBM_BUFMGR_RETURN_VAL_IF_FAIL(cond, val) {\
91 TBM_LOG_E("'%s' failed.\n", #cond);\
92 _tbm_bufmgr_mutex_unlock();\
104 _tbm_set_last_result(tbm_error_e err)
106 tbm_last_error = err;
110 _tbm_bufmgr_mutex_init(void)
112 static bool tbm_bufmgr_mutex_init = false;
114 if (tbm_bufmgr_mutex_init)
117 if (pthread_mutex_init(&tbm_bufmgr_lock, NULL)) {
118 TBM_LOG_E("fail: Cannot pthread_mutex_init for tbm_bufmgr_lock.\n");
122 tbm_bufmgr_mutex_init = true;
128 _tbm_bufmgr_mutex_lock(void)
130 if (!_tbm_bufmgr_mutex_init()) {
131 TBM_LOG_E("fail: _tbm_bufmgr_mutex_init()\n");
135 pthread_mutex_lock(&tbm_bufmgr_lock);
139 _tbm_bufmgr_mutex_unlock(void)
141 pthread_mutex_unlock(&tbm_bufmgr_lock);
145 _tbm_flag_to_str(int f)
147 static char str[255];
149 if (f == TBM_BO_DEFAULT)
150 snprintf(str, 255, "DEFAULT");
154 if (f & TBM_BO_SCANOUT)
155 c = snprintf(&str[c], 255, "SCANOUT");
157 if (f & TBM_BO_NONCACHABLE) {
159 c = snprintf(&str[c], 255, ", ");
160 c = snprintf(&str[c], 255, "NONCACHABLE,");
165 c = snprintf(&str[c], 255, ", ");
166 c = snprintf(&str[c], 255, "WC");
173 /* LCOV_EXCL_START */
175 _tbm_util_check_bo_cnt(tbm_bufmgr bufmgr)
177 static int last_chk_bo_cnt = 0;
179 if ((bufmgr->bo_cnt >= 500) && ((bufmgr->bo_cnt % 20) == 0) &&
180 (bufmgr->bo_cnt > last_chk_bo_cnt)) {
181 TBM_DEBUG("============TBM BO CNT DEBUG: bo_cnt=%d\n",
184 tbm_bufmgr_debug_show(bufmgr);
186 last_chk_bo_cnt = bufmgr->bo_cnt;
191 _tbm_util_get_max_surface_size(int *w, int *h)
193 tbm_surface_info_s info;
194 tbm_surface_h surface = NULL;
200 if (gBufMgr == NULL || LIST_IS_EMPTY(&gBufMgr->surf_list))
203 LIST_FOR_EACH_ENTRY(surface, &gBufMgr->surf_list, item_link) {
204 if (tbm_surface_get_info(surface, &info) == TBM_SURFACE_ERROR_NONE) {
208 if (*h < info.height)
217 _tbm_util_get_appname_brief(char *brief)
221 char temp[255] = {0,};
222 char *saveptr = NULL;
224 token = strtok_r(brief, delim, &saveptr);
226 while (token != NULL) {
227 memset(temp, 0x00, 255 * sizeof(char));
228 strncpy(temp, token, 254 * sizeof(char));
229 token = strtok_r(NULL, delim, &saveptr);
232 snprintf(brief, sizeof(temp), "%s", temp);
236 _tbm_util_get_appname_from_pid(long pid, char *str)
238 char fn_cmdline[255] = {0, }, cmdline[255];
242 snprintf(fn_cmdline, sizeof(fn_cmdline), "/proc/%ld/cmdline", pid);
244 fp = fopen(fn_cmdline, "r");
246 TBM_LOG_E("cannot file open %s\n", fn_cmdline);
250 if (!fgets(cmdline, 255, fp)) {
251 TBM_LOG_E("fail to get appname for pid(%ld)\n", pid);
258 len = strlen(cmdline);
260 memset(cmdline, 0x00, 255);
264 snprintf(str, sizeof(cmdline), "%s", cmdline);
269 *user_data_lookup(struct list_head *user_data_list, unsigned long key)
271 tbm_user_data *old_data = NULL;
273 if (LIST_IS_EMPTY(user_data_list))
276 LIST_FOR_EACH_ENTRY(old_data, user_data_list, item_link) {
277 if (old_data->key == key)
285 *user_data_create(unsigned long key, tbm_data_free data_free_func)
287 tbm_user_data *user_data;
289 user_data = calloc(1, sizeof(tbm_user_data));
291 TBM_LOG_E("fail to allocate an user_date\n");
295 user_data->key = key;
296 user_data->free_func = data_free_func;
302 user_data_delete(tbm_user_data *user_data)
304 if (user_data->data && user_data->free_func)
305 user_data->free_func(user_data->data);
307 LIST_DEL(&user_data->item_link);
313 _bo_lock(tbm_bo bo, int device, int opt)
315 tbm_bufmgr bufmgr = bo->bufmgr;
318 if (bufmgr->backend->bo_lock)
319 ret = bufmgr->backend->bo_lock(bo, device, opt);
325 _bo_unlock(tbm_bo bo)
327 tbm_bufmgr bufmgr = bo->bufmgr;
329 if (bufmgr->backend->bo_unlock)
330 bufmgr->backend->bo_unlock(bo);
334 _tbm_bo_lock(tbm_bo bo, int device, int opt)
344 /* do not try to lock the bo */
345 if (bufmgr->lock_type == LOCK_TRY_NEVER)
348 if (bo->lock_cnt < 0) {
349 TBM_LOG_E("error bo:%p LOCK_CNT=%d\n",
356 switch (bufmgr->lock_type) {
358 if (bo->lock_cnt == 0) {
359 _tbm_bufmgr_mutex_unlock();
360 ret = _bo_lock(bo, device, opt);
361 _tbm_bufmgr_mutex_lock();
367 case LOCK_TRY_ALWAYS:
368 _tbm_bufmgr_mutex_unlock();
369 ret = _bo_lock(bo, device, opt);
370 _tbm_bufmgr_mutex_lock();
375 TBM_LOG_E("error bo:%p lock_type[%d] is wrong.\n",
376 bo, bufmgr->lock_type);
381 TBM_DBG_LOCK(">> LOCK bo:%p(%d->%d)\n", bo, old, bo->lock_cnt);
387 _tbm_bo_unlock(tbm_bo bo)
397 /* do not try to unlock the bo */
398 if (bufmgr->lock_type == LOCK_TRY_NEVER)
403 switch (bufmgr->lock_type) {
405 if (bo->lock_cnt > 0) {
407 if (bo->lock_cnt == 0)
411 case LOCK_TRY_ALWAYS:
412 if (bo->lock_cnt > 0) {
418 TBM_LOG_E("error bo:%p lock_type[%d] is wrong.\n",
419 bo, bufmgr->lock_type);
423 if (bo->lock_cnt < 0)
426 TBM_DBG_LOCK(">> UNLOCK bo:%p(%d->%d)\n", bo, old, bo->lock_cnt);
430 _tbm_bo_is_valid(tbm_bo bo)
432 tbm_bo old_data = NULL;
434 if (bo == NULL || gBufMgr == NULL) {
435 TBM_LOG_E("error: bo is NULL or tbm_bufmgr was deinited\n");
439 if (LIST_IS_EMPTY(&gBufMgr->bo_list)) {
440 TBM_LOG_E("error: gBufMgr->bo_list is EMPTY.\n");
444 LIST_FOR_EACH_ENTRY(old_data, &gBufMgr->bo_list, item_link) {
449 TBM_LOG_E("error: No valid bo(%p).\n", bo);
454 /* LCOV_EXCL_START */
456 _check_version(TBMModuleVersionInfo *data)
461 abimaj = GET_ABI_MAJOR(data->abiversion);
462 abimin = GET_ABI_MINOR(data->abiversion);
464 TBM_DBG("TBM module %s: vendor=\"%s\" ABI=%d,%d\n",
465 data->modname ? data->modname : "UNKNOWN!",
466 data->vendor ? data->vendor : "UNKNOWN!", abimaj, abimin);
468 vermaj = GET_ABI_MAJOR(TBM_ABI_VERSION);
469 vermin = GET_ABI_MINOR(TBM_ABI_VERSION);
471 TBM_DBG("TBM ABI version %d.%d\n",
474 if (abimaj != vermaj) {
475 TBM_LOG_E("TBM module ABI major ver(%d) doesn't match the TBM's ver(%d)\n",
478 } else if (abimin > vermin) {
479 TBM_LOG_E("TBM module ABI minor ver(%d) is newer than the TBM's ver(%d)\n",
488 _tbm_bufmgr_load_module(tbm_bufmgr bufmgr, int fd, const char *file)
490 char path[PATH_MAX] = {0, };
491 TBMModuleVersionInfo *vers;
492 TBMModuleData *initdata;
496 snprintf(path, sizeof(path), BUFMGR_MODULE_DIR "/%s", file);
498 module_data = dlopen(path, RTLD_LAZY);
500 TBM_LOG_E("failed to load module: %s(%s)\n", dlerror(), file);
504 initdata = dlsym(module_data, "tbmModuleData");
506 TBM_LOG_E("Error: module does not have data object.\n");
510 vers = initdata->vers;
512 TBM_LOG_E("Error: module does not supply version information.\n");
516 init = initdata->init;
518 TBM_LOG_E("Error: module does not supply init symbol.\n");
522 if (!_check_version(vers)) {
523 TBM_LOG_E("Fail to check version.\n");
527 if (!init(bufmgr, fd)) {
528 TBM_LOG_E("Fail to init module(%s)\n", file);
532 if (!bufmgr->backend || !bufmgr->backend->priv) {
533 TBM_LOG_E("Error: module(%s) wrong operation. Check backend or backend's priv.\n", file);
537 bufmgr->module_data = module_data;
539 TBM_DBG("Success to load module(%s)\n", file);
544 dlclose(module_data);
549 _tbm_load_module(tbm_bufmgr bufmgr, int fd)
551 struct dirent **namelist;
554 /* load bufmgr priv from default lib */
555 if (_tbm_bufmgr_load_module(bufmgr, fd, DEFAULT_LIB))
558 /* load bufmgr priv from configured path */
559 n = scandir(BUFMGR_MODULE_DIR, &namelist, 0, alphasort);
561 TBM_LOG_E("no files : %s\n", BUFMGR_MODULE_DIR);
566 if (!ret && strstr(namelist[n]->d_name, PREFIX_LIB)) {
567 const char *p = strstr(namelist[n]->d_name, SUFFIX_LIB);
569 if (p && !strcmp(p, SUFFIX_LIB))
570 ret = _tbm_bufmgr_load_module(bufmgr, fd,
571 namelist[n]->d_name);
584 tbm_bufmgr_init(int fd)
586 #ifdef TBM_BUFMGR_INIT_TIME
587 struct timeval start_tv, end_tv;
591 #ifdef TBM_BUFMGR_INIT_TIME
592 /* get the start tv */
593 gettimeofday(&start_tv, NULL);
596 /* LCOV_EXCL_START */
598 env = getenv("TBM_DLOG");
601 TBM_LOG_D("TBM_DLOG=%s\n", env);
607 env = getenv("TBM_DEBUG");
610 TBM_LOG_D("TBM_DEBUG=%s\n", env);
616 env = getenv("TBM_TRACE");
619 TBM_LOG_D("TBM_TRACE=%s\n", env);
625 pthread_mutex_lock(&gLock);
628 TBM_LOG_W("!!!!!WARNING:: The tbm_bufmgr_init DOSE NOT use argument fd ANYMORE.\n");
629 TBM_LOG_W("!!!!!WARNING:: IT WILL BE CHANGED like tbm_bufmgr_init(int fd) --> tbm_bufmgr_init(void).\n");
632 /* initialize buffer manager */
634 gBufMgr->ref_count++;
635 TBM_TRACE("reuse tbm_bufmgr(%p) ref_count(%d) fd(%d)\n", gBufMgr, gBufMgr->ref_count, gBufMgr->fd);
636 pthread_mutex_unlock(&gLock);
640 TBM_DBG("bufmgr init\n");
642 /* allocate bufmgr */
643 gBufMgr = calloc(1, sizeof(struct _tbm_bufmgr));
645 _tbm_set_last_result(TBM_BO_ERROR_HEAP_ALLOC_FAILED);
646 TBM_TRACE("error: fail to alloc bufmgr fd(%d)\n", fd);
647 pthread_mutex_unlock(&gLock);
653 /* load bufmgr priv from env */
654 if (!_tbm_load_module(gBufMgr, gBufMgr->fd)) {
655 /* LCOV_EXCL_START */
656 _tbm_set_last_result(TBM_BO_ERROR_LOAD_MODULE_FAILED);
657 TBM_LOG_E("error : Fail to load bufmgr backend\n");
660 pthread_mutex_unlock(&gLock);
665 /* log for tbm backend_flag */
666 TBM_DBG("backend flag:%x:", gBufMgr->backend->flags);
669 gBufMgr->ref_count = 1;
671 TBM_DBG("create tizen bufmgr:%p ref_count:%d\n",
672 gBufMgr, gBufMgr->ref_count);
674 /* setup the lock_type */
675 env = getenv("BUFMGR_LOCK_TYPE");
676 if (env && !strcmp(env, "always"))
677 gBufMgr->lock_type = LOCK_TRY_ALWAYS;
678 else if (env && !strcmp(env, "none"))
679 gBufMgr->lock_type = LOCK_TRY_NEVER;
680 else if (env && !strcmp(env, "once"))
681 gBufMgr->lock_type = LOCK_TRY_ONCE;
683 gBufMgr->lock_type = LOCK_TRY_ALWAYS;
685 TBM_DBG("BUFMGR_LOCK_TYPE=%s\n", env ? env : "default:once");
687 TBM_TRACE("create tbm_bufmgr(%p) ref_count(%d) fd(%d)\n", gBufMgr, gBufMgr->ref_count, fd);
689 /* intialize bo_list */
690 LIST_INITHEAD(&gBufMgr->bo_list);
692 /* intialize surf_list */
693 LIST_INITHEAD(&gBufMgr->surf_list);
695 /* intialize surf_queue_list */
696 LIST_INITHEAD(&gBufMgr->surf_queue_list);
698 /* intialize debug_key_list */
699 LIST_INITHEAD(&gBufMgr->debug_key_list);
701 #ifdef TBM_BUFMGR_INIT_TIME
703 gettimeofday(&end_tv, NULL);
704 TBM_LOG_I("tbm_bufmgr_init time: %ld ms", ((end_tv.tv_sec * 1000 + end_tv.tv_usec / 1000) - (start_tv.tv_sec * 1000 + start_tv.tv_usec / 1000)));
707 pthread_mutex_unlock(&gLock);
713 tbm_bufmgr_deinit(tbm_bufmgr bufmgr)
715 TBM_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
717 pthread_mutex_lock(&gLock);
720 TBM_LOG_E("gBufmgr already destroy: bufmgr:%p\n", bufmgr);
721 pthread_mutex_unlock(&gLock);
726 if (bufmgr->ref_count > 0) {
727 TBM_TRACE("reduce a ref_count(%d) of tbm_bufmgr(%p)\n", bufmgr->ref_count, bufmgr);
728 pthread_mutex_unlock(&gLock);
732 /* destroy bo_list */
733 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
734 tbm_bo bo = NULL, tmp;
736 LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &bufmgr->bo_list, item_link) {
737 TBM_LOG_E("Un-freed bo(%p, ref:%d)\n", bo, bo->ref_cnt);
743 /* destroy surf_list */
744 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
745 tbm_surface_h surf = NULL, tmp;
747 LIST_FOR_EACH_ENTRY_SAFE(surf, tmp, &bufmgr->surf_list, item_link) {
748 TBM_LOG_E("Un-freed surf(%p, ref:%d)\n", surf, surf->refcnt);
749 tbm_surface_destroy(surf);
753 /* destroy bufmgr priv */
754 bufmgr->backend->bufmgr_deinit(bufmgr->backend->priv);
755 bufmgr->backend->priv = NULL;
756 tbm_backend_free(bufmgr->backend);
757 bufmgr->backend = NULL;
759 TBM_TRACE("destroy tbm_bufmgr(%p)\n", bufmgr);
761 dlclose(bufmgr->module_data);
769 pthread_mutex_unlock(&gLock);
773 tbm_bo_size(tbm_bo bo)
775 tbm_bufmgr bufmgr = gBufMgr;
778 _tbm_bufmgr_mutex_lock();
780 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
781 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
783 size = bufmgr->backend->bo_size(bo);
785 TBM_TRACE("bo(%p) size(%d)\n", bo, size);
787 _tbm_bufmgr_mutex_unlock();
793 tbm_bo_ref(tbm_bo bo)
795 _tbm_bufmgr_mutex_lock();
797 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), NULL);
798 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), NULL);
802 TBM_TRACE("bo(%p) ref_cnt(%d)\n", bo, bo->ref_cnt);
804 _tbm_bufmgr_mutex_unlock();
810 tbm_bo_unref(tbm_bo bo)
812 tbm_bufmgr bufmgr = gBufMgr;
814 _tbm_bufmgr_mutex_lock();
816 TBM_BUFMGR_RETURN_IF_FAIL(gBufMgr);
817 TBM_BUFMGR_RETURN_IF_FAIL(_tbm_bo_is_valid(bo));
819 TBM_TRACE("bo(%p) ref_cnt(%d)\n", bo, bo->ref_cnt - 1);
821 if (bo->ref_cnt <= 0) {
822 _tbm_bufmgr_mutex_unlock();
827 if (bo->ref_cnt == 0) {
828 /* destory the user_data_list */
829 if (!LIST_IS_EMPTY(&bo->user_data_list)) {
830 tbm_user_data *old_data = NULL, *tmp;
832 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp,
833 &bo->user_data_list, item_link) {
834 TBM_DBG("free user_data\n");
835 user_data_delete(old_data);
839 while (bo->lock_cnt > 0) {
840 TBM_LOG_E("error lock_cnt:%d\n", bo->lock_cnt);
845 /* call the bo_free */
846 bufmgr->backend->bo_free(bo);
849 LIST_DEL(&bo->item_link);
855 _tbm_bufmgr_mutex_unlock();
859 tbm_bo_alloc(tbm_bufmgr bufmgr, int size, int flags)
864 _tbm_bufmgr_mutex_lock();
866 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
867 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, NULL);
868 TBM_BUFMGR_RETURN_VAL_IF_FAIL(size > 0, NULL);
870 bo = calloc(1, sizeof(struct _tbm_bo));
872 TBM_LOG_E("error: fail to create of tbm_bo size(%d) flag(%s)\n",
873 size, _tbm_flag_to_str(flags));
874 _tbm_set_last_result(TBM_BO_ERROR_HEAP_ALLOC_FAILED);
875 _tbm_bufmgr_mutex_unlock();
879 _tbm_util_check_bo_cnt(bufmgr);
883 bo_priv = bufmgr->backend->bo_alloc(bo, size, flags);
885 TBM_LOG_E("error: fail to create of tbm_bo size(%d) flag(%s)\n",
886 size, _tbm_flag_to_str(flags));
887 _tbm_set_last_result(TBM_BO_ERROR_BO_ALLOC_FAILED);
889 _tbm_bufmgr_mutex_unlock();
899 TBM_TRACE("bo(%p) size(%d) refcnt(%d), flag(%s)\n", bo, size, bo->ref_cnt,
900 _tbm_flag_to_str(bo->flags));
902 LIST_INITHEAD(&bo->user_data_list);
904 LIST_ADD(&bo->item_link, &bufmgr->bo_list);
906 _tbm_bufmgr_mutex_unlock();
912 tbm_bo_import(tbm_bufmgr bufmgr, unsigned int key)
917 _tbm_bufmgr_mutex_lock();
919 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
920 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, NULL);
922 if (!bufmgr->backend->bo_import) {
923 _tbm_bufmgr_mutex_unlock();
927 _tbm_util_check_bo_cnt(bufmgr);
929 bo = calloc(1, sizeof(struct _tbm_bo));
931 TBM_LOG_E("error: fail to import of tbm_bo by key(%d)\n", key);
932 _tbm_bufmgr_mutex_unlock();
938 bo_priv = bufmgr->backend->bo_import(bo, key);
940 TBM_LOG_E("error: fail to import of tbm_bo by key(%d)\n", key);
941 _tbm_set_last_result(TBM_BO_ERROR_IMPORT_FAILED);
943 _tbm_bufmgr_mutex_unlock();
947 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
950 LIST_FOR_EACH_ENTRY(bo2, &bufmgr->bo_list, item_link) {
951 if (bo2->priv == bo_priv) {
952 TBM_TRACE("find bo(%p) ref(%d) key(%d) flag(%s) in list\n",
953 bo2, bo2->ref_cnt, key,
954 _tbm_flag_to_str(bo2->flags));
957 _tbm_bufmgr_mutex_unlock();
968 if (bufmgr->backend->bo_get_flags)
969 bo->flags = bufmgr->backend->bo_get_flags(bo);
971 bo->flags = TBM_BO_DEFAULT;
973 TBM_TRACE("import new bo(%p) ref(%d) key(%d) flag(%s) in list\n",
974 bo, bo->ref_cnt, key, _tbm_flag_to_str(bo->flags));
976 LIST_INITHEAD(&bo->user_data_list);
978 LIST_ADD(&bo->item_link, &bufmgr->bo_list);
980 _tbm_bufmgr_mutex_unlock();
986 tbm_bo_import_fd(tbm_bufmgr bufmgr, tbm_fd fd)
991 _tbm_bufmgr_mutex_lock();
993 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
994 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, NULL);
996 if (!bufmgr->backend->bo_import_fd) {
997 _tbm_bufmgr_mutex_unlock();
1001 _tbm_util_check_bo_cnt(bufmgr);
1003 bo = calloc(1, sizeof(struct _tbm_bo));
1005 TBM_LOG_E("error: fail to import tbm_bo by tbm_fd(%d)\n", fd);
1006 _tbm_bufmgr_mutex_unlock();
1010 bo->bufmgr = bufmgr;
1012 bo_priv = bufmgr->backend->bo_import_fd(bo, fd);
1014 TBM_LOG_E("error: fail to import tbm_bo by tbm_fd(%d)\n", fd);
1015 _tbm_set_last_result(TBM_BO_ERROR_IMPORT_FD_FAILED);
1017 _tbm_bufmgr_mutex_unlock();
1021 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
1024 LIST_FOR_EACH_ENTRY(bo2, &bufmgr->bo_list, item_link) {
1025 if (bo2->priv == bo_priv) {
1026 TBM_TRACE("find bo(%p) ref(%d) fd(%d) flag(%s) in list\n",
1027 bo2, bo2->ref_cnt, fd,
1028 _tbm_flag_to_str(bo2->flags));
1031 _tbm_bufmgr_mutex_unlock();
1042 if (bufmgr->backend->bo_get_flags)
1043 bo->flags = bufmgr->backend->bo_get_flags(bo);
1045 bo->flags = TBM_BO_DEFAULT;
1047 TBM_TRACE("import bo(%p) ref(%d) fd(%d) flag(%s)\n",
1048 bo, bo->ref_cnt, fd, _tbm_flag_to_str(bo->flags));
1050 LIST_INITHEAD(&bo->user_data_list);
1052 LIST_ADD(&bo->item_link, &bufmgr->bo_list);
1054 _tbm_bufmgr_mutex_unlock();
1060 tbm_bo_export(tbm_bo bo)
1062 tbm_bufmgr bufmgr = gBufMgr;
1065 _tbm_bufmgr_mutex_lock();
1067 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1068 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1070 if (!bufmgr->backend->bo_export) {
1071 _tbm_bufmgr_mutex_unlock();
1075 ret = bufmgr->backend->bo_export(bo);
1077 _tbm_set_last_result(TBM_BO_ERROR_EXPORT_FAILED);
1078 TBM_LOG_E("error: bo(%p) tbm_key(%d)\n", bo, ret);
1079 _tbm_bufmgr_mutex_unlock();
1083 TBM_TRACE("bo(%p) tbm_key(%u)\n", bo, ret);
1085 _tbm_bufmgr_mutex_unlock();
1091 tbm_bo_export_fd(tbm_bo bo)
1093 tbm_bufmgr bufmgr = gBufMgr;
1096 _tbm_bufmgr_mutex_lock();
1098 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), -1);
1099 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), -1);
1101 if (!bufmgr->backend->bo_export_fd) {
1102 _tbm_bufmgr_mutex_unlock();
1106 ret = bufmgr->backend->bo_export_fd(bo);
1108 _tbm_set_last_result(TBM_BO_ERROR_EXPORT_FD_FAILED);
1109 TBM_LOG_E("error: bo(%p) tbm_fd(%d)\n", bo, ret);
1110 _tbm_bufmgr_mutex_unlock();
1114 TBM_TRACE("bo(%p) tbm_fd(%d)\n", bo, ret);
1116 _tbm_bufmgr_mutex_unlock();
1122 tbm_bo_get_handle(tbm_bo bo, int device)
1124 tbm_bufmgr bufmgr = gBufMgr;
1125 tbm_bo_handle bo_handle;
1127 _tbm_bufmgr_mutex_lock();
1129 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), (tbm_bo_handle) NULL);
1130 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) NULL);
1132 bo_handle = bufmgr->backend->bo_get_handle(bo, device);
1133 if (bo_handle.ptr == NULL) {
1134 _tbm_set_last_result(TBM_BO_ERROR_GET_HANDLE_FAILED);
1135 TBM_LOG_E("error: bo(%p) bo_handle(%p)\n", bo, bo_handle.ptr);
1136 _tbm_bufmgr_mutex_unlock();
1137 return (tbm_bo_handle) NULL;
1140 TBM_TRACE("bo(%p) bo_handle(%p)\n", bo, bo_handle.ptr);
1142 _tbm_bufmgr_mutex_unlock();
1148 tbm_bo_map(tbm_bo bo, int device, int opt)
1150 tbm_bufmgr bufmgr = gBufMgr;
1151 tbm_bo_handle bo_handle;
1153 _tbm_bufmgr_mutex_lock();
1155 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), (tbm_bo_handle) NULL);
1156 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) NULL);
1158 if (!_tbm_bo_lock(bo, device, opt)) {
1159 _tbm_set_last_result(TBM_BO_ERROR_LOCK_FAILED);
1160 TBM_LOG_E("error: fail to lock bo:%p)\n", bo);
1161 _tbm_bufmgr_mutex_unlock();
1162 return (tbm_bo_handle) NULL;
1165 bo_handle = bufmgr->backend->bo_map(bo, device, opt);
1166 if (bo_handle.ptr == NULL) {
1167 _tbm_set_last_result(TBM_BO_ERROR_MAP_FAILED);
1168 TBM_LOG_E("error: fail to map bo:%p\n", bo);
1170 _tbm_bufmgr_mutex_unlock();
1171 return (tbm_bo_handle) NULL;
1174 /* increase the map_count */
1177 TBM_TRACE("bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
1179 _tbm_bufmgr_mutex_unlock();
1185 tbm_bo_unmap(tbm_bo bo)
1187 tbm_bufmgr bufmgr = gBufMgr;
1190 _tbm_bufmgr_mutex_lock();
1192 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1193 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1195 ret = bufmgr->backend->bo_unmap(bo);
1197 TBM_LOG_E("error: bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
1198 _tbm_set_last_result(TBM_BO_ERROR_UNMAP_FAILED);
1199 _tbm_bufmgr_mutex_unlock();
1203 /* decrease the map_count */
1206 TBM_TRACE("bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
1210 _tbm_bufmgr_mutex_unlock();
1216 tbm_bo_swap(tbm_bo bo1, tbm_bo bo2)
1218 tbm_bufmgr bufmgr = gBufMgr;
1221 _tbm_bufmgr_mutex_lock();
1223 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1224 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo1), 0);
1225 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo2), 0);
1227 TBM_TRACE("before: bo1(%p) bo2(%p)\n", bo1, bo2);
1229 if (bufmgr->backend->bo_size(bo1) != bufmgr->backend->bo_size(bo2)) {
1230 _tbm_set_last_result(TBM_BO_ERROR_SWAP_FAILED);
1231 TBM_LOG_E("error: bo1(%p) bo2(%p)\n", bo1, bo2);
1232 _tbm_bufmgr_mutex_unlock();
1236 TBM_TRACE("after: bo1(%p) bo2(%p)\n", bo1, bo2);
1239 bo1->priv = bo2->priv;
1242 _tbm_bufmgr_mutex_unlock();
1248 tbm_bo_locked(tbm_bo bo)
1250 tbm_bufmgr bufmgr = gBufMgr;
1252 _tbm_bufmgr_mutex_lock();
1254 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1255 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1257 if (bufmgr->lock_type == LOCK_TRY_NEVER) {
1258 TBM_LOG_E("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
1259 _tbm_bufmgr_mutex_unlock();
1263 if (bo->lock_cnt > 0) {
1264 TBM_TRACE("error: bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
1265 _tbm_bufmgr_mutex_unlock();
1269 TBM_TRACE("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
1270 _tbm_bufmgr_mutex_unlock();
1276 tbm_bo_add_user_data(tbm_bo bo, unsigned long key,
1277 tbm_data_free data_free_func)
1279 tbm_user_data *data;
1281 _tbm_bufmgr_mutex_lock();
1283 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1284 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1286 /* check if the data according to the key exist if so, return false. */
1287 data = user_data_lookup(&bo->user_data_list, key);
1289 TBM_TRACE("warning: user data already exist key(%ld)\n", key);
1290 _tbm_bufmgr_mutex_unlock();
1294 data = user_data_create(key, data_free_func);
1296 TBM_LOG_E("error: bo(%p) key(%lu)\n", bo, key);
1297 _tbm_bufmgr_mutex_unlock();
1301 TBM_TRACE("bo(%p) key(%lu) data(%p)\n", bo, key, data->data);
1303 LIST_ADD(&data->item_link, &bo->user_data_list);
1305 _tbm_bufmgr_mutex_unlock();
1311 tbm_bo_set_user_data(tbm_bo bo, unsigned long key, void *data)
1313 tbm_user_data *old_data;
1315 _tbm_bufmgr_mutex_lock();
1317 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1318 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1320 if (LIST_IS_EMPTY(&bo->user_data_list)) {
1321 TBM_TRACE("error: bo(%p) key(%lu)\n", bo, key);
1322 _tbm_bufmgr_mutex_unlock();
1326 old_data = user_data_lookup(&bo->user_data_list, key);
1328 TBM_TRACE("error: bo(%p) key(%lu)\n", bo, key);
1329 _tbm_bufmgr_mutex_unlock();
1333 if (old_data->data && old_data->free_func)
1334 old_data->free_func(old_data->data);
1335 old_data->data = data;
1337 TBM_TRACE("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1339 _tbm_bufmgr_mutex_unlock();
1345 tbm_bo_get_user_data(tbm_bo bo, unsigned long key, void **data)
1347 tbm_user_data *old_data;
1349 _tbm_bufmgr_mutex_lock();
1351 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1352 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1354 if (!data || LIST_IS_EMPTY(&bo->user_data_list)) {
1355 TBM_TRACE("error: bo(%p) key(%lu)\n", bo, key);
1356 _tbm_bufmgr_mutex_unlock();
1360 old_data = user_data_lookup(&bo->user_data_list, key);
1362 TBM_TRACE("error: bo(%p) key(%lu)\n", bo, key);
1364 _tbm_bufmgr_mutex_unlock();
1368 *data = old_data->data;
1370 TBM_TRACE("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1372 _tbm_bufmgr_mutex_unlock();
1378 tbm_bo_delete_user_data(tbm_bo bo, unsigned long key)
1380 tbm_user_data *old_data;
1382 _tbm_bufmgr_mutex_lock();
1384 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1385 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1387 if (LIST_IS_EMPTY(&bo->user_data_list)) {
1388 TBM_TRACE("error: bo(%p) key(%lu)\n", bo, key);
1389 _tbm_bufmgr_mutex_unlock();
1393 old_data = user_data_lookup(&bo->user_data_list, key);
1395 TBM_TRACE("error: bo(%p) key(%lu)\n", bo, key);
1396 _tbm_bufmgr_mutex_unlock();
1400 TBM_TRACE("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1402 user_data_delete(old_data);
1404 _tbm_bufmgr_mutex_unlock();
1410 tbm_bufmgr_get_capability(tbm_bufmgr bufmgr)
1412 unsigned int capabilities = TBM_BUFMGR_CAPABILITY_NONE;
1414 _tbm_bufmgr_mutex_lock();
1416 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), TBM_BUFMGR_CAPABILITY_NONE);
1417 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, TBM_BUFMGR_CAPABILITY_NONE);
1419 TBM_TRACE("tbm_bufmgr(%p) capability(%u)\n", bufmgr, bufmgr->capabilities);
1421 capabilities = bufmgr->capabilities;
1423 _tbm_bufmgr_mutex_unlock();
1425 return capabilities;
1429 tbm_bo_get_flags(tbm_bo bo)
1433 _tbm_bufmgr_mutex_lock();
1435 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1436 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1440 TBM_TRACE("bo(%p)\n", bo);
1442 _tbm_bufmgr_mutex_unlock();
1447 /* LCOV_EXCL_START */
1449 tbm_get_last_error(void)
1451 return tbm_last_error;
1455 tbm_bufmgr_debug_tbm_info_get(tbm_bufmgr bufmgr, char *str, int *len)
1457 char app_name[255] = {0,}, title[512] = {0,};
1458 tbm_surface_debug_data *debug_old_data = NULL;
1460 pthread_mutex_lock(&gLock);
1462 if (!TBM_BUFMGR_IS_VALID(bufmgr) || (bufmgr != gBufMgr)) {
1463 TBM_LOG_E("invalid bufmgr\n");
1464 pthread_mutex_unlock(&gLock);
1468 TBM_SNPRINTF(str, len, "\n");
1469 _tbm_util_get_appname_from_pid(getpid(), app_name);
1470 _tbm_util_get_appname_brief(app_name);
1471 TBM_SNPRINTF(str, len, "============TBM DEBUG: %s(%d)===========================\n",
1472 app_name, getpid());
1474 snprintf(title, 255, "%s", "no surface refcnt width height bpp size n_b n_p flags format app_name ");
1476 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
1477 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
1478 strncat(title, " ", 3);
1479 strncat(title, debug_old_data->key, strlen(debug_old_data->key) + 1);
1483 TBM_SNPRINTF(str, len, "[tbm_surface information]\n");
1484 TBM_SNPRINTF(str, len, "%s\n", title);
1486 /* show the tbm_surface information in surf_list */
1487 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
1488 tbm_surface_h surf = NULL;
1491 LIST_FOR_EACH_ENTRY(surf, &bufmgr->surf_list, item_link) {
1492 char data[512] = {0,};
1496 pid = _tbm_surface_internal_get_debug_pid(surf);
1498 /* if pid is null, set the self_pid */
1502 memset(app_name, 0x0, 255 * sizeof(char));
1503 _tbm_util_get_appname_from_pid(pid, app_name);
1504 _tbm_util_get_appname_brief(app_name);
1506 snprintf(data, 255, "%-2d %-9p %-4d %-5u %-6u %-3u %-6u %-2d %-2d %-3d %-8s %-15s",
1513 surf->info.size / 1024,
1517 _tbm_surface_internal_format_to_str(surf->info.format) + 11,
1520 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
1521 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
1524 strncat(data, " ", 3);
1526 value = _tbm_surface_internal_get_debug_data(surf, debug_old_data->key);
1528 strncat(data, value, strlen(value) + 1);
1530 strncat(data, "none", 5);
1533 TBM_SNPRINTF(str, len, "%s\n", data);
1535 for (i = 0; i < surf->num_bos; i++) {
1536 TBM_SNPRINTF(str, len, " bo:%-12p %-26d%-10d\n",
1538 surf->bos[i]->ref_cnt,
1539 bufmgr->backend->bo_size(surf->bos[i]) / 1024);
1543 TBM_SNPRINTF(str, len, " no tbm_surfaces.\n");
1544 TBM_SNPRINTF(str, len, "\n");
1546 TBM_SNPRINTF(str, len, "[tbm_bo information]\n");
1547 TBM_SNPRINTF(str, len, "no bo refcnt size lock_cnt map_cnt flags surface\n");
1549 /* show the tbm_bo information in bo_list */
1550 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
1554 LIST_FOR_EACH_ENTRY(bo, &bufmgr->bo_list, item_link) {
1555 TBM_SNPRINTF(str, len, "%-4d%-11p %-4d %-6d %-5d %-4u %-3d %-11p\n",
1559 bufmgr->backend->bo_size(bo) / 1024,
1566 TBM_SNPRINTF(str, len, "no tbm_bos.\n");
1567 TBM_SNPRINTF(str, len, "\n");
1569 TBM_SNPRINTF(str, len, "===============================================================\n");
1571 pthread_mutex_unlock(&gLock);
1575 tbm_bufmgr_debug_show(tbm_bufmgr bufmgr)
1578 int len = sizeof(str);
1579 tbm_bufmgr_debug_tbm_info_get(bufmgr, str, &len);
1580 TBM_DEBUG(" %s", str);
1584 tbm_bufmgr_debug_trace(tbm_bufmgr bufmgr, int onoff)
1586 _tbm_bufmgr_mutex_lock();
1588 TBM_BUFMGR_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
1589 TBM_BUFMGR_RETURN_IF_FAIL(bufmgr == gBufMgr);
1592 TBM_LOG_D("bufmgr=%p onoff=%d\n", bufmgr, onoff);
1596 _tbm_bufmgr_mutex_unlock();
1600 tbm_bufmgr_debug_queue_dump(char *path, int count, int onoff)
1602 pthread_mutex_lock(&gLock);
1605 TBM_LOG_D("count=%d onoff=%d\n", count, onoff);
1607 tbm_surface_internal_dump_end();
1612 TBM_LOG_E("path is null");
1613 pthread_mutex_unlock(&gLock);
1616 TBM_LOG_D("path=%s count=%d onoff=%d\n", path, count, onoff);
1618 if (_tbm_util_get_max_surface_size(&w, &h) == 0) {
1619 TBM_LOG_E("Fail to get tbm_surface size.\n");
1620 pthread_mutex_unlock(&gLock);
1624 tbm_surface_internal_dump_start(path, w, h, count);
1628 pthread_mutex_unlock(&gLock);
1633 tbm_bufmgr_debug_dump_all(char *path)
1635 int w, h, count = 0;
1636 tbm_surface_h surface = NULL;
1638 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
1639 TBM_LOG_D("path=%s\n", path);
1641 pthread_mutex_lock(&gLock);
1643 count = _tbm_util_get_max_surface_size(&w, &h);
1645 TBM_LOG_E("No tbm_surface.\n");
1646 pthread_mutex_unlock(&gLock);
1650 tbm_surface_internal_dump_start(path, w, h, count);
1652 LIST_FOR_EACH_ENTRY(surface, &gBufMgr->surf_list, item_link)
1653 tbm_surface_internal_dump_buffer(surface, "dump_all");
1655 tbm_surface_internal_dump_end();
1657 pthread_mutex_unlock(&gLock);
1662 /* internal function */
1664 _tbm_bufmgr_get_bufmgr(void)
1670 _tbm_bo_set_surface(tbm_bo bo, tbm_surface_h surface)
1672 _tbm_bufmgr_mutex_lock();
1674 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1675 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1677 bo->surface = surface;
1679 _tbm_bufmgr_mutex_unlock();
1685 tbm_bufmgr_bind_native_display(tbm_bufmgr bufmgr, void *NativeDisplay)
1689 _tbm_bufmgr_mutex_lock();
1691 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1693 if (!bufmgr->backend->bufmgr_bind_native_display) {
1694 TBM_TRACE("skip: tbm_bufmgr(%p) NativeDisplay(%p)\n",
1695 bufmgr, NativeDisplay);
1696 _tbm_bufmgr_mutex_unlock();
1700 ret = bufmgr->backend->bufmgr_bind_native_display(bufmgr, NativeDisplay);
1702 TBM_LOG_E("error: tbm_bufmgr(%p) NativeDisplay(%p)\n",
1703 bufmgr, NativeDisplay);
1704 _tbm_bufmgr_mutex_unlock();
1708 TBM_TRACE("tbm_bufmgr(%p) NativeDisplay(%p)\n", bufmgr, NativeDisplay);
1710 _tbm_bufmgr_mutex_unlock();
1714 /* LCOV_EXCL_STOP */
1716 int tbm_bufmgr_get_fd_limit(void)
1720 if (getrlimit(RLIMIT_NOFILE, &lim))
1723 return (int)lim.rlim_cur;