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 /* set the display_server flag before loading the backend module */
695 TBM_LOG_I("The tbm_bufmgr(%p) is used by display server. Need to bind the native_display.\n", gBufMgr);
696 gBufMgr->display_server = 1;
699 /* load bufmgr priv from env */
700 if (!_tbm_load_module(gBufMgr, gBufMgr->fd)) {
701 _tbm_set_last_result(TBM_BO_ERROR_LOAD_MODULE_FAILED);
702 TBM_LOG_E("error : Fail to load bufmgr backend\n");
705 pthread_mutex_unlock(&gLock);
711 /* log for tbm backend_flag */
712 TBM_DBG("backend flag:%x:", gBufMgr->backend->flags);
715 gBufMgr->ref_count = 1;
717 TBM_DBG("create tizen bufmgr:%p ref_count:%d\n",
718 gBufMgr, gBufMgr->ref_count);
720 /* setup the lock_type */
721 env = getenv("BUFMGR_LOCK_TYPE");
722 if (env && !strcmp(env, "always"))
723 gBufMgr->lock_type = LOCK_TRY_ALWAYS;
724 else if (env && !strcmp(env, "none"))
725 gBufMgr->lock_type = LOCK_TRY_NEVER;
726 else if (env && !strcmp(env, "once"))
727 gBufMgr->lock_type = LOCK_TRY_ONCE;
729 gBufMgr->lock_type = LOCK_TRY_ALWAYS;
731 TBM_DBG("BUFMGR_LOCK_TYPE=%s\n", env ? env : "default:once");
733 TBM_TRACE("create tbm_bufmgr(%p) ref_count(%d) fd(%d)\n", gBufMgr, gBufMgr->ref_count, fd);
735 /* intialize bo_list */
736 LIST_INITHEAD(&gBufMgr->bo_list);
738 /* intialize surf_list */
739 LIST_INITHEAD(&gBufMgr->surf_list);
741 /* intialize surf_queue_list */
742 LIST_INITHEAD(&gBufMgr->surf_queue_list);
744 /* intialize debug_key_list */
745 LIST_INITHEAD(&gBufMgr->debug_key_list);
747 #ifdef TBM_BUFMGR_INIT_TIME
749 gettimeofday(&end_tv, NULL);
750 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)));
753 pthread_mutex_unlock(&gLock);
759 tbm_bufmgr_init(int fd)
763 bufmgr = _tbm_bufmgr_init(fd, 0);
769 tbm_bufmgr_deinit(tbm_bufmgr bufmgr)
771 TBM_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
773 _tbm_bufmgr_mutex_lock();
774 pthread_mutex_lock(&gLock);
777 TBM_LOG_E("gBufmgr already destroy: bufmgr:%p\n", bufmgr);
778 pthread_mutex_unlock(&gLock);
779 _tbm_bufmgr_mutex_unlock();
784 if (bufmgr->ref_count > 0) {
785 TBM_TRACE("reduce a ref_count(%d) of tbm_bufmgr(%p)\n", bufmgr->ref_count, bufmgr);
786 pthread_mutex_unlock(&gLock);
787 _tbm_bufmgr_mutex_unlock();
791 /* destroy bo_list */
792 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
793 tbm_bo bo = NULL, tmp;
795 LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &bufmgr->bo_list, item_link) {
796 TBM_LOG_E("Un-freed bo(%p, ref:%d)\n", bo, bo->ref_cnt);
799 LIST_DELINIT(&bufmgr->bo_list);
802 /* destroy surf_list */
803 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
804 tbm_surface_h surf = NULL, tmp;
806 LIST_FOR_EACH_ENTRY_SAFE(surf, tmp, &bufmgr->surf_list, item_link) {
807 TBM_LOG_E("Un-freed surf(%p, ref:%d)\n", surf, surf->refcnt);
808 tbm_surface_destroy(surf);
810 LIST_DELINIT(&bufmgr->surf_list);
813 /* destroy bufmgr priv */
814 bufmgr->backend->bufmgr_deinit(bufmgr->backend->priv);
815 bufmgr->backend->priv = NULL;
816 tbm_backend_free(bufmgr->backend);
817 bufmgr->backend = NULL;
819 TBM_TRACE("destroy tbm_bufmgr(%p)\n", bufmgr);
821 dlclose(bufmgr->module_data);
829 pthread_mutex_unlock(&gLock);
830 _tbm_bufmgr_mutex_unlock();
834 tbm_bo_size(tbm_bo bo)
836 tbm_bufmgr bufmgr = gBufMgr;
839 _tbm_bufmgr_mutex_lock();
841 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
842 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
844 size = bufmgr->backend->bo_size(bo);
846 TBM_TRACE("bo(%p) size(%d)\n", bo, size);
848 _tbm_bufmgr_mutex_unlock();
854 tbm_bo_ref(tbm_bo bo)
856 _tbm_bufmgr_mutex_lock();
858 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), NULL);
859 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), NULL);
863 TBM_TRACE("bo(%p) ref_cnt(%d)\n", bo, bo->ref_cnt);
865 _tbm_bufmgr_mutex_unlock();
871 tbm_bo_unref(tbm_bo bo)
873 _tbm_bufmgr_mutex_lock();
875 TBM_BUFMGR_RETURN_IF_FAIL(gBufMgr);
876 TBM_BUFMGR_RETURN_IF_FAIL(_tbm_bo_is_valid(bo));
878 TBM_TRACE("bo(%p) ref_cnt(%d)\n", bo, bo->ref_cnt - 1);
880 if (bo->ref_cnt <= 0) {
881 _tbm_bufmgr_mutex_unlock();
886 if (bo->ref_cnt == 0)
889 _tbm_bufmgr_mutex_unlock();
893 tbm_bo_alloc(tbm_bufmgr bufmgr, int size, int flags)
898 _tbm_bufmgr_mutex_lock();
900 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
901 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, NULL);
902 TBM_BUFMGR_RETURN_VAL_IF_FAIL(size > 0, NULL);
904 bo = calloc(1, sizeof(struct _tbm_bo));
906 /* LCOV_EXCL_START */
907 TBM_LOG_E("error: fail to create of tbm_bo size(%d) flag(%s)\n",
908 size, _tbm_flag_to_str(flags));
909 _tbm_set_last_result(TBM_BO_ERROR_HEAP_ALLOC_FAILED);
910 _tbm_bufmgr_mutex_unlock();
915 _tbm_util_check_bo_cnt(bufmgr);
919 bo_priv = bufmgr->backend->bo_alloc(bo, size, flags);
921 /* LCOV_EXCL_START */
922 TBM_LOG_E("error: fail to create of tbm_bo size(%d) flag(%s)\n",
923 size, _tbm_flag_to_str(flags));
924 _tbm_set_last_result(TBM_BO_ERROR_BO_ALLOC_FAILED);
926 _tbm_bufmgr_mutex_unlock();
937 TBM_TRACE("bo(%p) size(%d) refcnt(%d), flag(%s)\n", bo, size, bo->ref_cnt,
938 _tbm_flag_to_str(bo->flags));
940 LIST_INITHEAD(&bo->user_data_list);
942 LIST_ADD(&bo->item_link, &bufmgr->bo_list);
944 _tbm_bufmgr_mutex_unlock();
950 tbm_bo_import(tbm_bufmgr bufmgr, unsigned int key)
955 _tbm_bufmgr_mutex_lock();
957 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
958 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, NULL);
960 if (!bufmgr->backend->bo_import) {
961 /* LCOV_EXCL_START */
962 _tbm_bufmgr_mutex_unlock();
967 _tbm_util_check_bo_cnt(bufmgr);
969 bo = calloc(1, sizeof(struct _tbm_bo));
971 /* LCOV_EXCL_START */
972 TBM_LOG_E("error: fail to import of tbm_bo by key(%d)\n", key);
973 _tbm_bufmgr_mutex_unlock();
980 bo_priv = bufmgr->backend->bo_import(bo, key);
982 /* LCOV_EXCL_START */
983 TBM_LOG_E("error: fail to import of tbm_bo by key(%d)\n", key);
984 _tbm_set_last_result(TBM_BO_ERROR_IMPORT_FAILED);
986 _tbm_bufmgr_mutex_unlock();
991 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
994 LIST_FOR_EACH_ENTRY(bo2, &bufmgr->bo_list, item_link) {
995 if (bo2->priv == bo_priv) {
996 TBM_TRACE("find bo(%p) ref(%d) key(%d) flag(%s) in list\n",
997 bo2, bo2->ref_cnt, key,
998 _tbm_flag_to_str(bo2->flags));
1001 _tbm_bufmgr_mutex_unlock();
1012 if (bufmgr->backend->bo_get_flags)
1013 bo->flags = bufmgr->backend->bo_get_flags(bo);
1015 bo->flags = TBM_BO_DEFAULT;
1017 TBM_TRACE("import new bo(%p) ref(%d) key(%d) flag(%s) in list\n",
1018 bo, bo->ref_cnt, key, _tbm_flag_to_str(bo->flags));
1020 LIST_INITHEAD(&bo->user_data_list);
1022 LIST_ADD(&bo->item_link, &bufmgr->bo_list);
1024 _tbm_bufmgr_mutex_unlock();
1030 tbm_bo_import_fd(tbm_bufmgr bufmgr, tbm_fd fd)
1035 _tbm_bufmgr_mutex_lock();
1037 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
1038 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, NULL);
1040 if (!bufmgr->backend->bo_import_fd) {
1041 /* LCOV_EXCL_START */
1042 _tbm_bufmgr_mutex_unlock();
1044 /* LCOV_EXCL_STOP */
1047 _tbm_util_check_bo_cnt(bufmgr);
1049 bo = calloc(1, sizeof(struct _tbm_bo));
1051 /* LCOV_EXCL_START */
1052 TBM_LOG_E("error: fail to import tbm_bo by tbm_fd(%d)\n", fd);
1053 _tbm_bufmgr_mutex_unlock();
1055 /* LCOV_EXCL_STOP */
1058 bo->bufmgr = bufmgr;
1060 bo_priv = bufmgr->backend->bo_import_fd(bo, fd);
1062 /* LCOV_EXCL_START */
1063 TBM_LOG_E("error: fail to import tbm_bo by tbm_fd(%d)\n", fd);
1064 _tbm_set_last_result(TBM_BO_ERROR_IMPORT_FD_FAILED);
1066 _tbm_bufmgr_mutex_unlock();
1068 /* LCOV_EXCL_STOP */
1071 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
1074 LIST_FOR_EACH_ENTRY(bo2, &bufmgr->bo_list, item_link) {
1075 if (bo2->priv == bo_priv) {
1076 TBM_TRACE("find bo(%p) ref(%d) fd(%d) flag(%s) in list\n",
1077 bo2, bo2->ref_cnt, fd,
1078 _tbm_flag_to_str(bo2->flags));
1081 _tbm_bufmgr_mutex_unlock();
1092 if (bufmgr->backend->bo_get_flags)
1093 bo->flags = bufmgr->backend->bo_get_flags(bo);
1095 bo->flags = TBM_BO_DEFAULT;
1097 TBM_TRACE("import bo(%p) ref(%d) fd(%d) flag(%s)\n",
1098 bo, bo->ref_cnt, fd, _tbm_flag_to_str(bo->flags));
1100 LIST_INITHEAD(&bo->user_data_list);
1102 LIST_ADD(&bo->item_link, &bufmgr->bo_list);
1104 _tbm_bufmgr_mutex_unlock();
1110 tbm_bo_export(tbm_bo bo)
1112 tbm_bufmgr bufmgr = gBufMgr;
1115 _tbm_bufmgr_mutex_lock();
1117 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1118 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1120 if (!bufmgr->backend->bo_export) {
1121 /* LCOV_EXCL_START */
1122 _tbm_bufmgr_mutex_unlock();
1124 /* LCOV_EXCL_STOP */
1127 ret = bufmgr->backend->bo_export(bo);
1129 /* LCOV_EXCL_START */
1130 _tbm_set_last_result(TBM_BO_ERROR_EXPORT_FAILED);
1131 TBM_LOG_E("error: bo(%p) tbm_key(%d)\n", bo, ret);
1132 _tbm_bufmgr_mutex_unlock();
1134 /* LCOV_EXCL_STOP */
1137 TBM_TRACE("bo(%p) tbm_key(%u)\n", bo, ret);
1139 _tbm_bufmgr_mutex_unlock();
1145 tbm_bo_export_fd(tbm_bo bo)
1147 tbm_bufmgr bufmgr = gBufMgr;
1150 _tbm_bufmgr_mutex_lock();
1152 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), -1);
1153 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), -1);
1155 if (!bufmgr->backend->bo_export_fd) {
1156 /* LCOV_EXCL_START */
1157 _tbm_bufmgr_mutex_unlock();
1159 /* LCOV_EXCL_STOP */
1162 ret = bufmgr->backend->bo_export_fd(bo);
1164 /* LCOV_EXCL_START */
1165 _tbm_set_last_result(TBM_BO_ERROR_EXPORT_FD_FAILED);
1166 TBM_LOG_E("error: bo(%p) tbm_fd(%d)\n", bo, ret);
1167 _tbm_bufmgr_mutex_unlock();
1169 /* LCOV_EXCL_STOP */
1172 TBM_TRACE("bo(%p) tbm_fd(%d)\n", bo, ret);
1174 _tbm_bufmgr_mutex_unlock();
1180 tbm_bo_get_handle(tbm_bo bo, int device)
1182 tbm_bufmgr bufmgr = gBufMgr;
1183 tbm_bo_handle bo_handle;
1185 _tbm_bufmgr_mutex_lock();
1187 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), (tbm_bo_handle) NULL);
1188 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) NULL);
1190 bo_handle = bufmgr->backend->bo_get_handle(bo, device);
1191 if (bo_handle.ptr == NULL) {
1192 /* LCOV_EXCL_START */
1193 _tbm_set_last_result(TBM_BO_ERROR_GET_HANDLE_FAILED);
1194 TBM_LOG_E("error: bo(%p) bo_handle(%p)\n", bo, bo_handle.ptr);
1195 _tbm_bufmgr_mutex_unlock();
1196 return (tbm_bo_handle) NULL;
1197 /* LCOV_EXCL_STOP */
1200 TBM_TRACE("bo(%p) bo_handle(%p)\n", bo, bo_handle.ptr);
1202 _tbm_bufmgr_mutex_unlock();
1208 tbm_bo_map(tbm_bo bo, int device, int opt)
1210 tbm_bufmgr bufmgr = gBufMgr;
1211 tbm_bo_handle bo_handle;
1213 _tbm_bufmgr_mutex_lock();
1215 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), (tbm_bo_handle) NULL);
1216 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) NULL);
1218 if (!_tbm_bo_lock(bo, device, opt)) {
1219 _tbm_set_last_result(TBM_BO_ERROR_LOCK_FAILED);
1220 TBM_LOG_E("error: fail to lock bo:%p)\n", bo);
1221 _tbm_bufmgr_mutex_unlock();
1222 return (tbm_bo_handle) NULL;
1225 bo_handle = bufmgr->backend->bo_map(bo, device, opt);
1226 if (bo_handle.ptr == NULL) {
1227 /* LCOV_EXCL_START */
1228 _tbm_set_last_result(TBM_BO_ERROR_MAP_FAILED);
1229 TBM_LOG_E("error: fail to map bo:%p\n", bo);
1231 _tbm_bufmgr_mutex_unlock();
1232 return (tbm_bo_handle) NULL;
1233 /* LCOV_EXCL_STOP */
1236 /* increase the map_count */
1239 TBM_TRACE("bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
1241 _tbm_bufmgr_mutex_unlock();
1247 tbm_bo_unmap(tbm_bo bo)
1249 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);
1256 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bo->map_cnt > 0, 0);
1258 ret = bufmgr->backend->bo_unmap(bo);
1260 /* LCOV_EXCL_START */
1261 TBM_LOG_E("error: bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
1262 _tbm_set_last_result(TBM_BO_ERROR_UNMAP_FAILED);
1263 _tbm_bufmgr_mutex_unlock();
1265 /* LCOV_EXCL_STOP */
1268 /* decrease the map_count */
1271 TBM_TRACE("bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
1275 _tbm_bufmgr_mutex_unlock();
1281 tbm_bo_swap(tbm_bo bo1, tbm_bo bo2)
1283 tbm_bufmgr bufmgr = gBufMgr;
1286 _tbm_bufmgr_mutex_lock();
1288 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1289 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo1), 0);
1290 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo2), 0);
1292 TBM_TRACE("before: bo1(%p) bo2(%p)\n", bo1, bo2);
1294 if (bufmgr->backend->bo_size(bo1) != bufmgr->backend->bo_size(bo2)) {
1295 _tbm_set_last_result(TBM_BO_ERROR_SWAP_FAILED);
1296 TBM_LOG_E("error: bo1(%p) bo2(%p)\n", bo1, bo2);
1297 _tbm_bufmgr_mutex_unlock();
1301 TBM_TRACE("after: bo1(%p) bo2(%p)\n", bo1, bo2);
1304 bo1->priv = bo2->priv;
1307 _tbm_bufmgr_mutex_unlock();
1313 tbm_bo_locked(tbm_bo bo)
1315 tbm_bufmgr bufmgr = gBufMgr;
1317 _tbm_bufmgr_mutex_lock();
1319 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1320 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1322 if (bufmgr->lock_type == LOCK_TRY_NEVER) {
1323 TBM_LOG_E("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
1324 _tbm_bufmgr_mutex_unlock();
1328 if (bo->lock_cnt > 0) {
1329 TBM_TRACE("error: bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
1330 _tbm_bufmgr_mutex_unlock();
1334 TBM_TRACE("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
1335 _tbm_bufmgr_mutex_unlock();
1341 tbm_bo_add_user_data(tbm_bo bo, unsigned long key,
1342 tbm_data_free data_free_func)
1344 tbm_user_data *data;
1346 _tbm_bufmgr_mutex_lock();
1348 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1349 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1351 /* check if the data according to the key exist if so, return false. */
1352 data = user_data_lookup(&bo->user_data_list, key);
1354 TBM_TRACE("warning: user data already exist key(%ld)\n", key);
1355 _tbm_bufmgr_mutex_unlock();
1359 data = user_data_create(key, data_free_func);
1361 TBM_LOG_E("error: bo(%p) key(%lu)\n", bo, key);
1362 _tbm_bufmgr_mutex_unlock();
1366 TBM_TRACE("bo(%p) key(%lu) data(%p)\n", bo, key, data->data);
1368 LIST_ADD(&data->item_link, &bo->user_data_list);
1370 _tbm_bufmgr_mutex_unlock();
1376 tbm_bo_set_user_data(tbm_bo bo, unsigned long key, void *data)
1378 tbm_user_data *old_data;
1380 _tbm_bufmgr_mutex_lock();
1382 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1383 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1385 if (LIST_IS_EMPTY(&bo->user_data_list)) {
1386 TBM_TRACE("error: bo(%p) key(%lu)\n", bo, key);
1387 _tbm_bufmgr_mutex_unlock();
1391 old_data = user_data_lookup(&bo->user_data_list, key);
1393 TBM_TRACE("error: bo(%p) key(%lu)\n", bo, key);
1394 _tbm_bufmgr_mutex_unlock();
1398 if (old_data->data && old_data->free_func)
1399 old_data->free_func(old_data->data);
1400 old_data->data = data;
1402 TBM_TRACE("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1404 _tbm_bufmgr_mutex_unlock();
1410 tbm_bo_get_user_data(tbm_bo bo, unsigned long key, void **data)
1412 tbm_user_data *old_data;
1414 _tbm_bufmgr_mutex_lock();
1416 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1417 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1419 if (!data || LIST_IS_EMPTY(&bo->user_data_list)) {
1420 TBM_TRACE("error: bo(%p) key(%lu)\n", bo, key);
1421 _tbm_bufmgr_mutex_unlock();
1425 old_data = user_data_lookup(&bo->user_data_list, key);
1427 TBM_TRACE("error: bo(%p) key(%lu)\n", bo, key);
1429 _tbm_bufmgr_mutex_unlock();
1433 *data = old_data->data;
1435 TBM_TRACE("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1437 _tbm_bufmgr_mutex_unlock();
1443 tbm_bo_delete_user_data(tbm_bo bo, unsigned long key)
1445 tbm_user_data *old_data;
1447 _tbm_bufmgr_mutex_lock();
1449 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1450 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1452 if (LIST_IS_EMPTY(&bo->user_data_list)) {
1453 TBM_TRACE("error: bo(%p) key(%lu)\n", bo, key);
1454 _tbm_bufmgr_mutex_unlock();
1458 old_data = user_data_lookup(&bo->user_data_list, key);
1460 TBM_TRACE("error: bo(%p) key(%lu)\n", bo, key);
1461 _tbm_bufmgr_mutex_unlock();
1465 TBM_TRACE("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1467 user_data_delete(old_data);
1469 _tbm_bufmgr_mutex_unlock();
1475 tbm_bufmgr_get_capability(tbm_bufmgr bufmgr)
1477 unsigned int capabilities = TBM_BUFMGR_CAPABILITY_NONE;
1479 _tbm_bufmgr_mutex_lock();
1481 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), TBM_BUFMGR_CAPABILITY_NONE);
1482 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, TBM_BUFMGR_CAPABILITY_NONE);
1484 TBM_TRACE("tbm_bufmgr(%p) capability(%u)\n", bufmgr, bufmgr->capabilities);
1486 capabilities = bufmgr->capabilities;
1488 _tbm_bufmgr_mutex_unlock();
1490 return capabilities;
1494 tbm_bo_get_flags(tbm_bo bo)
1498 _tbm_bufmgr_mutex_lock();
1500 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1501 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1505 TBM_TRACE("bo(%p)\n", bo);
1507 _tbm_bufmgr_mutex_unlock();
1512 /* LCOV_EXCL_START */
1514 tbm_get_last_error(void)
1516 return tbm_last_error;
1520 tbm_bufmgr_debug_tbm_info_get(tbm_bufmgr bufmgr)
1522 char app_name[255] = {0,}, title[512] = {0,};
1523 tbm_surface_debug_data *debug_old_data = NULL;
1528 pthread_mutex_lock(&gLock);
1530 if (!TBM_BUFMGR_IS_VALID(bufmgr) || (bufmgr != gBufMgr)) {
1531 TBM_LOG_E("invalid bufmgr\n");
1532 pthread_mutex_unlock(&gLock);
1538 TBM_LOG_E("Fail to allocate the string.\n");
1539 pthread_mutex_unlock(&gLock);
1543 TBM_SNRPRINTF(str, len, c, "\n");
1544 _tbm_util_get_appname_from_pid(getpid(), app_name);
1545 _tbm_util_get_appname_brief(app_name);
1546 TBM_SNRPRINTF(str, len, c, "============TBM DEBUG: %s(%d)===========================\n",
1547 app_name, getpid());
1549 snprintf(title, 255, "%s", "no surface refcnt width height bpp size n_b n_p flags format app_name ");
1551 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
1552 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
1553 strncat(title, " ", MAX_SIZE_N(title));
1554 strncat(title, debug_old_data->key, MAX_SIZE_N(title));
1558 TBM_SNRPRINTF(str, len, c, "[tbm_surface information]\n");
1559 TBM_SNRPRINTF(str, len, c, "%s\n", title);
1561 /* show the tbm_surface information in surf_list */
1562 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
1563 tbm_surface_h surf = NULL;
1566 LIST_FOR_EACH_ENTRY(surf, &bufmgr->surf_list, item_link) {
1567 char data[512] = {0,};
1571 pid = _tbm_surface_internal_get_debug_pid(surf);
1573 /* if pid is null, set the self_pid */
1577 memset(app_name, 0x0, 255 * sizeof(char));
1578 _tbm_util_get_appname_from_pid(pid, app_name);
1579 _tbm_util_get_appname_brief(app_name);
1581 snprintf(data, 255, "%-2d %-9p %-4d %-5u %-6u %-3u %-6u %-2d %-2d %-3d %-8s %-15s",
1588 surf->info.size / 1024,
1592 _tbm_surface_internal_format_to_str(surf->info.format) + 11,
1595 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
1596 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
1599 strncat(data, " ", MAX_SIZE_N(title));
1601 value = _tbm_surface_internal_get_debug_data(surf, debug_old_data->key);
1603 strncat(data, value, MAX_SIZE_N(title));
1605 strncat(data, "none", MAX_SIZE_N(title));
1608 TBM_SNRPRINTF(str, len, c, "%s\n", data);
1610 for (i = 0; i < surf->num_bos; i++) {
1611 TBM_SNRPRINTF(str, len, c, " bo:%-12p %-26d%-10d\n",
1613 surf->bos[i]->ref_cnt,
1614 bufmgr->backend->bo_size(surf->bos[i]) / 1024);
1618 TBM_SNRPRINTF(str, len, c, " no tbm_surfaces.\n");
1619 TBM_SNRPRINTF(str, len, c, "\n");
1621 TBM_SNRPRINTF(str, len, c, "[tbm_bo information]\n");
1622 TBM_SNRPRINTF(str, len, c, "no bo refcnt size lock_cnt map_cnt flags surface name\n");
1624 /* show the tbm_bo information in bo_list */
1625 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
1629 LIST_FOR_EACH_ENTRY(bo, &bufmgr->bo_list, item_link) {
1630 TBM_SNRPRINTF(str, len, c, "%-4d%-11p %-4d %-6d %-5d %-4u %-3d %-11p %-4d\n",
1634 bufmgr->backend->bo_size(bo) / 1024,
1639 bufmgr->backend->bo_export(bo));
1642 TBM_SNRPRINTF(str, len, c, "no tbm_bos.\n");
1643 TBM_SNRPRINTF(str, len, c, "\n");
1645 TBM_SNRPRINTF(str, len, c, "===============================================================\n");
1647 pthread_mutex_unlock(&gLock);
1653 tbm_bufmgr_debug_show(tbm_bufmgr bufmgr)
1656 str = tbm_bufmgr_debug_tbm_info_get(bufmgr);
1658 TBM_DEBUG(" %s", str);
1664 tbm_bufmgr_debug_trace(tbm_bufmgr bufmgr, int onoff)
1666 _tbm_bufmgr_mutex_lock();
1668 TBM_BUFMGR_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
1669 TBM_BUFMGR_RETURN_IF_FAIL(bufmgr == gBufMgr);
1672 TBM_LOG_D("bufmgr=%p onoff=%d\n", bufmgr, onoff);
1676 _tbm_bufmgr_mutex_unlock();
1680 tbm_bufmgr_debug_dump_set_scale(double scale)
1682 pthread_mutex_lock(&gLock);
1683 scale_factor = scale;
1684 pthread_mutex_unlock(&gLock);
1688 tbm_bufmgr_debug_get_ref_count(void)
1690 return (gBufMgr) ? gBufMgr->ref_count : 0;
1694 tbm_bufmgr_debug_queue_dump(char *path, int count, int onoff)
1696 pthread_mutex_lock(&gLock);
1699 TBM_LOG_D("count=%d onoff=%d\n", count, onoff);
1701 tbm_surface_internal_dump_end();
1706 TBM_LOG_E("path is null");
1707 pthread_mutex_unlock(&gLock);
1710 TBM_LOG_D("path=%s count=%d onoff=%d\n", path, count, onoff);
1712 if (_tbm_util_get_max_surface_size(&w, &h) == 0) {
1713 TBM_LOG_E("Fail to get tbm_surface size.\n");
1714 pthread_mutex_unlock(&gLock);
1718 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
1724 pthread_mutex_unlock(&gLock);
1729 tbm_bufmgr_debug_dump_all(char *path)
1731 int w, h, count = 0;
1732 tbm_surface_h surface = NULL;
1734 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
1735 TBM_LOG_D("path=%s\n", path);
1737 pthread_mutex_lock(&gLock);
1739 count = _tbm_util_get_max_surface_size(&w, &h);
1741 TBM_LOG_E("No tbm_surface.\n");
1742 pthread_mutex_unlock(&gLock);
1746 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
1749 LIST_FOR_EACH_ENTRY(surface, &gBufMgr->surf_list, item_link)
1750 tbm_surface_internal_dump_buffer(surface, "dump_all");
1752 tbm_surface_internal_dump_end();
1754 pthread_mutex_unlock(&gLock);
1759 /* internal function */
1761 _tbm_bufmgr_get_bufmgr(void)
1767 _tbm_bo_set_surface(tbm_bo bo, tbm_surface_h surface)
1769 _tbm_bufmgr_mutex_lock();
1771 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1772 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1774 bo->surface = surface;
1776 _tbm_bufmgr_mutex_unlock();
1782 tbm_bufmgr_bind_native_display(tbm_bufmgr bufmgr, void *native_display)
1786 _tbm_bufmgr_mutex_lock();
1788 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1790 if (!bufmgr->backend->bufmgr_bind_native_display) {
1791 TBM_TRACE("skip: tbm_bufmgr(%p) native_display(%p)\n",
1792 bufmgr, native_display);
1793 _tbm_bufmgr_mutex_unlock();
1797 ret = bufmgr->backend->bufmgr_bind_native_display(bufmgr, native_display);
1799 TBM_LOG_E("error: tbm_bufmgr(%p) native_display(%p)\n",
1800 bufmgr, native_display);
1801 _tbm_bufmgr_mutex_unlock();
1805 TBM_TRACE("tbm_bufmgr(%p) native_display(%p)\n", bufmgr, native_display);
1807 _tbm_bufmgr_mutex_unlock();
1813 tbm_bufmgr_server_init(void)
1817 bufmgr = _tbm_bufmgr_init(-1, 1);
1822 int tbm_bufmgr_get_fd_limit(void)
1826 if (getrlimit(RLIMIT_NOFILE, &lim))
1829 return (int)lim.rlim_cur;
1831 /* LCOV_EXCL_STOP */