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 **************************************************************************/
33 #include "tbm_bufmgr.h"
34 #include "tbm_bufmgr_int.h"
37 static pthread_mutex_t tbm_bo_lock = PTHREAD_MUTEX_INITIALIZER;
38 static __thread tbm_error_e tbm_last_error = TBM_ERROR_NONE;
39 static void _tbm_bo_mutex_unlock(void);
42 #define TBM_BO_RETURN_IF_FAIL(cond) {\
44 TBM_LOG_E("'%s' failed.\n", #cond);\
45 _tbm_bo_mutex_unlock();\
50 #define TBM_BO_RETURN_VAL_IF_FAIL(cond, val) {\
52 TBM_LOG_E("'%s' failed.\n", #cond);\
53 _tbm_bo_mutex_unlock();\
59 _tbm_set_last_result(tbm_error_e err)
66 _tbm_bo_mutex_init(void)
68 static bool tbm_bo_mutex_init = false;
70 if (tbm_bo_mutex_init)
73 if (pthread_mutex_init(&tbm_bo_lock, NULL)) {
74 TBM_LOG_E("fail: Cannot pthread_mutex_init for tbm_bo_lock.\n");
78 tbm_bo_mutex_init = true;
84 _tbm_bo_mutex_lock(void)
86 if (!_tbm_bo_mutex_init()) {
87 TBM_LOG_E("fail: _tbm_bo_mutex_init()\n");
91 pthread_mutex_lock(&tbm_bo_lock);
95 _tbm_bo_mutex_unlock(void)
97 pthread_mutex_unlock(&tbm_bo_lock);
101 _tbm_flag_to_str(int f)
103 static char str[255];
105 if (f == TBM_BO_DEFAULT)
106 snprintf(str, 255, "DEFAULT");
110 if (f & TBM_BO_SCANOUT)
111 c += snprintf(&str[c], 255-c, "SCANOUT");
113 if (f & TBM_BO_NONCACHABLE) {
114 if (c >= 0 && c < 255)
115 c += snprintf(&str[c], 255-c, ", ");
117 if (c >= 0 && c < 255)
118 c += snprintf(&str[c], 255-c, "NONCACHABLE,");
122 if (c >= 0 && c < 255)
123 c += snprintf(&str[c], 255-c, ", ");
125 if (c >= 0 && c < 255)
126 c += snprintf(&str[c], 255-c, "WC");
134 _tbm_util_check_bo_cnt(tbm_bufmgr bufmgr)
136 static int last_chk_bo_cnt = 0;
138 if ((bufmgr->bo_cnt >= 500) && ((bufmgr->bo_cnt % 20) == 0) &&
139 (bufmgr->bo_cnt > last_chk_bo_cnt)) {
140 TBM_DEBUG("============TBM BO CNT DEBUG: bo_cnt=%d\n", bufmgr->bo_cnt);
141 tbm_bufmgr_debug_show(bufmgr);
142 last_chk_bo_cnt = bufmgr->bo_cnt;
148 *user_data_lookup(struct list_head *user_data_list, unsigned long key)
150 tbm_user_data *old_data = NULL;
152 if (LIST_IS_EMPTY(user_data_list))
155 LIST_FOR_EACH_ENTRY(old_data, user_data_list, item_link) {
156 if (old_data->key == key)
164 *user_data_create(unsigned long key, tbm_data_free data_free_func)
166 tbm_user_data *user_data;
168 user_data = calloc(1, sizeof(tbm_user_data));
170 /* LCOV_EXCL_START */
171 TBM_LOG_E("fail to allocate an user_date\n");
176 user_data->key = key;
177 user_data->free_func = data_free_func;
183 user_data_delete(tbm_user_data *user_data)
185 if (user_data->data && user_data->free_func)
186 user_data->free_func(user_data->data);
188 LIST_DEL(&user_data->item_link);
194 _bo_lock(tbm_bo bo, int device, int opt)
198 if (bo->bufmgr->backend->bo_lock)
199 ret = bo->bufmgr->backend->bo_lock(bo, device, opt);
205 _bo_unlock(tbm_bo bo)
207 if (bo->bufmgr->backend->bo_unlock)
208 bo->bufmgr->backend->bo_unlock(bo);
212 _tbm_bo_lock(tbm_bo bo, int device, int opt)
219 /* do not try to lock the bo */
220 if (bo->bufmgr->bo_lock_type == TBM_BUFMGR_BO_LOCK_TYPE_NEVER)
223 if (bo->lock_cnt < 0) {
224 TBM_LOG_E("error bo:%p LOCK_CNT=%d\n",
231 switch (bo->bufmgr->bo_lock_type) {
232 case TBM_BUFMGR_BO_LOCK_TYPE_ONCE:
233 if (bo->lock_cnt == 0) {
234 _tbm_bo_mutex_unlock();
235 ret = _bo_lock(bo, device, opt);
236 _tbm_bo_mutex_lock();
242 case TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS:
243 _tbm_bo_mutex_unlock();
244 ret = _bo_lock(bo, device, opt);
245 _tbm_bo_mutex_lock();
250 TBM_LOG_E("error bo:%p bo_lock_type[%d] is wrong.\n",
251 bo, bo->bufmgr->bo_lock_type);
256 TBM_DBG_LOCK(">> LOCK bo:%p(%d->%d)\n", bo, old, bo->lock_cnt);
262 _tbm_bo_unlock(tbm_bo bo)
266 /* do not try to unlock the bo */
267 if (bo->bufmgr->bo_lock_type == TBM_BUFMGR_BO_LOCK_TYPE_NEVER)
272 switch (bo->bufmgr->bo_lock_type) {
273 case TBM_BUFMGR_BO_LOCK_TYPE_ONCE:
274 if (bo->lock_cnt > 0) {
276 if (bo->lock_cnt == 0)
280 case TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS:
281 if (bo->lock_cnt > 0) {
287 TBM_LOG_E("error bo:%p bo_lock_type[%d] is wrong.\n",
288 bo, bo->bufmgr->bo_lock_type);
292 if (bo->lock_cnt < 0)
295 TBM_DBG_LOCK(">> UNLOCK bo:%p(%d->%d)\n", bo, old, bo->lock_cnt);
299 _tbm_bo_is_valid(tbm_bo bo)
301 tbm_bufmgr bufmgr = NULL;
302 tbm_bo old_data = NULL;
305 TBM_LOG_E("error: bo is NULL.\n");
311 if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
312 TBM_LOG_E("error: bo->bufmgr is not valid.\n");
316 if (LIST_IS_EMPTY(&bo->bufmgr->bo_list)) {
317 TBM_LOG_E("error: bo->bo->bufmgr->bo_list is EMPTY.\n");
321 LIST_FOR_EACH_ENTRY(old_data, &bo->bufmgr->bo_list, item_link) {
326 TBM_LOG_E("error: No valid bo(%p).\n", bo);
332 tbm_bo_alloc(tbm_bufmgr bufmgr, int size, int flags)
337 _tbm_bo_mutex_lock();
339 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
340 TBM_BO_RETURN_VAL_IF_FAIL(size > 0, NULL);
342 bo = calloc(1, sizeof(struct _tbm_bo));
344 /* LCOV_EXCL_START */
345 TBM_LOG_E("error: fail to create of tbm_bo size(%d) flag(%s)\n",
346 size, _tbm_flag_to_str(flags));
347 _tbm_set_last_result(TBM_BO_ERROR_HEAP_ALLOC_FAILED);
348 _tbm_bo_mutex_unlock();
353 _tbm_util_check_bo_cnt(bufmgr);
357 bo_priv = bo->bufmgr->backend->bo_alloc(bo, size, flags);
359 /* LCOV_EXCL_START */
360 TBM_LOG_E("error: fail to create of tbm_bo size(%d) flag(%s)\n",
361 size, _tbm_flag_to_str(flags));
362 _tbm_set_last_result(TBM_BO_ERROR_BO_ALLOC_FAILED);
364 _tbm_bo_mutex_unlock();
369 bo->bufmgr->bo_cnt++;
375 TBM_TRACE("bo(%p) size(%d) refcnt(%d), flag(%s)\n", bo, size, bo->ref_cnt,
376 _tbm_flag_to_str(bo->flags));
378 LIST_INITHEAD(&bo->user_data_list);
380 LIST_ADD(&bo->item_link, &bo->bufmgr->bo_list);
382 _tbm_bo_mutex_unlock();
388 tbm_bo_ref(tbm_bo bo)
390 _tbm_bo_mutex_lock();
392 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), NULL);
396 TBM_TRACE("bo(%p) ref_cnt(%d)\n", bo, bo->ref_cnt);
398 _tbm_bo_mutex_unlock();
404 tbm_bo_unref(tbm_bo bo)
406 _tbm_bo_mutex_lock();
408 TBM_BO_RETURN_IF_FAIL(_tbm_bo_is_valid(bo));
410 TBM_TRACE("bo(%p) ref_cnt(%d)\n", bo, bo->ref_cnt - 1);
412 if (bo->ref_cnt <= 0) {
413 _tbm_bo_mutex_unlock();
418 if (bo->ref_cnt == 0)
421 _tbm_bo_mutex_unlock();
425 tbm_bo_map(tbm_bo bo, int device, int opt)
427 tbm_bo_handle bo_handle;
429 _tbm_bo_mutex_lock();
431 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) NULL);
433 if (!_tbm_bo_lock(bo, device, opt)) {
434 _tbm_set_last_result(TBM_BO_ERROR_LOCK_FAILED);
435 TBM_LOG_E("error: fail to lock bo:%p)\n", bo);
436 _tbm_bo_mutex_unlock();
437 return (tbm_bo_handle) NULL;
440 bo_handle = bo->bufmgr->backend->bo_map(bo, device, opt);
441 if (bo_handle.ptr == NULL) {
442 /* LCOV_EXCL_START */
443 _tbm_set_last_result(TBM_BO_ERROR_MAP_FAILED);
444 TBM_LOG_E("error: fail to map bo:%p\n", bo);
446 _tbm_bo_mutex_unlock();
447 return (tbm_bo_handle) NULL;
451 /* increase the map_count */
454 TBM_TRACE("bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
456 _tbm_bo_mutex_unlock();
462 tbm_bo_unmap(tbm_bo bo)
466 _tbm_bo_mutex_lock();
468 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
469 TBM_BO_RETURN_VAL_IF_FAIL(bo->map_cnt > 0, 0);
471 ret = bo->bufmgr->backend->bo_unmap(bo);
473 /* LCOV_EXCL_START */
474 TBM_LOG_E("error: bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
475 _tbm_set_last_result(TBM_BO_ERROR_UNMAP_FAILED);
476 _tbm_bo_mutex_unlock();
481 /* decrease the map_count */
484 TBM_TRACE("bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
488 _tbm_bo_mutex_unlock();
494 tbm_bo_get_handle(tbm_bo bo, int device)
496 tbm_bo_handle bo_handle;
498 _tbm_bo_mutex_lock();
500 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) NULL);
502 bo_handle = bo->bufmgr->backend->bo_get_handle(bo, device);
503 if (bo_handle.ptr == NULL) {
504 /* LCOV_EXCL_START */
505 _tbm_set_last_result(TBM_BO_ERROR_GET_HANDLE_FAILED);
506 TBM_LOG_E("error: bo(%p) bo_handle(%p)\n", bo, bo_handle.ptr);
507 _tbm_bo_mutex_unlock();
508 return (tbm_bo_handle) NULL;
512 TBM_TRACE("bo(%p) bo_handle(%p)\n", bo, bo_handle.ptr);
514 _tbm_bo_mutex_unlock();
520 tbm_bo_export(tbm_bo bo)
524 _tbm_bo_mutex_lock();
526 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
528 if (!bo->bufmgr->backend->bo_export) {
529 /* LCOV_EXCL_START */
530 _tbm_bo_mutex_unlock();
535 ret = bo->bufmgr->backend->bo_export(bo);
537 /* LCOV_EXCL_START */
538 _tbm_set_last_result(TBM_BO_ERROR_EXPORT_FAILED);
539 TBM_LOG_E("error: bo(%p) tbm_key(%d)\n", bo, ret);
540 _tbm_bo_mutex_unlock();
545 TBM_TRACE("bo(%p) tbm_key(%u)\n", bo, ret);
547 _tbm_bo_mutex_unlock();
553 tbm_bo_export_fd(tbm_bo bo)
557 _tbm_bo_mutex_lock();
559 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), -1);
561 if (!bo->bufmgr->backend->bo_export_fd) {
562 /* LCOV_EXCL_START */
563 _tbm_bo_mutex_unlock();
568 ret = bo->bufmgr->backend->bo_export_fd(bo);
570 /* LCOV_EXCL_START */
571 _tbm_set_last_result(TBM_BO_ERROR_EXPORT_FD_FAILED);
572 TBM_LOG_E("error: bo(%p) tbm_fd(%d)\n", bo, ret);
573 _tbm_bo_mutex_unlock();
578 TBM_TRACE("bo(%p) tbm_fd(%d)\n", bo, ret);
580 _tbm_bo_mutex_unlock();
586 tbm_bo_import(tbm_bufmgr bufmgr, unsigned int key)
592 _tbm_bo_mutex_lock();
594 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
596 if (!bufmgr->backend->bo_import) {
597 /* LCOV_EXCL_START */
598 _tbm_bo_mutex_unlock();
603 _tbm_util_check_bo_cnt(bufmgr);
605 bo = calloc(1, sizeof(struct _tbm_bo));
607 /* LCOV_EXCL_START */
608 TBM_LOG_E("error: fail to import of tbm_bo by key(%d)\n", key);
609 _tbm_bo_mutex_unlock();
616 bo_priv = bo->bufmgr->backend->bo_import(bo, key);
618 /* LCOV_EXCL_START */
619 TBM_LOG_E("error: fail to import of tbm_bo by key(%d)\n", key);
620 _tbm_set_last_result(TBM_BO_ERROR_IMPORT_FAILED);
622 _tbm_bo_mutex_unlock();
627 if (!LIST_IS_EMPTY(&bo->bufmgr->bo_list)) {
628 LIST_FOR_EACH_ENTRY(bo2, &bo->bufmgr->bo_list, item_link) {
629 if (bo2->priv == bo_priv) {
630 TBM_TRACE("find bo(%p) ref(%d) key(%d) flag(%s) in list\n",
631 bo2, bo2->ref_cnt, key,
632 _tbm_flag_to_str(bo2->flags));
635 _tbm_bo_mutex_unlock();
641 bo->bufmgr->bo_cnt++;
646 if (bo->bufmgr->backend->bo_get_flags)
647 bo->flags = bo->bufmgr->backend->bo_get_flags(bo);
649 bo->flags = TBM_BO_DEFAULT;
651 TBM_TRACE("import new bo(%p) ref(%d) key(%d) flag(%s) in list\n",
652 bo, bo->ref_cnt, key, _tbm_flag_to_str(bo->flags));
654 LIST_INITHEAD(&bo->user_data_list);
656 LIST_ADD(&bo->item_link, &bo->bufmgr->bo_list);
658 _tbm_bo_mutex_unlock();
664 tbm_bo_import_fd(tbm_bufmgr bufmgr, tbm_fd fd)
670 _tbm_bo_mutex_lock();
672 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
674 if (!bufmgr->backend->bo_import_fd) {
675 /* LCOV_EXCL_START */
676 _tbm_bo_mutex_unlock();
681 _tbm_util_check_bo_cnt(bufmgr);
683 bo = calloc(1, sizeof(struct _tbm_bo));
685 /* LCOV_EXCL_START */
686 TBM_LOG_E("error: fail to import tbm_bo by tbm_fd(%d)\n", fd);
687 _tbm_bo_mutex_unlock();
694 bo_priv = bo->bufmgr->backend->bo_import_fd(bo, fd);
696 /* LCOV_EXCL_START */
697 TBM_LOG_E("error: fail to import tbm_bo by tbm_fd(%d)\n", fd);
698 _tbm_set_last_result(TBM_BO_ERROR_IMPORT_FD_FAILED);
700 _tbm_bo_mutex_unlock();
705 if (!LIST_IS_EMPTY(&bo->bufmgr->bo_list)) {
707 LIST_FOR_EACH_ENTRY(bo2, &bo->bufmgr->bo_list, item_link) {
708 if (bo2->priv == bo_priv) {
709 TBM_TRACE("find bo(%p) ref(%d) fd(%d) flag(%s) in list\n",
710 bo2, bo2->ref_cnt, fd,
711 _tbm_flag_to_str(bo2->flags));
714 _tbm_bo_mutex_unlock();
720 bo->bufmgr->bo_cnt++;
725 if (bo->bufmgr->backend->bo_get_flags)
726 bo->flags = bo->bufmgr->backend->bo_get_flags(bo);
728 bo->flags = TBM_BO_DEFAULT;
730 TBM_TRACE("import bo(%p) ref(%d) fd(%d) flag(%s)\n",
731 bo, bo->ref_cnt, fd, _tbm_flag_to_str(bo->flags));
733 LIST_INITHEAD(&bo->user_data_list);
735 LIST_ADD(&bo->item_link, &bo->bufmgr->bo_list);
737 _tbm_bo_mutex_unlock();
743 tbm_bo_size(tbm_bo bo)
747 _tbm_bo_mutex_lock();
749 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
751 size = bo->bufmgr->backend->bo_size(bo);
753 TBM_TRACE("bo(%p) size(%d)\n", bo, size);
755 _tbm_bo_mutex_unlock();
761 tbm_bo_locked(tbm_bo bo)
763 _tbm_bo_mutex_lock();
765 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
767 if (bo->bufmgr->bo_lock_type == TBM_BUFMGR_BO_LOCK_TYPE_NEVER) {
768 TBM_LOG_E("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
769 _tbm_bo_mutex_unlock();
773 if (bo->lock_cnt > 0) {
774 TBM_TRACE("error: bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
775 _tbm_bo_mutex_unlock();
779 TBM_TRACE("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
780 _tbm_bo_mutex_unlock();
786 tbm_bo_swap(tbm_bo bo1, tbm_bo bo2)
790 _tbm_bo_mutex_lock();
792 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo1), 0);
793 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo2), 0);
795 TBM_TRACE("before: bo1(%p) bo2(%p)\n", bo1, bo2);
797 if (bo1->bufmgr->backend->bo_size(bo1) != bo2->bufmgr->backend->bo_size(bo2)) {
798 _tbm_set_last_result(TBM_BO_ERROR_SWAP_FAILED);
799 TBM_LOG_E("error: bo1(%p) bo2(%p)\n", bo1, bo2);
800 _tbm_bo_mutex_unlock();
804 TBM_TRACE("after: bo1(%p) bo2(%p)\n", bo1, bo2);
807 bo1->priv = bo2->priv;
810 _tbm_bo_mutex_unlock();
816 tbm_bo_add_user_data(tbm_bo bo, unsigned long key,
817 tbm_data_free data_free_func)
821 _tbm_bo_mutex_lock();
823 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
825 /* check if the data according to the key exist if so, return false. */
826 data = user_data_lookup(&bo->user_data_list, key);
828 TBM_TRACE("warning: user data already exist key(%ld)\n", key);
829 _tbm_bo_mutex_unlock();
833 data = user_data_create(key, data_free_func);
835 TBM_LOG_E("error: bo(%p) key(%lu)\n", bo, key);
836 _tbm_bo_mutex_unlock();
840 TBM_TRACE("bo(%p) key(%lu) data(%p)\n", bo, key, data->data);
842 LIST_ADD(&data->item_link, &bo->user_data_list);
844 _tbm_bo_mutex_unlock();
850 tbm_bo_delete_user_data(tbm_bo bo, unsigned long key)
852 tbm_user_data *old_data;
854 _tbm_bo_mutex_lock();
856 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
858 if (LIST_IS_EMPTY(&bo->user_data_list)) {
859 TBM_TRACE("error: bo(%p) key(%lu)\n", bo, key);
860 _tbm_bo_mutex_unlock();
864 old_data = user_data_lookup(&bo->user_data_list, key);
866 TBM_TRACE("error: bo(%p) key(%lu)\n", bo, key);
867 _tbm_bo_mutex_unlock();
871 TBM_TRACE("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
873 user_data_delete(old_data);
875 _tbm_bo_mutex_unlock();
881 tbm_bo_set_user_data(tbm_bo bo, unsigned long key, void *data)
883 tbm_user_data *old_data;
885 _tbm_bo_mutex_lock();
887 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
889 if (LIST_IS_EMPTY(&bo->user_data_list)) {
890 TBM_TRACE("error: bo(%p) key(%lu)\n", bo, key);
891 _tbm_bo_mutex_unlock();
895 old_data = user_data_lookup(&bo->user_data_list, key);
897 TBM_TRACE("error: bo(%p) key(%lu)\n", bo, key);
898 _tbm_bo_mutex_unlock();
902 if (old_data->data && old_data->free_func)
903 old_data->free_func(old_data->data);
904 old_data->data = data;
906 TBM_TRACE("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
908 _tbm_bo_mutex_unlock();
914 tbm_bo_get_user_data(tbm_bo bo, unsigned long key, void **data)
916 tbm_user_data *old_data;
918 _tbm_bo_mutex_lock();
920 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
922 if (!data || LIST_IS_EMPTY(&bo->user_data_list)) {
923 TBM_TRACE("error: bo(%p) key(%lu)\n", bo, key);
924 _tbm_bo_mutex_unlock();
928 old_data = user_data_lookup(&bo->user_data_list, key);
930 TBM_TRACE("error: bo(%p) key(%lu)\n", bo, key);
932 _tbm_bo_mutex_unlock();
936 *data = old_data->data;
938 TBM_TRACE("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
940 _tbm_bo_mutex_unlock();
945 /* LCOV_EXCL_START */
947 tbm_get_last_error(void)
949 return tbm_last_error;
954 tbm_bo_get_flags(tbm_bo bo)
958 _tbm_bo_mutex_lock();
960 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
964 TBM_TRACE("bo(%p)\n", bo);
966 _tbm_bo_mutex_unlock();
971 /* LCOV_EXCL_START */
972 /* internal function */
974 _tbm_bo_set_surface(tbm_bo bo, tbm_surface_h surface)
976 _tbm_bo_mutex_lock();
978 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
980 bo->surface = surface;
982 _tbm_bo_mutex_unlock();
988 _tbm_bo_free(tbm_bo bo)
990 /* destory the user_data_list */
991 if (!LIST_IS_EMPTY(&bo->user_data_list)) {
992 tbm_user_data *old_data = NULL, *tmp;
994 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp,
995 &bo->user_data_list, item_link) {
996 TBM_DBG("free user_data\n");
997 user_data_delete(old_data);
1001 while (bo->lock_cnt > 0) {
1002 TBM_LOG_E("error lock_cnt:%d\n", bo->lock_cnt);
1007 /* call the bo_free */
1008 bo->bufmgr->backend->bo_free(bo);
1011 bo->bufmgr->bo_cnt--;
1013 LIST_DEL(&bo->item_link);
1016 /* LCOV_EXCL_STOP */