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)
82 _tbm_util_get_appname_brief(char *brief)
86 char temp[255] = {0,};
89 token = strtok_r(brief, delim, &saveptr);
91 while (token != NULL) {
92 memset(temp, 0x00, 255 * sizeof(char));
93 strncpy(temp, token, 254 * sizeof(char));
94 token = strtok_r(NULL, delim, &saveptr);
97 snprintf(brief, sizeof(temp), "%s", temp);
101 _tbm_util_get_appname_from_pid(long pid, char *str)
106 char fn_cmdline[255] = {0,};
107 char cmdline[255] = {0,};
109 snprintf(fn_cmdline, sizeof(fn_cmdline), "/proc/%ld/cmdline", app_pid);
111 fp = fopen(fn_cmdline, "r");
113 fprintf(stderr, "cannot file open /proc/%ld/cmdline", app_pid);
117 if (!fgets(cmdline, 255, fp)) {
118 fprintf(stderr, "fail to get appname for pid(%ld)\n", app_pid);
124 len = strlen(cmdline);
126 memset(cmdline, 0x00, 255);
130 snprintf(str, sizeof(cmdline), "%s", cmdline);
135 *user_data_lookup(struct list_head *user_data_list, unsigned long key)
137 tbm_user_data *user_data = NULL;
138 tbm_user_data *old_data = NULL, *tmp = NULL;
140 if (!LIST_IS_EMPTY(user_data_list)) {
141 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, user_data_list, item_link) {
142 if (old_data->key == key) {
143 user_data = old_data;
153 *user_data_create(unsigned long key, tbm_data_free data_free_func)
155 tbm_user_data *user_data = NULL;
157 user_data = calloc(1, sizeof(tbm_user_data));
161 user_data->key = key;
162 user_data->free_func = data_free_func;
163 user_data->data = (void *)0;
169 user_data_delete(tbm_user_data *user_data)
171 if (user_data->data && user_data->free_func)
172 user_data->free_func(user_data->data);
174 LIST_DEL(&user_data->item_link);
180 _bo_lock(tbm_bo bo, int device, int opt)
182 tbm_bufmgr bufmgr = bo->bufmgr;
185 if (bufmgr->backend->bo_lock)
186 ret = bufmgr->backend->bo_lock(bo, device, opt);
194 _bo_unlock(tbm_bo bo)
196 tbm_bufmgr bufmgr = bo->bufmgr;
198 if (bufmgr->backend->bo_unlock)
199 bufmgr->backend->bo_unlock(bo);
203 _tbm_bo_lock(tbm_bo bo, int device, int opt)
205 tbm_bufmgr bufmgr = NULL;
214 /* do not try to lock the bo */
215 if (bufmgr->lock_type == LOCK_TRY_NEVER)
218 if (bo->lock_cnt < 0) {
219 TBM_LOG_E("error bo:%p LOCK_CNT=%d\n",
224 if (bufmgr->lock_type == LOCK_TRY_ONCE) {
225 if (bo->lock_cnt == 0) {
226 pthread_mutex_unlock(&bufmgr->lock);
227 ret = _bo_lock(bo, device, opt);
228 pthread_mutex_lock(&bufmgr->lock);
233 } else if (bufmgr->lock_type == LOCK_TRY_ALWAYS) {
234 pthread_mutex_unlock(&bufmgr->lock);
235 ret = _bo_lock(bo, device, opt);
236 pthread_mutex_lock(&bufmgr->lock);
240 TBM_LOG_E("error bo:%p lock_type is wrong.\n",
244 DBG_LOCK(">> LOCK bo:%p(%d->%d)\n",
245 bo, old, bo->lock_cnt);
251 _tbm_bo_unlock(tbm_bo bo)
253 tbm_bufmgr bufmgr = NULL;
262 /* do not try to unlock the bo */
263 if (bufmgr->lock_type == LOCK_TRY_NEVER)
267 if (bufmgr->lock_type == LOCK_TRY_ONCE) {
268 if (bo->lock_cnt > 0) {
270 if (bo->lock_cnt == 0)
273 } else if (bufmgr->lock_type == LOCK_TRY_ALWAYS) {
274 if (bo->lock_cnt > 0) {
279 TBM_LOG_E("error bo:%p lock_type is wrong.\n",
283 if (bo->lock_cnt < 0)
286 DBG_LOCK(">> UNLOCK bo:%p(%d->%d)\n",
287 bo, old, bo->lock_cnt);
291 _tbm_bo_is_valid(tbm_bo bo)
293 tbm_bo old_data = NULL, tmp = NULL;
298 if (!LIST_IS_EMPTY(&gBufMgr->bo_list)) {
299 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &gBufMgr->bo_list, item_link) {
309 _tbm_bo_ref(tbm_bo bo)
315 _tbm_bo_unref(tbm_bo bo)
317 tbm_bufmgr bufmgr = bo->bufmgr;
318 tbm_user_data *old_data = NULL, *tmp = NULL;
320 if (bo->ref_cnt <= 0)
324 if (bo->ref_cnt == 0) {
325 /* destory the user_data_list */
326 if (!LIST_IS_EMPTY(&bo->user_data_list)) {
327 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &bo->user_data_list, item_link) {
328 DBG("free user_data\n");
329 user_data_delete(old_data);
333 if (bo->lock_cnt > 0) {
334 TBM_LOG_E("error lock_cnt:%d\n",
339 /* call the bo_free */
340 bufmgr->backend->bo_free(bo);
343 LIST_DEL(&bo->item_link);
350 /* LCOV_EXCL_START */
352 _check_version(TBMModuleVersionInfo *data)
357 abimaj = GET_ABI_MAJOR(data->abiversion);
358 abimin = GET_ABI_MINOR(data->abiversion);
360 DBG("TBM module %s: vendor=\"%s\" ABI=%d,%d\n",
361 data->modname ? data->modname : "UNKNOWN!",
362 data->vendor ? data->vendor : "UNKNOWN!", abimaj, abimin);
364 vermaj = GET_ABI_MAJOR(TBM_ABI_VERSION);
365 vermin = GET_ABI_MINOR(TBM_ABI_VERSION);
367 DBG("TBM ABI version %d.%d\n",
370 if (abimaj != vermaj) {
371 TBM_LOG_E("TBM module ABI major ver(%d) doesn't match the TBM's ver(%d)\n",
374 } else if (abimin > vermin) {
375 TBM_LOG_E("TBM module ABI minor ver(%d) is newer than the TBM's ver(%d)\n",
383 _tbm_bufmgr_load_module(tbm_bufmgr bufmgr, int fd, const char *file)
385 char path[PATH_MAX] = { 0, };
386 TBMModuleData *initdata = NULL;
389 snprintf(path, sizeof(path), BUFMGR_MODULE_DIR "/%s", file);
391 module_data = dlopen(path, RTLD_LAZY);
393 TBM_LOG_E("failed to load module: %s(%s)\n",
398 initdata = dlsym(module_data, "tbmModuleData");
401 TBMModuleVersionInfo *vers;
403 vers = initdata->vers;
404 init = initdata->init;
407 if (!_check_version(vers)) {
408 dlclose(module_data);
412 TBM_LOG_E("Error: module does not supply version information.\n");
414 dlclose(module_data);
419 if (!init(bufmgr, fd)) {
420 TBM_LOG_E("Fail to init module(%s)\n",
422 dlclose(module_data);
426 if (!bufmgr->backend || !bufmgr->backend->priv) {
427 TBM_LOG_E("Error: module(%s) wrong operation. Check backend or backend's priv.\n",
429 dlclose(module_data);
433 TBM_LOG_E("Error: module does not supply init symbol.\n");
434 dlclose(module_data);
438 TBM_LOG_E("Error: module does not have data object.\n");
439 dlclose(module_data);
443 bufmgr->module_data = module_data;
445 DBG("Success to load module(%s)\n",
452 _tbm_load_module(tbm_bufmgr bufmgr, int fd)
454 struct dirent **namelist;
455 const char *p = NULL;
459 /* load bufmgr priv from default lib */
460 ret = _tbm_bufmgr_load_module(bufmgr, fd, DEFAULT_LIB);
462 /* load bufmgr priv from configured path */
464 n = scandir(BUFMGR_MODULE_DIR, &namelist, 0, alphasort);
466 TBM_LOG_E("no files : %s\n",
470 if (!ret && strstr(namelist[n]->d_name, PREFIX_LIB)) {
471 p = strstr(namelist[n]->d_name, SUFFIX_LIB);
472 if (p && !strcmp(p, SUFFIX_LIB))
473 ret = _tbm_bufmgr_load_module(bufmgr, fd, namelist[n]->d_name);
486 tbm_bufmgr_init(int fd)
490 pthread_mutex_lock(&gLock);
492 /* LCOV_EXCL_START */
494 env = getenv("TBM_DLOG");
497 TBM_LOG_D("TBM_DLOG=%s\n", env);
504 env = getenv("TBM_DEBUG");
507 TBM_LOG_D("TBM_DEBUG=%s\n", env);
514 /* initialize buffer manager */
516 gBufMgr->ref_count++;
518 DBG("bufmgr:%p ref: fd=%d, ref_count:%d\n",
519 gBufMgr, gBufMgr->fd, gBufMgr->ref_count);
520 pthread_mutex_unlock(&gLock);
524 DBG("bufmgr init\n");
526 /* allocate bufmgr */
527 gBufMgr = calloc(1, sizeof(struct _tbm_bufmgr));
529 _tbm_set_last_result(TBM_BO_ERROR_HEAP_ALLOC_FAILED);
530 pthread_mutex_unlock(&gLock);
536 /* load bufmgr priv from env */
537 if (!_tbm_load_module(gBufMgr, gBufMgr->fd)) {
538 /* LCOV_EXCL_START */
539 _tbm_set_last_result(TBM_BO_ERROR_LOAD_MODULE_FAILED);
540 TBM_LOG_E("error : Fail to load bufmgr backend\n");
544 pthread_mutex_unlock(&gLock);
549 /* log for tbm backend_flag */
550 DBG("backend flag:%x:", gBufMgr->backend->flags);
553 gBufMgr->ref_count = 1;
555 DBG("create tizen bufmgr:%p ref_count:%d\n",
556 gBufMgr, gBufMgr->ref_count);
558 if (pthread_mutex_init(&gBufMgr->lock, NULL) != 0) {
559 /* LCOV_EXCL_START */
560 _tbm_set_last_result(TBM_BO_ERROR_THREAD_INIT_FAILED);
561 gBufMgr->backend->bufmgr_deinit(gBufMgr->backend->priv);
562 tbm_backend_free(gBufMgr->backend);
563 dlclose(gBufMgr->module_data);
566 pthread_mutex_unlock(&gLock);
571 /* setup the lock_type */
572 env = getenv("BUFMGR_LOCK_TYPE");
573 if (env && !strcmp(env, "always"))
574 gBufMgr->lock_type = LOCK_TRY_ALWAYS;
575 else if (env && !strcmp(env, "none"))
576 gBufMgr->lock_type = LOCK_TRY_NEVER;
577 else if (env && !strcmp(env, "once"))
578 gBufMgr->lock_type = LOCK_TRY_ONCE;
580 gBufMgr->lock_type = LOCK_TRY_ALWAYS;
582 DBG("BUFMGR_LOCK_TYPE=%s\n",
583 env ? env : "default:once");
585 /* intialize bo_list */
586 LIST_INITHEAD(&gBufMgr->bo_list);
588 /* intialize surf_list */
589 LIST_INITHEAD(&gBufMgr->surf_list);
591 pthread_mutex_unlock(&gLock);
596 tbm_bufmgr_deinit(tbm_bufmgr bufmgr)
598 TBM_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
603 tbm_surface_h surf = NULL;
604 tbm_surface_h tmp_surf = NULL;
606 pthread_mutex_lock(&gLock);
609 TBM_LOG_E("gBufmgr already destroy: bufmgr:%p\n", bufmgr);
610 pthread_mutex_unlock(&gLock);
615 if (bufmgr->ref_count > 0) {
616 DBG("tizen bufmgr destroy: bufmgr:%p, ref_count:%d\n",
617 bufmgr, bufmgr->ref_count);
618 pthread_mutex_unlock(&gLock);
622 /* destroy bo_list */
623 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
624 LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &bufmgr->bo_list, item_link) {
625 TBM_LOG_E("Un-freed bo(%p, ref:%d)\n",
632 /* destroy surf_list */
633 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
634 LIST_FOR_EACH_ENTRY_SAFE(surf, tmp_surf, &bufmgr->surf_list, item_link) {
635 TBM_LOG_E("Un-freed surf(%p, ref:%d)\n",
637 tbm_surface_destroy(surf);
641 /* destroy bufmgr priv */
642 bufmgr->backend->bufmgr_deinit(bufmgr->backend->priv);
643 bufmgr->backend->priv = NULL;
644 tbm_backend_free(bufmgr->backend);
645 bufmgr->backend = NULL;
647 pthread_mutex_destroy(&bufmgr->lock);
649 DBG("tizen bufmgr destroy: bufmgr:%p\n",
652 dlclose(bufmgr->module_data);
661 pthread_mutex_unlock(&gLock);
665 tbm_bo_size(tbm_bo bo)
667 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
669 tbm_bufmgr bufmgr = bo->bufmgr;
672 pthread_mutex_lock(&bufmgr->lock);
674 size = bufmgr->backend->bo_size(bo);
676 pthread_mutex_unlock(&bufmgr->lock);
682 tbm_bo_ref(tbm_bo bo)
684 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), NULL);
686 tbm_bufmgr bufmgr = bo->bufmgr;
688 pthread_mutex_lock(&bufmgr->lock);
692 pthread_mutex_unlock(&bufmgr->lock);
698 tbm_bo_unref(tbm_bo bo)
700 TBM_RETURN_IF_FAIL(_tbm_bo_is_valid(bo));
702 tbm_bufmgr bufmgr = bo->bufmgr;
704 pthread_mutex_lock(&bufmgr->lock);
708 pthread_mutex_unlock(&bufmgr->lock);
712 tbm_bo_alloc(tbm_bufmgr bufmgr, int size, int flags)
714 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr) && (size > 0), NULL);
717 void *bo_priv = NULL;
719 bo = calloc(1, sizeof(struct _tbm_bo));
721 _tbm_set_last_result(TBM_BO_ERROR_HEAP_ALLOC_FAILED);
727 pthread_mutex_lock(&bufmgr->lock);
729 bo_priv = bufmgr->backend->bo_alloc(bo, size, flags);
731 _tbm_set_last_result(TBM_BO_ERROR_BO_ALLOC_FAILED);
733 pthread_mutex_unlock(&bufmgr->lock);
741 LIST_INITHEAD(&bo->user_data_list);
743 LIST_ADD(&bo->item_link, &bufmgr->bo_list);
745 pthread_mutex_unlock(&bufmgr->lock);
751 tbm_bo_import(tbm_bufmgr bufmgr, unsigned int key)
753 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
758 void *bo_priv = NULL;
760 pthread_mutex_lock(&bufmgr->lock);
762 bo = calloc(1, sizeof(struct _tbm_bo));
764 pthread_mutex_unlock(&bufmgr->lock);
770 bo_priv = bufmgr->backend->bo_import(bo, key);
772 _tbm_set_last_result(TBM_BO_ERROR_IMPORT_FAILED);
774 pthread_mutex_unlock(&bufmgr->lock);
778 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
779 LIST_FOR_EACH_ENTRY_SAFE(bo2, tmp, &bufmgr->bo_list, item_link) {
780 if (bo2->priv == bo_priv) {
781 DBG("find bo(%p, ref:%d key:%d) in list\n",
782 bo2, bo2->ref_cnt, key);
786 pthread_mutex_unlock(&bufmgr->lock);
795 if (bufmgr->backend->bo_get_flags)
796 bo->flags = bufmgr->backend->bo_get_flags(bo);
798 bo->flags = TBM_BO_DEFAULT;
800 LIST_INITHEAD(&bo->user_data_list);
802 LIST_ADD(&bo->item_link, &bufmgr->bo_list);
804 pthread_mutex_unlock(&bufmgr->lock);
810 tbm_bo_import_fd(tbm_bufmgr bufmgr, tbm_fd fd)
812 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
817 void *bo_priv = NULL;
819 pthread_mutex_lock(&bufmgr->lock);
821 bo = calloc(1, sizeof(struct _tbm_bo));
823 pthread_mutex_unlock(&bufmgr->lock);
829 bo_priv = bufmgr->backend->bo_import_fd(bo, fd);
831 _tbm_set_last_result(TBM_BO_ERROR_IMPORT_FD_FAILED);
833 pthread_mutex_unlock(&bufmgr->lock);
837 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
838 LIST_FOR_EACH_ENTRY_SAFE(bo2, tmp, &bufmgr->bo_list, item_link) {
839 if (bo2->priv == bo_priv) {
840 DBG("find bo(%p, ref:%d, fd:%d) in list\n",
841 bo2, bo2->ref_cnt, fd);
845 pthread_mutex_unlock(&bufmgr->lock);
854 if (bufmgr->backend->bo_get_flags)
855 bo->flags = bufmgr->backend->bo_get_flags(bo);
857 bo->flags = TBM_BO_DEFAULT;
859 LIST_INITHEAD(&bo->user_data_list);
861 LIST_ADD(&bo->item_link, &bufmgr->bo_list);
863 pthread_mutex_unlock(&bufmgr->lock);
869 tbm_bo_export(tbm_bo bo)
871 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
878 pthread_mutex_lock(&bufmgr->lock);
879 ret = bufmgr->backend->bo_export(bo);
881 _tbm_set_last_result(TBM_BO_ERROR_EXPORT_FAILED);
882 pthread_mutex_unlock(&bufmgr->lock);
885 pthread_mutex_unlock(&bufmgr->lock);
891 tbm_bo_export_fd(tbm_bo bo)
893 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), -1);
900 pthread_mutex_lock(&bufmgr->lock);
901 ret = bufmgr->backend->bo_export_fd(bo);
903 _tbm_set_last_result(TBM_BO_ERROR_EXPORT_FD_FAILED);
904 pthread_mutex_unlock(&bufmgr->lock);
907 pthread_mutex_unlock(&bufmgr->lock);
913 tbm_bo_get_handle(tbm_bo bo, int device)
915 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) 0);
918 tbm_bo_handle bo_handle;
922 pthread_mutex_lock(&bufmgr->lock);
923 bo_handle = bufmgr->backend->bo_get_handle(bo, device);
924 if (bo_handle.ptr == NULL) {
925 _tbm_set_last_result(TBM_BO_ERROR_GET_HANDLE_FAILED);
926 pthread_mutex_unlock(&bufmgr->lock);
927 return (tbm_bo_handle) NULL;
929 pthread_mutex_unlock(&bufmgr->lock);
935 tbm_bo_map(tbm_bo bo, int device, int opt)
937 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) 0);
940 tbm_bo_handle bo_handle;
944 pthread_mutex_lock(&bufmgr->lock);
946 if (!_tbm_bo_lock(bo, device, opt)) {
947 _tbm_set_last_result(TBM_BO_ERROR_LOCK_FAILED);
948 TBM_LOG_E("error fail to lock bo:%p)\n",
950 pthread_mutex_unlock(&bufmgr->lock);
951 return (tbm_bo_handle) NULL;
954 bo_handle = bufmgr->backend->bo_map(bo, device, opt);
955 if (bo_handle.ptr == NULL) {
956 _tbm_set_last_result(TBM_BO_ERROR_MAP_FAILED);
957 TBM_LOG_E("error fail to map bo:%p\n",
961 pthread_mutex_unlock(&bufmgr->lock);
962 return (tbm_bo_handle) NULL;
965 /* increase the map_count */
968 pthread_mutex_unlock(&bufmgr->lock);
974 tbm_bo_unmap(tbm_bo bo)
976 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
983 pthread_mutex_lock(&bufmgr->lock);
985 ret = bufmgr->backend->bo_unmap(bo);
988 _tbm_set_last_result(TBM_BO_ERROR_UNMAP_FAILED);
989 pthread_mutex_unlock(&bufmgr->lock);
993 /* decrease the map_count */
998 pthread_mutex_unlock(&bufmgr->lock);
1004 tbm_bo_swap(tbm_bo bo1, tbm_bo bo2)
1006 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo1), 0);
1007 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo2), 0);
1011 pthread_mutex_lock(&bo1->bufmgr->lock);
1013 if (bo1->bufmgr->backend->bo_size(bo1) != bo2->bufmgr->backend->bo_size(bo2)) {
1014 _tbm_set_last_result(TBM_BO_ERROR_SWAP_FAILED);
1015 pthread_mutex_unlock(&bo1->bufmgr->lock);
1020 bo1->priv = bo2->priv;
1023 pthread_mutex_unlock(&bo1->bufmgr->lock);
1029 tbm_bo_locked(tbm_bo bo)
1031 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1035 bufmgr = bo->bufmgr;
1037 if (bufmgr->lock_type == LOCK_TRY_NEVER)
1040 pthread_mutex_lock(&bufmgr->lock);
1042 if (bo->lock_cnt > 0) {
1043 pthread_mutex_unlock(&bufmgr->lock);
1047 pthread_mutex_unlock(&bufmgr->lock);
1053 tbm_bo_add_user_data(tbm_bo bo, unsigned long key,
1054 tbm_data_free data_free_func)
1056 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1058 tbm_user_data *data;
1060 /* check if the data according to the key exist if so, return false. */
1061 data = user_data_lookup(&bo->user_data_list, key);
1063 TBM_LOG_W("waring user data already exist. key:%ld\n",
1068 data = user_data_create(key, data_free_func);
1072 LIST_ADD(&data->item_link, &bo->user_data_list);
1078 tbm_bo_set_user_data(tbm_bo bo, unsigned long key, void *data)
1080 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1082 tbm_user_data *old_data;
1084 if (LIST_IS_EMPTY(&bo->user_data_list))
1087 old_data = user_data_lookup(&bo->user_data_list, key);
1091 if (old_data->data && old_data->free_func)
1092 old_data->free_func(old_data->data);
1094 old_data->data = data;
1100 tbm_bo_get_user_data(tbm_bo bo, unsigned long key, void **data)
1102 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1104 tbm_user_data *old_data;
1106 if (!data || LIST_IS_EMPTY(&bo->user_data_list))
1109 old_data = user_data_lookup(&bo->user_data_list, key);
1115 *data = old_data->data;
1121 tbm_bo_delete_user_data(tbm_bo bo, unsigned long key)
1123 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1125 tbm_user_data *old_data = (void *)0;
1127 if (LIST_IS_EMPTY(&bo->user_data_list))
1130 old_data = user_data_lookup(&bo->user_data_list, key);
1134 user_data_delete(old_data);
1140 tbm_bufmgr_get_capability(tbm_bufmgr bufmgr)
1142 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), 0);
1144 unsigned int capability = TBM_BUFMGR_CAPABILITY_NONE;
1146 if (bufmgr->backend->bo_import && bufmgr->backend->bo_export)
1147 capability |= TBM_BUFMGR_CAPABILITY_SHARE_KEY;
1149 if (bufmgr->backend->bo_import_fd && bufmgr->backend->bo_export_fd)
1150 capability |= TBM_BUFMGR_CAPABILITY_SHARE_FD;
1156 tbm_bo_get_flags(tbm_bo bo)
1158 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1163 /* LCOV_EXCL_START */
1165 tbm_get_last_error(void)
1167 return tbm_last_error;
1171 tbm_bufmgr_debug_show(tbm_bufmgr bufmgr)
1173 TBM_RETURN_IF_FAIL(bufmgr != NULL);
1174 tbm_bo bo = NULL, tmp_bo = NULL;
1177 tbm_surface_h surf = NULL, tmp_surf = NULL;
1180 char app_name[255] = {0,};
1181 unsigned int pid = 0;
1183 pthread_mutex_lock(&gLock);
1186 _tbm_util_get_appname_from_pid(getpid(), app_name);
1187 _tbm_util_get_appname_brief(app_name);
1188 TBM_DEBUG("============TBM DEBUG: %s(%d)===========================\n",
1189 app_name, getpid());
1190 memset(app_name, 0x0, 255 * sizeof(char));
1192 TBM_DEBUG("[tbm_surface information]\n");
1193 TBM_DEBUG("no surface refcnt width height bpp size num_bos num_planes flags format app_name\n");
1194 /* show the tbm_surface information in surf_list */
1195 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
1196 LIST_FOR_EACH_ENTRY_SAFE(surf, tmp_surf, &bufmgr->surf_list, item_link) {
1197 pid = _tbm_surface_internal_get_debug_pid(surf);
1199 /* if pid is null, set the self_pid */
1203 _tbm_util_get_appname_from_pid(pid, app_name);
1204 _tbm_util_get_appname_brief(app_name);
1206 TBM_DEBUG("%-4d%-23p%-6d%-7d%-8d%-5d%-12d%-10d%-9d%-4d%-20s%s\n",
1213 surf->info.size / 1024,
1217 _tbm_surface_internal_format_to_str(surf->info.format),
1220 for (i = 0; i < surf->num_bos; i++) {
1221 TBM_DEBUG(" bo:%-12p %-26d%-10d\n",
1223 surf->bos[i]->ref_cnt,
1224 tbm_bo_size(surf->bos[i]) / 1024);
1227 memset(app_name, 0x0, 255 * sizeof(char));
1230 TBM_DEBUG("no tbm_surfaces.\n");
1234 TBM_DEBUG("[tbm_bo information]\n");
1235 TBM_DEBUG("no bo refcnt size lock_cnt map_cnt flags surface\n");
1237 /* show the tbm_bo information in bo_list */
1238 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
1239 LIST_FOR_EACH_ENTRY_SAFE(bo, tmp_bo, &bufmgr->bo_list, item_link) {
1240 TBM_DEBUG("%-4d%-11p %-6d%-12d%-9d%-9d%-4d%-11p\n",
1244 tbm_bo_size(bo) / 1024,
1251 TBM_DEBUG("no tbm_bos.\n");
1255 TBM_DEBUG("===============================================================\n");
1257 pthread_mutex_unlock(&gLock);
1262 tbm_bufmgr_debug_trace(tbm_bufmgr bufmgr, int onoff)
1264 TBM_LOG_D("bufmgr=%p onoff=%d\n", bufmgr, onoff);
1265 TBM_LOG_D("Not implemented yet.\n");
1268 /* internal function */
1270 _tbm_bo_set_surface(tbm_bo bo, tbm_surface_h surface)
1272 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1274 bo->surface = surface;
1280 tbm_bufmgr_bind_native_display(tbm_bufmgr bufmgr, void *NativeDisplay)
1282 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), 0);
1286 pthread_mutex_lock(&bufmgr->lock);
1288 if (!bufmgr->backend->bufmgr_bind_native_display) {
1289 pthread_mutex_unlock(&bufmgr->lock);
1293 ret = bufmgr->backend->bufmgr_bind_native_display(bufmgr, NativeDisplay);
1295 pthread_mutex_unlock(&bufmgr->lock);
1299 pthread_mutex_unlock(&bufmgr->lock);
1303 /* LCOV_EXCL_STOP */