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);
195 _bo_unlock(tbm_bo bo)
197 tbm_bufmgr bufmgr = bo->bufmgr;
199 if (bufmgr->backend->bo_unlock) {
200 bufmgr->backend->bo_unlock(bo);
205 _tbm_bo_lock(tbm_bo bo, int device, int opt)
207 tbm_bufmgr bufmgr = NULL;
216 /* do not try to lock the bo */
217 if (bufmgr->lock_type == LOCK_TRY_NEVER)
220 if (bo->lock_cnt < 0) {
221 TBM_LOG_E("error bo:%p LOCK_CNT=%d\n",
226 if (bufmgr->lock_type == LOCK_TRY_ONCE) {
227 if (bo->lock_cnt == 0) {
228 pthread_mutex_unlock(&bufmgr->lock);
229 ret = _bo_lock(bo, device, opt);
230 pthread_mutex_lock(&bufmgr->lock);
235 } else if (bufmgr->lock_type == LOCK_TRY_ALWAYS) {
236 pthread_mutex_unlock(&bufmgr->lock);
237 ret = _bo_lock(bo, device, opt);
238 pthread_mutex_lock(&bufmgr->lock);
242 TBM_LOG_E("error bo:%p lock_type is wrong.\n",
246 DBG_LOCK(">> LOCK bo:%p(%d->%d)\n",
247 bo, old, bo->lock_cnt);
253 _tbm_bo_unlock(tbm_bo bo)
255 tbm_bufmgr bufmgr = NULL;
264 /* do not try to unlock the bo */
265 if (bufmgr->lock_type == LOCK_TRY_NEVER)
269 if (bufmgr->lock_type == LOCK_TRY_ONCE) {
270 if (bo->lock_cnt > 0) {
272 if (bo->lock_cnt == 0)
275 } else if (bufmgr->lock_type == LOCK_TRY_ALWAYS) {
276 if (bo->lock_cnt > 0) {
281 TBM_LOG_E("error bo:%p lock_type is wrong.\n",
285 if (bo->lock_cnt < 0)
288 DBG_LOCK(">> UNLOCK bo:%p(%d->%d)\n",
289 bo, old, bo->lock_cnt);
293 _tbm_bo_is_valid(tbm_bo bo)
295 tbm_bo old_data = NULL, tmp = NULL;
300 if (!LIST_IS_EMPTY(&gBufMgr->bo_list)) {
301 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &gBufMgr->bo_list, item_link) {
311 _tbm_bo_ref(tbm_bo bo)
317 _tbm_bo_unref(tbm_bo bo)
319 tbm_bufmgr bufmgr = bo->bufmgr;
320 tbm_user_data *old_data = NULL, *tmp = NULL;
322 if (bo->ref_cnt <= 0)
326 if (bo->ref_cnt == 0) {
327 /* destory the user_data_list */
328 if (!LIST_IS_EMPTY(&bo->user_data_list)) {
329 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &bo->user_data_list, item_link) {
330 DBG("free user_data\n");
331 user_data_delete(old_data);
335 if (bo->lock_cnt > 0) {
336 TBM_LOG_E("error lock_cnt:%d\n",
341 /* call the bo_free */
342 bufmgr->backend->bo_free(bo);
345 LIST_DEL(&bo->item_link);
352 /* LCOV_EXCL_START */
354 _check_version(TBMModuleVersionInfo *data)
359 abimaj = GET_ABI_MAJOR(data->abiversion);
360 abimin = GET_ABI_MINOR(data->abiversion);
362 DBG("TBM module %s: vendor=\"%s\" ABI=%d,%d\n",
363 data->modname ? data->modname : "UNKNOWN!",
364 data->vendor ? data->vendor : "UNKNOWN!", abimaj, abimin);
366 vermaj = GET_ABI_MAJOR(TBM_ABI_VERSION);
367 vermin = GET_ABI_MINOR(TBM_ABI_VERSION);
369 DBG("TBM ABI version %d.%d\n",
372 if (abimaj != vermaj) {
373 TBM_LOG_E("TBM module ABI major ver(%d) doesn't match the TBM's ver(%d)\n",
376 } else if (abimin > vermin) {
377 TBM_LOG_E("TBM module ABI minor ver(%d) is newer than the TBM's ver(%d)\n",
385 _tbm_bufmgr_load_module(tbm_bufmgr bufmgr, int fd, const char *file)
387 char path[PATH_MAX] = { 0, };
388 TBMModuleData *initdata = NULL;
391 snprintf(path, sizeof(path), BUFMGR_MODULE_DIR "/%s", file);
393 module_data = dlopen(path, RTLD_LAZY);
395 TBM_LOG_E("failed to load module: %s(%s)\n",
400 initdata = dlsym(module_data, "tbmModuleData");
403 TBMModuleVersionInfo *vers;
405 vers = initdata->vers;
406 init = initdata->init;
409 if (!_check_version(vers)) {
410 dlclose(module_data);
414 TBM_LOG_E("Error: module does not supply version information.\n");
416 dlclose(module_data);
421 if (!init(bufmgr, fd)) {
422 TBM_LOG_E("Fail to init module(%s)\n",
424 dlclose(module_data);
428 if (!bufmgr->backend || !bufmgr->backend->priv) {
429 TBM_LOG_E("Error: module(%s) wrong operation. Check backend or backend's priv.\n",
431 dlclose(module_data);
435 TBM_LOG_E("Error: module does not supply init symbol.\n");
436 dlclose(module_data);
440 TBM_LOG_E("Error: module does not have data object.\n");
441 dlclose(module_data);
445 bufmgr->module_data = module_data;
447 DBG("Success to load module(%s)\n",
454 _tbm_load_module(tbm_bufmgr bufmgr, int fd)
456 struct dirent **namelist;
457 const char *p = NULL;
461 /* load bufmgr priv from default lib */
462 ret = _tbm_bufmgr_load_module(bufmgr, fd, DEFAULT_LIB);
464 /* load bufmgr priv from configured path */
466 n = scandir(BUFMGR_MODULE_DIR, &namelist, 0, alphasort);
468 TBM_LOG_E("no files : %s\n",
472 if (!ret && strstr(namelist[n]->d_name, PREFIX_LIB)) {
473 p = strstr(namelist[n]->d_name, SUFFIX_LIB);
474 if (p && !strcmp(p, SUFFIX_LIB))
475 ret = _tbm_bufmgr_load_module(bufmgr, fd, namelist[n]->d_name);
488 tbm_bufmgr_init(int fd)
492 pthread_mutex_lock(&gLock);
494 /* LCOV_EXCL_START */
496 env = getenv("TBM_DLOG");
499 TBM_LOG_D("TBM_DLOG=%s\n", env);
506 env = getenv("TBM_DEBUG");
509 TBM_LOG_D("TBM_DEBUG=%s\n", env);
516 /* initialize buffer manager */
518 gBufMgr->ref_count++;
520 DBG("bufmgr:%p ref: fd=%d, ref_count:%d\n",
521 gBufMgr, gBufMgr->fd, gBufMgr->ref_count);
522 pthread_mutex_unlock(&gLock);
526 DBG("bufmgr init\n");
528 /* allocate bufmgr */
529 gBufMgr = calloc(1, sizeof(struct _tbm_bufmgr));
531 _tbm_set_last_result(TBM_BO_ERROR_HEAP_ALLOC_FAILED);
532 pthread_mutex_unlock(&gLock);
538 /* load bufmgr priv from env */
539 if (!_tbm_load_module(gBufMgr, gBufMgr->fd)) {
540 /* LCOV_EXCL_START */
541 _tbm_set_last_result(TBM_BO_ERROR_LOAD_MODULE_FAILED);
542 TBM_LOG_E("error : Fail to load bufmgr backend\n");
546 pthread_mutex_unlock(&gLock);
551 /* log for tbm backend_flag */
552 DBG("backend flag:%x:", gBufMgr->backend->flags);
555 gBufMgr->ref_count = 1;
557 DBG("create tizen bufmgr:%p ref_count:%d\n",
558 gBufMgr, gBufMgr->ref_count);
560 if (pthread_mutex_init(&gBufMgr->lock, NULL) != 0) {
561 /* LCOV_EXCL_START */
562 _tbm_set_last_result(TBM_BO_ERROR_THREAD_INIT_FAILED);
563 gBufMgr->backend->bufmgr_deinit(gBufMgr->backend->priv);
564 tbm_backend_free(gBufMgr->backend);
565 dlclose(gBufMgr->module_data);
568 pthread_mutex_unlock(&gLock);
573 /* setup the lock_type */
574 env = getenv("BUFMGR_LOCK_TYPE");
575 if (env && !strcmp(env, "always"))
576 gBufMgr->lock_type = LOCK_TRY_ALWAYS;
577 else if (env && !strcmp(env, "none"))
578 gBufMgr->lock_type = LOCK_TRY_NEVER;
579 else if (env && !strcmp(env, "once"))
580 gBufMgr->lock_type = LOCK_TRY_ONCE;
582 gBufMgr->lock_type = LOCK_TRY_ALWAYS;
584 DBG("BUFMGR_LOCK_TYPE=%s\n",
585 env ? env : "default:once");
587 /* intialize bo_list */
588 LIST_INITHEAD(&gBufMgr->bo_list);
590 /* intialize surf_list */
591 LIST_INITHEAD(&gBufMgr->surf_list);
593 pthread_mutex_unlock(&gLock);
598 tbm_bufmgr_deinit(tbm_bufmgr bufmgr)
600 TBM_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
605 tbm_surface_h surf = NULL;
606 tbm_surface_h tmp_surf = NULL;
608 pthread_mutex_lock(&gLock);
611 TBM_LOG_E("gBufmgr already destroy: bufmgr:%p\n", bufmgr);
612 pthread_mutex_unlock(&gLock);
617 if (bufmgr->ref_count > 0) {
618 DBG("tizen bufmgr destroy: bufmgr:%p, ref_count:%d\n",
619 bufmgr, bufmgr->ref_count);
620 pthread_mutex_unlock(&gLock);
624 /* destroy bo_list */
625 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
626 LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &bufmgr->bo_list, item_link) {
627 TBM_LOG_E("Un-freed bo(%p, ref:%d)\n",
634 /* destroy surf_list */
635 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
636 LIST_FOR_EACH_ENTRY_SAFE(surf, tmp_surf, &bufmgr->surf_list, item_link) {
637 TBM_LOG_E("Un-freed surf(%p, ref:%d)\n",
639 tbm_surface_destroy(surf);
643 /* destroy bufmgr priv */
644 bufmgr->backend->bufmgr_deinit(bufmgr->backend->priv);
645 bufmgr->backend->priv = NULL;
646 tbm_backend_free(bufmgr->backend);
647 bufmgr->backend = NULL;
649 pthread_mutex_destroy(&bufmgr->lock);
651 DBG("tizen bufmgr destroy: bufmgr:%p\n",
654 dlclose(bufmgr->module_data);
663 pthread_mutex_unlock(&gLock);
667 tbm_bo_size(tbm_bo bo)
669 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
671 tbm_bufmgr bufmgr = bo->bufmgr;
674 pthread_mutex_lock(&bufmgr->lock);
676 size = bufmgr->backend->bo_size(bo);
678 pthread_mutex_unlock(&bufmgr->lock);
684 tbm_bo_ref(tbm_bo bo)
686 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), NULL);
688 tbm_bufmgr bufmgr = bo->bufmgr;
690 pthread_mutex_lock(&bufmgr->lock);
694 pthread_mutex_unlock(&bufmgr->lock);
700 tbm_bo_unref(tbm_bo bo)
702 TBM_RETURN_IF_FAIL(_tbm_bo_is_valid(bo));
704 tbm_bufmgr bufmgr = bo->bufmgr;
706 pthread_mutex_lock(&bufmgr->lock);
710 pthread_mutex_unlock(&bufmgr->lock);
714 tbm_bo_alloc(tbm_bufmgr bufmgr, int size, int flags)
716 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr) && (size > 0), NULL);
719 void *bo_priv = NULL;
721 bo = calloc(1, sizeof(struct _tbm_bo));
723 _tbm_set_last_result(TBM_BO_ERROR_HEAP_ALLOC_FAILED);
729 pthread_mutex_lock(&bufmgr->lock);
731 bo_priv = bufmgr->backend->bo_alloc(bo, size, flags);
733 _tbm_set_last_result(TBM_BO_ERROR_BO_ALLOC_FAILED);
735 pthread_mutex_unlock(&bufmgr->lock);
743 LIST_INITHEAD(&bo->user_data_list);
745 LIST_ADD(&bo->item_link, &bufmgr->bo_list);
747 pthread_mutex_unlock(&bufmgr->lock);
753 tbm_bo_import(tbm_bufmgr bufmgr, unsigned int key)
755 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
760 void *bo_priv = NULL;
762 pthread_mutex_lock(&bufmgr->lock);
764 bo = calloc(1, sizeof(struct _tbm_bo));
766 pthread_mutex_unlock(&bufmgr->lock);
772 bo_priv = bufmgr->backend->bo_import(bo, key);
774 _tbm_set_last_result(TBM_BO_ERROR_IMPORT_FAILED);
776 pthread_mutex_unlock(&bufmgr->lock);
780 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
781 LIST_FOR_EACH_ENTRY_SAFE(bo2, tmp, &bufmgr->bo_list, item_link) {
782 if (bo2->priv == bo_priv) {
783 DBG("find bo(%p, ref:%d key:%d) in list\n",
784 bo2, bo2->ref_cnt, key);
788 pthread_mutex_unlock(&bufmgr->lock);
797 if (bufmgr->backend->bo_get_flags)
798 bo->flags = bufmgr->backend->bo_get_flags(bo);
800 bo->flags = TBM_BO_DEFAULT;
802 LIST_INITHEAD(&bo->user_data_list);
804 LIST_ADD(&bo->item_link, &bufmgr->bo_list);
806 pthread_mutex_unlock(&bufmgr->lock);
812 tbm_bo_import_fd(tbm_bufmgr bufmgr, tbm_fd fd)
814 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
819 void *bo_priv = NULL;
821 pthread_mutex_lock(&bufmgr->lock);
823 bo = calloc(1, sizeof(struct _tbm_bo));
825 pthread_mutex_unlock(&bufmgr->lock);
831 bo_priv = bufmgr->backend->bo_import_fd(bo, fd);
833 _tbm_set_last_result(TBM_BO_ERROR_IMPORT_FD_FAILED);
835 pthread_mutex_unlock(&bufmgr->lock);
839 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
840 LIST_FOR_EACH_ENTRY_SAFE(bo2, tmp, &bufmgr->bo_list, item_link) {
841 if (bo2->priv == bo_priv) {
842 DBG("find bo(%p, ref:%d, fd:%d) in list\n",
843 bo2, bo2->ref_cnt, fd);
847 pthread_mutex_unlock(&bufmgr->lock);
856 if (bufmgr->backend->bo_get_flags)
857 bo->flags = bufmgr->backend->bo_get_flags(bo);
859 bo->flags = TBM_BO_DEFAULT;
861 LIST_INITHEAD(&bo->user_data_list);
863 LIST_ADD(&bo->item_link, &bufmgr->bo_list);
865 pthread_mutex_unlock(&bufmgr->lock);
871 tbm_bo_export(tbm_bo bo)
873 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
880 pthread_mutex_lock(&bufmgr->lock);
881 ret = bufmgr->backend->bo_export(bo);
883 _tbm_set_last_result(TBM_BO_ERROR_EXPORT_FAILED);
884 pthread_mutex_unlock(&bufmgr->lock);
887 pthread_mutex_unlock(&bufmgr->lock);
893 tbm_bo_export_fd(tbm_bo bo)
895 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), -1);
902 pthread_mutex_lock(&bufmgr->lock);
903 ret = bufmgr->backend->bo_export_fd(bo);
905 _tbm_set_last_result(TBM_BO_ERROR_EXPORT_FD_FAILED);
906 pthread_mutex_unlock(&bufmgr->lock);
909 pthread_mutex_unlock(&bufmgr->lock);
915 tbm_bo_get_handle(tbm_bo bo, int device)
917 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) 0);
920 tbm_bo_handle bo_handle;
924 pthread_mutex_lock(&bufmgr->lock);
925 bo_handle = bufmgr->backend->bo_get_handle(bo, device);
926 if (bo_handle.ptr == NULL) {
927 _tbm_set_last_result(TBM_BO_ERROR_GET_HANDLE_FAILED);
928 pthread_mutex_unlock(&bufmgr->lock);
929 return (tbm_bo_handle) NULL;
931 pthread_mutex_unlock(&bufmgr->lock);
937 tbm_bo_map(tbm_bo bo, int device, int opt)
939 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) 0);
942 tbm_bo_handle bo_handle;
946 pthread_mutex_lock(&bufmgr->lock);
948 if (!_tbm_bo_lock(bo, device, opt)) {
949 _tbm_set_last_result(TBM_BO_ERROR_LOCK_FAILED);
950 TBM_LOG_E("error fail to lock bo:%p)\n",
952 pthread_mutex_unlock(&bufmgr->lock);
953 return (tbm_bo_handle) NULL;
956 bo_handle = bufmgr->backend->bo_map(bo, device, opt);
957 if (bo_handle.ptr == NULL) {
958 _tbm_set_last_result(TBM_BO_ERROR_MAP_FAILED);
959 TBM_LOG_E("error fail to map bo:%p\n",
963 pthread_mutex_unlock(&bufmgr->lock);
964 return (tbm_bo_handle) NULL;
967 /* increase the map_count */
970 pthread_mutex_unlock(&bufmgr->lock);
976 tbm_bo_unmap(tbm_bo bo)
978 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
985 pthread_mutex_lock(&bufmgr->lock);
987 ret = bufmgr->backend->bo_unmap(bo);
990 _tbm_set_last_result(TBM_BO_ERROR_UNMAP_FAILED);
991 pthread_mutex_unlock(&bufmgr->lock);
995 /* decrease the map_count */
1000 pthread_mutex_unlock(&bufmgr->lock);
1006 tbm_bo_swap(tbm_bo bo1, tbm_bo bo2)
1008 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo1), 0);
1009 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo2), 0);
1013 pthread_mutex_lock(&bo1->bufmgr->lock);
1015 if (bo1->bufmgr->backend->bo_size(bo1) != bo2->bufmgr->backend->bo_size(bo2)) {
1016 _tbm_set_last_result(TBM_BO_ERROR_SWAP_FAILED);
1017 pthread_mutex_unlock(&bo1->bufmgr->lock);
1022 bo1->priv = bo2->priv;
1025 pthread_mutex_unlock(&bo1->bufmgr->lock);
1031 tbm_bo_locked(tbm_bo bo)
1033 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1037 bufmgr = bo->bufmgr;
1039 if (bufmgr->lock_type == LOCK_TRY_NEVER)
1042 pthread_mutex_lock(&bufmgr->lock);
1044 if (bo->lock_cnt > 0) {
1045 pthread_mutex_unlock(&bufmgr->lock);
1049 pthread_mutex_unlock(&bufmgr->lock);
1055 tbm_bo_add_user_data(tbm_bo bo, unsigned long key,
1056 tbm_data_free data_free_func)
1058 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1060 tbm_user_data *data;
1062 /* check if the data according to the key exist if so, return false. */
1063 data = user_data_lookup(&bo->user_data_list, key);
1065 TBM_LOG_W("waring user data already exist. key:%ld\n",
1070 data = user_data_create(key, data_free_func);
1074 LIST_ADD(&data->item_link, &bo->user_data_list);
1080 tbm_bo_set_user_data(tbm_bo bo, unsigned long key, void *data)
1082 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1084 tbm_user_data *old_data;
1086 if (LIST_IS_EMPTY(&bo->user_data_list))
1089 old_data = user_data_lookup(&bo->user_data_list, key);
1093 if (old_data->data && old_data->free_func)
1094 old_data->free_func(old_data->data);
1096 old_data->data = data;
1102 tbm_bo_get_user_data(tbm_bo bo, unsigned long key, void **data)
1104 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1106 tbm_user_data *old_data;
1108 if (!data || LIST_IS_EMPTY(&bo->user_data_list))
1111 old_data = user_data_lookup(&bo->user_data_list, key);
1117 *data = old_data->data;
1123 tbm_bo_delete_user_data(tbm_bo bo, unsigned long key)
1125 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1127 tbm_user_data *old_data = (void *)0;
1129 if (LIST_IS_EMPTY(&bo->user_data_list))
1132 old_data = user_data_lookup(&bo->user_data_list, key);
1136 user_data_delete(old_data);
1142 tbm_bufmgr_get_capability(tbm_bufmgr bufmgr)
1144 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), 0);
1146 unsigned int capability = TBM_BUFMGR_CAPABILITY_NONE;
1148 if (bufmgr->backend->bo_import && bufmgr->backend->bo_export)
1149 capability |= TBM_BUFMGR_CAPABILITY_SHARE_KEY;
1151 if (bufmgr->backend->bo_import_fd && bufmgr->backend->bo_export_fd)
1152 capability |= TBM_BUFMGR_CAPABILITY_SHARE_FD;
1158 tbm_bo_get_flags(tbm_bo bo)
1160 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1165 /* LCOV_EXCL_START */
1167 tbm_get_last_error(void)
1169 return tbm_last_error;
1173 tbm_bufmgr_debug_show(tbm_bufmgr bufmgr)
1175 TBM_RETURN_IF_FAIL(bufmgr != NULL);
1176 tbm_bo bo = NULL, tmp_bo = NULL;
1179 tbm_surface_h surf = NULL, tmp_surf = NULL;
1182 char app_name[255] = {0,};
1183 unsigned int pid = 0;
1185 pthread_mutex_lock(&gLock);
1188 _tbm_util_get_appname_from_pid(getpid(), app_name);
1189 _tbm_util_get_appname_brief(app_name);
1190 TBM_DEBUG("============TBM DEBUG: %s(%d)===========================\n",
1191 app_name, getpid());
1192 memset(app_name, 0x0, 255 * sizeof(char));
1194 TBM_DEBUG("[tbm_surface information]\n");
1195 TBM_DEBUG("no surface refcnt width height bpp size num_bos num_planes flags format app_name\n");
1196 /* show the tbm_surface information in surf_list */
1197 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
1198 LIST_FOR_EACH_ENTRY_SAFE(surf, tmp_surf, &bufmgr->surf_list, item_link) {
1199 pid = _tbm_surface_internal_get_debug_pid(surf);
1201 /* if pid is null, set the self_pid */
1205 _tbm_util_get_appname_from_pid(pid, app_name);
1206 _tbm_util_get_appname_brief(app_name);
1208 TBM_DEBUG("%-4d%-23p%-6d%-7d%-8d%-5d%-12d%-10d%-9d%-4d%-20s%s\n",
1215 surf->info.size / 1024,
1219 _tbm_surface_internal_format_to_str(surf->info.format),
1222 for (i = 0; i < surf->num_bos; i++) {
1223 TBM_DEBUG(" bo:%-12p %-26d%-10d\n",
1225 surf->bos[i]->ref_cnt,
1226 tbm_bo_size(surf->bos[i]) / 1024);
1229 memset(app_name, 0x0, 255 * sizeof(char));
1232 TBM_DEBUG("no tbm_surfaces.\n");
1236 TBM_DEBUG("[tbm_bo information]\n");
1237 TBM_DEBUG("no bo refcnt size lock_cnt map_cnt flags surface\n");
1239 /* show the tbm_bo information in bo_list */
1240 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
1241 LIST_FOR_EACH_ENTRY_SAFE(bo, tmp_bo, &bufmgr->bo_list, item_link) {
1242 TBM_DEBUG("%-4d%-11p %-6d%-12d%-9d%-9d%-4d%-11p\n",
1246 tbm_bo_size(bo) / 1024,
1253 TBM_DEBUG("no tbm_bos.\n");
1257 TBM_DEBUG("===============================================================\n");
1259 pthread_mutex_unlock(&gLock);
1264 tbm_bufmgr_debug_trace(tbm_bufmgr bufmgr, int onoff)
1266 TBM_LOG_D("bufmgr=%p onoff=%d\n", bufmgr, onoff);
1267 TBM_LOG_D("Not implemented yet.\n");
1270 /* internal function */
1272 _tbm_bo_set_surface(tbm_bo bo, tbm_surface_h surface)
1274 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1276 bo->surface = surface;
1282 tbm_bufmgr_bind_native_display(tbm_bufmgr bufmgr, void *NativeDisplay)
1284 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), 0);
1288 pthread_mutex_lock(&bufmgr->lock);
1290 if (!bufmgr->backend->bufmgr_bind_native_display) {
1291 pthread_mutex_unlock(&bufmgr->lock);
1295 ret = bufmgr->backend->bufmgr_bind_native_display(bufmgr, NativeDisplay);
1297 pthread_mutex_unlock(&bufmgr->lock);
1301 pthread_mutex_unlock(&bufmgr->lock);
1305 /* LCOV_EXCL_STOP */