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 TBM_LOG_E("gBufmgr already destroy: bufmgr:%p\n", bufmgr);
602 pthread_mutex_unlock(&gLock);
607 if (bufmgr->ref_count > 0) {
608 DBG("tizen bufmgr destroy: bufmgr:%p, ref_count:%d\n",
609 bufmgr, bufmgr->ref_count);
610 pthread_mutex_unlock(&gLock);
614 /* destroy bo_list */
615 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
616 LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &bufmgr->bo_list, item_link) {
617 TBM_LOG_E("Un-freed bo(%p, ref:%d)\n",
624 /* destroy surf_list */
625 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
626 LIST_FOR_EACH_ENTRY_SAFE(surf, tmp_surf, &bufmgr->surf_list, item_link) {
627 TBM_LOG_E("Un-freed surf(%p, ref:%d)\n",
629 tbm_surface_destroy(surf);
633 /* destroy bufmgr priv */
634 bufmgr->backend->bufmgr_deinit(bufmgr->backend->priv);
635 bufmgr->backend->priv = NULL;
636 tbm_backend_free(bufmgr->backend);
637 bufmgr->backend = NULL;
639 pthread_mutex_destroy(&bufmgr->lock);
641 DBG("tizen bufmgr destroy: bufmgr:%p\n",
644 dlclose(bufmgr->module_data);
653 pthread_mutex_unlock(&gLock);
657 tbm_bo_size(tbm_bo bo)
659 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
661 tbm_bufmgr bufmgr = bo->bufmgr;
664 pthread_mutex_lock(&bufmgr->lock);
666 size = bufmgr->backend->bo_size(bo);
668 pthread_mutex_unlock(&bufmgr->lock);
674 tbm_bo_ref(tbm_bo bo)
676 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), NULL);
678 tbm_bufmgr bufmgr = bo->bufmgr;
680 pthread_mutex_lock(&bufmgr->lock);
684 pthread_mutex_unlock(&bufmgr->lock);
690 tbm_bo_unref(tbm_bo bo)
692 TBM_RETURN_IF_FAIL(_tbm_bo_is_valid(bo));
694 tbm_bufmgr bufmgr = bo->bufmgr;
696 pthread_mutex_lock(&bufmgr->lock);
700 pthread_mutex_unlock(&bufmgr->lock);
704 tbm_bo_alloc(tbm_bufmgr bufmgr, int size, int flags)
706 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr) && (size > 0), NULL);
709 void *bo_priv = NULL;
711 bo = calloc(1, sizeof(struct _tbm_bo));
713 _tbm_set_last_result(TBM_BO_ERROR_HEAP_ALLOC_FAILED);
719 pthread_mutex_lock(&bufmgr->lock);
721 bo_priv = bufmgr->backend->bo_alloc(bo, size, flags);
723 _tbm_set_last_result(TBM_BO_ERROR_BO_ALLOC_FAILED);
725 pthread_mutex_unlock(&bufmgr->lock);
733 LIST_INITHEAD(&bo->user_data_list);
735 LIST_ADD(&bo->item_link, &bufmgr->bo_list);
737 pthread_mutex_unlock(&bufmgr->lock);
743 tbm_bo_import(tbm_bufmgr bufmgr, unsigned int key)
745 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
750 void *bo_priv = NULL;
752 pthread_mutex_lock(&bufmgr->lock);
754 bo = calloc(1, sizeof(struct _tbm_bo));
756 pthread_mutex_unlock(&bufmgr->lock);
762 bo_priv = bufmgr->backend->bo_import(bo, key);
764 _tbm_set_last_result(TBM_BO_ERROR_IMPORT_FAILED);
766 pthread_mutex_unlock(&bufmgr->lock);
770 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
771 LIST_FOR_EACH_ENTRY_SAFE(bo2, tmp, &bufmgr->bo_list, item_link) {
772 if (bo2->priv == bo_priv) {
773 DBG("find bo(%p, ref:%d key:%d) in list\n",
774 bo2, bo2->ref_cnt, key);
778 pthread_mutex_unlock(&bufmgr->lock);
787 if (bufmgr->backend->bo_get_flags)
788 bo->flags = bufmgr->backend->bo_get_flags(bo);
790 bo->flags = TBM_BO_DEFAULT;
792 LIST_INITHEAD(&bo->user_data_list);
794 LIST_ADD(&bo->item_link, &bufmgr->bo_list);
796 pthread_mutex_unlock(&bufmgr->lock);
802 tbm_bo_import_fd(tbm_bufmgr bufmgr, tbm_fd fd)
804 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
809 void *bo_priv = NULL;
811 pthread_mutex_lock(&bufmgr->lock);
813 bo = calloc(1, sizeof(struct _tbm_bo));
815 pthread_mutex_unlock(&bufmgr->lock);
821 bo_priv = bufmgr->backend->bo_import_fd(bo, fd);
823 _tbm_set_last_result(TBM_BO_ERROR_IMPORT_FD_FAILED);
825 pthread_mutex_unlock(&bufmgr->lock);
829 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
830 LIST_FOR_EACH_ENTRY_SAFE(bo2, tmp, &bufmgr->bo_list, item_link) {
831 if (bo2->priv == bo_priv) {
832 DBG("find bo(%p, ref:%d, fd:%d) in list\n",
833 bo2, bo2->ref_cnt, fd);
837 pthread_mutex_unlock(&bufmgr->lock);
846 if (bufmgr->backend->bo_get_flags)
847 bo->flags = bufmgr->backend->bo_get_flags(bo);
849 bo->flags = TBM_BO_DEFAULT;
851 LIST_INITHEAD(&bo->user_data_list);
853 LIST_ADD(&bo->item_link, &bufmgr->bo_list);
855 pthread_mutex_unlock(&bufmgr->lock);
861 tbm_bo_export(tbm_bo bo)
863 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
870 pthread_mutex_lock(&bufmgr->lock);
871 ret = bufmgr->backend->bo_export(bo);
873 _tbm_set_last_result(TBM_BO_ERROR_EXPORT_FAILED);
874 pthread_mutex_unlock(&bufmgr->lock);
877 pthread_mutex_unlock(&bufmgr->lock);
883 tbm_bo_export_fd(tbm_bo bo)
885 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), -1);
892 pthread_mutex_lock(&bufmgr->lock);
893 ret = bufmgr->backend->bo_export_fd(bo);
895 _tbm_set_last_result(TBM_BO_ERROR_EXPORT_FD_FAILED);
896 pthread_mutex_unlock(&bufmgr->lock);
899 pthread_mutex_unlock(&bufmgr->lock);
905 tbm_bo_get_handle(tbm_bo bo, int device)
907 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) 0);
910 tbm_bo_handle bo_handle;
914 pthread_mutex_lock(&bufmgr->lock);
915 bo_handle = bufmgr->backend->bo_get_handle(bo, device);
916 if (bo_handle.ptr == NULL) {
917 _tbm_set_last_result(TBM_BO_ERROR_GET_HANDLE_FAILED);
918 pthread_mutex_unlock(&bufmgr->lock);
919 return (tbm_bo_handle) NULL;
921 pthread_mutex_unlock(&bufmgr->lock);
927 tbm_bo_map(tbm_bo bo, int device, int opt)
929 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) 0);
932 tbm_bo_handle bo_handle;
936 pthread_mutex_lock(&bufmgr->lock);
938 if (!_tbm_bo_lock(bo, device, opt)) {
939 _tbm_set_last_result(TBM_BO_ERROR_LOCK_FAILED);
940 TBM_LOG_E("error fail to lock bo:%p)\n",
942 pthread_mutex_unlock(&bufmgr->lock);
943 return (tbm_bo_handle) NULL;
946 bo_handle = bufmgr->backend->bo_map(bo, device, opt);
947 if (bo_handle.ptr == NULL) {
948 _tbm_set_last_result(TBM_BO_ERROR_MAP_FAILED);
949 TBM_LOG_E("error fail to map bo:%p\n",
953 pthread_mutex_unlock(&bufmgr->lock);
954 return (tbm_bo_handle) NULL;
957 /* increase the map_count */
960 pthread_mutex_unlock(&bufmgr->lock);
966 tbm_bo_unmap(tbm_bo bo)
968 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
975 pthread_mutex_lock(&bufmgr->lock);
977 ret = bufmgr->backend->bo_unmap(bo);
980 _tbm_set_last_result(TBM_BO_ERROR_UNMAP_FAILED);
981 pthread_mutex_unlock(&bufmgr->lock);
985 /* decrease the map_count */
990 pthread_mutex_unlock(&bufmgr->lock);
996 tbm_bo_swap(tbm_bo bo1, tbm_bo bo2)
998 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo1), 0);
999 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo2), 0);
1003 pthread_mutex_lock(&bo1->bufmgr->lock);
1005 if (bo1->bufmgr->backend->bo_size(bo1) != bo2->bufmgr->backend->bo_size(bo2)) {
1006 _tbm_set_last_result(TBM_BO_ERROR_SWAP_FAILED);
1007 pthread_mutex_unlock(&bo1->bufmgr->lock);
1012 bo1->priv = bo2->priv;
1015 pthread_mutex_unlock(&bo1->bufmgr->lock);
1021 tbm_bo_locked(tbm_bo bo)
1023 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1027 bufmgr = bo->bufmgr;
1029 if (bufmgr->lock_type == LOCK_TRY_NEVER)
1032 pthread_mutex_lock(&bufmgr->lock);
1034 if (bo->lock_cnt > 0) {
1035 pthread_mutex_unlock(&bufmgr->lock);
1039 pthread_mutex_unlock(&bufmgr->lock);
1045 tbm_bo_add_user_data(tbm_bo bo, unsigned long key,
1046 tbm_data_free data_free_func)
1048 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1050 tbm_user_data *data;
1052 /* check if the data according to the key exist if so, return false. */
1053 data = user_data_lookup(&bo->user_data_list, key);
1055 TBM_LOG_W("waring user data already exist. key:%ld\n",
1060 data = user_data_create(key, data_free_func);
1064 LIST_ADD(&data->item_link, &bo->user_data_list);
1070 tbm_bo_set_user_data(tbm_bo bo, unsigned long key, void *data)
1072 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1074 tbm_user_data *old_data;
1076 if (LIST_IS_EMPTY(&bo->user_data_list))
1079 old_data = user_data_lookup(&bo->user_data_list, key);
1083 if (old_data->data && old_data->free_func)
1084 old_data->free_func(old_data->data);
1086 old_data->data = data;
1092 tbm_bo_get_user_data(tbm_bo bo, unsigned long key, void **data)
1094 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1096 tbm_user_data *old_data;
1098 if (!data || LIST_IS_EMPTY(&bo->user_data_list))
1101 old_data = user_data_lookup(&bo->user_data_list, key);
1107 *data = old_data->data;
1113 tbm_bo_delete_user_data(tbm_bo bo, unsigned long key)
1115 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1117 tbm_user_data *old_data = (void *)0;
1119 if (LIST_IS_EMPTY(&bo->user_data_list))
1122 old_data = user_data_lookup(&bo->user_data_list, key);
1126 user_data_delete(old_data);
1132 tbm_get_last_error(void)
1134 return tbm_last_error;
1138 tbm_bufmgr_get_capability(tbm_bufmgr bufmgr)
1140 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), 0);
1142 unsigned int capability = TBM_BUFMGR_CAPABILITY_NONE;
1144 if (bufmgr->backend->bo_import && bufmgr->backend->bo_export)
1145 capability |= TBM_BUFMGR_CAPABILITY_SHARE_KEY;
1147 if (bufmgr->backend->bo_import_fd && bufmgr->backend->bo_export_fd)
1148 capability |= TBM_BUFMGR_CAPABILITY_SHARE_FD;
1154 tbm_bo_get_flags(tbm_bo bo)
1156 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1162 tbm_bufmgr_debug_show(tbm_bufmgr bufmgr)
1164 TBM_RETURN_IF_FAIL(bufmgr != NULL);
1165 tbm_bo bo = NULL, tmp_bo = NULL;
1168 tbm_surface_h surf = NULL, tmp_surf = NULL;
1171 char app_name[255] = {0,};
1172 unsigned int pid = 0;
1174 pthread_mutex_lock(&gLock);
1177 _tbm_util_get_appname_from_pid(getpid(), app_name);
1178 _tbm_util_get_appname_brief(app_name);
1179 TBM_DEBUG("============TBM DEBUG: %s(%d)===========================\n",
1180 app_name, getpid());
1181 memset(app_name, 0x0, 255 * sizeof(char));
1183 TBM_DEBUG("[tbm_surface information]\n");
1184 TBM_DEBUG("no surface refcnt width height bpp size num_bos num_planes flags format app_name\n");
1185 /* show the tbm_surface information in surf_list */
1186 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
1187 LIST_FOR_EACH_ENTRY_SAFE(surf, tmp_surf, &bufmgr->surf_list, item_link) {
1188 pid = _tbm_surface_internal_get_debug_pid(surf);
1190 /* if pid is null, set the self_pid */
1194 _tbm_util_get_appname_from_pid(pid, app_name);
1195 _tbm_util_get_appname_brief(app_name);
1197 TBM_DEBUG("%-4d%-23p%-6d%-7d%-8d%-5d%-12d%-10d%-9d%-4d%-20s%s\n",
1204 surf->info.size / 1024,
1208 _tbm_surface_internal_format_to_str(surf->info.format),
1211 for (i = 0; i < surf->num_bos; i++) {
1212 TBM_DEBUG(" bo:%-12p %-26d%-10d\n",
1214 surf->bos[i]->ref_cnt,
1215 tbm_bo_size(surf->bos[i]) / 1024);
1218 memset(app_name, 0x0, 255 * sizeof(char));
1221 TBM_DEBUG("no tbm_surfaces.\n");
1225 TBM_DEBUG("[tbm_bo information]\n");
1226 TBM_DEBUG("no bo refcnt size lock_cnt map_cnt flags surface\n");
1228 /* show the tbm_bo information in bo_list */
1229 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
1230 LIST_FOR_EACH_ENTRY_SAFE(bo, tmp_bo, &bufmgr->bo_list, item_link) {
1231 TBM_DEBUG("%-4d%-11p %-6d%-12d%-9d%-9d%-4d%-11p\n",
1235 tbm_bo_size(bo) / 1024,
1242 TBM_DEBUG("no tbm_bos.\n");
1246 TBM_DEBUG("===============================================================\n");
1248 pthread_mutex_unlock(&gLock);
1253 tbm_bufmgr_debug_trace(tbm_bufmgr bufmgr, int onoff)
1255 TBM_LOG_D("bufmgr=%p onoff=%d\n", bufmgr, onoff);
1256 TBM_LOG_D("Not implemented yet.\n");
1259 /* internal function */
1261 _tbm_bo_set_surface(tbm_bo bo, tbm_surface_h surface)
1263 TBM_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1265 bo->surface = surface;
1271 tbm_bufmgr_bind_native_display(tbm_bufmgr bufmgr, void *NativeDisplay)
1273 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), 0);
1277 pthread_mutex_lock(&bufmgr->lock);
1279 if (!bufmgr->backend->bufmgr_bind_native_display) {
1280 pthread_mutex_unlock(&bufmgr->lock);
1284 ret = bufmgr->backend->bufmgr_bind_native_display(bufmgr, NativeDisplay);
1286 pthread_mutex_unlock(&bufmgr->lock);
1290 pthread_mutex_unlock(&bufmgr->lock);