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"
47 #define PREFIX_LIB "libtbm_"
48 #define SUFFIX_LIB ".so"
49 #define DEFAULT_LIB PREFIX_LIB"default"SUFFIX_LIB
51 /* values to indicate unspecified fields in XF86ModReqInfo. */
52 #define MAJOR_UNSPEC 0xFF
53 #define MINOR_UNSPEC 0xFF
54 #define PATCH_UNSPEC 0xFFFF
55 #define ABI_VERS_UNSPEC 0xFFFFFFFF
57 #define MODULE_VERSION_NUMERIC(maj, min, patch) \
58 ((((maj) & 0xFF) << 24) | (((min) & 0xFF) << 16) | (patch & 0xFFFF))
59 #define GET_MODULE_MAJOR_VERSION(vers) (((vers) >> 24) & 0xFF)
60 #define GET_MODULE_MINOR_VERSION(vers) (((vers) >> 16) & 0xFF)
61 #define GET_MODULE_PATCHLEVEL(vers) ((vers) & 0xFFFF)
69 pthread_mutex_t gLock = PTHREAD_MUTEX_INITIALIZER;
72 static __thread tbm_error_e tbm_last_error = TBM_ERROR_NONE;
75 _tbm_set_last_result(tbm_error_e err)
81 static int last_chk_bo_cnt = 0;
83 _tbm_util_check_bo_cnt(tbm_bufmgr bufmgr)
85 if (bufmgr->bo_cnt >= 500 && ((bufmgr->bo_cnt % 20) == 0)) {
86 if (bufmgr->bo_cnt > last_chk_bo_cnt) {
87 TBM_DEBUG("============TBM BO CNT DEBUG: bo_cnt=%d\n", bufmgr->bo_cnt);
88 tbm_bufmgr_debug_show(bufmgr);
89 last_chk_bo_cnt = bufmgr->bo_cnt;
95 _tbm_util_get_appname_brief(char *brief)
99 char temp[255] = {0,};
100 char *saveptr = NULL;
102 token = strtok_r(brief, delim, &saveptr);
104 while (token != NULL) {
105 memset(temp, 0x00, 255 * sizeof(char));
106 strncpy(temp, token, 254 * sizeof(char));
107 token = strtok_r(NULL, delim, &saveptr);
110 snprintf(brief, sizeof(temp), "%s", temp);
114 _tbm_util_get_appname_from_pid(long pid, char *str)
119 char fn_cmdline[255] = {0,};
120 char cmdline[255] = {0,};
122 snprintf(fn_cmdline, sizeof(fn_cmdline), "/proc/%ld/cmdline", app_pid);
124 fp = fopen(fn_cmdline, "r");
126 fprintf(stderr, "cannot file open /proc/%ld/cmdline", app_pid);
130 if (!fgets(cmdline, 255, fp)) {
131 fprintf(stderr, "fail to get appname for pid(%ld)\n", app_pid);
137 len = strlen(cmdline);
139 memset(cmdline, 0x00, 255);
143 snprintf(str, sizeof(cmdline), "%s", cmdline);
148 *user_data_lookup(struct list_head *user_data_list, unsigned long key)
150 tbm_user_data *user_data = NULL;
151 tbm_user_data *old_data = NULL, *tmp = NULL;
153 if (!LIST_IS_EMPTY(user_data_list)) {
154 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, user_data_list, item_link) {
155 if (old_data->key == key) {
156 user_data = old_data;
166 *user_data_create(unsigned long key, tbm_data_free data_free_func)
168 tbm_user_data *user_data = NULL;
170 user_data = calloc(1, sizeof(tbm_user_data));
174 user_data->key = key;
175 user_data->free_func = data_free_func;
176 user_data->data = (void *)0;
182 user_data_delete(tbm_user_data *user_data)
184 if (user_data->data && user_data->free_func)
185 user_data->free_func(user_data->data);
187 LIST_DEL(&user_data->item_link);
193 _bo_lock(tbm_bo bo, int device, int opt)
195 tbm_bufmgr bufmgr = bo->bufmgr;
198 if (bufmgr->backend->bo_lock)
199 ret = bufmgr->backend->bo_lock(bo, device, opt);
207 _bo_unlock(tbm_bo bo)
209 tbm_bufmgr bufmgr = bo->bufmgr;
211 if (bufmgr->backend->bo_unlock)
212 bufmgr->backend->bo_unlock(bo);
216 _tbm_bo_lock(tbm_bo bo, int device, int opt)
218 tbm_bufmgr bufmgr = NULL;
227 /* do not try to lock the bo */
228 if (bufmgr->lock_type == LOCK_TRY_NEVER)
231 if (bo->lock_cnt < 0) {
232 TBM_LOG_E("error bo:%p LOCK_CNT=%d\n",
237 if (bufmgr->lock_type == LOCK_TRY_ONCE) {
238 if (bo->lock_cnt == 0) {
239 pthread_mutex_unlock(&bufmgr->lock);
240 ret = _bo_lock(bo, device, opt);
241 pthread_mutex_lock(&bufmgr->lock);
246 } else if (bufmgr->lock_type == LOCK_TRY_ALWAYS) {
247 pthread_mutex_unlock(&bufmgr->lock);
248 ret = _bo_lock(bo, device, opt);
249 pthread_mutex_lock(&bufmgr->lock);
253 TBM_LOG_E("error bo:%p lock_type is wrong.\n",
257 DBG_LOCK(">> LOCK bo:%p(%d->%d)\n",
258 bo, old, bo->lock_cnt);
264 _tbm_bo_unlock(tbm_bo bo)
266 tbm_bufmgr bufmgr = NULL;
275 /* do not try to unlock the bo */
276 if (bufmgr->lock_type == LOCK_TRY_NEVER)
280 if (bufmgr->lock_type == LOCK_TRY_ONCE) {
281 if (bo->lock_cnt > 0) {
283 if (bo->lock_cnt == 0)
286 } else if (bufmgr->lock_type == LOCK_TRY_ALWAYS) {
287 if (bo->lock_cnt > 0) {
292 TBM_LOG_E("error bo:%p lock_type is wrong.\n",
296 if (bo->lock_cnt < 0)
299 DBG_LOCK(">> UNLOCK bo:%p(%d->%d)\n",
300 bo, old, bo->lock_cnt);
304 _tbm_bo_is_valid(tbm_bo bo)
306 tbm_bo old_data = NULL, tmp = NULL;
311 if (!LIST_IS_EMPTY(&gBufMgr->bo_list)) {
312 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &gBufMgr->bo_list, item_link) {
322 _tbm_bo_ref(tbm_bo bo)
328 _tbm_bo_unref(tbm_bo bo)
330 tbm_bufmgr bufmgr = bo->bufmgr;
331 tbm_user_data *old_data = NULL, *tmp = NULL;
333 if (bo->ref_cnt <= 0)
337 if (bo->ref_cnt == 0) {
338 /* destory the user_data_list */
339 if (!LIST_IS_EMPTY(&bo->user_data_list)) {
340 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &bo->user_data_list, item_link) {
341 DBG("free user_data\n");
342 user_data_delete(old_data);
346 if (bo->lock_cnt > 0) {
347 TBM_LOG_E("error lock_cnt:%d\n",
352 /* call the bo_free */
353 bufmgr->backend->bo_free(bo);
356 LIST_DEL(&bo->item_link);
365 /* LCOV_EXCL_START */
367 _check_version(TBMModuleVersionInfo *data)
372 abimaj = GET_ABI_MAJOR(data->abiversion);
373 abimin = GET_ABI_MINOR(data->abiversion);
375 DBG("TBM module %s: vendor=\"%s\" ABI=%d,%d\n",
376 data->modname ? data->modname : "UNKNOWN!",
377 data->vendor ? data->vendor : "UNKNOWN!", abimaj, abimin);
379 vermaj = GET_ABI_MAJOR(TBM_ABI_VERSION);
380 vermin = GET_ABI_MINOR(TBM_ABI_VERSION);
382 DBG("TBM ABI version %d.%d\n",
385 if (abimaj != vermaj) {
386 TBM_LOG_E("TBM module ABI major ver(%d) doesn't match the TBM's ver(%d)\n",
389 } else if (abimin > vermin) {
390 TBM_LOG_E("TBM module ABI minor ver(%d) is newer than the TBM's ver(%d)\n",
398 _tbm_bufmgr_load_module(tbm_bufmgr bufmgr, int fd, const char *file)
400 char path[PATH_MAX] = { 0, };
401 TBMModuleData *initdata = NULL;
404 snprintf(path, sizeof(path), BUFMGR_MODULE_DIR "/%s", file);
406 module_data = dlopen(path, RTLD_LAZY);
408 TBM_LOG_E("failed to load module: %s(%s)\n",
413 initdata = dlsym(module_data, "tbmModuleData");
416 TBMModuleVersionInfo *vers;
418 vers = initdata->vers;
419 init = initdata->init;
422 if (!_check_version(vers)) {
423 dlclose(module_data);
427 TBM_LOG_E("Error: module does not supply version information.\n");
429 dlclose(module_data);
434 if (!init(bufmgr, fd)) {
435 TBM_LOG_E("Fail to init module(%s)\n",
437 dlclose(module_data);
441 if (!bufmgr->backend || !bufmgr->backend->priv) {
442 TBM_LOG_E("Error: module(%s) wrong operation. Check backend or backend's priv.\n",
444 dlclose(module_data);
448 TBM_LOG_E("Error: module does not supply init symbol.\n");
449 dlclose(module_data);
453 TBM_LOG_E("Error: module does not have data object.\n");
454 dlclose(module_data);
458 bufmgr->module_data = module_data;
460 DBG("Success to load module(%s)\n",
467 _tbm_load_module(tbm_bufmgr bufmgr, int fd)
469 struct dirent **namelist;
470 const char *p = NULL;
474 /* load bufmgr priv from default lib */
475 ret = _tbm_bufmgr_load_module(bufmgr, fd, DEFAULT_LIB);
477 /* load bufmgr priv from configured path */
479 n = scandir(BUFMGR_MODULE_DIR, &namelist, 0, alphasort);
481 TBM_LOG_E("no files : %s\n",
485 if (!ret && strstr(namelist[n]->d_name, PREFIX_LIB)) {
486 p = strstr(namelist[n]->d_name, SUFFIX_LIB);
487 if (p && !strcmp(p, SUFFIX_LIB))
488 ret = _tbm_bufmgr_load_module(bufmgr, fd, namelist[n]->d_name);
501 tbm_bufmgr_init(int fd)
505 pthread_mutex_lock(&gLock);
507 /* LCOV_EXCL_START */
509 env = getenv("TBM_DLOG");
512 TBM_LOG_D("TBM_DLOG=%s\n", env);
519 env = getenv("TBM_DEBUG");
522 TBM_LOG_D("TBM_DEBUG=%s\n", env);
529 /* initialize buffer manager */
531 gBufMgr->ref_count++;
533 DBG("bufmgr:%p ref: fd=%d, ref_count:%d\n",
534 gBufMgr, gBufMgr->fd, gBufMgr->ref_count);
535 pthread_mutex_unlock(&gLock);
539 DBG("bufmgr init\n");
541 /* allocate bufmgr */
542 gBufMgr = calloc(1, sizeof(struct _tbm_bufmgr));
544 _tbm_set_last_result(TBM_BO_ERROR_HEAP_ALLOC_FAILED);
545 pthread_mutex_unlock(&gLock);
551 /* load bufmgr priv from env */
552 if (!_tbm_load_module(gBufMgr, gBufMgr->fd)) {
553 /* LCOV_EXCL_START */
554 _tbm_set_last_result(TBM_BO_ERROR_LOAD_MODULE_FAILED);
555 TBM_LOG_E("error : Fail to load bufmgr backend\n");
559 pthread_mutex_unlock(&gLock);
564 /* log for tbm backend_flag */
565 DBG("backend flag:%x:", gBufMgr->backend->flags);
568 gBufMgr->ref_count = 1;
570 DBG("create tizen bufmgr:%p ref_count:%d\n",
571 gBufMgr, gBufMgr->ref_count);
573 if (pthread_mutex_init(&gBufMgr->lock, NULL) != 0) {
574 /* LCOV_EXCL_START */
575 _tbm_set_last_result(TBM_BO_ERROR_THREAD_INIT_FAILED);
576 gBufMgr->backend->bufmgr_deinit(gBufMgr->backend->priv);
577 tbm_backend_free(gBufMgr->backend);
578 dlclose(gBufMgr->module_data);
581 pthread_mutex_unlock(&gLock);
586 /* setup the lock_type */
587 env = getenv("BUFMGR_LOCK_TYPE");
588 if (env && !strcmp(env, "always"))
589 gBufMgr->lock_type = LOCK_TRY_ALWAYS;
590 else if (env && !strcmp(env, "none"))
591 gBufMgr->lock_type = LOCK_TRY_NEVER;
592 else if (env && !strcmp(env, "once"))
593 gBufMgr->lock_type = LOCK_TRY_ONCE;
595 gBufMgr->lock_type = LOCK_TRY_ALWAYS;
597 DBG("BUFMGR_LOCK_TYPE=%s\n",
598 env ? env : "default:once");
600 /* intialize bo_list */
601 LIST_INITHEAD(&gBufMgr->bo_list);
603 /* intialize surf_list */
604 LIST_INITHEAD(&gBufMgr->surf_list);
606 pthread_mutex_unlock(&gLock);
611 tbm_bufmgr_deinit(tbm_bufmgr bufmgr)
613 TBM_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
618 tbm_surface_h surf = NULL;
619 tbm_surface_h tmp_surf = NULL;
621 pthread_mutex_lock(&gLock);
624 TBM_LOG_E("gBufmgr already destroy: bufmgr:%p\n", bufmgr);
625 pthread_mutex_unlock(&gLock);
630 if (bufmgr->ref_count > 0) {
631 DBG("tizen bufmgr destroy: bufmgr:%p, ref_count:%d\n",
632 bufmgr, bufmgr->ref_count);
633 pthread_mutex_unlock(&gLock);
637 /* destroy bo_list */
638 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
639 LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &bufmgr->bo_list, item_link) {
640 TBM_LOG_E("Un-freed bo(%p, ref:%d)\n",
647 /* destroy surf_list */
648 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
649 LIST_FOR_EACH_ENTRY_SAFE(surf, tmp_surf, &bufmgr->surf_list, item_link) {
650 TBM_LOG_E("Un-freed surf(%p, ref:%d)\n",
652 tbm_surface_destroy(surf);
656 /* destroy bufmgr priv */
657 bufmgr->backend->bufmgr_deinit(bufmgr->backend->priv);
658 bufmgr->backend->priv = NULL;
659 tbm_backend_free(bufmgr->backend);
660 bufmgr->backend = NULL;
662 pthread_mutex_destroy(&bufmgr->lock);
664 DBG("tizen bufmgr destroy: bufmgr:%p\n",
667 dlclose(bufmgr->module_data);
676 pthread_mutex_unlock(&gLock);
680 tbm_bo_size(tbm_bo bo)
682 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
684 tbm_bufmgr bufmgr = bo->bufmgr;
687 pthread_mutex_lock(&bufmgr->lock);
689 size = bufmgr->backend->bo_size(bo);
691 pthread_mutex_unlock(&bufmgr->lock);
697 tbm_bo_ref(tbm_bo bo)
699 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), NULL);
701 tbm_bufmgr bufmgr = bo->bufmgr;
703 pthread_mutex_lock(&bufmgr->lock);
707 pthread_mutex_unlock(&bufmgr->lock);
713 tbm_bo_unref(tbm_bo bo)
715 TBM_RETURN_IF_FAIL(_tbm_bo_is_valid(bo));
717 tbm_bufmgr bufmgr = bo->bufmgr;
719 pthread_mutex_lock(&bufmgr->lock);
723 pthread_mutex_unlock(&bufmgr->lock);
727 tbm_bo_alloc(tbm_bufmgr bufmgr, int size, int flags)
729 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr) && (size > 0), NULL);
732 void *bo_priv = NULL;
734 bo = calloc(1, sizeof(struct _tbm_bo));
736 _tbm_set_last_result(TBM_BO_ERROR_HEAP_ALLOC_FAILED);
740 _tbm_util_check_bo_cnt(bufmgr);
745 pthread_mutex_lock(&bufmgr->lock);
747 bo_priv = bufmgr->backend->bo_alloc(bo, size, flags);
749 _tbm_set_last_result(TBM_BO_ERROR_BO_ALLOC_FAILED);
751 pthread_mutex_unlock(&bufmgr->lock);
759 LIST_INITHEAD(&bo->user_data_list);
761 LIST_ADD(&bo->item_link, &bufmgr->bo_list);
763 pthread_mutex_unlock(&bufmgr->lock);
769 tbm_bo_import(tbm_bufmgr bufmgr, unsigned int key)
771 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
776 void *bo_priv = NULL;
778 _tbm_util_check_bo_cnt(bufmgr);
780 pthread_mutex_lock(&bufmgr->lock);
782 bo = calloc(1, sizeof(struct _tbm_bo));
784 pthread_mutex_unlock(&bufmgr->lock);
792 bo_priv = bufmgr->backend->bo_import(bo, key);
794 _tbm_set_last_result(TBM_BO_ERROR_IMPORT_FAILED);
796 pthread_mutex_unlock(&bufmgr->lock);
800 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
801 LIST_FOR_EACH_ENTRY_SAFE(bo2, tmp, &bufmgr->bo_list, item_link) {
802 if (bo2->priv == bo_priv) {
803 DBG("find bo(%p, ref:%d key:%d) in list\n",
804 bo2, bo2->ref_cnt, key);
808 pthread_mutex_unlock(&bufmgr->lock);
817 if (bufmgr->backend->bo_get_flags)
818 bo->flags = bufmgr->backend->bo_get_flags(bo);
820 bo->flags = TBM_BO_DEFAULT;
822 LIST_INITHEAD(&bo->user_data_list);
824 LIST_ADD(&bo->item_link, &bufmgr->bo_list);
826 pthread_mutex_unlock(&bufmgr->lock);
832 tbm_bo_import_fd(tbm_bufmgr bufmgr, tbm_fd fd)
834 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
839 void *bo_priv = NULL;
841 _tbm_util_check_bo_cnt(bufmgr);
843 pthread_mutex_lock(&bufmgr->lock);
845 bo = calloc(1, sizeof(struct _tbm_bo));
847 pthread_mutex_unlock(&bufmgr->lock);
855 bo_priv = bufmgr->backend->bo_import_fd(bo, fd);
857 _tbm_set_last_result(TBM_BO_ERROR_IMPORT_FD_FAILED);
859 pthread_mutex_unlock(&bufmgr->lock);
863 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
864 LIST_FOR_EACH_ENTRY_SAFE(bo2, tmp, &bufmgr->bo_list, item_link) {
865 if (bo2->priv == bo_priv) {
866 DBG("find bo(%p, ref:%d, fd:%d) in list\n",
867 bo2, bo2->ref_cnt, fd);
871 pthread_mutex_unlock(&bufmgr->lock);
880 if (bufmgr->backend->bo_get_flags)
881 bo->flags = bufmgr->backend->bo_get_flags(bo);
883 bo->flags = TBM_BO_DEFAULT;
885 LIST_INITHEAD(&bo->user_data_list);
887 LIST_ADD(&bo->item_link, &bufmgr->bo_list);
889 pthread_mutex_unlock(&bufmgr->lock);
895 tbm_bo_export(tbm_bo bo)
897 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
904 pthread_mutex_lock(&bufmgr->lock);
905 ret = bufmgr->backend->bo_export(bo);
907 _tbm_set_last_result(TBM_BO_ERROR_EXPORT_FAILED);
908 pthread_mutex_unlock(&bufmgr->lock);
911 pthread_mutex_unlock(&bufmgr->lock);
917 tbm_bo_export_fd(tbm_bo bo)
919 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), -1);
926 pthread_mutex_lock(&bufmgr->lock);
927 ret = bufmgr->backend->bo_export_fd(bo);
929 _tbm_set_last_result(TBM_BO_ERROR_EXPORT_FD_FAILED);
930 pthread_mutex_unlock(&bufmgr->lock);
933 pthread_mutex_unlock(&bufmgr->lock);
939 tbm_bo_get_handle(tbm_bo bo, int device)
941 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) 0);
944 tbm_bo_handle bo_handle;
948 pthread_mutex_lock(&bufmgr->lock);
949 bo_handle = bufmgr->backend->bo_get_handle(bo, device);
950 if (bo_handle.ptr == NULL) {
951 _tbm_set_last_result(TBM_BO_ERROR_GET_HANDLE_FAILED);
952 pthread_mutex_unlock(&bufmgr->lock);
953 return (tbm_bo_handle) NULL;
955 pthread_mutex_unlock(&bufmgr->lock);
961 tbm_bo_map(tbm_bo bo, int device, int opt)
963 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) 0);
966 tbm_bo_handle bo_handle;
970 pthread_mutex_lock(&bufmgr->lock);
972 if (!_tbm_bo_lock(bo, device, opt)) {
973 _tbm_set_last_result(TBM_BO_ERROR_LOCK_FAILED);
974 TBM_LOG_E("error fail to lock bo:%p)\n",
976 pthread_mutex_unlock(&bufmgr->lock);
977 return (tbm_bo_handle) NULL;
980 bo_handle = bufmgr->backend->bo_map(bo, device, opt);
981 if (bo_handle.ptr == NULL) {
982 _tbm_set_last_result(TBM_BO_ERROR_MAP_FAILED);
983 TBM_LOG_E("error fail to map bo:%p\n",
987 pthread_mutex_unlock(&bufmgr->lock);
988 return (tbm_bo_handle) NULL;
991 /* increase the map_count */
994 pthread_mutex_unlock(&bufmgr->lock);
1000 tbm_bo_unmap(tbm_bo bo)
1002 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1007 bufmgr = bo->bufmgr;
1009 pthread_mutex_lock(&bufmgr->lock);
1011 ret = bufmgr->backend->bo_unmap(bo);
1014 _tbm_set_last_result(TBM_BO_ERROR_UNMAP_FAILED);
1015 pthread_mutex_unlock(&bufmgr->lock);
1019 /* decrease the map_count */
1024 pthread_mutex_unlock(&bufmgr->lock);
1030 tbm_bo_swap(tbm_bo bo1, tbm_bo bo2)
1032 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo1), 0);
1033 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo2), 0);
1037 pthread_mutex_lock(&bo1->bufmgr->lock);
1039 if (bo1->bufmgr->backend->bo_size(bo1) != bo2->bufmgr->backend->bo_size(bo2)) {
1040 _tbm_set_last_result(TBM_BO_ERROR_SWAP_FAILED);
1041 pthread_mutex_unlock(&bo1->bufmgr->lock);
1046 bo1->priv = bo2->priv;
1049 pthread_mutex_unlock(&bo1->bufmgr->lock);
1055 tbm_bo_locked(tbm_bo bo)
1057 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1061 bufmgr = bo->bufmgr;
1063 if (bufmgr->lock_type == LOCK_TRY_NEVER)
1066 pthread_mutex_lock(&bufmgr->lock);
1068 if (bo->lock_cnt > 0) {
1069 pthread_mutex_unlock(&bufmgr->lock);
1073 pthread_mutex_unlock(&bufmgr->lock);
1079 tbm_bo_add_user_data(tbm_bo bo, unsigned long key,
1080 tbm_data_free data_free_func)
1082 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1084 tbm_user_data *data;
1086 /* check if the data according to the key exist if so, return false. */
1087 data = user_data_lookup(&bo->user_data_list, key);
1089 TBM_LOG_W("waring user data already exist. key:%ld\n",
1094 data = user_data_create(key, data_free_func);
1098 LIST_ADD(&data->item_link, &bo->user_data_list);
1104 tbm_bo_set_user_data(tbm_bo bo, unsigned long key, void *data)
1106 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1108 tbm_user_data *old_data;
1110 if (LIST_IS_EMPTY(&bo->user_data_list))
1113 old_data = user_data_lookup(&bo->user_data_list, key);
1117 if (old_data->data && old_data->free_func)
1118 old_data->free_func(old_data->data);
1120 old_data->data = data;
1126 tbm_bo_get_user_data(tbm_bo bo, unsigned long key, void **data)
1128 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1130 tbm_user_data *old_data;
1132 if (!data || LIST_IS_EMPTY(&bo->user_data_list))
1135 old_data = user_data_lookup(&bo->user_data_list, key);
1141 *data = old_data->data;
1147 tbm_bo_delete_user_data(tbm_bo bo, unsigned long key)
1149 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1151 tbm_user_data *old_data = (void *)0;
1153 if (LIST_IS_EMPTY(&bo->user_data_list))
1156 old_data = user_data_lookup(&bo->user_data_list, key);
1160 user_data_delete(old_data);
1166 tbm_bufmgr_get_capability(tbm_bufmgr bufmgr)
1168 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), 0);
1170 unsigned int capability = TBM_BUFMGR_CAPABILITY_NONE;
1172 if (bufmgr->backend->bo_import && bufmgr->backend->bo_export)
1173 capability |= TBM_BUFMGR_CAPABILITY_SHARE_KEY;
1175 if (bufmgr->backend->bo_import_fd && bufmgr->backend->bo_export_fd)
1176 capability |= TBM_BUFMGR_CAPABILITY_SHARE_FD;
1182 tbm_bo_get_flags(tbm_bo bo)
1184 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1189 /* LCOV_EXCL_START */
1191 tbm_get_last_error(void)
1193 return tbm_last_error;
1197 tbm_bufmgr_debug_show(tbm_bufmgr bufmgr)
1199 TBM_RETURN_IF_FAIL(bufmgr != NULL);
1200 tbm_bo bo = NULL, tmp_bo = NULL;
1203 tbm_surface_h surf = NULL, tmp_surf = NULL;
1206 char app_name[255] = {0,};
1207 unsigned int pid = 0;
1209 pthread_mutex_lock(&gLock);
1212 _tbm_util_get_appname_from_pid(getpid(), app_name);
1213 _tbm_util_get_appname_brief(app_name);
1214 TBM_DEBUG("============TBM DEBUG: %s(%d)===========================\n",
1215 app_name, getpid());
1216 memset(app_name, 0x0, 255 * sizeof(char));
1218 TBM_DEBUG("[tbm_surface information]\n");
1219 TBM_DEBUG("no surface refcnt width height bpp size num_bos num_planes flags format app_name\n");
1220 /* show the tbm_surface information in surf_list */
1221 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
1222 LIST_FOR_EACH_ENTRY_SAFE(surf, tmp_surf, &bufmgr->surf_list, item_link) {
1223 pid = _tbm_surface_internal_get_debug_pid(surf);
1225 /* if pid is null, set the self_pid */
1229 _tbm_util_get_appname_from_pid(pid, app_name);
1230 _tbm_util_get_appname_brief(app_name);
1232 TBM_DEBUG("%-4d%-23p%-6d%-7d%-8d%-5d%-12d%-10d%-9d%-4d%-20s%s\n",
1239 surf->info.size / 1024,
1243 _tbm_surface_internal_format_to_str(surf->info.format),
1246 for (i = 0; i < surf->num_bos; i++) {
1247 TBM_DEBUG(" bo:%-12p %-26d%-10d\n",
1249 surf->bos[i]->ref_cnt,
1250 tbm_bo_size(surf->bos[i]) / 1024);
1253 memset(app_name, 0x0, 255 * sizeof(char));
1256 TBM_DEBUG("no tbm_surfaces.\n");
1260 TBM_DEBUG("[tbm_bo information]\n");
1261 TBM_DEBUG("no bo refcnt size lock_cnt map_cnt flags surface\n");
1263 /* show the tbm_bo information in bo_list */
1264 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
1265 LIST_FOR_EACH_ENTRY_SAFE(bo, tmp_bo, &bufmgr->bo_list, item_link) {
1266 TBM_DEBUG("%-4d%-11p %-6d%-12d%-9d%-9d%-4d%-11p\n",
1270 tbm_bo_size(bo) / 1024,
1277 TBM_DEBUG("no tbm_bos.\n");
1281 TBM_DEBUG("===============================================================\n");
1283 pthread_mutex_unlock(&gLock);
1288 tbm_bufmgr_debug_trace(tbm_bufmgr bufmgr, int onoff)
1290 TBM_LOG_D("bufmgr=%p onoff=%d\n", bufmgr, onoff);
1291 TBM_LOG_D("Not implemented yet.\n");
1294 /* internal function */
1296 _tbm_bo_set_surface(tbm_bo bo, tbm_surface_h surface)
1298 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1300 bo->surface = surface;
1306 tbm_bufmgr_bind_native_display(tbm_bufmgr bufmgr, void *NativeDisplay)
1308 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), 0);
1312 pthread_mutex_lock(&bufmgr->lock);
1314 if (!bufmgr->backend->bufmgr_bind_native_display) {
1315 pthread_mutex_unlock(&bufmgr->lock);
1319 ret = bufmgr->backend->bufmgr_bind_native_display(bufmgr, NativeDisplay);
1321 pthread_mutex_unlock(&bufmgr->lock);
1325 pthread_mutex_unlock(&bufmgr->lock);
1329 /* LCOV_EXCL_STOP */