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 _tbm_util_get_appname_brief(char *brief)
85 char temp[255] = {0,};
88 token = strtok_r(brief, delim, &saveptr);
90 while (token != NULL) {
91 memset(temp, 0x00, 255 * sizeof(char));
92 strncpy(temp, token, 254 * sizeof(char));
93 token = strtok_r(NULL, delim, &saveptr);
96 snprintf(brief, sizeof(temp), "%s", temp);
100 _tbm_util_get_appname_from_pid(long pid, char *str)
105 char fn_cmdline[255] = {0,};
106 char cmdline[255] = {0,};
108 snprintf(fn_cmdline, sizeof(fn_cmdline), "/proc/%ld/cmdline", app_pid);
110 fp = fopen(fn_cmdline, "r");
112 fprintf(stderr, "cannot file open /proc/%ld/cmdline", app_pid);
116 if (!fgets(cmdline, 255, fp)) {
117 fprintf(stderr, "fail to get appname for pid(%ld)\n", app_pid);
123 len = strlen(cmdline);
125 memset(cmdline, 0x00, 255);
129 snprintf(str, sizeof(cmdline), "%s", cmdline);
133 *user_data_lookup(struct list_head *user_data_list, unsigned long key)
135 tbm_user_data *user_data = NULL;
136 tbm_user_data *old_data = NULL, *tmp = NULL;
138 if (!LIST_IS_EMPTY(user_data_list)) {
139 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, user_data_list, item_link) {
140 if (old_data->key == key) {
141 user_data = old_data;
151 *user_data_create(unsigned long key, tbm_data_free data_free_func)
153 tbm_user_data *user_data = NULL;
155 user_data = calloc(1, sizeof(tbm_user_data));
159 user_data->key = key;
160 user_data->free_func = data_free_func;
161 user_data->data = (void *)0;
167 user_data_delete(tbm_user_data *user_data)
169 if (user_data->data && user_data->free_func)
170 user_data->free_func(user_data->data);
172 LIST_DEL(&user_data->item_link);
178 _bo_lock(tbm_bo bo, int device, int opt)
180 tbm_bufmgr bufmgr = bo->bufmgr;
183 if (bufmgr->backend->bo_lock) {
184 ret = bufmgr->backend->bo_lock(bo, device, opt);
193 _bo_unlock(tbm_bo bo)
195 tbm_bufmgr bufmgr = bo->bufmgr;
197 if (bufmgr->backend->bo_unlock) {
198 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);
351 _check_version(TBMModuleVersionInfo *data)
356 abimaj = GET_ABI_MAJOR(data->abiversion);
357 abimin = GET_ABI_MINOR(data->abiversion);
359 DBG("TBM module %s: vendor=\"%s\" ABI=%d,%d\n",
360 data->modname ? data->modname : "UNKNOWN!",
361 data->vendor ? data->vendor : "UNKNOWN!", abimaj, abimin);
363 vermaj = GET_ABI_MAJOR(TBM_ABI_VERSION);
364 vermin = GET_ABI_MINOR(TBM_ABI_VERSION);
366 DBG("TBM ABI version %d.%d\n",
369 if (abimaj != vermaj) {
370 TBM_LOG_E("TBM module ABI major ver(%d) doesn't match the TBM's ver(%d)\n",
373 } else if (abimin > vermin) {
374 TBM_LOG_E("TBM module ABI minor ver(%d) is newer than the TBM's ver(%d)\n",
382 _tbm_bufmgr_load_module(tbm_bufmgr bufmgr, int fd, const char *file)
384 char path[PATH_MAX] = { 0, };
385 TBMModuleData *initdata = NULL;
388 snprintf(path, sizeof(path), BUFMGR_MODULE_DIR "/%s", file);
390 module_data = dlopen(path, RTLD_LAZY);
392 TBM_LOG_E("failed to load module: %s(%s)\n",
397 initdata = dlsym(module_data, "tbmModuleData");
400 TBMModuleVersionInfo *vers;
402 vers = initdata->vers;
403 init = initdata->init;
406 if (!_check_version(vers)) {
407 dlclose(module_data);
411 TBM_LOG_E("Error: module does not supply version information.\n");
413 dlclose(module_data);
418 if (!init(bufmgr, fd)) {
419 TBM_LOG_E("Fail to init module(%s)\n",
421 dlclose(module_data);
425 if (!bufmgr->backend || !bufmgr->backend->priv) {
426 TBM_LOG_E("Error: module(%s) wrong operation. Check backend or backend's priv.\n",
428 dlclose(module_data);
432 TBM_LOG_E("Error: module does not supply init symbol.\n");
433 dlclose(module_data);
437 TBM_LOG_E("Error: module does not have data object.\n");
438 dlclose(module_data);
442 bufmgr->module_data = module_data;
444 DBG("Success to load module(%s)\n",
451 _tbm_load_module(tbm_bufmgr bufmgr, int fd)
453 struct dirent **namelist;
454 const char *p = NULL;
458 /* load bufmgr priv from default lib */
459 ret = _tbm_bufmgr_load_module(bufmgr, fd, DEFAULT_LIB);
461 /* load bufmgr priv from configured path */
463 n = scandir(BUFMGR_MODULE_DIR, &namelist, 0, alphasort);
465 TBM_LOG_E("no files : %s\n",
469 if (!ret && strstr(namelist[n]->d_name, PREFIX_LIB)) {
470 p = strstr(namelist[n]->d_name, SUFFIX_LIB);
471 if (p && !strcmp(p, SUFFIX_LIB))
472 ret = _tbm_bufmgr_load_module(bufmgr, fd, namelist[n]->d_name);
484 tbm_bufmgr_init(int fd)
488 pthread_mutex_lock(&gLock);
491 env = getenv("TBM_DLOG");
494 TBM_LOG_D("TBM_DLOG=%s\n", env);
501 env = getenv("TBM_DEBUG");
504 TBM_LOG_D("TBM_DEBUG=%s\n", env);
510 /* initialize buffer manager */
512 gBufMgr->ref_count++;
514 DBG("bufmgr:%p ref: fd=%d, ref_count:%d\n",
515 gBufMgr, gBufMgr->fd, gBufMgr->ref_count);
516 pthread_mutex_unlock(&gLock);
520 DBG("bufmgr init\n");
522 /* allocate bufmgr */
523 gBufMgr = calloc(1, sizeof(struct _tbm_bufmgr));
525 _tbm_set_last_result(TBM_BO_ERROR_HEAP_ALLOC_FAILED);
526 pthread_mutex_unlock(&gLock);
532 /* load bufmgr priv from env */
533 if (!_tbm_load_module(gBufMgr, gBufMgr->fd)) {
534 _tbm_set_last_result(TBM_BO_ERROR_LOAD_MODULE_FAILED);
535 TBM_LOG_E("error : Fail to load bufmgr backend\n");
539 pthread_mutex_unlock(&gLock);
543 /* log for tbm backend_flag */
544 DBG("backend flag:%x:", gBufMgr->backend->flags);
547 gBufMgr->ref_count = 1;
549 DBG("create tizen bufmgr:%p ref_count:%d\n",
550 gBufMgr, gBufMgr->ref_count);
552 if (pthread_mutex_init(&gBufMgr->lock, NULL) != 0) {
553 _tbm_set_last_result(TBM_BO_ERROR_THREAD_INIT_FAILED);
554 gBufMgr->backend->bufmgr_deinit(gBufMgr->backend->priv);
555 tbm_backend_free(gBufMgr->backend);
556 dlclose(gBufMgr->module_data);
559 pthread_mutex_unlock(&gLock);
563 /* setup the lock_type */
564 env = getenv("BUFMGR_LOCK_TYPE");
565 if (env && !strcmp(env, "always"))
566 gBufMgr->lock_type = LOCK_TRY_ALWAYS;
567 else if (env && !strcmp(env, "none"))
568 gBufMgr->lock_type = LOCK_TRY_NEVER;
569 else if (env && !strcmp(env, "once"))
570 gBufMgr->lock_type = LOCK_TRY_ONCE;
572 gBufMgr->lock_type = LOCK_TRY_ALWAYS;
574 DBG("BUFMGR_LOCK_TYPE=%s\n",
575 env ? env : "default:once");
577 /* intialize bo_list */
578 LIST_INITHEAD(&gBufMgr->bo_list);
580 /* intialize surf_list */
581 LIST_INITHEAD(&gBufMgr->surf_list);
583 pthread_mutex_unlock(&gLock);
588 tbm_bufmgr_deinit(tbm_bufmgr bufmgr)
590 TBM_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
595 tbm_surface_h surf = NULL;
596 tbm_surface_h tmp_surf = NULL;
598 pthread_mutex_lock(&gLock);
601 if (bufmgr->ref_count > 0) {
602 DBG("tizen bufmgr destroy: bufmgr:%p, ref_count:%d\n",
603 bufmgr, bufmgr->ref_count);
604 pthread_mutex_unlock(&gLock);
608 /* destroy bo_list */
609 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
610 LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &bufmgr->bo_list, item_link) {
611 TBM_LOG_E("Un-freed bo(%p, ref:%d)\n",
618 /* destroy surf_list */
619 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
620 LIST_FOR_EACH_ENTRY_SAFE(surf, tmp_surf, &bufmgr->surf_list, item_link) {
621 TBM_LOG_E("Un-freed surf(%p, ref:%d)\n",
623 tbm_surface_destroy(surf);
627 /* destroy bufmgr priv */
628 bufmgr->backend->bufmgr_deinit(bufmgr->backend->priv);
629 bufmgr->backend->priv = NULL;
630 tbm_backend_free(bufmgr->backend);
631 bufmgr->backend = NULL;
633 pthread_mutex_destroy(&bufmgr->lock);
635 DBG("tizen bufmgr destroy: bufmgr:%p\n",
638 dlclose(bufmgr->module_data);
647 pthread_mutex_unlock(&gLock);
651 tbm_bo_size(tbm_bo bo)
653 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
655 tbm_bufmgr bufmgr = bo->bufmgr;
658 pthread_mutex_lock(&bufmgr->lock);
660 size = bufmgr->backend->bo_size(bo);
662 pthread_mutex_unlock(&bufmgr->lock);
668 tbm_bo_ref(tbm_bo bo)
670 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), NULL);
672 tbm_bufmgr bufmgr = bo->bufmgr;
674 pthread_mutex_lock(&bufmgr->lock);
678 pthread_mutex_unlock(&bufmgr->lock);
684 tbm_bo_unref(tbm_bo bo)
686 TBM_RETURN_IF_FAIL(_tbm_bo_is_valid(bo));
688 tbm_bufmgr bufmgr = bo->bufmgr;
690 pthread_mutex_lock(&bufmgr->lock);
694 pthread_mutex_unlock(&bufmgr->lock);
698 tbm_bo_alloc(tbm_bufmgr bufmgr, int size, int flags)
700 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr) && (size > 0), NULL);
703 void *bo_priv = NULL;
705 bo = calloc(1, sizeof(struct _tbm_bo));
707 _tbm_set_last_result(TBM_BO_ERROR_HEAP_ALLOC_FAILED);
713 pthread_mutex_lock(&bufmgr->lock);
715 bo_priv = bufmgr->backend->bo_alloc(bo, size, flags);
717 _tbm_set_last_result(TBM_BO_ERROR_BO_ALLOC_FAILED);
719 pthread_mutex_unlock(&bufmgr->lock);
727 LIST_INITHEAD(&bo->user_data_list);
729 LIST_ADD(&bo->item_link, &bufmgr->bo_list);
731 pthread_mutex_unlock(&bufmgr->lock);
737 tbm_bo_import(tbm_bufmgr bufmgr, unsigned int key)
739 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
744 void *bo_priv = NULL;
746 pthread_mutex_lock(&bufmgr->lock);
748 bo = calloc(1, sizeof(struct _tbm_bo));
750 pthread_mutex_unlock(&bufmgr->lock);
756 bo_priv = bufmgr->backend->bo_import(bo, key);
758 _tbm_set_last_result(TBM_BO_ERROR_IMPORT_FAILED);
760 pthread_mutex_unlock(&bufmgr->lock);
764 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
765 LIST_FOR_EACH_ENTRY_SAFE(bo2, tmp, &bufmgr->bo_list, item_link) {
766 if (bo2->priv == bo_priv) {
767 DBG("find bo(%p, ref:%d key:%d) in list\n",
768 bo2, bo2->ref_cnt, key);
772 pthread_mutex_unlock(&bufmgr->lock);
781 if (bufmgr->backend->bo_get_flags)
782 bo->flags = bufmgr->backend->bo_get_flags(bo);
784 bo->flags = TBM_BO_DEFAULT;
786 LIST_INITHEAD(&bo->user_data_list);
788 LIST_ADD(&bo->item_link, &bufmgr->bo_list);
790 pthread_mutex_unlock(&bufmgr->lock);
796 tbm_bo_import_fd(tbm_bufmgr bufmgr, tbm_fd fd)
798 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
803 void *bo_priv = NULL;
805 pthread_mutex_lock(&bufmgr->lock);
807 bo = calloc(1, sizeof(struct _tbm_bo));
809 pthread_mutex_unlock(&bufmgr->lock);
815 bo_priv = bufmgr->backend->bo_import_fd(bo, fd);
817 _tbm_set_last_result(TBM_BO_ERROR_IMPORT_FD_FAILED);
819 pthread_mutex_unlock(&bufmgr->lock);
823 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
824 LIST_FOR_EACH_ENTRY_SAFE(bo2, tmp, &bufmgr->bo_list, item_link) {
825 if (bo2->priv == bo_priv) {
826 DBG("find bo(%p, ref:%d, fd:%d) in list\n",
827 bo2, bo2->ref_cnt, fd);
831 pthread_mutex_unlock(&bufmgr->lock);
840 if (bufmgr->backend->bo_get_flags)
841 bo->flags = bufmgr->backend->bo_get_flags(bo);
843 bo->flags = TBM_BO_DEFAULT;
845 LIST_INITHEAD(&bo->user_data_list);
847 LIST_ADD(&bo->item_link, &bufmgr->bo_list);
849 pthread_mutex_unlock(&bufmgr->lock);
855 tbm_bo_export(tbm_bo bo)
857 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
864 pthread_mutex_lock(&bufmgr->lock);
865 ret = bufmgr->backend->bo_export(bo);
867 _tbm_set_last_result(TBM_BO_ERROR_EXPORT_FAILED);
868 pthread_mutex_unlock(&bufmgr->lock);
871 pthread_mutex_unlock(&bufmgr->lock);
877 tbm_bo_export_fd(tbm_bo bo)
879 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), -1);
886 pthread_mutex_lock(&bufmgr->lock);
887 ret = bufmgr->backend->bo_export_fd(bo);
889 _tbm_set_last_result(TBM_BO_ERROR_EXPORT_FD_FAILED);
890 pthread_mutex_unlock(&bufmgr->lock);
893 pthread_mutex_unlock(&bufmgr->lock);
899 tbm_bo_get_handle(tbm_bo bo, int device)
901 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) 0);
904 tbm_bo_handle bo_handle;
908 pthread_mutex_lock(&bufmgr->lock);
909 bo_handle = bufmgr->backend->bo_get_handle(bo, device);
910 if (bo_handle.ptr == NULL) {
911 _tbm_set_last_result(TBM_BO_ERROR_GET_HANDLE_FAILED);
912 pthread_mutex_unlock(&bufmgr->lock);
913 return (tbm_bo_handle) NULL;
915 pthread_mutex_unlock(&bufmgr->lock);
921 tbm_bo_map(tbm_bo bo, int device, int opt)
923 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) 0);
926 tbm_bo_handle bo_handle;
930 pthread_mutex_lock(&bufmgr->lock);
932 if (!_tbm_bo_lock(bo, device, opt)) {
933 _tbm_set_last_result(TBM_BO_ERROR_LOCK_FAILED);
934 TBM_LOG_E("error fail to lock bo:%p)\n",
936 pthread_mutex_unlock(&bufmgr->lock);
937 return (tbm_bo_handle) NULL;
940 bo_handle = bufmgr->backend->bo_map(bo, device, opt);
941 if (bo_handle.ptr == NULL) {
942 _tbm_set_last_result(TBM_BO_ERROR_MAP_FAILED);
943 TBM_LOG_E("error fail to map bo:%p\n",
947 pthread_mutex_unlock(&bufmgr->lock);
948 return (tbm_bo_handle) NULL;
951 /* increase the map_count */
954 pthread_mutex_unlock(&bufmgr->lock);
960 tbm_bo_unmap(tbm_bo bo)
962 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
969 pthread_mutex_lock(&bufmgr->lock);
971 ret = bufmgr->backend->bo_unmap(bo);
974 _tbm_set_last_result(TBM_BO_ERROR_UNMAP_FAILED);
975 pthread_mutex_unlock(&bufmgr->lock);
979 /* decrease the map_count */
984 pthread_mutex_unlock(&bufmgr->lock);
990 tbm_bo_swap(tbm_bo bo1, tbm_bo bo2)
992 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo1), 0);
993 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo2), 0);
997 pthread_mutex_lock(&bo1->bufmgr->lock);
999 if (bo1->bufmgr->backend->bo_size(bo1) != bo2->bufmgr->backend->bo_size(bo2)) {
1000 _tbm_set_last_result(TBM_BO_ERROR_SWAP_FAILED);
1001 pthread_mutex_unlock(&bo1->bufmgr->lock);
1006 bo1->priv = bo2->priv;
1009 pthread_mutex_unlock(&bo1->bufmgr->lock);
1015 tbm_bo_locked(tbm_bo bo)
1017 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1021 bufmgr = bo->bufmgr;
1023 if (bufmgr->lock_type == LOCK_TRY_NEVER)
1026 pthread_mutex_lock(&bufmgr->lock);
1028 if (bo->lock_cnt > 0) {
1029 pthread_mutex_unlock(&bufmgr->lock);
1033 pthread_mutex_unlock(&bufmgr->lock);
1039 tbm_bo_add_user_data(tbm_bo bo, unsigned long key,
1040 tbm_data_free data_free_func)
1042 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1044 tbm_user_data *data;
1046 /* check if the data according to the key exist if so, return false. */
1047 data = user_data_lookup(&bo->user_data_list, key);
1049 TBM_LOG_W("waring user data already exist. key:%ld\n",
1054 data = user_data_create(key, data_free_func);
1058 LIST_ADD(&data->item_link, &bo->user_data_list);
1064 tbm_bo_set_user_data(tbm_bo bo, unsigned long key, void *data)
1066 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1068 tbm_user_data *old_data;
1070 if (LIST_IS_EMPTY(&bo->user_data_list))
1073 old_data = user_data_lookup(&bo->user_data_list, key);
1077 if (old_data->data && old_data->free_func)
1078 old_data->free_func(old_data->data);
1080 old_data->data = data;
1086 tbm_bo_get_user_data(tbm_bo bo, unsigned long key, void **data)
1088 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1090 tbm_user_data *old_data;
1092 if (!data || LIST_IS_EMPTY(&bo->user_data_list))
1095 old_data = user_data_lookup(&bo->user_data_list, key);
1101 *data = old_data->data;
1107 tbm_bo_delete_user_data(tbm_bo bo, unsigned long key)
1109 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1111 tbm_user_data *old_data = (void *)0;
1113 if (LIST_IS_EMPTY(&bo->user_data_list))
1116 old_data = user_data_lookup(&bo->user_data_list, key);
1120 user_data_delete(old_data);
1126 tbm_get_last_error(void)
1128 return tbm_last_error;
1132 tbm_bufmgr_get_capability(tbm_bufmgr bufmgr)
1134 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), 0);
1136 unsigned int capability = TBM_BUFMGR_CAPABILITY_NONE;
1138 if (bufmgr->backend->bo_import && bufmgr->backend->bo_export)
1139 capability |= TBM_BUFMGR_CAPABILITY_SHARE_KEY;
1141 if (bufmgr->backend->bo_import_fd && bufmgr->backend->bo_export_fd)
1142 capability |= TBM_BUFMGR_CAPABILITY_SHARE_FD;
1148 tbm_bo_get_flags(tbm_bo bo)
1150 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1156 tbm_bufmgr_debug_show(tbm_bufmgr bufmgr)
1158 TBM_RETURN_IF_FAIL(bufmgr != NULL);
1159 tbm_bo bo = NULL, tmp_bo = NULL;
1162 tbm_surface_h surf = NULL, tmp_surf = NULL;
1165 char app_name[255] = {0,};
1166 unsigned int pid = 0;
1168 pthread_mutex_lock(&gLock);
1171 _tbm_util_get_appname_from_pid(getpid(), app_name);
1172 _tbm_util_get_appname_brief(app_name);
1173 TBM_DEBUG("============TBM DEBUG: %s(%d)===========================\n",
1174 app_name, getpid());
1175 memset(app_name, 0x0, 255 * sizeof(char));
1177 TBM_DEBUG("[tbm_surface information]\n");
1178 TBM_DEBUG("no surface refcnt width height bpp size num_bos num_planes flags format app_name\n");
1179 /* show the tbm_surface information in surf_list */
1180 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
1181 LIST_FOR_EACH_ENTRY_SAFE(surf, tmp_surf, &bufmgr->surf_list, item_link) {
1182 pid = _tbm_surface_internal_get_debug_pid(surf);
1184 /* if pid is null, set the self_pid */
1188 _tbm_util_get_appname_from_pid(pid, app_name);
1189 _tbm_util_get_appname_brief(app_name);
1191 TBM_DEBUG("%-4d%-23p%-6d%-7d%-8d%-5d%-12d%-10d%-9d%-4d%-20s%s\n",
1198 surf->info.size / 1024,
1202 _tbm_surface_internal_format_to_str(surf->info.format),
1205 for (i = 0; i < surf->num_bos; i++) {
1206 TBM_DEBUG(" bo:%-12p %-26d%-10d\n",
1208 surf->bos[i]->ref_cnt,
1209 tbm_bo_size(surf->bos[i]) / 1024);
1212 memset(app_name, 0x0, 255 * sizeof(char));
1215 TBM_DEBUG("no tbm_surfaces.\n");
1219 TBM_DEBUG("[tbm_bo information]\n");
1220 TBM_DEBUG("no bo refcnt size lock_cnt map_cnt flags surface\n");
1222 /* show the tbm_bo information in bo_list */
1223 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
1224 LIST_FOR_EACH_ENTRY_SAFE(bo, tmp_bo, &bufmgr->bo_list, item_link) {
1225 TBM_DEBUG("%-4d%-11p %-6d%-12d%-9d%-9d%-4d%-11p\n",
1229 tbm_bo_size(bo) / 1024,
1236 TBM_DEBUG("no tbm_bos.\n");
1240 TBM_DEBUG("===============================================================\n");
1242 pthread_mutex_unlock(&gLock);
1247 tbm_bufmgr_debug_trace(tbm_bufmgr bufmgr, int onoff)
1249 TBM_LOG_D("bufmgr=%p onoff=%d\n", bufmgr, onoff);
1250 TBM_LOG_D("Not implemented yet.\n");
1253 /* internal function */
1255 _tbm_bo_set_surface(tbm_bo bo, tbm_surface_h surface)
1257 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1259 bo->surface = surface;
1265 tbm_bufmgr_bind_native_display(tbm_bufmgr bufmgr, void *NativeDisplay)
1267 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), 0);
1271 pthread_mutex_lock(&bufmgr->lock);
1273 if (!bufmgr->backend->bufmgr_bind_native_display) {
1274 pthread_mutex_unlock(&bufmgr->lock);
1278 ret = bufmgr->backend->bufmgr_bind_native_display(bufmgr, NativeDisplay);
1280 pthread_mutex_unlock(&bufmgr->lock);
1284 pthread_mutex_unlock(&bufmgr->lock);