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)
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;
109 /* LCOV_EXCL_START */
111 _tbm_bufmgr_mutex_init(void)
113 static bool tbm_bufmgr_mutex_init = false;
115 if (tbm_bufmgr_mutex_init)
118 if (pthread_mutex_init(&tbm_bufmgr_lock, NULL)) {
119 TBM_LOG_E("fail: Cannot pthread_mutex_init for tbm_bufmgr_lock.\n");
123 tbm_bufmgr_mutex_init = true;
129 _tbm_bufmgr_mutex_lock(void)
131 if (!_tbm_bufmgr_mutex_init()) {
132 TBM_LOG_E("fail: _tbm_bufmgr_mutex_init()\n");
136 pthread_mutex_lock(&tbm_bufmgr_lock);
140 _tbm_bufmgr_mutex_unlock(void)
142 pthread_mutex_unlock(&tbm_bufmgr_lock);
146 _tbm_flag_to_str(int f)
148 static char str[255];
150 if (f == TBM_BO_DEFAULT)
151 snprintf(str, 255, "DEFAULT");
155 if (f & TBM_BO_SCANOUT)
156 c = snprintf(&str[c], 255, "SCANOUT");
158 if (f & TBM_BO_NONCACHABLE) {
160 c = snprintf(&str[c], 255, ", ");
161 c = snprintf(&str[c], 255, "NONCACHABLE,");
166 c = snprintf(&str[c], 255, ", ");
167 c = snprintf(&str[c], 255, "WC");
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 /* LCOV_EXCL_START */
292 TBM_LOG_E("fail to allocate an user_date\n");
297 user_data->key = key;
298 user_data->free_func = data_free_func;
304 user_data_delete(tbm_user_data *user_data)
306 if (user_data->data && user_data->free_func)
307 user_data->free_func(user_data->data);
309 LIST_DEL(&user_data->item_link);
315 _bo_lock(tbm_bo bo, int device, int opt)
317 tbm_bufmgr bufmgr = bo->bufmgr;
320 if (bufmgr->backend->bo_lock)
321 ret = bufmgr->backend->bo_lock(bo, device, opt);
327 _bo_unlock(tbm_bo bo)
329 tbm_bufmgr bufmgr = bo->bufmgr;
331 if (bufmgr->backend->bo_unlock)
332 bufmgr->backend->bo_unlock(bo);
336 _tbm_bo_lock(tbm_bo bo, int device, int opt)
346 /* do not try to lock the bo */
347 if (bufmgr->lock_type == LOCK_TRY_NEVER)
350 if (bo->lock_cnt < 0) {
351 TBM_LOG_E("error bo:%p LOCK_CNT=%d\n",
358 switch (bufmgr->lock_type) {
360 if (bo->lock_cnt == 0) {
361 _tbm_bufmgr_mutex_unlock();
362 ret = _bo_lock(bo, device, opt);
363 _tbm_bufmgr_mutex_lock();
369 case LOCK_TRY_ALWAYS:
370 _tbm_bufmgr_mutex_unlock();
371 ret = _bo_lock(bo, device, opt);
372 _tbm_bufmgr_mutex_lock();
377 TBM_LOG_E("error bo:%p lock_type[%d] is wrong.\n",
378 bo, bufmgr->lock_type);
383 TBM_DBG_LOCK(">> LOCK bo:%p(%d->%d)\n", bo, old, bo->lock_cnt);
389 _tbm_bo_unlock(tbm_bo bo)
399 /* do not try to unlock the bo */
400 if (bufmgr->lock_type == LOCK_TRY_NEVER)
405 switch (bufmgr->lock_type) {
407 if (bo->lock_cnt > 0) {
409 if (bo->lock_cnt == 0)
413 case LOCK_TRY_ALWAYS:
414 if (bo->lock_cnt > 0) {
420 TBM_LOG_E("error bo:%p lock_type[%d] is wrong.\n",
421 bo, bufmgr->lock_type);
425 if (bo->lock_cnt < 0)
428 TBM_DBG_LOCK(">> UNLOCK bo:%p(%d->%d)\n", bo, old, bo->lock_cnt);
432 _tbm_bo_is_valid(tbm_bo bo)
434 tbm_bo old_data = NULL;
436 if (bo == NULL || gBufMgr == NULL) {
437 TBM_LOG_E("error: bo is NULL or tbm_bufmgr was deinited\n");
441 if (LIST_IS_EMPTY(&gBufMgr->bo_list)) {
442 TBM_LOG_E("error: gBufMgr->bo_list is EMPTY.\n");
446 LIST_FOR_EACH_ENTRY(old_data, &gBufMgr->bo_list, item_link) {
451 TBM_LOG_E("error: No valid bo(%p).\n", bo);
457 _tbm_bo_free(tbm_bo bo)
459 tbm_bufmgr bufmgr = bo->bufmgr;
461 /* destory the user_data_list */
462 if (!LIST_IS_EMPTY(&bo->user_data_list)) {
463 tbm_user_data *old_data = NULL, *tmp;
465 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp,
466 &bo->user_data_list, item_link) {
467 TBM_DBG("free user_data\n");
468 user_data_delete(old_data);
472 while (bo->lock_cnt > 0) {
473 TBM_LOG_E("error lock_cnt:%d\n", bo->lock_cnt);
478 /* call the bo_free */
479 bufmgr->backend->bo_free(bo);
482 LIST_DEL(&bo->item_link);
488 /* LCOV_EXCL_START */
490 _check_version(TBMModuleVersionInfo *data)
495 abimaj = GET_ABI_MAJOR(data->abiversion);
496 abimin = GET_ABI_MINOR(data->abiversion);
498 TBM_DBG("TBM module %s: vendor=\"%s\" ABI=%d,%d\n",
499 data->modname ? data->modname : "UNKNOWN!",
500 data->vendor ? data->vendor : "UNKNOWN!", abimaj, abimin);
502 vermaj = GET_ABI_MAJOR(TBM_ABI_VERSION);
503 vermin = GET_ABI_MINOR(TBM_ABI_VERSION);
505 TBM_DBG("TBM ABI version %d.%d\n",
508 if (abimaj != vermaj) {
509 TBM_LOG_E("TBM module ABI major ver(%d) doesn't match the TBM's ver(%d)\n",
512 } else if (abimin > vermin) {
513 TBM_LOG_E("TBM module ABI minor ver(%d) is newer than the TBM's ver(%d)\n",
522 _tbm_bufmgr_load_module(tbm_bufmgr bufmgr, int fd, const char *file)
524 char path[PATH_MAX] = {0, };
525 TBMModuleVersionInfo *vers;
526 TBMModuleData *initdata;
530 snprintf(path, sizeof(path), BUFMGR_MODULE_DIR "/%s", file);
532 module_data = dlopen(path, RTLD_LAZY);
534 TBM_LOG_E("failed to load module: %s(%s)\n", dlerror(), file);
538 initdata = dlsym(module_data, "tbmModuleData");
540 TBM_LOG_E("Error: module does not have data object.\n");
544 vers = initdata->vers;
546 TBM_LOG_E("Error: module does not supply version information.\n");
550 init = initdata->init;
552 TBM_LOG_E("Error: module does not supply init symbol.\n");
556 if (!_check_version(vers)) {
557 TBM_LOG_E("Fail to check version.\n");
561 if (!init(bufmgr, fd)) {
562 TBM_LOG_E("Fail to init module(%s)\n", file);
566 if (!bufmgr->backend || !bufmgr->backend->priv) {
567 TBM_LOG_E("Error: module(%s) wrong operation. Check backend or backend's priv.\n", file);
571 bufmgr->module_data = module_data;
573 TBM_DBG("Success to load module(%s)\n", file);
578 dlclose(module_data);
583 _tbm_load_module(tbm_bufmgr bufmgr, int fd)
585 struct dirent **namelist;
588 /* load bufmgr priv from default lib */
589 if (_tbm_bufmgr_load_module(bufmgr, fd, DEFAULT_LIB))
592 /* load bufmgr priv from configured path */
593 n = scandir(BUFMGR_MODULE_DIR, &namelist, 0, alphasort);
595 TBM_LOG_E("no files : %s\n", BUFMGR_MODULE_DIR);
600 if (!ret && strstr(namelist[n]->d_name, PREFIX_LIB)) {
601 const char *p = strstr(namelist[n]->d_name, SUFFIX_LIB);
603 if (p && !strcmp(p, SUFFIX_LIB))
604 ret = _tbm_bufmgr_load_module(bufmgr, fd,
605 namelist[n]->d_name);
618 tbm_bufmgr_init(int fd)
620 #ifdef TBM_BUFMGR_INIT_TIME
621 struct timeval start_tv, end_tv;
625 #ifdef TBM_BUFMGR_INIT_TIME
626 /* get the start tv */
627 gettimeofday(&start_tv, NULL);
630 /* LCOV_EXCL_START */
632 env = getenv("TBM_DLOG");
635 TBM_LOG_D("TBM_DLOG=%s\n", env);
641 env = getenv("TBM_DEBUG");
644 TBM_LOG_D("TBM_DEBUG=%s\n", env);
650 env = getenv("TBM_TRACE");
653 TBM_LOG_D("TBM_TRACE=%s\n", env);
658 pthread_mutex_lock(&gLock);
661 TBM_LOG_W("!!!!!WARNING:: The tbm_bufmgr_init DOSE NOT use argument fd ANYMORE.\n");
662 TBM_LOG_W("!!!!!WARNING:: IT WILL BE CHANGED like tbm_bufmgr_init(int fd) --> tbm_bufmgr_init(void).\n");
666 /* initialize buffer manager */
668 gBufMgr->ref_count++;
669 TBM_TRACE("reuse tbm_bufmgr(%p) ref_count(%d) fd(%d)\n", gBufMgr, gBufMgr->ref_count, gBufMgr->fd);
670 pthread_mutex_unlock(&gLock);
674 TBM_DBG("bufmgr init\n");
676 /* allocate bufmgr */
677 gBufMgr = calloc(1, sizeof(struct _tbm_bufmgr));
679 _tbm_set_last_result(TBM_BO_ERROR_HEAP_ALLOC_FAILED);
680 TBM_TRACE("error: fail to alloc bufmgr fd(%d)\n", fd);
681 pthread_mutex_unlock(&gLock);
687 /* load bufmgr priv from env */
688 if (!_tbm_load_module(gBufMgr, gBufMgr->fd)) {
689 _tbm_set_last_result(TBM_BO_ERROR_LOAD_MODULE_FAILED);
690 TBM_LOG_E("error : Fail to load bufmgr backend\n");
693 pthread_mutex_unlock(&gLock);
699 /* log for tbm backend_flag */
700 TBM_DBG("backend flag:%x:", gBufMgr->backend->flags);
703 gBufMgr->ref_count = 1;
705 TBM_DBG("create tizen bufmgr:%p ref_count:%d\n",
706 gBufMgr, gBufMgr->ref_count);
708 /* setup the lock_type */
709 env = getenv("BUFMGR_LOCK_TYPE");
710 if (env && !strcmp(env, "always"))
711 gBufMgr->lock_type = LOCK_TRY_ALWAYS;
712 else if (env && !strcmp(env, "none"))
713 gBufMgr->lock_type = LOCK_TRY_NEVER;
714 else if (env && !strcmp(env, "once"))
715 gBufMgr->lock_type = LOCK_TRY_ONCE;
717 gBufMgr->lock_type = LOCK_TRY_ALWAYS;
719 TBM_DBG("BUFMGR_LOCK_TYPE=%s\n", env ? env : "default:once");
721 TBM_TRACE("create tbm_bufmgr(%p) ref_count(%d) fd(%d)\n", gBufMgr, gBufMgr->ref_count, fd);
723 /* intialize bo_list */
724 LIST_INITHEAD(&gBufMgr->bo_list);
726 /* intialize surf_list */
727 LIST_INITHEAD(&gBufMgr->surf_list);
729 /* intialize surf_queue_list */
730 LIST_INITHEAD(&gBufMgr->surf_queue_list);
732 /* intialize debug_key_list */
733 LIST_INITHEAD(&gBufMgr->debug_key_list);
735 #ifdef TBM_BUFMGR_INIT_TIME
737 gettimeofday(&end_tv, NULL);
738 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)));
741 pthread_mutex_unlock(&gLock);
747 tbm_bufmgr_deinit(tbm_bufmgr bufmgr)
749 TBM_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
751 _tbm_bufmgr_mutex_lock();
752 pthread_mutex_lock(&gLock);
755 TBM_LOG_E("gBufmgr already destroy: bufmgr:%p\n", bufmgr);
756 pthread_mutex_unlock(&gLock);
757 _tbm_bufmgr_mutex_unlock();
762 if (bufmgr->ref_count > 0) {
763 TBM_TRACE("reduce a ref_count(%d) of tbm_bufmgr(%p)\n", bufmgr->ref_count, bufmgr);
764 pthread_mutex_unlock(&gLock);
765 _tbm_bufmgr_mutex_unlock();
769 /* destroy bo_list */
770 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
771 tbm_bo bo = NULL, tmp;
773 LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &bufmgr->bo_list, item_link) {
774 TBM_LOG_E("Un-freed bo(%p, ref:%d)\n", bo, bo->ref_cnt);
779 /* destroy surf_list */
780 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
781 tbm_surface_h surf = NULL, tmp;
783 LIST_FOR_EACH_ENTRY_SAFE(surf, tmp, &bufmgr->surf_list, item_link) {
784 TBM_LOG_E("Un-freed surf(%p, ref:%d)\n", surf, surf->refcnt);
785 tbm_surface_destroy(surf);
789 /* destroy bufmgr priv */
790 bufmgr->backend->bufmgr_deinit(bufmgr->backend->priv);
791 bufmgr->backend->priv = NULL;
792 tbm_backend_free(bufmgr->backend);
793 bufmgr->backend = NULL;
795 TBM_TRACE("destroy tbm_bufmgr(%p)\n", bufmgr);
797 dlclose(bufmgr->module_data);
805 pthread_mutex_unlock(&gLock);
806 _tbm_bufmgr_mutex_unlock();
810 tbm_bo_size(tbm_bo bo)
812 tbm_bufmgr bufmgr = gBufMgr;
815 _tbm_bufmgr_mutex_lock();
817 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
818 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
820 size = bufmgr->backend->bo_size(bo);
822 TBM_TRACE("bo(%p) size(%d)\n", bo, size);
824 _tbm_bufmgr_mutex_unlock();
830 tbm_bo_ref(tbm_bo bo)
832 _tbm_bufmgr_mutex_lock();
834 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), NULL);
835 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), NULL);
839 TBM_TRACE("bo(%p) ref_cnt(%d)\n", bo, bo->ref_cnt);
841 _tbm_bufmgr_mutex_unlock();
847 tbm_bo_unref(tbm_bo bo)
849 _tbm_bufmgr_mutex_lock();
851 TBM_BUFMGR_RETURN_IF_FAIL(gBufMgr);
852 TBM_BUFMGR_RETURN_IF_FAIL(_tbm_bo_is_valid(bo));
854 TBM_TRACE("bo(%p) ref_cnt(%d)\n", bo, bo->ref_cnt - 1);
856 if (bo->ref_cnt <= 0) {
857 _tbm_bufmgr_mutex_unlock();
862 if (bo->ref_cnt == 0)
865 _tbm_bufmgr_mutex_unlock();
869 tbm_bo_alloc(tbm_bufmgr bufmgr, int size, int flags)
874 _tbm_bufmgr_mutex_lock();
876 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
877 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, NULL);
878 TBM_BUFMGR_RETURN_VAL_IF_FAIL(size > 0, NULL);
880 bo = calloc(1, sizeof(struct _tbm_bo));
882 /* LCOV_EXCL_START */
883 TBM_LOG_E("error: fail to create of tbm_bo size(%d) flag(%s)\n",
884 size, _tbm_flag_to_str(flags));
885 _tbm_set_last_result(TBM_BO_ERROR_HEAP_ALLOC_FAILED);
886 _tbm_bufmgr_mutex_unlock();
891 _tbm_util_check_bo_cnt(bufmgr);
895 bo_priv = bufmgr->backend->bo_alloc(bo, size, flags);
897 /* LCOV_EXCL_START */
898 TBM_LOG_E("error: fail to create of tbm_bo size(%d) flag(%s)\n",
899 size, _tbm_flag_to_str(flags));
900 _tbm_set_last_result(TBM_BO_ERROR_BO_ALLOC_FAILED);
902 _tbm_bufmgr_mutex_unlock();
913 TBM_TRACE("bo(%p) size(%d) refcnt(%d), flag(%s)\n", bo, size, bo->ref_cnt,
914 _tbm_flag_to_str(bo->flags));
916 LIST_INITHEAD(&bo->user_data_list);
918 LIST_ADD(&bo->item_link, &bufmgr->bo_list);
920 _tbm_bufmgr_mutex_unlock();
926 tbm_bo_import(tbm_bufmgr bufmgr, unsigned int key)
931 _tbm_bufmgr_mutex_lock();
933 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
934 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, NULL);
936 if (!bufmgr->backend->bo_import) {
937 /* LCOV_EXCL_START */
938 _tbm_bufmgr_mutex_unlock();
943 _tbm_util_check_bo_cnt(bufmgr);
945 bo = calloc(1, sizeof(struct _tbm_bo));
947 /* LCOV_EXCL_START */
948 TBM_LOG_E("error: fail to import of tbm_bo by key(%d)\n", key);
949 _tbm_bufmgr_mutex_unlock();
956 bo_priv = bufmgr->backend->bo_import(bo, key);
958 /* LCOV_EXCL_START */
959 TBM_LOG_E("error: fail to import of tbm_bo by key(%d)\n", key);
960 _tbm_set_last_result(TBM_BO_ERROR_IMPORT_FAILED);
962 _tbm_bufmgr_mutex_unlock();
967 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
970 LIST_FOR_EACH_ENTRY(bo2, &bufmgr->bo_list, item_link) {
971 if (bo2->priv == bo_priv) {
972 TBM_TRACE("find bo(%p) ref(%d) key(%d) flag(%s) in list\n",
973 bo2, bo2->ref_cnt, key,
974 _tbm_flag_to_str(bo2->flags));
977 _tbm_bufmgr_mutex_unlock();
988 if (bufmgr->backend->bo_get_flags)
989 bo->flags = bufmgr->backend->bo_get_flags(bo);
991 bo->flags = TBM_BO_DEFAULT;
993 TBM_TRACE("import new bo(%p) ref(%d) key(%d) flag(%s) in list\n",
994 bo, bo->ref_cnt, key, _tbm_flag_to_str(bo->flags));
996 LIST_INITHEAD(&bo->user_data_list);
998 LIST_ADD(&bo->item_link, &bufmgr->bo_list);
1000 _tbm_bufmgr_mutex_unlock();
1006 tbm_bo_import_fd(tbm_bufmgr bufmgr, tbm_fd fd)
1011 _tbm_bufmgr_mutex_lock();
1013 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
1014 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, NULL);
1016 if (!bufmgr->backend->bo_import_fd) {
1017 /* LCOV_EXCL_START */
1018 _tbm_bufmgr_mutex_unlock();
1020 /* LCOV_EXCL_STOP */
1023 _tbm_util_check_bo_cnt(bufmgr);
1025 bo = calloc(1, sizeof(struct _tbm_bo));
1027 /* LCOV_EXCL_START */
1028 TBM_LOG_E("error: fail to import tbm_bo by tbm_fd(%d)\n", fd);
1029 _tbm_bufmgr_mutex_unlock();
1031 /* LCOV_EXCL_STOP */
1034 bo->bufmgr = bufmgr;
1036 bo_priv = bufmgr->backend->bo_import_fd(bo, fd);
1038 /* LCOV_EXCL_START */
1039 TBM_LOG_E("error: fail to import tbm_bo by tbm_fd(%d)\n", fd);
1040 _tbm_set_last_result(TBM_BO_ERROR_IMPORT_FD_FAILED);
1042 _tbm_bufmgr_mutex_unlock();
1044 /* LCOV_EXCL_STOP */
1047 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
1050 LIST_FOR_EACH_ENTRY(bo2, &bufmgr->bo_list, item_link) {
1051 if (bo2->priv == bo_priv) {
1052 TBM_TRACE("find bo(%p) ref(%d) fd(%d) flag(%s) in list\n",
1053 bo2, bo2->ref_cnt, fd,
1054 _tbm_flag_to_str(bo2->flags));
1057 _tbm_bufmgr_mutex_unlock();
1068 if (bufmgr->backend->bo_get_flags)
1069 bo->flags = bufmgr->backend->bo_get_flags(bo);
1071 bo->flags = TBM_BO_DEFAULT;
1073 TBM_TRACE("import bo(%p) ref(%d) fd(%d) flag(%s)\n",
1074 bo, bo->ref_cnt, fd, _tbm_flag_to_str(bo->flags));
1076 LIST_INITHEAD(&bo->user_data_list);
1078 LIST_ADD(&bo->item_link, &bufmgr->bo_list);
1080 _tbm_bufmgr_mutex_unlock();
1086 tbm_bo_export(tbm_bo bo)
1088 tbm_bufmgr bufmgr = gBufMgr;
1091 _tbm_bufmgr_mutex_lock();
1093 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1094 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1096 if (!bufmgr->backend->bo_export) {
1097 /* LCOV_EXCL_START */
1098 _tbm_bufmgr_mutex_unlock();
1100 /* LCOV_EXCL_STOP */
1103 ret = bufmgr->backend->bo_export(bo);
1105 /* LCOV_EXCL_START */
1106 _tbm_set_last_result(TBM_BO_ERROR_EXPORT_FAILED);
1107 TBM_LOG_E("error: bo(%p) tbm_key(%d)\n", bo, ret);
1108 _tbm_bufmgr_mutex_unlock();
1110 /* LCOV_EXCL_STOP */
1113 TBM_TRACE("bo(%p) tbm_key(%u)\n", bo, ret);
1115 _tbm_bufmgr_mutex_unlock();
1121 tbm_bo_export_fd(tbm_bo bo)
1123 tbm_bufmgr bufmgr = gBufMgr;
1126 _tbm_bufmgr_mutex_lock();
1128 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), -1);
1129 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), -1);
1131 if (!bufmgr->backend->bo_export_fd) {
1132 /* LCOV_EXCL_START */
1133 _tbm_bufmgr_mutex_unlock();
1135 /* LCOV_EXCL_STOP */
1138 ret = bufmgr->backend->bo_export_fd(bo);
1140 /* LCOV_EXCL_START */
1141 _tbm_set_last_result(TBM_BO_ERROR_EXPORT_FD_FAILED);
1142 TBM_LOG_E("error: bo(%p) tbm_fd(%d)\n", bo, ret);
1143 _tbm_bufmgr_mutex_unlock();
1145 /* LCOV_EXCL_STOP */
1148 TBM_TRACE("bo(%p) tbm_fd(%d)\n", bo, ret);
1150 _tbm_bufmgr_mutex_unlock();
1156 tbm_bo_get_handle(tbm_bo bo, int device)
1158 tbm_bufmgr bufmgr = gBufMgr;
1159 tbm_bo_handle bo_handle;
1161 _tbm_bufmgr_mutex_lock();
1163 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), (tbm_bo_handle) NULL);
1164 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) NULL);
1166 bo_handle = bufmgr->backend->bo_get_handle(bo, device);
1167 if (bo_handle.ptr == NULL) {
1168 /* LCOV_EXCL_START */
1169 _tbm_set_last_result(TBM_BO_ERROR_GET_HANDLE_FAILED);
1170 TBM_LOG_E("error: bo(%p) bo_handle(%p)\n", bo, bo_handle.ptr);
1171 _tbm_bufmgr_mutex_unlock();
1172 return (tbm_bo_handle) NULL;
1173 /* LCOV_EXCL_STOP */
1176 TBM_TRACE("bo(%p) bo_handle(%p)\n", bo, bo_handle.ptr);
1178 _tbm_bufmgr_mutex_unlock();
1184 tbm_bo_map(tbm_bo bo, int device, int opt)
1186 tbm_bufmgr bufmgr = gBufMgr;
1187 tbm_bo_handle bo_handle;
1189 _tbm_bufmgr_mutex_lock();
1191 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), (tbm_bo_handle) NULL);
1192 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) NULL);
1194 if (!_tbm_bo_lock(bo, device, opt)) {
1195 _tbm_set_last_result(TBM_BO_ERROR_LOCK_FAILED);
1196 TBM_LOG_E("error: fail to lock bo:%p)\n", bo);
1197 _tbm_bufmgr_mutex_unlock();
1198 return (tbm_bo_handle) NULL;
1201 bo_handle = bufmgr->backend->bo_map(bo, device, opt);
1202 if (bo_handle.ptr == NULL) {
1203 /* LCOV_EXCL_START */
1204 _tbm_set_last_result(TBM_BO_ERROR_MAP_FAILED);
1205 TBM_LOG_E("error: fail to map bo:%p\n", bo);
1207 _tbm_bufmgr_mutex_unlock();
1208 return (tbm_bo_handle) NULL;
1209 /* LCOV_EXCL_STOP */
1212 /* increase the map_count */
1215 TBM_TRACE("bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
1217 _tbm_bufmgr_mutex_unlock();
1223 tbm_bo_unmap(tbm_bo bo)
1225 tbm_bufmgr bufmgr = gBufMgr;
1228 _tbm_bufmgr_mutex_lock();
1230 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1231 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1233 ret = bufmgr->backend->bo_unmap(bo);
1235 /* LCOV_EXCL_START */
1236 TBM_LOG_E("error: bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
1237 _tbm_set_last_result(TBM_BO_ERROR_UNMAP_FAILED);
1238 _tbm_bufmgr_mutex_unlock();
1240 /* LCOV_EXCL_STOP */
1243 /* decrease the map_count */
1246 TBM_TRACE("bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
1250 _tbm_bufmgr_mutex_unlock();
1256 tbm_bo_swap(tbm_bo bo1, tbm_bo bo2)
1258 tbm_bufmgr bufmgr = gBufMgr;
1261 _tbm_bufmgr_mutex_lock();
1263 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1264 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo1), 0);
1265 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo2), 0);
1267 TBM_TRACE("before: bo1(%p) bo2(%p)\n", bo1, bo2);
1269 if (bufmgr->backend->bo_size(bo1) != bufmgr->backend->bo_size(bo2)) {
1270 _tbm_set_last_result(TBM_BO_ERROR_SWAP_FAILED);
1271 TBM_LOG_E("error: bo1(%p) bo2(%p)\n", bo1, bo2);
1272 _tbm_bufmgr_mutex_unlock();
1276 TBM_TRACE("after: bo1(%p) bo2(%p)\n", bo1, bo2);
1279 bo1->priv = bo2->priv;
1282 _tbm_bufmgr_mutex_unlock();
1288 tbm_bo_locked(tbm_bo bo)
1290 tbm_bufmgr bufmgr = gBufMgr;
1292 _tbm_bufmgr_mutex_lock();
1294 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1295 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1297 if (bufmgr->lock_type == LOCK_TRY_NEVER) {
1298 TBM_LOG_E("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
1299 _tbm_bufmgr_mutex_unlock();
1303 if (bo->lock_cnt > 0) {
1304 TBM_TRACE("error: bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
1305 _tbm_bufmgr_mutex_unlock();
1309 TBM_TRACE("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
1310 _tbm_bufmgr_mutex_unlock();
1316 tbm_bo_add_user_data(tbm_bo bo, unsigned long key,
1317 tbm_data_free data_free_func)
1319 tbm_user_data *data;
1321 _tbm_bufmgr_mutex_lock();
1323 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1324 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1326 /* check if the data according to the key exist if so, return false. */
1327 data = user_data_lookup(&bo->user_data_list, key);
1329 TBM_TRACE("warning: user data already exist key(%ld)\n", key);
1330 _tbm_bufmgr_mutex_unlock();
1334 data = user_data_create(key, data_free_func);
1336 TBM_LOG_E("error: bo(%p) key(%lu)\n", bo, key);
1337 _tbm_bufmgr_mutex_unlock();
1341 TBM_TRACE("bo(%p) key(%lu) data(%p)\n", bo, key, data->data);
1343 LIST_ADD(&data->item_link, &bo->user_data_list);
1345 _tbm_bufmgr_mutex_unlock();
1351 tbm_bo_set_user_data(tbm_bo bo, unsigned long key, void *data)
1353 tbm_user_data *old_data;
1355 _tbm_bufmgr_mutex_lock();
1357 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1358 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1360 if (LIST_IS_EMPTY(&bo->user_data_list)) {
1361 TBM_TRACE("error: bo(%p) key(%lu)\n", bo, key);
1362 _tbm_bufmgr_mutex_unlock();
1366 old_data = user_data_lookup(&bo->user_data_list, key);
1368 TBM_TRACE("error: bo(%p) key(%lu)\n", bo, key);
1369 _tbm_bufmgr_mutex_unlock();
1373 if (old_data->data && old_data->free_func)
1374 old_data->free_func(old_data->data);
1375 old_data->data = data;
1377 TBM_TRACE("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1379 _tbm_bufmgr_mutex_unlock();
1385 tbm_bo_get_user_data(tbm_bo bo, unsigned long key, void **data)
1387 tbm_user_data *old_data;
1389 _tbm_bufmgr_mutex_lock();
1391 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1392 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1394 if (!data || LIST_IS_EMPTY(&bo->user_data_list)) {
1395 TBM_TRACE("error: bo(%p) key(%lu)\n", bo, key);
1396 _tbm_bufmgr_mutex_unlock();
1400 old_data = user_data_lookup(&bo->user_data_list, key);
1402 TBM_TRACE("error: bo(%p) key(%lu)\n", bo, key);
1404 _tbm_bufmgr_mutex_unlock();
1408 *data = old_data->data;
1410 TBM_TRACE("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1412 _tbm_bufmgr_mutex_unlock();
1418 tbm_bo_delete_user_data(tbm_bo bo, unsigned long key)
1420 tbm_user_data *old_data;
1422 _tbm_bufmgr_mutex_lock();
1424 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1425 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1427 if (LIST_IS_EMPTY(&bo->user_data_list)) {
1428 TBM_TRACE("error: bo(%p) key(%lu)\n", bo, key);
1429 _tbm_bufmgr_mutex_unlock();
1433 old_data = user_data_lookup(&bo->user_data_list, key);
1435 TBM_TRACE("error: bo(%p) key(%lu)\n", bo, key);
1436 _tbm_bufmgr_mutex_unlock();
1440 TBM_TRACE("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1442 user_data_delete(old_data);
1444 _tbm_bufmgr_mutex_unlock();
1450 tbm_bufmgr_get_capability(tbm_bufmgr bufmgr)
1452 unsigned int capabilities = TBM_BUFMGR_CAPABILITY_NONE;
1454 _tbm_bufmgr_mutex_lock();
1456 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), TBM_BUFMGR_CAPABILITY_NONE);
1457 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, TBM_BUFMGR_CAPABILITY_NONE);
1459 TBM_TRACE("tbm_bufmgr(%p) capability(%u)\n", bufmgr, bufmgr->capabilities);
1461 capabilities = bufmgr->capabilities;
1463 _tbm_bufmgr_mutex_unlock();
1465 return capabilities;
1469 tbm_bo_get_flags(tbm_bo bo)
1473 _tbm_bufmgr_mutex_lock();
1475 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1476 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1480 TBM_TRACE("bo(%p)\n", bo);
1482 _tbm_bufmgr_mutex_unlock();
1487 /* LCOV_EXCL_START */
1489 tbm_get_last_error(void)
1491 return tbm_last_error;
1495 tbm_bufmgr_debug_tbm_info_get(tbm_bufmgr bufmgr, char *str, int *len)
1497 char app_name[255] = {0,}, title[512] = {0,};
1498 tbm_surface_debug_data *debug_old_data = NULL;
1500 pthread_mutex_lock(&gLock);
1502 if (!TBM_BUFMGR_IS_VALID(bufmgr) || (bufmgr != gBufMgr)) {
1503 TBM_LOG_E("invalid bufmgr\n");
1504 pthread_mutex_unlock(&gLock);
1508 TBM_SNPRINTF(str, len, "\n");
1509 _tbm_util_get_appname_from_pid(getpid(), app_name);
1510 _tbm_util_get_appname_brief(app_name);
1511 TBM_SNPRINTF(str, len, "============TBM DEBUG: %s(%d)===========================\n",
1512 app_name, getpid());
1514 snprintf(title, 255, "%s", "no surface refcnt width height bpp size n_b n_p flags format app_name ");
1516 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
1517 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
1518 strncat(title, " ", 3);
1519 strncat(title, debug_old_data->key, strlen(debug_old_data->key) + 1);
1523 TBM_SNPRINTF(str, len, "[tbm_surface information]\n");
1524 TBM_SNPRINTF(str, len, "%s\n", title);
1526 /* show the tbm_surface information in surf_list */
1527 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
1528 tbm_surface_h surf = NULL;
1531 LIST_FOR_EACH_ENTRY(surf, &bufmgr->surf_list, item_link) {
1532 char data[512] = {0,};
1536 pid = _tbm_surface_internal_get_debug_pid(surf);
1538 /* if pid is null, set the self_pid */
1542 memset(app_name, 0x0, 255 * sizeof(char));
1543 _tbm_util_get_appname_from_pid(pid, app_name);
1544 _tbm_util_get_appname_brief(app_name);
1546 snprintf(data, 255, "%-2d %-9p %-4d %-5u %-6u %-3u %-6u %-2d %-2d %-3d %-8s %-15s",
1553 surf->info.size / 1024,
1557 _tbm_surface_internal_format_to_str(surf->info.format) + 11,
1560 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
1561 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
1564 strncat(data, " ", 3);
1566 value = _tbm_surface_internal_get_debug_data(surf, debug_old_data->key);
1568 strncat(data, value, strlen(value) + 1);
1570 strncat(data, "none", 5);
1573 TBM_SNPRINTF(str, len, "%s\n", data);
1575 for (i = 0; i < surf->num_bos; i++) {
1576 TBM_SNPRINTF(str, len, " bo:%-12p %-26d%-10d\n",
1578 surf->bos[i]->ref_cnt,
1579 bufmgr->backend->bo_size(surf->bos[i]) / 1024);
1583 TBM_SNPRINTF(str, len, " no tbm_surfaces.\n");
1584 TBM_SNPRINTF(str, len, "\n");
1586 TBM_SNPRINTF(str, len, "[tbm_bo information]\n");
1587 TBM_SNPRINTF(str, len, "no bo refcnt size lock_cnt map_cnt flags surface\n");
1589 /* show the tbm_bo information in bo_list */
1590 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
1594 LIST_FOR_EACH_ENTRY(bo, &bufmgr->bo_list, item_link) {
1595 TBM_SNPRINTF(str, len, "%-4d%-11p %-4d %-6d %-5d %-4u %-3d %-11p\n",
1599 bufmgr->backend->bo_size(bo) / 1024,
1606 TBM_SNPRINTF(str, len, "no tbm_bos.\n");
1607 TBM_SNPRINTF(str, len, "\n");
1609 TBM_SNPRINTF(str, len, "===============================================================\n");
1611 pthread_mutex_unlock(&gLock);
1615 tbm_bufmgr_debug_show(tbm_bufmgr bufmgr)
1618 int len = sizeof(str);
1619 tbm_bufmgr_debug_tbm_info_get(bufmgr, str, &len);
1620 TBM_DEBUG(" %s", str);
1624 tbm_bufmgr_debug_trace(tbm_bufmgr bufmgr, int onoff)
1626 _tbm_bufmgr_mutex_lock();
1628 TBM_BUFMGR_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
1629 TBM_BUFMGR_RETURN_IF_FAIL(bufmgr == gBufMgr);
1632 TBM_LOG_D("bufmgr=%p onoff=%d\n", bufmgr, onoff);
1636 _tbm_bufmgr_mutex_unlock();
1640 tbm_bufmgr_debug_dump_set_scale(double scale)
1642 pthread_mutex_lock(&gLock);
1643 scale_factor = scale;
1644 pthread_mutex_unlock(&gLock);
1648 tbm_bufmgr_debug_queue_dump(char *path, int count, int onoff)
1650 pthread_mutex_lock(&gLock);
1653 TBM_LOG_D("count=%d onoff=%d\n", count, onoff);
1655 tbm_surface_internal_dump_end();
1660 TBM_LOG_E("path is null");
1661 pthread_mutex_unlock(&gLock);
1664 TBM_LOG_D("path=%s count=%d onoff=%d\n", path, count, onoff);
1666 if (_tbm_util_get_max_surface_size(&w, &h) == 0) {
1667 TBM_LOG_E("Fail to get tbm_surface size.\n");
1668 pthread_mutex_unlock(&gLock);
1672 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
1678 pthread_mutex_unlock(&gLock);
1683 tbm_bufmgr_debug_dump_all(char *path)
1685 int w, h, count = 0;
1686 tbm_surface_h surface = NULL;
1688 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
1689 TBM_LOG_D("path=%s\n", path);
1691 pthread_mutex_lock(&gLock);
1693 count = _tbm_util_get_max_surface_size(&w, &h);
1695 TBM_LOG_E("No tbm_surface.\n");
1696 pthread_mutex_unlock(&gLock);
1700 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
1703 LIST_FOR_EACH_ENTRY(surface, &gBufMgr->surf_list, item_link)
1704 tbm_surface_internal_dump_buffer(surface, "dump_all");
1706 tbm_surface_internal_dump_end();
1708 pthread_mutex_unlock(&gLock);
1713 /* internal function */
1715 _tbm_bufmgr_get_bufmgr(void)
1721 _tbm_bo_set_surface(tbm_bo bo, tbm_surface_h surface)
1723 _tbm_bufmgr_mutex_lock();
1725 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1726 TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1728 bo->surface = surface;
1730 _tbm_bufmgr_mutex_unlock();
1736 tbm_bufmgr_bind_native_display(tbm_bufmgr bufmgr, void *NativeDisplay)
1740 _tbm_bufmgr_mutex_lock();
1742 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1744 if (!bufmgr->backend->bufmgr_bind_native_display) {
1745 TBM_TRACE("skip: tbm_bufmgr(%p) NativeDisplay(%p)\n",
1746 bufmgr, NativeDisplay);
1747 _tbm_bufmgr_mutex_unlock();
1751 ret = bufmgr->backend->bufmgr_bind_native_display(bufmgr, NativeDisplay);
1753 TBM_LOG_E("error: tbm_bufmgr(%p) NativeDisplay(%p)\n",
1754 bufmgr, NativeDisplay);
1755 _tbm_bufmgr_mutex_unlock();
1759 TBM_TRACE("tbm_bufmgr(%p) NativeDisplay(%p)\n", bufmgr, NativeDisplay);
1761 _tbm_bufmgr_mutex_unlock();
1766 int tbm_bufmgr_get_fd_limit(void)
1770 if (getrlimit(RLIMIT_NOFILE, &lim))
1773 return (int)lim.rlim_cur;
1775 /* LCOV_EXCL_STOP */