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_ERR("'%s' failed.\n", #cond);\
45 _tbm_bo_mutex_unlock();\
50 #define TBM_BO_RETURN_VAL_IF_FAIL(cond, val) {\
52 TBM_ERR("'%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_ERR("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_ERR("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_DBG("============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_ERR("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_ERR("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_ERR("error bo:%p bo_lock_type[%d] is wrong.\n",
251 bo, bo->bufmgr->bo_lock_type);
256 TBM_DBG(">> 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_ERR("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(">> 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_ERR("error: bo is NULL.\n");
309 bufmgr = tbm_bufmgr_get();
310 if (bufmgr == NULL) {
311 TBM_ERR("error: bufmgr is NULL.\n");
315 if (LIST_IS_EMPTY(&bufmgr->bo_list)) {
316 TBM_ERR("error: bo->bo->bufmgr->bo_list is EMPTY.\n");
320 LIST_FOR_EACH_ENTRY(old_data, &bufmgr->bo_list, item_link) {
325 TBM_ERR("error: No valid bo(%p).\n", bo);
331 tbm_bo_alloc(tbm_bufmgr bufmgr, int size, int flags)
336 _tbm_bo_mutex_lock();
338 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
339 TBM_BO_RETURN_VAL_IF_FAIL(size > 0, NULL);
341 bo = calloc(1, sizeof(struct _tbm_bo));
343 /* LCOV_EXCL_START */
344 TBM_ERR("error: fail to create of tbm_bo size(%d) flag(%s)\n",
345 size, _tbm_flag_to_str(flags));
346 _tbm_set_last_result(TBM_BO_ERROR_HEAP_ALLOC_FAILED);
347 _tbm_bo_mutex_unlock();
352 _tbm_util_check_bo_cnt(bufmgr);
356 bo_priv = bo->bufmgr->backend->bo_alloc(bo, size, flags);
358 /* LCOV_EXCL_START */
359 TBM_ERR("error: fail to create of tbm_bo size(%d) flag(%s)\n",
360 size, _tbm_flag_to_str(flags));
361 _tbm_set_last_result(TBM_BO_ERROR_BO_ALLOC_FAILED);
363 _tbm_bo_mutex_unlock();
368 bo->bufmgr->bo_cnt++;
374 TBM_TRACE_BO("bo(%p) size(%d) refcnt(%d), flag(%s)\n", bo, size, bo->ref_cnt,
375 _tbm_flag_to_str(bo->flags));
377 LIST_INITHEAD(&bo->user_data_list);
379 LIST_ADD(&bo->item_link, &bo->bufmgr->bo_list);
381 _tbm_bo_mutex_unlock();
387 tbm_bo_ref(tbm_bo bo)
389 _tbm_bo_mutex_lock();
391 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), NULL);
395 TBM_TRACE_BO("bo(%p) ref_cnt(%d)\n", bo, bo->ref_cnt);
397 _tbm_bo_mutex_unlock();
403 tbm_bo_unref(tbm_bo bo)
405 _tbm_bo_mutex_lock();
407 TBM_BO_RETURN_IF_FAIL(_tbm_bo_is_valid(bo));
409 TBM_TRACE_BO("bo(%p) ref_cnt(%d)\n", bo, bo->ref_cnt - 1);
411 if (bo->ref_cnt <= 0) {
412 _tbm_bo_mutex_unlock();
417 if (bo->ref_cnt == 0)
420 _tbm_bo_mutex_unlock();
424 tbm_bo_map(tbm_bo bo, int device, int opt)
426 tbm_bo_handle bo_handle;
428 _tbm_bo_mutex_lock();
430 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) NULL);
432 if (!_tbm_bo_lock(bo, device, opt)) {
433 _tbm_set_last_result(TBM_BO_ERROR_LOCK_FAILED);
434 TBM_ERR("error: fail to lock bo:%p)\n", bo);
435 _tbm_bo_mutex_unlock();
436 return (tbm_bo_handle) NULL;
439 bo_handle = bo->bufmgr->backend->bo_map(bo, device, opt);
440 if (bo_handle.ptr == NULL) {
441 /* LCOV_EXCL_START */
442 _tbm_set_last_result(TBM_BO_ERROR_MAP_FAILED);
443 TBM_ERR("error: fail to map bo:%p\n", bo);
445 _tbm_bo_mutex_unlock();
446 return (tbm_bo_handle) NULL;
450 /* increase the map_count */
453 TBM_TRACE_BO("bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
455 _tbm_bo_mutex_unlock();
461 tbm_bo_unmap(tbm_bo bo)
465 _tbm_bo_mutex_lock();
467 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
468 TBM_BO_RETURN_VAL_IF_FAIL(bo->map_cnt > 0, 0);
470 ret = bo->bufmgr->backend->bo_unmap(bo);
472 /* LCOV_EXCL_START */
473 TBM_ERR("error: bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
474 _tbm_set_last_result(TBM_BO_ERROR_UNMAP_FAILED);
475 _tbm_bo_mutex_unlock();
480 /* decrease the map_count */
483 TBM_TRACE_BO("bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
487 _tbm_bo_mutex_unlock();
493 tbm_bo_get_handle(tbm_bo bo, int device)
495 tbm_bo_handle bo_handle;
497 _tbm_bo_mutex_lock();
499 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) NULL);
501 bo_handle = bo->bufmgr->backend->bo_get_handle(bo, device);
502 if (bo_handle.ptr == NULL) {
503 /* LCOV_EXCL_START */
504 _tbm_set_last_result(TBM_BO_ERROR_GET_HANDLE_FAILED);
505 TBM_ERR("error: bo(%p) bo_handle(%p)\n", bo, bo_handle.ptr);
506 _tbm_bo_mutex_unlock();
507 return (tbm_bo_handle) NULL;
511 TBM_TRACE_BO("bo(%p) bo_handle(%p)\n", bo, bo_handle.ptr);
513 _tbm_bo_mutex_unlock();
519 tbm_bo_export(tbm_bo bo)
523 _tbm_bo_mutex_lock();
525 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
527 if (!bo->bufmgr->backend->bo_export) {
528 /* LCOV_EXCL_START */
529 _tbm_bo_mutex_unlock();
534 ret = bo->bufmgr->backend->bo_export(bo);
536 /* LCOV_EXCL_START */
537 _tbm_set_last_result(TBM_BO_ERROR_EXPORT_FAILED);
538 TBM_ERR("error: bo(%p) tbm_key(%d)\n", bo, ret);
539 _tbm_bo_mutex_unlock();
544 TBM_TRACE_BO("bo(%p) tbm_key(%u)\n", bo, ret);
546 _tbm_bo_mutex_unlock();
552 tbm_bo_export_fd(tbm_bo bo)
556 _tbm_bo_mutex_lock();
558 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), -1);
560 if (!bo->bufmgr->backend->bo_export_fd) {
561 /* LCOV_EXCL_START */
562 _tbm_bo_mutex_unlock();
567 ret = bo->bufmgr->backend->bo_export_fd(bo);
569 /* LCOV_EXCL_START */
570 _tbm_set_last_result(TBM_BO_ERROR_EXPORT_FD_FAILED);
571 TBM_ERR("error: bo(%p) tbm_fd(%d)\n", bo, ret);
572 _tbm_bo_mutex_unlock();
577 TBM_TRACE_BO("bo(%p) tbm_fd(%d)\n", bo, ret);
579 _tbm_bo_mutex_unlock();
585 tbm_bo_import(tbm_bufmgr bufmgr, unsigned int key)
591 _tbm_bo_mutex_lock();
593 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
595 if (!bufmgr->backend->bo_import) {
596 /* LCOV_EXCL_START */
597 _tbm_bo_mutex_unlock();
602 _tbm_util_check_bo_cnt(bufmgr);
604 bo = calloc(1, sizeof(struct _tbm_bo));
606 /* LCOV_EXCL_START */
607 TBM_ERR("error: fail to import of tbm_bo by key(%d)\n", key);
608 _tbm_bo_mutex_unlock();
615 bo_priv = bo->bufmgr->backend->bo_import(bo, key);
617 /* LCOV_EXCL_START */
618 TBM_ERR("error: fail to import of tbm_bo by key(%d)\n", key);
619 _tbm_set_last_result(TBM_BO_ERROR_IMPORT_FAILED);
621 _tbm_bo_mutex_unlock();
626 if (!LIST_IS_EMPTY(&bo->bufmgr->bo_list)) {
627 LIST_FOR_EACH_ENTRY(bo2, &bo->bufmgr->bo_list, item_link) {
628 if (bo2->priv == bo_priv) {
629 TBM_TRACE_BO("find bo(%p) ref(%d) key(%d) flag(%s) in list\n",
630 bo2, bo2->ref_cnt, key,
631 _tbm_flag_to_str(bo2->flags));
634 _tbm_bo_mutex_unlock();
640 bo->bufmgr->bo_cnt++;
645 if (bo->bufmgr->backend->bo_get_flags)
646 bo->flags = bo->bufmgr->backend->bo_get_flags(bo);
648 bo->flags = TBM_BO_DEFAULT;
650 TBM_TRACE_BO("import new bo(%p) ref(%d) key(%d) flag(%s) in list\n",
651 bo, bo->ref_cnt, key, _tbm_flag_to_str(bo->flags));
653 LIST_INITHEAD(&bo->user_data_list);
655 LIST_ADD(&bo->item_link, &bo->bufmgr->bo_list);
657 _tbm_bo_mutex_unlock();
663 tbm_bo_import_fd(tbm_bufmgr bufmgr, tbm_fd fd)
669 _tbm_bo_mutex_lock();
671 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
673 if (!bufmgr->backend->bo_import_fd) {
674 /* LCOV_EXCL_START */
675 _tbm_bo_mutex_unlock();
680 _tbm_util_check_bo_cnt(bufmgr);
682 bo = calloc(1, sizeof(struct _tbm_bo));
684 /* LCOV_EXCL_START */
685 TBM_ERR("error: fail to import tbm_bo by tbm_fd(%d)\n", fd);
686 _tbm_bo_mutex_unlock();
693 bo_priv = bo->bufmgr->backend->bo_import_fd(bo, fd);
695 /* LCOV_EXCL_START */
696 TBM_ERR("error: fail to import tbm_bo by tbm_fd(%d)\n", fd);
697 _tbm_set_last_result(TBM_BO_ERROR_IMPORT_FD_FAILED);
699 _tbm_bo_mutex_unlock();
704 if (!LIST_IS_EMPTY(&bo->bufmgr->bo_list)) {
706 LIST_FOR_EACH_ENTRY(bo2, &bo->bufmgr->bo_list, item_link) {
707 if (bo2->priv == bo_priv) {
708 TBM_TRACE_BO("find bo(%p) ref(%d) fd(%d) flag(%s) in list\n",
709 bo2, bo2->ref_cnt, fd,
710 _tbm_flag_to_str(bo2->flags));
713 _tbm_bo_mutex_unlock();
719 bo->bufmgr->bo_cnt++;
724 if (bo->bufmgr->backend->bo_get_flags)
725 bo->flags = bo->bufmgr->backend->bo_get_flags(bo);
727 bo->flags = TBM_BO_DEFAULT;
729 TBM_TRACE_BO("import bo(%p) ref(%d) fd(%d) flag(%s)\n",
730 bo, bo->ref_cnt, fd, _tbm_flag_to_str(bo->flags));
732 LIST_INITHEAD(&bo->user_data_list);
734 LIST_ADD(&bo->item_link, &bo->bufmgr->bo_list);
736 _tbm_bo_mutex_unlock();
742 tbm_bo_size(tbm_bo bo)
746 _tbm_bo_mutex_lock();
748 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
750 size = bo->bufmgr->backend->bo_size(bo);
752 TBM_TRACE_BO("bo(%p) size(%d)\n", bo, size);
754 _tbm_bo_mutex_unlock();
760 tbm_bo_locked(tbm_bo bo)
762 _tbm_bo_mutex_lock();
764 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
766 if (bo->bufmgr->bo_lock_type == TBM_BUFMGR_BO_LOCK_TYPE_NEVER) {
767 TBM_ERR("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
768 _tbm_bo_mutex_unlock();
772 if (bo->lock_cnt > 0) {
773 TBM_TRACE_BO("error: bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
774 _tbm_bo_mutex_unlock();
778 TBM_TRACE_BO("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
779 _tbm_bo_mutex_unlock();
785 tbm_bo_swap(tbm_bo bo1, tbm_bo bo2)
789 _tbm_bo_mutex_lock();
791 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo1), 0);
792 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo2), 0);
794 TBM_TRACE_BO("before: bo1(%p) bo2(%p)\n", bo1, bo2);
796 if (bo1->bufmgr->backend->bo_size(bo1) != bo2->bufmgr->backend->bo_size(bo2)) {
797 _tbm_set_last_result(TBM_BO_ERROR_SWAP_FAILED);
798 TBM_ERR("error: bo1(%p) bo2(%p)\n", bo1, bo2);
799 _tbm_bo_mutex_unlock();
803 TBM_TRACE_BO("after: bo1(%p) bo2(%p)\n", bo1, bo2);
806 bo1->priv = bo2->priv;
809 _tbm_bo_mutex_unlock();
815 tbm_bo_add_user_data(tbm_bo bo, unsigned long key,
816 tbm_data_free data_free_func)
820 _tbm_bo_mutex_lock();
822 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
824 /* check if the data according to the key exist if so, return false. */
825 data = user_data_lookup(&bo->user_data_list, key);
827 TBM_TRACE_BO("warning: user data already exist key(%ld)\n", key);
828 _tbm_bo_mutex_unlock();
832 data = user_data_create(key, data_free_func);
834 TBM_ERR("error: bo(%p) key(%lu)\n", bo, key);
835 _tbm_bo_mutex_unlock();
839 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, data->data);
841 LIST_ADD(&data->item_link, &bo->user_data_list);
843 _tbm_bo_mutex_unlock();
849 tbm_bo_delete_user_data(tbm_bo bo, unsigned long key)
851 tbm_user_data *old_data;
853 _tbm_bo_mutex_lock();
855 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
857 if (LIST_IS_EMPTY(&bo->user_data_list)) {
858 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
859 _tbm_bo_mutex_unlock();
863 old_data = user_data_lookup(&bo->user_data_list, key);
865 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
866 _tbm_bo_mutex_unlock();
870 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
872 user_data_delete(old_data);
874 _tbm_bo_mutex_unlock();
880 tbm_bo_set_user_data(tbm_bo bo, unsigned long key, void *data)
882 tbm_user_data *old_data;
884 _tbm_bo_mutex_lock();
886 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
888 if (LIST_IS_EMPTY(&bo->user_data_list)) {
889 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
890 _tbm_bo_mutex_unlock();
894 old_data = user_data_lookup(&bo->user_data_list, key);
896 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
897 _tbm_bo_mutex_unlock();
901 if (old_data->data && old_data->free_func)
902 old_data->free_func(old_data->data);
903 old_data->data = data;
905 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
907 _tbm_bo_mutex_unlock();
913 tbm_bo_get_user_data(tbm_bo bo, unsigned long key, void **data)
915 tbm_user_data *old_data;
917 _tbm_bo_mutex_lock();
919 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
921 if (!data || LIST_IS_EMPTY(&bo->user_data_list)) {
922 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
923 _tbm_bo_mutex_unlock();
927 old_data = user_data_lookup(&bo->user_data_list, key);
929 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
931 _tbm_bo_mutex_unlock();
935 *data = old_data->data;
937 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
939 _tbm_bo_mutex_unlock();
944 /* LCOV_EXCL_START */
946 tbm_get_last_error(void)
948 return tbm_last_error;
953 tbm_bo_get_flags(tbm_bo bo)
957 _tbm_bo_mutex_lock();
959 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
963 TBM_TRACE_BO("bo(%p)\n", bo);
965 _tbm_bo_mutex_unlock();
970 /* LCOV_EXCL_START */
971 /* internal function */
973 _tbm_bo_set_surface(tbm_bo bo, tbm_surface_h surface)
975 _tbm_bo_mutex_lock();
977 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
979 bo->surface = surface;
981 _tbm_bo_mutex_unlock();
987 _tbm_bo_free(tbm_bo bo)
989 /* destory the user_data_list */
990 if (!LIST_IS_EMPTY(&bo->user_data_list)) {
991 tbm_user_data *old_data = NULL, *tmp;
993 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp,
994 &bo->user_data_list, item_link) {
995 TBM_DBG("free user_data\n");
996 user_data_delete(old_data);
1000 while (bo->lock_cnt > 0) {
1001 TBM_ERR("error lock_cnt:%d\n", bo->lock_cnt);
1006 /* call the bo_free */
1007 bo->bufmgr->backend->bo_free(bo);
1010 bo->bufmgr->bo_cnt--;
1012 LIST_DEL(&bo->item_link);
1015 /* LCOV_EXCL_STOP */