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)
199 if (bo->bufmgr->backend_module_data) {
200 if (bo->bufmgr->bo_func->bo_lock) {
201 error = bo->bufmgr->bo_func->bo_lock(bo->bo_data, device, opt);
202 if (error != TBM_ERROR_NONE) {
203 TBM_WRN("fail to lock");
208 if (bo->bufmgr->backend->bo_lock)
209 ret = bo->bufmgr->backend->bo_lock(bo, device, opt);
216 _bo_unlock(tbm_bo bo)
220 if (bo->bufmgr->backend_module_data) {
221 if (bo->bufmgr->bo_func->bo_unlock) {
222 error = bo->bufmgr->bo_func->bo_unlock(bo->bo_data);
223 if (error != TBM_ERROR_NONE)
224 TBM_WRN("fail to unlock");
227 if (bo->bufmgr->backend->bo_unlock)
228 bo->bufmgr->backend->bo_unlock(bo);
233 _tbm_bo_lock(tbm_bo bo, int device, int opt)
240 /* do not try to lock the bo */
241 if (bo->bufmgr->bo_lock_type == TBM_BUFMGR_BO_LOCK_TYPE_NEVER)
244 if (bo->lock_cnt < 0) {
245 TBM_ERR("error bo:%p LOCK_CNT=%d\n",
252 switch (bo->bufmgr->bo_lock_type) {
253 case TBM_BUFMGR_BO_LOCK_TYPE_ONCE:
254 if (bo->lock_cnt == 0) {
255 _tbm_bo_mutex_unlock();
256 ret = _bo_lock(bo, device, opt);
257 _tbm_bo_mutex_lock();
263 case TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS:
264 _tbm_bo_mutex_unlock();
265 ret = _bo_lock(bo, device, opt);
266 _tbm_bo_mutex_lock();
271 TBM_ERR("error bo:%p bo_lock_type[%d] is wrong.\n",
272 bo, bo->bufmgr->bo_lock_type);
277 TBM_DBG(">> LOCK bo:%p(%d->%d)\n", bo, old, bo->lock_cnt);
283 _tbm_bo_unlock(tbm_bo bo)
287 /* do not try to unlock the bo */
288 if (bo->bufmgr->bo_lock_type == TBM_BUFMGR_BO_LOCK_TYPE_NEVER)
293 switch (bo->bufmgr->bo_lock_type) {
294 case TBM_BUFMGR_BO_LOCK_TYPE_ONCE:
295 if (bo->lock_cnt > 0) {
297 if (bo->lock_cnt == 0)
301 case TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS:
302 if (bo->lock_cnt > 0) {
308 TBM_ERR("error bo:%p bo_lock_type[%d] is wrong.\n",
309 bo, bo->bufmgr->bo_lock_type);
313 if (bo->lock_cnt < 0)
316 TBM_DBG(">> UNLOCK bo:%p(%d->%d)\n", bo, old, bo->lock_cnt);
320 _tbm_bo_is_valid(tbm_bo bo)
322 tbm_bufmgr bufmgr = NULL;
323 tbm_bo old_data = NULL;
326 TBM_ERR("error: bo is NULL.\n");
330 bufmgr = tbm_bufmgr_get();
331 if (bufmgr == NULL) {
332 TBM_ERR("error: bufmgr is NULL.\n");
336 if (LIST_IS_EMPTY(&bufmgr->bo_list)) {
337 TBM_ERR("error: bo->bo->bufmgr->bo_list is EMPTY.\n");
341 LIST_FOR_EACH_ENTRY(old_data, &bufmgr->bo_list, item_link) {
346 TBM_ERR("error: No valid bo(%p).\n", bo);
352 tbm_bo_alloc(tbm_bufmgr bufmgr, int size, int flags)
356 tbm_backend_bo_data *bo_data;
359 _tbm_bo_mutex_lock();
361 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
362 TBM_BO_RETURN_VAL_IF_FAIL(size > 0, NULL);
364 bo = calloc(1, sizeof(struct _tbm_bo));
366 /* LCOV_EXCL_START */
367 TBM_ERR("error: fail to create of tbm_bo size(%d) flag(%s)\n",
368 size, _tbm_flag_to_str(flags));
369 _tbm_set_last_result(TBM_BO_ERROR_HEAP_ALLOC_FAILED);
370 _tbm_bo_mutex_unlock();
375 _tbm_util_check_bo_cnt(bufmgr);
379 if (bufmgr->backend_module_data) {
380 bo_data = bufmgr->bufmgr_func->bufmgr_alloc_bo(bufmgr->bufmgr_data, size, flags, &error);
382 /* LCOV_EXCL_START */
383 TBM_ERR("error: fail to create of tbm_bo size(%d) flag(%s)\n",
384 size, _tbm_flag_to_str(flags));
385 _tbm_set_last_result(TBM_BO_ERROR_BO_ALLOC_FAILED);
387 _tbm_bo_mutex_unlock();
391 bo->bo_data = bo_data;
393 bo_priv = bo->bufmgr->backend->bo_alloc(bo, size, flags);
395 /* LCOV_EXCL_START */
396 TBM_ERR("error: fail to create of tbm_bo size(%d) flag(%s)\n",
397 size, _tbm_flag_to_str(flags));
398 _tbm_set_last_result(TBM_BO_ERROR_BO_ALLOC_FAILED);
400 _tbm_bo_mutex_unlock();
407 bo->bufmgr->bo_cnt++;
411 TBM_TRACE_BO("bo(%p) size(%d) refcnt(%d), flag(%s)\n", bo, size, bo->ref_cnt,
412 _tbm_flag_to_str(bo->flags));
414 LIST_INITHEAD(&bo->user_data_list);
416 LIST_ADD(&bo->item_link, &bo->bufmgr->bo_list);
418 _tbm_bo_mutex_unlock();
424 tbm_bo_ref(tbm_bo bo)
426 _tbm_bo_mutex_lock();
428 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), NULL);
432 TBM_TRACE_BO("bo(%p) ref_cnt(%d)\n", bo, bo->ref_cnt);
434 _tbm_bo_mutex_unlock();
440 tbm_bo_unref(tbm_bo bo)
442 _tbm_bo_mutex_lock();
444 TBM_BO_RETURN_IF_FAIL(_tbm_bo_is_valid(bo));
446 TBM_TRACE_BO("bo(%p) ref_cnt(%d)\n", bo, bo->ref_cnt - 1);
448 if (bo->ref_cnt <= 0) {
449 _tbm_bo_mutex_unlock();
454 if (bo->ref_cnt == 0)
457 _tbm_bo_mutex_unlock();
461 tbm_bo_map(tbm_bo bo, int device, int opt)
463 tbm_bo_handle bo_handle;
466 _tbm_bo_mutex_lock();
468 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) NULL);
470 if (!_tbm_bo_lock(bo, device, opt)) {
471 _tbm_set_last_result(TBM_BO_ERROR_LOCK_FAILED);
472 TBM_ERR("error: fail to lock bo:%p)\n", bo);
473 _tbm_bo_mutex_unlock();
474 return (tbm_bo_handle) NULL;
477 if (bo->bufmgr->backend_module_data) {
478 bo_handle = bo->bufmgr->bo_func->bo_map(bo->bo_data, device, opt, &error);
479 if (bo_handle.ptr == NULL) {
480 /* LCOV_EXCL_START */
481 _tbm_set_last_result(TBM_BO_ERROR_MAP_FAILED);
482 TBM_ERR("error: fail to map bo:%p error:%d\n", bo, error);
484 _tbm_bo_mutex_unlock();
485 return (tbm_bo_handle) NULL;
489 bo_handle = bo->bufmgr->backend->bo_map(bo, device, opt);
490 if (bo_handle.ptr == NULL) {
491 /* LCOV_EXCL_START */
492 _tbm_set_last_result(TBM_BO_ERROR_MAP_FAILED);
493 TBM_ERR("error: fail to map bo:%p\n", bo);
495 _tbm_bo_mutex_unlock();
496 return (tbm_bo_handle) NULL;
501 /* increase the map_count */
504 TBM_TRACE_BO("bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
506 _tbm_bo_mutex_unlock();
512 tbm_bo_unmap(tbm_bo bo)
517 _tbm_bo_mutex_lock();
519 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
520 TBM_BO_RETURN_VAL_IF_FAIL(bo->map_cnt > 0, 0);
522 if (bo->bufmgr->backend_module_data) {
523 error = bo->bufmgr->bo_func->bo_unmap(bo->bo_data);
524 if (error != TBM_ERROR_NONE) {
525 /* LCOV_EXCL_START */
526 TBM_ERR("error: bo(%p) map_cnt(%d) error(%d)\n", bo, bo->map_cnt, error);
527 _tbm_set_last_result(TBM_BO_ERROR_UNMAP_FAILED);
529 _tbm_bo_mutex_unlock();
534 ret = bo->bufmgr->backend->bo_unmap(bo);
536 /* LCOV_EXCL_START */
537 TBM_ERR("error: bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
538 _tbm_set_last_result(TBM_BO_ERROR_UNMAP_FAILED);
539 _tbm_bo_mutex_unlock();
545 /* decrease the map_count */
548 TBM_TRACE_BO("bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
552 _tbm_bo_mutex_unlock();
558 tbm_bo_get_handle(tbm_bo bo, int device)
560 tbm_bo_handle bo_handle;
563 _tbm_bo_mutex_lock();
565 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) NULL);
567 if (bo->bufmgr->backend_module_data) {
568 bo_handle = bo->bufmgr->bo_func->bo_get_handle(bo->bo_data, device, &error);
569 if (bo_handle.ptr == NULL) {
570 /* LCOV_EXCL_START */
571 _tbm_set_last_result(TBM_BO_ERROR_GET_HANDLE_FAILED);
572 TBM_ERR("error: bo(%p) bo_handle(%p) error(%d)\n", bo, bo_handle.ptr, error);
573 _tbm_bo_mutex_unlock();
574 return (tbm_bo_handle) NULL;
578 bo_handle = bo->bufmgr->backend->bo_get_handle(bo, device);
579 if (bo_handle.ptr == NULL) {
580 /* LCOV_EXCL_START */
581 _tbm_set_last_result(TBM_BO_ERROR_GET_HANDLE_FAILED);
582 TBM_ERR("error: bo(%p) bo_handle(%p)\n", bo, bo_handle.ptr);
583 _tbm_bo_mutex_unlock();
584 return (tbm_bo_handle) NULL;
589 TBM_TRACE_BO("bo(%p) bo_handle(%p)\n", bo, bo_handle.ptr);
591 _tbm_bo_mutex_unlock();
597 tbm_bo_export(tbm_bo bo)
602 _tbm_bo_mutex_lock();
604 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
606 if (bo->bufmgr->backend_module_data) {
607 if (!bo->bufmgr->bo_func->bo_export_key) {
608 /* LCOV_EXCL_START */
609 _tbm_bo_mutex_unlock();
614 ret = bo->bufmgr->bo_func->bo_export_key(bo->bo_data, &error);
616 /* LCOV_EXCL_START */
617 _tbm_set_last_result(TBM_BO_ERROR_EXPORT_FAILED);
618 TBM_ERR("error: bo(%p) tbm_key(%d) error(%d)\n", bo, ret, error);
619 _tbm_bo_mutex_unlock();
624 if (!bo->bufmgr->backend->bo_export) {
625 /* LCOV_EXCL_START */
626 _tbm_bo_mutex_unlock();
631 ret = bo->bufmgr->backend->bo_export(bo);
633 /* LCOV_EXCL_START */
634 _tbm_set_last_result(TBM_BO_ERROR_EXPORT_FAILED);
635 TBM_ERR("error: bo(%p) tbm_key(%d)\n", bo, ret);
636 _tbm_bo_mutex_unlock();
642 TBM_TRACE_BO("bo(%p) tbm_key(%u)\n", bo, ret);
644 _tbm_bo_mutex_unlock();
650 tbm_bo_export_fd(tbm_bo bo)
655 _tbm_bo_mutex_lock();
657 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), -1);
659 if (bo->bufmgr->backend_module_data) {
660 if (!bo->bufmgr->bo_func->bo_export_fd) {
661 /* LCOV_EXCL_START */
662 _tbm_bo_mutex_unlock();
667 ret = bo->bufmgr->bo_func->bo_export_fd(bo->bo_data, &error);
669 /* LCOV_EXCL_START */
670 _tbm_set_last_result(TBM_BO_ERROR_EXPORT_FD_FAILED);
671 TBM_ERR("error: bo(%p) tbm_fd(%d) error(%d)\n", bo, ret, error);
672 _tbm_bo_mutex_unlock();
677 if (!bo->bufmgr->backend->bo_export_fd) {
678 /* LCOV_EXCL_START */
679 _tbm_bo_mutex_unlock();
684 ret = bo->bufmgr->backend->bo_export_fd(bo);
686 /* LCOV_EXCL_START */
687 _tbm_set_last_result(TBM_BO_ERROR_EXPORT_FD_FAILED);
688 TBM_ERR("error: bo(%p) tbm_fd(%d)\n", bo, ret);
689 _tbm_bo_mutex_unlock();
695 TBM_TRACE_BO("bo(%p) tbm_fd(%d)\n", bo, ret);
697 _tbm_bo_mutex_unlock();
703 tbm_bo_import(tbm_bufmgr bufmgr, unsigned int key)
709 tbm_backend_bo_data *bo_data;
711 _tbm_bo_mutex_lock();
713 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
715 if (bufmgr->backend_module_data) {
716 if (!bufmgr->bufmgr_func->bufmgr_import_key) {
717 /* LCOV_EXCL_START */
718 _tbm_bo_mutex_unlock();
723 if (!bufmgr->backend->bo_import) {
724 /* LCOV_EXCL_START */
725 _tbm_bo_mutex_unlock();
731 _tbm_util_check_bo_cnt(bufmgr);
733 bo = calloc(1, sizeof(struct _tbm_bo));
735 /* LCOV_EXCL_START */
736 TBM_ERR("error: fail to import of tbm_bo by key(%d)\n", key);
737 _tbm_bo_mutex_unlock();
744 if (bo->bufmgr->backend_module_data) {
745 bo_data = bo->bufmgr->bufmgr_func->bufmgr_import_key(bufmgr->bufmgr_data, key, &error);
747 /* LCOV_EXCL_START */
748 TBM_ERR("error: fail to import of tbm_bo by key(%d). error(%d)\n", key, error);
749 _tbm_set_last_result(TBM_BO_ERROR_IMPORT_FAILED);
751 _tbm_bo_mutex_unlock();
756 if (!LIST_IS_EMPTY(&bo->bufmgr->bo_list)) {
757 LIST_FOR_EACH_ENTRY(bo2, &bo->bufmgr->bo_list, item_link) {
758 if (bo2->bo_data == bo_data) {
759 TBM_TRACE_BO("find bo(%p) ref(%d) key(%d) flag(%s) in list\n",
760 bo2, bo2->ref_cnt, key,
761 _tbm_flag_to_str(bo2->flags));
764 _tbm_bo_mutex_unlock();
769 bo->bo_data = bo_data;
771 bo_priv = bo->bufmgr->backend->bo_import(bo, key);
773 /* LCOV_EXCL_START */
774 TBM_ERR("error: fail to import of tbm_bo by key(%d)\n", key);
775 _tbm_set_last_result(TBM_BO_ERROR_IMPORT_FAILED);
777 _tbm_bo_mutex_unlock();
782 if (!LIST_IS_EMPTY(&bo->bufmgr->bo_list)) {
783 LIST_FOR_EACH_ENTRY(bo2, &bo->bufmgr->bo_list, item_link) {
784 if (bo2->priv == bo_priv) {
785 TBM_TRACE_BO("find bo(%p) ref(%d) key(%d) flag(%s) in list\n",
786 bo2, bo2->ref_cnt, key,
787 _tbm_flag_to_str(bo2->flags));
790 _tbm_bo_mutex_unlock();
798 bo->bufmgr->bo_cnt++;
801 if (bo->bufmgr->backend_module_data) {
802 bo->flags = bo->bufmgr->bo_func->bo_get_memory_types(bo->bo_data, &error);
803 if (error != TBM_ERROR_NONE) {
804 TBM_ERR("fail to get the bo flags(memory_types)");
805 bo->flags = TBM_BO_DEFAULT;
808 if (bo->bufmgr->backend->bo_get_flags)
809 bo->flags = bo->bufmgr->backend->bo_get_flags(bo);
811 bo->flags = TBM_BO_DEFAULT;
814 TBM_TRACE_BO("import new bo(%p) ref(%d) key(%d) flag(%s) in list\n",
815 bo, bo->ref_cnt, key, _tbm_flag_to_str(bo->flags));
817 LIST_INITHEAD(&bo->user_data_list);
819 LIST_ADD(&bo->item_link, &bo->bufmgr->bo_list);
821 _tbm_bo_mutex_unlock();
827 tbm_bo_import_fd(tbm_bufmgr bufmgr, tbm_fd fd)
832 tbm_backend_bo_data *bo_data;
835 _tbm_bo_mutex_lock();
837 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
839 if (bufmgr->backend_module_data) {
840 if (!bufmgr->bufmgr_func->bufmgr_import_fd) {
841 /* LCOV_EXCL_START */
842 _tbm_bo_mutex_unlock();
847 if (!bufmgr->backend->bo_import_fd) {
848 /* LCOV_EXCL_START */
849 _tbm_bo_mutex_unlock();
855 _tbm_util_check_bo_cnt(bufmgr);
857 bo = calloc(1, sizeof(struct _tbm_bo));
859 /* LCOV_EXCL_START */
860 TBM_ERR("error: fail to import tbm_bo by tbm_fd(%d)\n", fd);
861 _tbm_bo_mutex_unlock();
868 if (bo->bufmgr->backend_module_data) {
869 bo_data = bo->bufmgr->bufmgr_func->bufmgr_import_fd(bufmgr->bufmgr_data, fd, &error);
871 /* LCOV_EXCL_START */
872 TBM_ERR("error: fail to import tbm_bo by tbm_fd(%d). error(%d)\n", fd, error);
873 _tbm_set_last_result(TBM_BO_ERROR_IMPORT_FD_FAILED);
875 _tbm_bo_mutex_unlock();
880 if (!LIST_IS_EMPTY(&bo->bufmgr->bo_list)) {
881 LIST_FOR_EACH_ENTRY(bo2, &bo->bufmgr->bo_list, item_link) {
882 if (bo2->bo_data == bo_data) {
883 TBM_TRACE_BO("find bo(%p) ref(%d) fd(%d) flag(%s) in list\n",
884 bo2, bo2->ref_cnt, fd,
885 _tbm_flag_to_str(bo2->flags));
888 _tbm_bo_mutex_unlock();
893 bo->bo_data = bo_data;
895 bo_priv = bo->bufmgr->backend->bo_import_fd(bo, fd);
897 /* LCOV_EXCL_START */
898 TBM_ERR("error: fail to import tbm_bo by tbm_fd(%d)\n", fd);
899 _tbm_set_last_result(TBM_BO_ERROR_IMPORT_FD_FAILED);
901 _tbm_bo_mutex_unlock();
906 if (!LIST_IS_EMPTY(&bo->bufmgr->bo_list)) {
907 LIST_FOR_EACH_ENTRY(bo2, &bo->bufmgr->bo_list, item_link) {
908 if (bo2->priv == bo_priv) {
909 TBM_TRACE_BO("find bo(%p) ref(%d) fd(%d) flag(%s) in list\n",
910 bo2, bo2->ref_cnt, fd,
911 _tbm_flag_to_str(bo2->flags));
914 _tbm_bo_mutex_unlock();
922 bo->bufmgr->bo_cnt++;
925 if (bo->bufmgr->backend_module_data) {
926 bo->flags = bo->bufmgr->bo_func->bo_get_memory_types(bo->bo_data, &error);
927 if (error != TBM_ERROR_NONE) {
928 TBM_ERR("fail to get the bo flags(memory_types)");
929 bo->flags = TBM_BO_DEFAULT;
932 if (bo->bufmgr->backend->bo_get_flags)
933 bo->flags = bo->bufmgr->backend->bo_get_flags(bo);
935 bo->flags = TBM_BO_DEFAULT;
938 TBM_TRACE_BO("import bo(%p) ref(%d) fd(%d) flag(%s)\n",
939 bo, bo->ref_cnt, fd, _tbm_flag_to_str(bo->flags));
941 LIST_INITHEAD(&bo->user_data_list);
943 LIST_ADD(&bo->item_link, &bo->bufmgr->bo_list);
945 _tbm_bo_mutex_unlock();
951 tbm_bo_size(tbm_bo bo)
956 _tbm_bo_mutex_lock();
958 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
960 if (bo->bufmgr->backend_module_data) {
961 size = bo->bufmgr->bo_func->bo_get_size(bo->bo_data, &error);
962 if (error != TBM_ERROR_NONE)
963 TBM_ERR("fail to get the size of the bo_data(%d).", error);
965 size = bo->bufmgr->backend->bo_size(bo);
967 TBM_TRACE_BO("bo(%p) size(%d)\n", bo, size);
969 _tbm_bo_mutex_unlock();
975 tbm_bo_locked(tbm_bo bo)
977 _tbm_bo_mutex_lock();
979 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
981 if (bo->bufmgr->bo_lock_type == TBM_BUFMGR_BO_LOCK_TYPE_NEVER) {
982 TBM_ERR("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
983 _tbm_bo_mutex_unlock();
987 if (bo->lock_cnt > 0) {
988 TBM_TRACE_BO("error: bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
989 _tbm_bo_mutex_unlock();
993 TBM_TRACE_BO("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
994 _tbm_bo_mutex_unlock();
1000 tbm_bo_swap(tbm_bo bo1, tbm_bo bo2)
1002 tbm_error_e error1, error2;
1003 int size1 = -1, size2 = -2;
1006 _tbm_bo_mutex_lock();
1008 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo1), 0);
1009 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo2), 0);
1011 TBM_TRACE_BO("before: bo1(%p) bo2(%p)\n", bo1, bo2);
1013 if (bo1->bufmgr->backend_module_data) {
1014 size1 = bo1->bufmgr->bo_func->bo_get_size(bo1->bo_data, &error1);
1015 if (error1 != TBM_ERROR_NONE) {
1016 TBM_ERR("fail to get the size of bo1.(%d)", error1);
1019 size2 = bo2->bufmgr->bo_func->bo_get_size(bo2->bo_data, &error2);
1020 if (error2 != TBM_ERROR_NONE) {
1021 TBM_ERR("fail to get the size of bo2.(%d)", error2);
1025 size1 = bo1->bufmgr->backend->bo_size(bo1);
1026 size2 = bo2->bufmgr->backend->bo_size(bo2);
1029 if (size1 != size2) {
1030 TBM_ERR("error: bo1 size(%d) and bo2 size(%d) is different.", size1, size2);
1034 TBM_TRACE_BO("after: bo1(%p) bo2(%p)\n", bo1, bo2);
1037 bo1->priv = bo2->priv;
1040 _tbm_bo_mutex_unlock();
1045 _tbm_set_last_result(TBM_BO_ERROR_SWAP_FAILED);
1046 TBM_ERR("error: bo1(%p) bo2(%p)\n", bo1, bo2);
1047 _tbm_bo_mutex_unlock();
1053 tbm_bo_add_user_data(tbm_bo bo, unsigned long key,
1054 tbm_data_free data_free_func)
1056 tbm_user_data *data;
1058 _tbm_bo_mutex_lock();
1060 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
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_TRACE_BO("warning: user data already exist key(%ld)\n", key);
1066 _tbm_bo_mutex_unlock();
1070 data = user_data_create(key, data_free_func);
1072 TBM_ERR("error: bo(%p) key(%lu)\n", bo, key);
1073 _tbm_bo_mutex_unlock();
1077 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, data->data);
1079 LIST_ADD(&data->item_link, &bo->user_data_list);
1081 _tbm_bo_mutex_unlock();
1087 tbm_bo_delete_user_data(tbm_bo bo, unsigned long key)
1089 tbm_user_data *old_data;
1091 _tbm_bo_mutex_lock();
1093 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1095 if (LIST_IS_EMPTY(&bo->user_data_list)) {
1096 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1097 _tbm_bo_mutex_unlock();
1101 old_data = user_data_lookup(&bo->user_data_list, key);
1103 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1104 _tbm_bo_mutex_unlock();
1108 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1110 user_data_delete(old_data);
1112 _tbm_bo_mutex_unlock();
1118 tbm_bo_set_user_data(tbm_bo bo, unsigned long key, void *data)
1120 tbm_user_data *old_data;
1122 _tbm_bo_mutex_lock();
1124 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1126 if (LIST_IS_EMPTY(&bo->user_data_list)) {
1127 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1128 _tbm_bo_mutex_unlock();
1132 old_data = user_data_lookup(&bo->user_data_list, key);
1134 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1135 _tbm_bo_mutex_unlock();
1139 if (old_data->data && old_data->free_func)
1140 old_data->free_func(old_data->data);
1141 old_data->data = data;
1143 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1145 _tbm_bo_mutex_unlock();
1151 tbm_bo_get_user_data(tbm_bo bo, unsigned long key, void **data)
1153 tbm_user_data *old_data;
1155 _tbm_bo_mutex_lock();
1157 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1159 if (!data || LIST_IS_EMPTY(&bo->user_data_list)) {
1160 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1161 _tbm_bo_mutex_unlock();
1165 old_data = user_data_lookup(&bo->user_data_list, key);
1167 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1169 _tbm_bo_mutex_unlock();
1173 *data = old_data->data;
1175 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1177 _tbm_bo_mutex_unlock();
1182 /* LCOV_EXCL_START */
1184 tbm_get_last_error(void)
1186 return tbm_last_error;
1188 /* LCOV_EXCL_STOP */
1191 tbm_bo_get_flags(tbm_bo bo)
1195 _tbm_bo_mutex_lock();
1197 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1201 TBM_TRACE_BO("bo(%p)\n", bo);
1203 _tbm_bo_mutex_unlock();
1208 /* LCOV_EXCL_START */
1209 /* internal function */
1211 _tbm_bo_set_surface(tbm_bo bo, tbm_surface_h surface)
1213 _tbm_bo_mutex_lock();
1215 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1217 bo->surface = surface;
1219 _tbm_bo_mutex_unlock();
1225 _tbm_bo_free(tbm_bo bo)
1227 /* destory the user_data_list */
1228 if (!LIST_IS_EMPTY(&bo->user_data_list)) {
1229 tbm_user_data *old_data = NULL, *tmp;
1231 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp,
1232 &bo->user_data_list, item_link) {
1233 TBM_DBG("free user_data\n");
1234 user_data_delete(old_data);
1238 while (bo->lock_cnt > 0) {
1239 TBM_ERR("error lock_cnt:%d\n", bo->lock_cnt);
1244 /* call the bo_free */
1245 if (bo->bufmgr->backend_module_data) {
1246 bo->bufmgr->bo_func->bo_free(bo->bo_data);
1249 bo->bufmgr->backend->bo_free(bo);
1253 bo->bufmgr->bo_cnt--;
1255 LIST_DEL(&bo->item_link);
1258 /* LCOV_EXCL_STOP */