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;
59 static double scale_factor = 0;
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)
80 #define MAX_SIZE_N(dest) (sizeof(dest) - strlen(dest) - 1)
83 #define TBM_BUFMGR_RETURN_IF_FAIL(cond) {\
85 TBM_LOG_E("'%s' failed.\n", #cond);\
86 _tbm_bufmgr_mutex_unlock();\
91 #define TBM_BUFMGR_RETURN_VAL_IF_FAIL(cond, val) {\
93 TBM_LOG_E("'%s' failed.\n", #cond);\
94 _tbm_bufmgr_mutex_unlock();\
106 _tbm_set_last_result(tbm_error_e err)
108 tbm_last_error = err;
111 /* LCOV_EXCL_START */
113 _tbm_bufmgr_mutex_init(void)
115 static bool tbm_bufmgr_mutex_init = false;
117 if (tbm_bufmgr_mutex_init)
120 if (pthread_mutex_init(&tbm_bufmgr_lock, NULL)) {
121 TBM_LOG_E("fail: Cannot pthread_mutex_init for tbm_bufmgr_lock.\n");
125 tbm_bufmgr_mutex_init = true;
131 _tbm_bufmgr_mutex_lock(void)
133 if (!_tbm_bufmgr_mutex_init()) {
134 TBM_LOG_E("fail: _tbm_bufmgr_mutex_init()\n");
138 pthread_mutex_lock(&tbm_bufmgr_lock);
142 _tbm_bufmgr_mutex_unlock(void)
144 pthread_mutex_unlock(&tbm_bufmgr_lock);
148 _tbm_flag_to_str(int f)
150 static char str[255];
152 if (f == TBM_BO_DEFAULT)
153 snprintf(str, 255, "DEFAULT");
157 if (f & TBM_BO_SCANOUT)
158 c += snprintf(&str[c], 255-c, "SCANOUT");
160 if (f & TBM_BO_NONCACHABLE) {
161 if (c >= 0 && c < 255)
162 c += snprintf(&str[c], 255-c, ", ");
164 if (c >= 0 && c < 255)
165 c += snprintf(&str[c], 255-c, "NONCACHABLE,");
169 if (c >= 0 && c < 255)
170 c += snprintf(&str[c], 255-c, ", ");
172 if (c >= 0 && c < 255)
173 c += snprintf(&str[c], 255-c, "WC");
181 _tbm_util_check_bo_cnt(tbm_bufmgr bufmgr)
183 static int last_chk_bo_cnt = 0;
185 if ((bufmgr->bo_cnt >= 500) && ((bufmgr->bo_cnt % 20) == 0) &&
186 (bufmgr->bo_cnt > last_chk_bo_cnt)) {
187 TBM_DEBUG("============TBM BO CNT DEBUG: bo_cnt=%d\n",
190 tbm_bufmgr_debug_show(bufmgr);
192 last_chk_bo_cnt = bufmgr->bo_cnt;
197 _tbm_util_get_max_surface_size(int *w, int *h)
199 tbm_surface_info_s info;
200 tbm_surface_h surface = NULL;
206 if (gBufMgr == NULL || LIST_IS_EMPTY(&gBufMgr->surf_list))
209 LIST_FOR_EACH_ENTRY(surface, &gBufMgr->surf_list, item_link) {
210 if (tbm_surface_get_info(surface, &info) == TBM_SURFACE_ERROR_NONE) {
214 if (*h < info.height)
223 _tbm_util_get_appname_brief(char *brief)
227 char temp[255] = {0,};
228 char *saveptr = NULL;
230 token = strtok_r(brief, delim, &saveptr);
232 while (token != NULL) {
233 memset(temp, 0x00, 255 * sizeof(char));
234 strncpy(temp, token, 254 * sizeof(char));
235 token = strtok_r(NULL, delim, &saveptr);
238 snprintf(brief, sizeof(temp), "%s", temp);
242 _tbm_util_get_appname_from_pid(long pid, char *str)
244 char fn_cmdline[255] = {0, }, cmdline[255];
248 snprintf(fn_cmdline, sizeof(fn_cmdline), "/proc/%ld/cmdline", pid);
250 fp = fopen(fn_cmdline, "r");
252 TBM_LOG_E("cannot file open %s\n", fn_cmdline);
256 if (!fgets(cmdline, 255, fp)) {
257 TBM_LOG_E("fail to get appname for pid(%ld)\n", pid);
264 len = strlen(cmdline);
266 memset(cmdline, 0x00, 255);
270 snprintf(str, sizeof(cmdline), "%s", cmdline);
275 *user_data_lookup(struct list_head *user_data_list, unsigned long key)
277 tbm_user_data *old_data = NULL;
279 if (LIST_IS_EMPTY(user_data_list))
282 LIST_FOR_EACH_ENTRY(old_data, user_data_list, item_link) {
283 if (old_data->key == key)
291 *user_data_create(unsigned long key, tbm_data_free data_free_func)
293 tbm_user_data *user_data;
295 user_data = calloc(1, sizeof(tbm_user_data));
297 /* LCOV_EXCL_START */
298 TBM_LOG_E("fail to allocate an user_date\n");
303 user_data->key = key;
304 user_data->free_func = data_free_func;
310 user_data_delete(tbm_user_data *user_data)
312 if (user_data->data && user_data->free_func)
313 user_data->free_func(user_data->data);
315 LIST_DEL(&user_data->item_link);
321 _bo_lock(tbm_bo bo, int device, int opt)
323 tbm_bufmgr bufmgr = bo->bufmgr;
326 if (bufmgr->backend->bo_lock)
327 ret = bufmgr->backend->bo_lock(bo, device, opt);
333 _bo_unlock(tbm_bo bo)
335 tbm_bufmgr bufmgr = bo->bufmgr;
337 if (bufmgr->backend->bo_unlock)
338 bufmgr->backend->bo_unlock(bo);
342 _tbm_bo_lock(tbm_bo bo, int device, int opt)
352 /* do not try to lock the bo */
353 if (bufmgr->lock_type == LOCK_TRY_NEVER)
356 if (bo->lock_cnt < 0) {
357 TBM_LOG_E("error bo:%p LOCK_CNT=%d\n",
364 switch (bufmgr->lock_type) {
366 if (bo->lock_cnt == 0) {
367 _tbm_bufmgr_mutex_unlock();
368 ret = _bo_lock(bo, device, opt);
369 _tbm_bufmgr_mutex_lock();
375 case LOCK_TRY_ALWAYS:
376 _tbm_bufmgr_mutex_unlock();
377 ret = _bo_lock(bo, device, opt);
378 _tbm_bufmgr_mutex_lock();
383 TBM_LOG_E("error bo:%p lock_type[%d] is wrong.\n",
384 bo, bufmgr->lock_type);
389 TBM_DBG_LOCK(">> LOCK bo:%p(%d->%d)\n", bo, old, bo->lock_cnt);
395 _tbm_bo_unlock(tbm_bo bo)
405 /* do not try to unlock the bo */
406 if (bufmgr->lock_type == LOCK_TRY_NEVER)
411 switch (bufmgr->lock_type) {
413 if (bo->lock_cnt > 0) {
415 if (bo->lock_cnt == 0)
419 case LOCK_TRY_ALWAYS:
420 if (bo->lock_cnt > 0) {
426 TBM_LOG_E("error bo:%p lock_type[%d] is wrong.\n",
427 bo, bufmgr->lock_type);
431 if (bo->lock_cnt < 0)
434 TBM_DBG_LOCK(">> UNLOCK bo:%p(%d->%d)\n", bo, old, bo->lock_cnt);
438 _tbm_bo_is_valid(tbm_bo bo)
440 tbm_bo old_data = NULL;
442 if (bo == NULL || gBufMgr == NULL) {
443 TBM_LOG_E("error: bo is NULL or tbm_bufmgr was deinited\n");
447 if (LIST_IS_EMPTY(&gBufMgr->bo_list)) {
448 TBM_LOG_E("error: gBufMgr->bo_list is EMPTY.\n");
452 LIST_FOR_EACH_ENTRY(old_data, &gBufMgr->bo_list, item_link) {
457 TBM_LOG_E("error: No valid bo(%p).\n", bo);
463 _tbm_bo_free(tbm_bo bo)
465 tbm_bufmgr bufmgr = bo->bufmgr;
467 /* destory the user_data_list */
468 if (!LIST_IS_EMPTY(&bo->user_data_list)) {
469 tbm_user_data *old_data = NULL, *tmp;
471 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp,
472 &bo->user_data_list, item_link) {
473 TBM_DBG("free user_data\n");
474 user_data_delete(old_data);
478 while (bo->lock_cnt > 0) {
479 TBM_LOG_E("error lock_cnt:%d\n", bo->lock_cnt);
484 /* call the bo_free */
485 bufmgr->backend->bo_free(bo);
488 LIST_DEL(&bo->item_link);
494 /* LCOV_EXCL_START */
496 _check_version(TBMModuleVersionInfo *data)
501 abimaj = GET_ABI_MAJOR(data->abiversion);
502 abimin = GET_ABI_MINOR(data->abiversion);
504 TBM_DBG("TBM module %s: vendor=\"%s\" ABI=%d,%d\n",
505 data->modname ? data->modname : "UNKNOWN!",
506 data->vendor ? data->vendor : "UNKNOWN!", abimaj, abimin);
508 vermaj = GET_ABI_MAJOR(TBM_ABI_VERSION);
509 vermin = GET_ABI_MINOR(TBM_ABI_VERSION);
511 TBM_DBG("TBM ABI version %d.%d\n",
514 if (abimaj != vermaj) {
515 TBM_LOG_E("TBM module ABI major ver(%d) doesn't match the TBM's ver(%d)\n",
518 } else if (abimin > vermin) {
519 TBM_LOG_E("TBM module ABI minor ver(%d) is newer than the TBM's ver(%d)\n",
528 _tbm_bufmgr_load_module(tbm_bufmgr bufmgr, int fd, const char *file)
530 char path[PATH_MAX] = {0, };
531 TBMModuleVersionInfo *vers;
532 TBMModuleData *initdata;
536 snprintf(path, sizeof(path), BUFMGR_MODULE_DIR "/%s", file);
538 module_data = dlopen(path, RTLD_LAZY);
540 TBM_LOG_E("failed to load module: %s(%s)\n", dlerror(), file);
544 initdata = dlsym(module_data, "tbmModuleData");
546 TBM_LOG_E("Error: module does not have data object.\n");
550 vers = initdata->vers;
552 TBM_LOG_E("Error: module does not supply version information.\n");
556 init = initdata->init;
558 TBM_LOG_E("Error: module does not supply init symbol.\n");
562 if (!_check_version(vers)) {
563 TBM_LOG_E("Fail to check version.\n");
567 if (!init(bufmgr, fd)) {
568 TBM_LOG_E("Fail to init module(%s)\n", file);
572 if (!bufmgr->backend || !bufmgr->backend->priv) {
573 TBM_LOG_E("Error: module(%s) wrong operation. Check backend or backend's priv.\n", file);
577 bufmgr->module_data = module_data;
579 TBM_DBG("Success to load module(%s)\n", file);
584 dlclose(module_data);
589 _tbm_load_module(tbm_bufmgr bufmgr, int fd)
591 struct dirent **namelist;
594 /* load bufmgr priv from default lib */
595 if (_tbm_bufmgr_load_module(bufmgr, fd, DEFAULT_LIB))
598 /* load bufmgr priv from configured path */
599 n = scandir(BUFMGR_MODULE_DIR, &namelist, 0, alphasort);
601 TBM_LOG_E("no files : %s\n", BUFMGR_MODULE_DIR);
606 if (!ret && strstr(namelist[n]->d_name, PREFIX_LIB)) {
607 const char *p = strstr(namelist[n]->d_name, SUFFIX_LIB);
609 if (p && !strcmp(p, SUFFIX_LIB))
610 ret = _tbm_bufmgr_load_module(bufmgr, fd,
611 namelist[n]->d_name);
624 _tbm_bufmgr_init(int fd, int server)
626 #ifdef TBM_BUFMGR_INIT_TIME
627 struct timeval start_tv, end_tv;
631 #ifdef TBM_BUFMGR_INIT_TIME
632 /* get the start tv */
633 gettimeofday(&start_tv, NULL);
636 /* LCOV_EXCL_START */
638 env = getenv("TBM_DLOG");
641 TBM_LOG_D("TBM_DLOG=%s\n", env);
647 env = getenv("TBM_DEBUG");
650 TBM_LOG_D("TBM_DEBUG=%s\n", env);
656 env = getenv("TBM_TRACE");
659 TBM_LOG_D("TBM_TRACE=%s\n", env);
664 pthread_mutex_lock(&gLock);
667 TBM_LOG_W("!!!!!WARNING:: The tbm_bufmgr_init DOSE NOT use argument fd ANYMORE.\n");
668 TBM_LOG_W("!!!!!WARNING:: IT WILL BE CHANGED like tbm_bufmgr_init(int fd) --> tbm_bufmgr_init(void).\n");
672 /* initialize buffer manager */
674 gBufMgr->ref_count++;
675 TBM_TRACE("reuse tbm_bufmgr(%p) ref_count(%d) fd(%d)\n", gBufMgr, gBufMgr->ref_count, gBufMgr->fd);
676 pthread_mutex_unlock(&gLock);
680 TBM_DBG("bufmgr init\n");
682 /* allocate bufmgr */
683 gBufMgr = calloc(1, sizeof(struct _tbm_bufmgr));
685 _tbm_set_last_result(TBM_BO_ERROR_HEAP_ALLOC_FAILED);
686 TBM_TRACE("error: fail to alloc bufmgr fd(%d)\n", fd);
687 pthread_mutex_unlock(&gLock);
693 /* load bufmgr priv from env */
694 if (!_tbm_load_module(gBufMgr, gBufMgr->fd)) {
695 _tbm_set_last_result(TBM_BO_ERROR_LOAD_MODULE_FAILED);
696 TBM_LOG_E("error : Fail to load bufmgr backend\n");
699 pthread_mutex_unlock(&gLock);
705 /* log for tbm backend_flag */
706 TBM_DBG("backend flag:%x:", gBufMgr->backend->flags);
709 gBufMgr->ref_count = 1;
711 TBM_DBG("create tizen bufmgr:%p ref_count:%d\n",
712 gBufMgr, gBufMgr->ref_count);
714 /* setup the lock_type */
715 env = getenv("BUFMGR_LOCK_TYPE");
716 if (env && !strcmp(env, "always"))
717 gBufMgr->lock_type = LOCK_TRY_ALWAYS;
718 else if (env && !strcmp(env, "none"))
719 gBufMgr->lock_type = LOCK_TRY_NEVER;
720 else if (env && !strcmp(env, "once"))
721 gBufMgr->lock_type = LOCK_TRY_ONCE;
723 gBufMgr->lock_type = LOCK_TRY_ALWAYS;
725 TBM_DBG("BUFMGR_LOCK_TYPE=%s\n", env ? env : "default:once");
727 TBM_TRACE("create tbm_bufmgr(%p) ref_count(%d) fd(%d)\n", gBufMgr, gBufMgr->ref_count, fd);
729 /* intialize bo_list */
730 LIST_INITHEAD(&gBufMgr->bo_list);
732 /* intialize surf_list */
733 LIST_INITHEAD(&gBufMgr->surf_list);
735 /* intialize surf_queue_list */
736 LIST_INITHEAD(&gBufMgr->surf_queue_list);
738 /* intialize debug_key_list */
739 LIST_INITHEAD(&gBufMgr->debug_key_list);
741 #ifdef TBM_BUFMGR_INIT_TIME
743 gettimeofday(&end_tv, NULL);
744 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)));
747 pthread_mutex_unlock(&gLock);
753 tbm_bufmgr_init(int fd)
757 bufmgr = _tbm_bufmgr_init(fd, 0);
763 tbm_bufmgr_deinit(tbm_bufmgr bufmgr)
765 TBM_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
767 _tbm_bufmgr_mutex_lock();
768 pthread_mutex_lock(&gLock);
771 TBM_LOG_E("gBufmgr already destroy: bufmgr:%p\n", bufmgr);
772 pthread_mutex_unlock(&gLock);
773 _tbm_bufmgr_mutex_unlock();
778 if (bufmgr->ref_count > 0) {
779 TBM_TRACE("reduce a ref_count(%d) of tbm_bufmgr(%p)\n", bufmgr->ref_count, bufmgr);
780 pthread_mutex_unlock(&gLock);
781 _tbm_bufmgr_mutex_unlock();
785 /* destroy bo_list */
786 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
787 tbm_bo bo = NULL, tmp;
789 LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &bufmgr->bo_list, item_link) {
790 TBM_LOG_E("Un-freed bo(%p, ref:%d)\n", bo, bo->ref_cnt);
793 LIST_DELINIT(&bufmgr->bo_list);
796 /* destroy surf_list */
797 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
798 tbm_surface_h surf = NULL, tmp;
800 LIST_FOR_EACH_ENTRY_SAFE(surf, tmp, &bufmgr->surf_list, item_link) {
801 TBM_LOG_E("Un-freed surf(%p, ref:%d)\n", surf, surf->refcnt);
802 tbm_surface_destroy(surf);
804 LIST_DELINIT(&bufmgr->surf_list);
807 /* destroy bufmgr priv */
808 bufmgr->backend->bufmgr_deinit(bufmgr->backend->priv);
809 bufmgr->backend->priv = NULL;
810 tbm_backend_free(bufmgr->backend);
811 bufmgr->backend = NULL;
813 TBM_TRACE("destroy tbm_bufmgr(%p)\n", bufmgr);
815 dlclose(bufmgr->module_data);
823 pthread_mutex_unlock(&gLock);
824 _tbm_bufmgr_mutex_unlock();
828 tbm_bo_size(tbm_bo bo)
830 tbm_bufmgr bufmgr = gBufMgr;
833 _tbm_bufmgr_mutex_lock();
835 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
836 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
838 size = bufmgr->backend->bo_size(bo);
840 TBM_TRACE("bo(%p) size(%d)\n", bo, size);
842 _tbm_bufmgr_mutex_unlock();
848 tbm_bo_ref(tbm_bo bo)
850 _tbm_bufmgr_mutex_lock();
852 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), NULL);
853 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), NULL);
857 TBM_TRACE("bo(%p) ref_cnt(%d)\n", bo, bo->ref_cnt);
859 _tbm_bufmgr_mutex_unlock();
865 tbm_bo_unref(tbm_bo bo)
867 _tbm_bufmgr_mutex_lock();
869 TBM_BUFMGR_RETURN_IF_FAIL(gBufMgr);
870 TBM_BUFMGR_RETURN_IF_FAIL(_tbm_bo_is_valid(bo));
872 TBM_TRACE("bo(%p) ref_cnt(%d)\n", bo, bo->ref_cnt - 1);
874 if (bo->ref_cnt <= 0) {
875 _tbm_bufmgr_mutex_unlock();
880 if (bo->ref_cnt == 0)
883 _tbm_bufmgr_mutex_unlock();
887 tbm_bo_alloc(tbm_bufmgr bufmgr, int size, int flags)
892 _tbm_bufmgr_mutex_lock();
894 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
895 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, NULL);
896 TBM_BUFMGR_RETURN_VAL_IF_FAIL(size > 0, NULL);
898 bo = calloc(1, sizeof(struct _tbm_bo));
900 /* LCOV_EXCL_START */
901 TBM_LOG_E("error: fail to create of tbm_bo size(%d) flag(%s)\n",
902 size, _tbm_flag_to_str(flags));
903 _tbm_set_last_result(TBM_BO_ERROR_HEAP_ALLOC_FAILED);
904 _tbm_bufmgr_mutex_unlock();
909 _tbm_util_check_bo_cnt(bufmgr);
913 bo_priv = bufmgr->backend->bo_alloc(bo, size, flags);
915 /* LCOV_EXCL_START */
916 TBM_LOG_E("error: fail to create of tbm_bo size(%d) flag(%s)\n",
917 size, _tbm_flag_to_str(flags));
918 _tbm_set_last_result(TBM_BO_ERROR_BO_ALLOC_FAILED);
920 _tbm_bufmgr_mutex_unlock();
931 TBM_TRACE("bo(%p) size(%d) refcnt(%d), flag(%s)\n", bo, size, bo->ref_cnt,
932 _tbm_flag_to_str(bo->flags));
934 LIST_INITHEAD(&bo->user_data_list);
936 LIST_ADD(&bo->item_link, &bufmgr->bo_list);
938 _tbm_bufmgr_mutex_unlock();
944 tbm_bo_import(tbm_bufmgr bufmgr, unsigned int key)
949 _tbm_bufmgr_mutex_lock();
951 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
952 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, NULL);
954 if (!bufmgr->backend->bo_import) {
955 /* LCOV_EXCL_START */
956 _tbm_bufmgr_mutex_unlock();
961 _tbm_util_check_bo_cnt(bufmgr);
963 bo = calloc(1, sizeof(struct _tbm_bo));
965 /* LCOV_EXCL_START */
966 TBM_LOG_E("error: fail to import of tbm_bo by key(%d)\n", key);
967 _tbm_bufmgr_mutex_unlock();
974 bo_priv = bufmgr->backend->bo_import(bo, key);
976 /* LCOV_EXCL_START */
977 TBM_LOG_E("error: fail to import of tbm_bo by key(%d)\n", key);
978 _tbm_set_last_result(TBM_BO_ERROR_IMPORT_FAILED);
980 _tbm_bufmgr_mutex_unlock();
985 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
988 LIST_FOR_EACH_ENTRY(bo2, &bufmgr->bo_list, item_link) {
989 if (bo2->priv == bo_priv) {
990 TBM_TRACE("find bo(%p) ref(%d) key(%d) flag(%s) in list\n",
991 bo2, bo2->ref_cnt, key,
992 _tbm_flag_to_str(bo2->flags));
995 _tbm_bufmgr_mutex_unlock();
1006 if (bufmgr->backend->bo_get_flags)
1007 bo->flags = bufmgr->backend->bo_get_flags(bo);
1009 bo->flags = TBM_BO_DEFAULT;
1011 TBM_TRACE("import new bo(%p) ref(%d) key(%d) flag(%s) in list\n",
1012 bo, bo->ref_cnt, key, _tbm_flag_to_str(bo->flags));
1014 LIST_INITHEAD(&bo->user_data_list);
1016 LIST_ADD(&bo->item_link, &bufmgr->bo_list);
1018 _tbm_bufmgr_mutex_unlock();
1024 tbm_bo_import_fd(tbm_bufmgr bufmgr, tbm_fd fd)
1029 _tbm_bufmgr_mutex_lock();
1031 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
1032 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, NULL);
1034 if (!bufmgr->backend->bo_import_fd) {
1035 /* LCOV_EXCL_START */
1036 _tbm_bufmgr_mutex_unlock();
1038 /* LCOV_EXCL_STOP */
1041 _tbm_util_check_bo_cnt(bufmgr);
1043 bo = calloc(1, sizeof(struct _tbm_bo));
1045 /* LCOV_EXCL_START */
1046 TBM_LOG_E("error: fail to import tbm_bo by tbm_fd(%d)\n", fd);
1047 _tbm_bufmgr_mutex_unlock();
1049 /* LCOV_EXCL_STOP */
1052 bo->bufmgr = bufmgr;
1054 bo_priv = bufmgr->backend->bo_import_fd(bo, fd);
1056 /* LCOV_EXCL_START */
1057 TBM_LOG_E("error: fail to import tbm_bo by tbm_fd(%d)\n", fd);
1058 _tbm_set_last_result(TBM_BO_ERROR_IMPORT_FD_FAILED);
1060 _tbm_bufmgr_mutex_unlock();
1062 /* LCOV_EXCL_STOP */
1065 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
1068 LIST_FOR_EACH_ENTRY(bo2, &bufmgr->bo_list, item_link) {
1069 if (bo2->priv == bo_priv) {
1070 TBM_TRACE("find bo(%p) ref(%d) fd(%d) flag(%s) in list\n",
1071 bo2, bo2->ref_cnt, fd,
1072 _tbm_flag_to_str(bo2->flags));
1075 _tbm_bufmgr_mutex_unlock();
1086 if (bufmgr->backend->bo_get_flags)
1087 bo->flags = bufmgr->backend->bo_get_flags(bo);
1089 bo->flags = TBM_BO_DEFAULT;
1091 TBM_TRACE("import bo(%p) ref(%d) fd(%d) flag(%s)\n",
1092 bo, bo->ref_cnt, fd, _tbm_flag_to_str(bo->flags));
1094 LIST_INITHEAD(&bo->user_data_list);
1096 LIST_ADD(&bo->item_link, &bufmgr->bo_list);
1098 _tbm_bufmgr_mutex_unlock();
1104 tbm_bo_export(tbm_bo bo)
1106 tbm_bufmgr bufmgr = gBufMgr;
1109 _tbm_bufmgr_mutex_lock();
1111 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1112 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1114 if (!bufmgr->backend->bo_export) {
1115 /* LCOV_EXCL_START */
1116 _tbm_bufmgr_mutex_unlock();
1118 /* LCOV_EXCL_STOP */
1121 ret = bufmgr->backend->bo_export(bo);
1123 /* LCOV_EXCL_START */
1124 _tbm_set_last_result(TBM_BO_ERROR_EXPORT_FAILED);
1125 TBM_LOG_E("error: bo(%p) tbm_key(%d)\n", bo, ret);
1126 _tbm_bufmgr_mutex_unlock();
1128 /* LCOV_EXCL_STOP */
1131 TBM_TRACE("bo(%p) tbm_key(%u)\n", bo, ret);
1133 _tbm_bufmgr_mutex_unlock();
1139 tbm_bo_export_fd(tbm_bo bo)
1141 tbm_bufmgr bufmgr = gBufMgr;
1144 _tbm_bufmgr_mutex_lock();
1146 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), -1);
1147 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), -1);
1149 if (!bufmgr->backend->bo_export_fd) {
1150 /* LCOV_EXCL_START */
1151 _tbm_bufmgr_mutex_unlock();
1153 /* LCOV_EXCL_STOP */
1156 ret = bufmgr->backend->bo_export_fd(bo);
1158 /* LCOV_EXCL_START */
1159 _tbm_set_last_result(TBM_BO_ERROR_EXPORT_FD_FAILED);
1160 TBM_LOG_E("error: bo(%p) tbm_fd(%d)\n", bo, ret);
1161 _tbm_bufmgr_mutex_unlock();
1163 /* LCOV_EXCL_STOP */
1166 TBM_TRACE("bo(%p) tbm_fd(%d)\n", bo, ret);
1168 _tbm_bufmgr_mutex_unlock();
1174 tbm_bo_get_handle(tbm_bo bo, int device)
1176 tbm_bufmgr bufmgr = gBufMgr;
1177 tbm_bo_handle bo_handle;
1179 _tbm_bufmgr_mutex_lock();
1181 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), (tbm_bo_handle) NULL);
1182 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) NULL);
1184 bo_handle = bufmgr->backend->bo_get_handle(bo, device);
1185 if (bo_handle.ptr == NULL) {
1186 /* LCOV_EXCL_START */
1187 _tbm_set_last_result(TBM_BO_ERROR_GET_HANDLE_FAILED);
1188 TBM_LOG_E("error: bo(%p) bo_handle(%p)\n", bo, bo_handle.ptr);
1189 _tbm_bufmgr_mutex_unlock();
1190 return (tbm_bo_handle) NULL;
1191 /* LCOV_EXCL_STOP */
1194 TBM_TRACE("bo(%p) bo_handle(%p)\n", bo, bo_handle.ptr);
1196 _tbm_bufmgr_mutex_unlock();
1202 tbm_bo_map(tbm_bo bo, int device, int opt)
1204 tbm_bufmgr bufmgr = gBufMgr;
1205 tbm_bo_handle bo_handle;
1207 _tbm_bufmgr_mutex_lock();
1209 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), (tbm_bo_handle) NULL);
1210 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) NULL);
1212 if (!_tbm_bo_lock(bo, device, opt)) {
1213 _tbm_set_last_result(TBM_BO_ERROR_LOCK_FAILED);
1214 TBM_LOG_E("error: fail to lock bo:%p)\n", bo);
1215 _tbm_bufmgr_mutex_unlock();
1216 return (tbm_bo_handle) NULL;
1219 bo_handle = bufmgr->backend->bo_map(bo, device, opt);
1220 if (bo_handle.ptr == NULL) {
1221 /* LCOV_EXCL_START */
1222 _tbm_set_last_result(TBM_BO_ERROR_MAP_FAILED);
1223 TBM_LOG_E("error: fail to map bo:%p\n", bo);
1225 _tbm_bufmgr_mutex_unlock();
1226 return (tbm_bo_handle) NULL;
1227 /* LCOV_EXCL_STOP */
1230 /* increase the map_count */
1233 TBM_TRACE("bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
1235 _tbm_bufmgr_mutex_unlock();
1241 tbm_bo_unmap(tbm_bo bo)
1243 tbm_bufmgr bufmgr = gBufMgr;
1246 _tbm_bufmgr_mutex_lock();
1248 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1249 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1250 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bo->map_cnt > 0, 0);
1252 ret = bufmgr->backend->bo_unmap(bo);
1254 /* LCOV_EXCL_START */
1255 TBM_LOG_E("error: bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
1256 _tbm_set_last_result(TBM_BO_ERROR_UNMAP_FAILED);
1257 _tbm_bufmgr_mutex_unlock();
1259 /* LCOV_EXCL_STOP */
1262 /* decrease the map_count */
1265 TBM_TRACE("bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
1269 _tbm_bufmgr_mutex_unlock();
1275 tbm_bo_swap(tbm_bo bo1, tbm_bo bo2)
1277 tbm_bufmgr bufmgr = gBufMgr;
1280 _tbm_bufmgr_mutex_lock();
1282 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1283 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo1), 0);
1284 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo2), 0);
1286 TBM_TRACE("before: bo1(%p) bo2(%p)\n", bo1, bo2);
1288 if (bufmgr->backend->bo_size(bo1) != bufmgr->backend->bo_size(bo2)) {
1289 _tbm_set_last_result(TBM_BO_ERROR_SWAP_FAILED);
1290 TBM_LOG_E("error: bo1(%p) bo2(%p)\n", bo1, bo2);
1291 _tbm_bufmgr_mutex_unlock();
1295 TBM_TRACE("after: bo1(%p) bo2(%p)\n", bo1, bo2);
1298 bo1->priv = bo2->priv;
1301 _tbm_bufmgr_mutex_unlock();
1307 tbm_bo_locked(tbm_bo bo)
1309 tbm_bufmgr bufmgr = gBufMgr;
1311 _tbm_bufmgr_mutex_lock();
1313 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1314 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1316 if (bufmgr->lock_type == LOCK_TRY_NEVER) {
1317 TBM_LOG_E("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
1318 _tbm_bufmgr_mutex_unlock();
1322 if (bo->lock_cnt > 0) {
1323 TBM_TRACE("error: bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
1324 _tbm_bufmgr_mutex_unlock();
1328 TBM_TRACE("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
1329 _tbm_bufmgr_mutex_unlock();
1335 tbm_bo_add_user_data(tbm_bo bo, unsigned long key,
1336 tbm_data_free data_free_func)
1338 tbm_user_data *data;
1340 _tbm_bufmgr_mutex_lock();
1342 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1343 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1345 /* check if the data according to the key exist if so, return false. */
1346 data = user_data_lookup(&bo->user_data_list, key);
1348 TBM_TRACE("warning: user data already exist key(%ld)\n", key);
1349 _tbm_bufmgr_mutex_unlock();
1353 data = user_data_create(key, data_free_func);
1355 TBM_LOG_E("error: bo(%p) key(%lu)\n", bo, key);
1356 _tbm_bufmgr_mutex_unlock();
1360 TBM_TRACE("bo(%p) key(%lu) data(%p)\n", bo, key, data->data);
1362 LIST_ADD(&data->item_link, &bo->user_data_list);
1364 _tbm_bufmgr_mutex_unlock();
1370 tbm_bo_set_user_data(tbm_bo bo, unsigned long key, void *data)
1372 tbm_user_data *old_data;
1374 _tbm_bufmgr_mutex_lock();
1376 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1377 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1379 if (LIST_IS_EMPTY(&bo->user_data_list)) {
1380 TBM_TRACE("error: bo(%p) key(%lu)\n", bo, key);
1381 _tbm_bufmgr_mutex_unlock();
1385 old_data = user_data_lookup(&bo->user_data_list, key);
1387 TBM_TRACE("error: bo(%p) key(%lu)\n", bo, key);
1388 _tbm_bufmgr_mutex_unlock();
1392 if (old_data->data && old_data->free_func)
1393 old_data->free_func(old_data->data);
1394 old_data->data = data;
1396 TBM_TRACE("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1398 _tbm_bufmgr_mutex_unlock();
1404 tbm_bo_get_user_data(tbm_bo bo, unsigned long key, void **data)
1406 tbm_user_data *old_data;
1408 _tbm_bufmgr_mutex_lock();
1410 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1411 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1413 if (!data || LIST_IS_EMPTY(&bo->user_data_list)) {
1414 TBM_TRACE("error: bo(%p) key(%lu)\n", bo, key);
1415 _tbm_bufmgr_mutex_unlock();
1419 old_data = user_data_lookup(&bo->user_data_list, key);
1421 TBM_TRACE("error: bo(%p) key(%lu)\n", bo, key);
1423 _tbm_bufmgr_mutex_unlock();
1427 *data = old_data->data;
1429 TBM_TRACE("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1431 _tbm_bufmgr_mutex_unlock();
1437 tbm_bo_delete_user_data(tbm_bo bo, unsigned long key)
1439 tbm_user_data *old_data;
1441 _tbm_bufmgr_mutex_lock();
1443 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1444 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1446 if (LIST_IS_EMPTY(&bo->user_data_list)) {
1447 TBM_TRACE("error: bo(%p) key(%lu)\n", bo, key);
1448 _tbm_bufmgr_mutex_unlock();
1452 old_data = user_data_lookup(&bo->user_data_list, key);
1454 TBM_TRACE("error: bo(%p) key(%lu)\n", bo, key);
1455 _tbm_bufmgr_mutex_unlock();
1459 TBM_TRACE("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1461 user_data_delete(old_data);
1463 _tbm_bufmgr_mutex_unlock();
1469 tbm_bufmgr_get_capability(tbm_bufmgr bufmgr)
1471 unsigned int capabilities = TBM_BUFMGR_CAPABILITY_NONE;
1473 _tbm_bufmgr_mutex_lock();
1475 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), TBM_BUFMGR_CAPABILITY_NONE);
1476 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, TBM_BUFMGR_CAPABILITY_NONE);
1478 TBM_TRACE("tbm_bufmgr(%p) capability(%u)\n", bufmgr, bufmgr->capabilities);
1480 capabilities = bufmgr->capabilities;
1482 _tbm_bufmgr_mutex_unlock();
1484 return capabilities;
1488 tbm_bo_get_flags(tbm_bo bo)
1492 _tbm_bufmgr_mutex_lock();
1494 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1495 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1499 TBM_TRACE("bo(%p)\n", bo);
1501 _tbm_bufmgr_mutex_unlock();
1506 /* LCOV_EXCL_START */
1508 tbm_get_last_error(void)
1510 return tbm_last_error;
1514 tbm_bufmgr_debug_tbm_info_get(tbm_bufmgr bufmgr)
1516 char app_name[255] = {0,}, title[512] = {0,};
1517 tbm_surface_debug_data *debug_old_data = NULL;
1522 pthread_mutex_lock(&gLock);
1524 if (!TBM_BUFMGR_IS_VALID(bufmgr) || (bufmgr != gBufMgr)) {
1525 TBM_LOG_E("invalid bufmgr\n");
1526 pthread_mutex_unlock(&gLock);
1532 TBM_LOG_E("Fail to allocate the string.\n");
1533 pthread_mutex_unlock(&gLock);
1537 TBM_SNRPRINTF(str, len, c, "\n");
1538 _tbm_util_get_appname_from_pid(getpid(), app_name);
1539 _tbm_util_get_appname_brief(app_name);
1540 TBM_SNRPRINTF(str, len, c, "============TBM DEBUG: %s(%d)===========================\n",
1541 app_name, getpid());
1543 snprintf(title, 255, "%s", "no surface refcnt width height bpp size n_b n_p flags format app_name ");
1545 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
1546 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
1547 strncat(title, " ", MAX_SIZE_N(title));
1548 strncat(title, debug_old_data->key, MAX_SIZE_N(title));
1552 TBM_SNRPRINTF(str, len, c, "[tbm_surface information]\n");
1553 TBM_SNRPRINTF(str, len, c, "%s\n", title);
1555 /* show the tbm_surface information in surf_list */
1556 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
1557 tbm_surface_h surf = NULL;
1560 LIST_FOR_EACH_ENTRY(surf, &bufmgr->surf_list, item_link) {
1561 char data[512] = {0,};
1565 pid = _tbm_surface_internal_get_debug_pid(surf);
1567 /* if pid is null, set the self_pid */
1571 memset(app_name, 0x0, 255 * sizeof(char));
1572 _tbm_util_get_appname_from_pid(pid, app_name);
1573 _tbm_util_get_appname_brief(app_name);
1575 snprintf(data, 255, "%-2d %-9p %-4d %-5u %-6u %-3u %-6u %-2d %-2d %-3d %-8s %-15s",
1582 surf->info.size / 1024,
1586 _tbm_surface_internal_format_to_str(surf->info.format) + 11,
1589 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
1590 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
1593 strncat(data, " ", MAX_SIZE_N(title));
1595 value = _tbm_surface_internal_get_debug_data(surf, debug_old_data->key);
1597 strncat(data, value, MAX_SIZE_N(title));
1599 strncat(data, "none", MAX_SIZE_N(title));
1602 TBM_SNRPRINTF(str, len, c, "%s\n", data);
1604 for (i = 0; i < surf->num_bos; i++) {
1605 TBM_SNRPRINTF(str, len, c, " bo:%-12p %-26d%-10d\n",
1607 surf->bos[i]->ref_cnt,
1608 bufmgr->backend->bo_size(surf->bos[i]) / 1024);
1612 TBM_SNRPRINTF(str, len, c, " no tbm_surfaces.\n");
1613 TBM_SNRPRINTF(str, len, c, "\n");
1615 TBM_SNRPRINTF(str, len, c, "[tbm_bo information]\n");
1616 TBM_SNRPRINTF(str, len, c, "no bo refcnt size lock_cnt map_cnt flags surface name\n");
1618 /* show the tbm_bo information in bo_list */
1619 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
1623 LIST_FOR_EACH_ENTRY(bo, &bufmgr->bo_list, item_link) {
1624 TBM_SNRPRINTF(str, len, c, "%-4d%-11p %-4d %-6d %-5d %-4u %-3d %-11p %-4d\n",
1628 bufmgr->backend->bo_size(bo) / 1024,
1633 bufmgr->backend->bo_export(bo));
1636 TBM_SNRPRINTF(str, len, c, "no tbm_bos.\n");
1637 TBM_SNRPRINTF(str, len, c, "\n");
1639 TBM_SNRPRINTF(str, len, c, "===============================================================\n");
1641 pthread_mutex_unlock(&gLock);
1647 tbm_bufmgr_debug_show(tbm_bufmgr bufmgr)
1650 str = tbm_bufmgr_debug_tbm_info_get(bufmgr);
1652 TBM_DEBUG(" %s", str);
1658 tbm_bufmgr_debug_trace(tbm_bufmgr bufmgr, int onoff)
1660 _tbm_bufmgr_mutex_lock();
1662 TBM_BUFMGR_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
1663 TBM_BUFMGR_RETURN_IF_FAIL(bufmgr == gBufMgr);
1666 TBM_LOG_D("bufmgr=%p onoff=%d\n", bufmgr, onoff);
1670 _tbm_bufmgr_mutex_unlock();
1674 tbm_bufmgr_debug_dump_set_scale(double scale)
1676 pthread_mutex_lock(&gLock);
1677 scale_factor = scale;
1678 pthread_mutex_unlock(&gLock);
1682 tbm_bufmgr_debug_get_ref_count(void)
1684 return (gBufMgr) ? gBufMgr->ref_count : 0;
1688 tbm_bufmgr_debug_queue_dump(char *path, int count, int onoff)
1690 pthread_mutex_lock(&gLock);
1693 TBM_LOG_D("count=%d onoff=%d\n", count, onoff);
1695 tbm_surface_internal_dump_end();
1700 TBM_LOG_E("path is null");
1701 pthread_mutex_unlock(&gLock);
1704 TBM_LOG_D("path=%s count=%d onoff=%d\n", path, count, onoff);
1706 if (_tbm_util_get_max_surface_size(&w, &h) == 0) {
1707 TBM_LOG_E("Fail to get tbm_surface size.\n");
1708 pthread_mutex_unlock(&gLock);
1712 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
1718 pthread_mutex_unlock(&gLock);
1723 tbm_bufmgr_debug_dump_all(char *path)
1725 int w, h, count = 0;
1726 tbm_surface_h surface = NULL;
1728 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
1729 TBM_LOG_D("path=%s\n", path);
1731 pthread_mutex_lock(&gLock);
1733 count = _tbm_util_get_max_surface_size(&w, &h);
1735 TBM_LOG_E("No tbm_surface.\n");
1736 pthread_mutex_unlock(&gLock);
1740 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
1743 LIST_FOR_EACH_ENTRY(surface, &gBufMgr->surf_list, item_link)
1744 tbm_surface_internal_dump_buffer(surface, "dump_all");
1746 tbm_surface_internal_dump_end();
1748 pthread_mutex_unlock(&gLock);
1753 /* internal function */
1755 _tbm_bufmgr_get_bufmgr(void)
1761 _tbm_bo_set_surface(tbm_bo bo, tbm_surface_h surface)
1763 _tbm_bufmgr_mutex_lock();
1765 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1766 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1768 bo->surface = surface;
1770 _tbm_bufmgr_mutex_unlock();
1776 tbm_bufmgr_bind_native_display(tbm_bufmgr bufmgr, void *native_display)
1780 _tbm_bufmgr_mutex_lock();
1782 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1784 if (!bufmgr->backend->bufmgr_bind_native_display) {
1785 TBM_TRACE("skip: tbm_bufmgr(%p) native_display(%p)\n",
1786 bufmgr, native_display);
1787 _tbm_bufmgr_mutex_unlock();
1791 ret = bufmgr->backend->bufmgr_bind_native_display(bufmgr, native_display);
1793 TBM_LOG_E("error: tbm_bufmgr(%p) native_display(%p)\n",
1794 bufmgr, native_display);
1795 _tbm_bufmgr_mutex_unlock();
1799 TBM_TRACE("tbm_bufmgr(%p) native_display(%p)\n", bufmgr, native_display);
1801 _tbm_bufmgr_mutex_unlock();
1806 int tbm_bufmgr_get_fd_limit(void)
1810 if (getrlimit(RLIMIT_NOFILE, &lim))
1813 return (int)lim.rlim_cur;
1815 /* LCOV_EXCL_STOP */