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 void _tbm_bo_mutex_unlock(void);
41 #define TBM_BO_RETURN_IF_FAIL(cond) {\
43 TBM_ERR("'%s' failed.\n", #cond);\
44 _tbm_bo_mutex_unlock();\
49 #define TBM_BO_RETURN_VAL_IF_FAIL(cond, val) {\
51 TBM_ERR("'%s' failed.\n", #cond);\
52 _tbm_bo_mutex_unlock();\
59 _tbm_bo_mutex_init(void)
61 static bool tbm_bo_mutex_init = false;
63 if (tbm_bo_mutex_init)
66 if (pthread_mutex_init(&tbm_bo_lock, NULL)) {
67 TBM_ERR("fail: Cannot pthread_mutex_init for tbm_bo_lock.\n");
71 tbm_bo_mutex_init = true;
77 _tbm_bo_mutex_lock(void)
79 if (!_tbm_bo_mutex_init()) {
80 TBM_ERR("fail: _tbm_bo_mutex_init()\n");
84 pthread_mutex_lock(&tbm_bo_lock);
88 _tbm_bo_mutex_unlock(void)
90 pthread_mutex_unlock(&tbm_bo_lock);
94 _tbm_flag_to_str(int f)
98 if (f == TBM_BO_DEFAULT)
99 snprintf(str, 255, "DEFAULT");
103 if (f & TBM_BO_SCANOUT)
104 c += snprintf(&str[c], 255-c, "SCANOUT");
106 if (f & TBM_BO_NONCACHABLE) {
107 if (c >= 0 && c < 255)
108 c += snprintf(&str[c], 255-c, ", ");
110 if (c >= 0 && c < 255)
111 c += snprintf(&str[c], 255-c, "NONCACHABLE,");
115 if (c >= 0 && c < 255)
116 c += snprintf(&str[c], 255-c, ", ");
118 if (c >= 0 && c < 255)
119 c += snprintf(&str[c], 255-c, "WC");
127 _tbm_util_check_bo_cnt(tbm_bufmgr bufmgr)
129 static int last_chk_bo_cnt = 0;
131 if ((bufmgr->bo_cnt >= 500) && ((bufmgr->bo_cnt % 20) == 0) &&
132 (bufmgr->bo_cnt > last_chk_bo_cnt)) {
133 TBM_DBG("============TBM BO CNT DEBUG: bo_cnt=%d\n", bufmgr->bo_cnt);
134 tbm_bufmgr_debug_show(bufmgr);
135 last_chk_bo_cnt = bufmgr->bo_cnt;
141 *user_data_lookup(struct list_head *user_data_list, unsigned long key)
143 tbm_user_data *old_data = NULL;
145 if (LIST_IS_EMPTY(user_data_list))
148 LIST_FOR_EACH_ENTRY(old_data, user_data_list, item_link) {
149 if (old_data->key == key)
157 *user_data_create(unsigned long key, tbm_data_free data_free_func)
159 tbm_user_data *user_data;
161 user_data = calloc(1, sizeof(tbm_user_data));
163 /* LCOV_EXCL_START */
164 TBM_ERR("fail to allocate an user_date\n");
169 user_data->key = key;
170 user_data->free_func = data_free_func;
176 user_data_delete(tbm_user_data *user_data)
178 if (user_data->data && user_data->free_func)
179 user_data->free_func(user_data->data);
181 LIST_DEL(&user_data->item_link);
187 _bo_lock(tbm_bo bo, int device, int opt)
192 if (bo->bufmgr->backend_module_data) {
193 if (bo->bufmgr->bo_func->bo_lock) {
194 error = bo->bufmgr->bo_func->bo_lock(bo->bo_data, device, opt);
195 if (error != TBM_ERROR_NONE) {
196 TBM_WRN("fail to lock");
201 if (bo->bufmgr->backend->bo_lock)
202 ret = bo->bufmgr->backend->bo_lock(bo, device, opt);
209 _bo_unlock(tbm_bo bo)
213 if (bo->bufmgr->backend_module_data) {
214 if (bo->bufmgr->bo_func->bo_unlock) {
215 error = bo->bufmgr->bo_func->bo_unlock(bo->bo_data);
216 if (error != TBM_ERROR_NONE)
217 TBM_WRN("fail to unlock");
220 if (bo->bufmgr->backend->bo_unlock)
221 bo->bufmgr->backend->bo_unlock(bo);
226 _tbm_bo_lock(tbm_bo bo, int device, int opt)
233 /* do not try to lock the bo */
234 if (bo->bufmgr->bo_lock_type == TBM_BUFMGR_BO_LOCK_TYPE_NEVER)
237 if (bo->lock_cnt < 0) {
238 TBM_ERR("error bo:%p LOCK_CNT=%d\n",
245 switch (bo->bufmgr->bo_lock_type) {
246 case TBM_BUFMGR_BO_LOCK_TYPE_ONCE:
247 if (bo->lock_cnt == 0) {
248 _tbm_bo_mutex_unlock();
249 ret = _bo_lock(bo, device, opt);
250 _tbm_bo_mutex_lock();
256 case TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS:
257 _tbm_bo_mutex_unlock();
258 ret = _bo_lock(bo, device, opt);
259 _tbm_bo_mutex_lock();
264 TBM_ERR("error bo:%p bo_lock_type[%d] is wrong.\n",
265 bo, bo->bufmgr->bo_lock_type);
270 TBM_DBG(">> LOCK bo:%p(%d->%d)\n", bo, old, bo->lock_cnt);
276 _tbm_bo_unlock(tbm_bo bo)
280 /* do not try to unlock the bo */
281 if (bo->bufmgr->bo_lock_type == TBM_BUFMGR_BO_LOCK_TYPE_NEVER)
286 switch (bo->bufmgr->bo_lock_type) {
287 case TBM_BUFMGR_BO_LOCK_TYPE_ONCE:
288 if (bo->lock_cnt > 0) {
290 if (bo->lock_cnt == 0)
294 case TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS:
295 if (bo->lock_cnt > 0) {
301 TBM_ERR("error bo:%p bo_lock_type[%d] is wrong.\n",
302 bo, bo->bufmgr->bo_lock_type);
306 if (bo->lock_cnt < 0)
309 TBM_DBG(">> UNLOCK bo:%p(%d->%d)\n", bo, old, bo->lock_cnt);
313 _tbm_bo_is_valid(tbm_bo bo)
315 tbm_bufmgr bufmgr = NULL;
316 tbm_bo old_data = NULL;
319 TBM_ERR("error: bo is NULL.\n");
323 bufmgr = tbm_bufmgr_get();
324 if (bufmgr == NULL) {
325 TBM_ERR("error: bufmgr is NULL.\n");
329 if (LIST_IS_EMPTY(&bufmgr->bo_list)) {
330 TBM_ERR("error: bo->bo->bufmgr->bo_list is EMPTY.\n");
334 LIST_FOR_EACH_ENTRY(old_data, &bufmgr->bo_list, item_link) {
339 TBM_ERR("error: No valid bo(%p).\n", bo);
345 tbm_bo_alloc(tbm_bufmgr bufmgr, int size, int flags)
349 tbm_backend_bo_data *bo_data;
352 _tbm_bo_mutex_lock();
354 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
355 TBM_BO_RETURN_VAL_IF_FAIL(size > 0, NULL);
357 bo = calloc(1, sizeof(struct _tbm_bo));
359 /* LCOV_EXCL_START */
360 TBM_ERR("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_HEAP_ALLOC_FAILED);
363 _tbm_bo_mutex_unlock();
368 _tbm_util_check_bo_cnt(bufmgr);
372 if (bufmgr->backend_module_data) {
373 bo_data = bufmgr->bufmgr_func->bufmgr_alloc_bo(bufmgr->bufmgr_data, (unsigned int)size, flags, &error);
375 /* LCOV_EXCL_START */
376 TBM_ERR("error: fail to create of tbm_bo size(%d) flag(%s)\n",
377 size, _tbm_flag_to_str(flags));
378 _tbm_set_last_result(TBM_BO_ERROR_BO_ALLOC_FAILED);
380 _tbm_bo_mutex_unlock();
384 bo->bo_data = bo_data;
386 bo_priv = bo->bufmgr->backend->bo_alloc(bo, size, flags);
388 /* LCOV_EXCL_START */
389 TBM_ERR("error: fail to create of tbm_bo size(%d) flag(%s)\n",
390 size, _tbm_flag_to_str(flags));
391 _tbm_set_last_result(TBM_BO_ERROR_BO_ALLOC_FAILED);
393 _tbm_bo_mutex_unlock();
400 bo->bufmgr->bo_cnt++;
404 TBM_TRACE_BO("bo(%p) size(%d) refcnt(%d), flag(%s)\n", bo, size, bo->ref_cnt,
405 _tbm_flag_to_str(bo->flags));
407 LIST_INITHEAD(&bo->user_data_list);
409 LIST_ADD(&bo->item_link, &bo->bufmgr->bo_list);
411 _tbm_bo_mutex_unlock();
417 tbm_bo_ref(tbm_bo bo)
419 _tbm_bo_mutex_lock();
421 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), NULL);
425 TBM_TRACE_BO("bo(%p) ref_cnt(%d)\n", bo, bo->ref_cnt);
427 _tbm_bo_mutex_unlock();
433 tbm_bo_unref(tbm_bo bo)
435 _tbm_bo_mutex_lock();
437 TBM_BO_RETURN_IF_FAIL(_tbm_bo_is_valid(bo));
439 TBM_TRACE_BO("bo(%p) ref_cnt(%d)\n", bo, bo->ref_cnt - 1);
441 if (bo->ref_cnt <= 0) {
442 _tbm_bo_mutex_unlock();
447 if (bo->ref_cnt == 0)
450 _tbm_bo_mutex_unlock();
454 tbm_bo_map(tbm_bo bo, int device, int opt)
456 tbm_bo_handle bo_handle;
459 _tbm_bo_mutex_lock();
461 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) NULL);
463 if (!_tbm_bo_lock(bo, device, opt)) {
464 _tbm_set_last_result(TBM_BO_ERROR_LOCK_FAILED);
465 TBM_ERR("error: fail to lock bo:%p)\n", bo);
466 _tbm_bo_mutex_unlock();
467 return (tbm_bo_handle) NULL;
470 if (bo->bufmgr->backend_module_data) {
471 bo_handle = bo->bufmgr->bo_func->bo_map(bo->bo_data, device, opt, &error);
472 if (bo_handle.ptr == NULL) {
473 /* LCOV_EXCL_START */
474 _tbm_set_last_result(TBM_BO_ERROR_MAP_FAILED);
475 TBM_ERR("error: fail to map bo:%p error:%d\n", bo, error);
477 _tbm_bo_mutex_unlock();
478 return (tbm_bo_handle) NULL;
482 bo_handle = bo->bufmgr->backend->bo_map(bo, device, opt);
483 if (bo_handle.ptr == NULL) {
484 /* LCOV_EXCL_START */
485 _tbm_set_last_result(TBM_BO_ERROR_MAP_FAILED);
486 TBM_ERR("error: fail to map bo:%p\n", bo);
488 _tbm_bo_mutex_unlock();
489 return (tbm_bo_handle) NULL;
494 /* increase the map_count */
497 TBM_TRACE_BO("bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
499 _tbm_bo_mutex_unlock();
505 tbm_bo_unmap(tbm_bo bo)
510 _tbm_bo_mutex_lock();
512 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
513 TBM_BO_RETURN_VAL_IF_FAIL(bo->map_cnt > 0, 0);
515 if (bo->bufmgr->backend_module_data) {
516 error = bo->bufmgr->bo_func->bo_unmap(bo->bo_data);
517 if (error != TBM_ERROR_NONE) {
518 /* LCOV_EXCL_START */
519 TBM_ERR("error: bo(%p) map_cnt(%d) error(%d)\n", bo, bo->map_cnt, error);
520 _tbm_set_last_result(TBM_BO_ERROR_UNMAP_FAILED);
522 _tbm_bo_mutex_unlock();
527 ret = bo->bufmgr->backend->bo_unmap(bo);
529 /* LCOV_EXCL_START */
530 TBM_ERR("error: bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
531 _tbm_set_last_result(TBM_BO_ERROR_UNMAP_FAILED);
532 _tbm_bo_mutex_unlock();
538 /* decrease the map_count */
541 TBM_TRACE_BO("bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
545 _tbm_bo_mutex_unlock();
551 tbm_bo_get_handle(tbm_bo bo, int device)
553 tbm_bo_handle bo_handle;
556 _tbm_bo_mutex_lock();
558 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) NULL);
560 if (bo->bufmgr->backend_module_data) {
561 bo_handle = bo->bufmgr->bo_func->bo_get_handle(bo->bo_data, device, &error);
562 if (bo_handle.ptr == NULL) {
563 /* LCOV_EXCL_START */
564 _tbm_set_last_result(TBM_BO_ERROR_GET_HANDLE_FAILED);
565 TBM_ERR("error: bo(%p) bo_handle(%p) error(%d)\n", bo, bo_handle.ptr, error);
566 _tbm_bo_mutex_unlock();
567 return (tbm_bo_handle) NULL;
571 bo_handle = bo->bufmgr->backend->bo_get_handle(bo, device);
572 if (bo_handle.ptr == NULL) {
573 /* LCOV_EXCL_START */
574 _tbm_set_last_result(TBM_BO_ERROR_GET_HANDLE_FAILED);
575 TBM_ERR("error: bo(%p) bo_handle(%p)\n", bo, bo_handle.ptr);
576 _tbm_bo_mutex_unlock();
577 return (tbm_bo_handle) NULL;
582 TBM_TRACE_BO("bo(%p) bo_handle(%p)\n", bo, bo_handle.ptr);
584 _tbm_bo_mutex_unlock();
590 tbm_bo_export(tbm_bo bo)
595 _tbm_bo_mutex_lock();
597 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
599 if (bo->bufmgr->backend_module_data) {
600 if (!bo->bufmgr->bo_func->bo_export_key) {
601 /* LCOV_EXCL_START */
602 _tbm_bo_mutex_unlock();
607 ret = bo->bufmgr->bo_func->bo_export_key(bo->bo_data, &error);
609 /* LCOV_EXCL_START */
610 _tbm_set_last_result(TBM_BO_ERROR_EXPORT_FAILED);
611 TBM_ERR("error: bo(%p) tbm_key(%d) error(%d)\n", bo, ret, error);
612 _tbm_bo_mutex_unlock();
617 if (!bo->bufmgr->backend->bo_export) {
618 /* LCOV_EXCL_START */
619 _tbm_bo_mutex_unlock();
624 ret = bo->bufmgr->backend->bo_export(bo);
626 /* LCOV_EXCL_START */
627 _tbm_set_last_result(TBM_BO_ERROR_EXPORT_FAILED);
628 TBM_ERR("error: bo(%p) tbm_key(%d)\n", bo, ret);
629 _tbm_bo_mutex_unlock();
635 TBM_TRACE_BO("bo(%p) tbm_key(%u)\n", bo, ret);
637 _tbm_bo_mutex_unlock();
643 tbm_bo_export_fd(tbm_bo bo)
648 _tbm_bo_mutex_lock();
650 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), -1);
652 if (bo->bufmgr->backend_module_data) {
653 if (!bo->bufmgr->bo_func->bo_export_fd) {
654 /* LCOV_EXCL_START */
655 _tbm_bo_mutex_unlock();
660 ret = bo->bufmgr->bo_func->bo_export_fd(bo->bo_data, &error);
662 /* LCOV_EXCL_START */
663 _tbm_set_last_result(TBM_BO_ERROR_EXPORT_FD_FAILED);
664 TBM_ERR("error: bo(%p) tbm_fd(%d) error(%d)\n", bo, ret, error);
665 _tbm_bo_mutex_unlock();
670 if (!bo->bufmgr->backend->bo_export_fd) {
671 /* LCOV_EXCL_START */
672 _tbm_bo_mutex_unlock();
677 ret = bo->bufmgr->backend->bo_export_fd(bo);
679 /* LCOV_EXCL_START */
680 _tbm_set_last_result(TBM_BO_ERROR_EXPORT_FD_FAILED);
681 TBM_ERR("error: bo(%p) tbm_fd(%d)\n", bo, ret);
682 _tbm_bo_mutex_unlock();
688 TBM_TRACE_BO("bo(%p) tbm_fd(%d)\n", bo, ret);
690 _tbm_bo_mutex_unlock();
696 tbm_bo_import(tbm_bufmgr bufmgr, unsigned int key)
702 tbm_backend_bo_data *bo_data;
704 _tbm_bo_mutex_lock();
706 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
708 if (bufmgr->backend_module_data) {
709 if (!bufmgr->bufmgr_func->bufmgr_import_key) {
710 /* LCOV_EXCL_START */
711 _tbm_bo_mutex_unlock();
716 if (!bufmgr->backend->bo_import) {
717 /* LCOV_EXCL_START */
718 _tbm_bo_mutex_unlock();
724 _tbm_util_check_bo_cnt(bufmgr);
726 bo = calloc(1, sizeof(struct _tbm_bo));
728 /* LCOV_EXCL_START */
729 TBM_ERR("error: fail to import of tbm_bo by key(%d)\n", key);
730 _tbm_bo_mutex_unlock();
737 if (bo->bufmgr->backend_module_data) {
738 bo_data = bo->bufmgr->bufmgr_func->bufmgr_import_key(bufmgr->bufmgr_data, key, &error);
740 /* LCOV_EXCL_START */
741 TBM_ERR("error: fail to import of tbm_bo by key(%d). error(%d)\n", key, error);
742 _tbm_set_last_result(TBM_BO_ERROR_IMPORT_FAILED);
744 _tbm_bo_mutex_unlock();
749 if (!LIST_IS_EMPTY(&bo->bufmgr->bo_list)) {
750 LIST_FOR_EACH_ENTRY(bo2, &bo->bufmgr->bo_list, item_link) {
751 if (bo2->bo_data == bo_data) {
752 TBM_TRACE_BO("find bo(%p) ref(%d) key(%d) flag(%s) in list\n",
753 bo2, bo2->ref_cnt, key,
754 _tbm_flag_to_str(bo2->flags));
757 _tbm_bo_mutex_unlock();
762 bo->bo_data = bo_data;
764 bo_priv = bo->bufmgr->backend->bo_import(bo, key);
766 /* LCOV_EXCL_START */
767 TBM_ERR("error: fail to import of tbm_bo by key(%d)\n", key);
768 _tbm_set_last_result(TBM_BO_ERROR_IMPORT_FAILED);
770 _tbm_bo_mutex_unlock();
775 if (!LIST_IS_EMPTY(&bo->bufmgr->bo_list)) {
776 LIST_FOR_EACH_ENTRY(bo2, &bo->bufmgr->bo_list, item_link) {
777 if (bo2->priv == bo_priv) {
778 TBM_TRACE_BO("find bo(%p) ref(%d) key(%d) flag(%s) in list\n",
779 bo2, bo2->ref_cnt, key,
780 _tbm_flag_to_str(bo2->flags));
783 _tbm_bo_mutex_unlock();
791 bo->bufmgr->bo_cnt++;
794 if (bo->bufmgr->backend_module_data) {
795 bo->flags = bo->bufmgr->bo_func->bo_get_memory_types(bo->bo_data, &error);
796 if (error != TBM_ERROR_NONE) {
797 TBM_ERR("fail to get the bo flags(memory_types)");
798 bo->flags = TBM_BO_DEFAULT;
801 if (bo->bufmgr->backend->bo_get_flags)
802 bo->flags = bo->bufmgr->backend->bo_get_flags(bo);
804 bo->flags = TBM_BO_DEFAULT;
807 TBM_TRACE_BO("import new bo(%p) ref(%d) key(%d) flag(%s) in list\n",
808 bo, bo->ref_cnt, key, _tbm_flag_to_str(bo->flags));
810 LIST_INITHEAD(&bo->user_data_list);
812 LIST_ADD(&bo->item_link, &bo->bufmgr->bo_list);
814 _tbm_bo_mutex_unlock();
820 tbm_bo_import_fd(tbm_bufmgr bufmgr, tbm_fd fd)
825 tbm_backend_bo_data *bo_data;
828 _tbm_bo_mutex_lock();
830 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
832 if (bufmgr->backend_module_data) {
833 if (!bufmgr->bufmgr_func->bufmgr_import_fd) {
834 /* LCOV_EXCL_START */
835 _tbm_bo_mutex_unlock();
840 if (!bufmgr->backend->bo_import_fd) {
841 /* LCOV_EXCL_START */
842 _tbm_bo_mutex_unlock();
848 _tbm_util_check_bo_cnt(bufmgr);
850 bo = calloc(1, sizeof(struct _tbm_bo));
852 /* LCOV_EXCL_START */
853 TBM_ERR("error: fail to import tbm_bo by tbm_fd(%d)\n", fd);
854 _tbm_bo_mutex_unlock();
861 if (bo->bufmgr->backend_module_data) {
862 bo_data = bo->bufmgr->bufmgr_func->bufmgr_import_fd(bufmgr->bufmgr_data, fd, &error);
864 /* LCOV_EXCL_START */
865 TBM_ERR("error: fail to import tbm_bo by tbm_fd(%d). error(%d)\n", fd, error);
866 _tbm_set_last_result(TBM_BO_ERROR_IMPORT_FD_FAILED);
868 _tbm_bo_mutex_unlock();
873 if (!LIST_IS_EMPTY(&bo->bufmgr->bo_list)) {
874 LIST_FOR_EACH_ENTRY(bo2, &bo->bufmgr->bo_list, item_link) {
875 if (bo2->bo_data == bo_data) {
876 TBM_TRACE_BO("find bo(%p) ref(%d) fd(%d) flag(%s) in list\n",
877 bo2, bo2->ref_cnt, fd,
878 _tbm_flag_to_str(bo2->flags));
881 _tbm_bo_mutex_unlock();
886 bo->bo_data = bo_data;
888 bo_priv = bo->bufmgr->backend->bo_import_fd(bo, fd);
890 /* LCOV_EXCL_START */
891 TBM_ERR("error: fail to import tbm_bo by tbm_fd(%d)\n", fd);
892 _tbm_set_last_result(TBM_BO_ERROR_IMPORT_FD_FAILED);
894 _tbm_bo_mutex_unlock();
899 if (!LIST_IS_EMPTY(&bo->bufmgr->bo_list)) {
900 LIST_FOR_EACH_ENTRY(bo2, &bo->bufmgr->bo_list, item_link) {
901 if (bo2->priv == bo_priv) {
902 TBM_TRACE_BO("find bo(%p) ref(%d) fd(%d) flag(%s) in list\n",
903 bo2, bo2->ref_cnt, fd,
904 _tbm_flag_to_str(bo2->flags));
907 _tbm_bo_mutex_unlock();
915 bo->bufmgr->bo_cnt++;
918 if (bo->bufmgr->backend_module_data) {
919 bo->flags = bo->bufmgr->bo_func->bo_get_memory_types(bo->bo_data, &error);
920 if (error != TBM_ERROR_NONE) {
921 TBM_ERR("fail to get the bo flags(memory_types)");
922 bo->flags = TBM_BO_DEFAULT;
925 if (bo->bufmgr->backend->bo_get_flags)
926 bo->flags = bo->bufmgr->backend->bo_get_flags(bo);
928 bo->flags = TBM_BO_DEFAULT;
931 TBM_TRACE_BO("import bo(%p) ref(%d) fd(%d) flag(%s)\n",
932 bo, bo->ref_cnt, fd, _tbm_flag_to_str(bo->flags));
934 LIST_INITHEAD(&bo->user_data_list);
936 LIST_ADD(&bo->item_link, &bo->bufmgr->bo_list);
938 _tbm_bo_mutex_unlock();
944 tbm_bo_size(tbm_bo bo)
949 _tbm_bo_mutex_lock();
951 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
953 if (bo->bufmgr->backend_module_data) {
954 size = bo->bufmgr->bo_func->bo_get_size(bo->bo_data, &error);
955 if (error != TBM_ERROR_NONE)
956 TBM_ERR("fail to get the size of the bo_data(%d).", error);
958 size = bo->bufmgr->backend->bo_size(bo);
960 TBM_TRACE_BO("bo(%p) size(%d)\n", bo, size);
962 _tbm_bo_mutex_unlock();
968 tbm_bo_locked(tbm_bo bo)
970 _tbm_bo_mutex_lock();
972 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
974 if (bo->bufmgr->bo_lock_type == TBM_BUFMGR_BO_LOCK_TYPE_NEVER) {
975 TBM_ERR("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
976 _tbm_bo_mutex_unlock();
980 if (bo->lock_cnt > 0) {
981 TBM_TRACE_BO("error: bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
982 _tbm_bo_mutex_unlock();
986 TBM_TRACE_BO("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
987 _tbm_bo_mutex_unlock();
993 tbm_bo_swap(tbm_bo bo1, tbm_bo bo2)
995 tbm_error_e error1, error2;
996 int size1 = -1, size2 = -2;
999 _tbm_bo_mutex_lock();
1001 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo1), 0);
1002 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo2), 0);
1004 TBM_TRACE_BO("before: bo1(%p) bo2(%p)\n", bo1, bo2);
1006 if (bo1->bufmgr->backend_module_data) {
1007 size1 = bo1->bufmgr->bo_func->bo_get_size(bo1->bo_data, &error1);
1008 if (error1 != TBM_ERROR_NONE) {
1009 TBM_ERR("fail to get the size of bo1.(%d)", error1);
1012 size2 = bo2->bufmgr->bo_func->bo_get_size(bo2->bo_data, &error2);
1013 if (error2 != TBM_ERROR_NONE) {
1014 TBM_ERR("fail to get the size of bo2.(%d)", error2);
1018 size1 = bo1->bufmgr->backend->bo_size(bo1);
1019 size2 = bo2->bufmgr->backend->bo_size(bo2);
1022 if (size1 != size2) {
1023 TBM_ERR("error: bo1 size(%d) and bo2 size(%d) is different.", size1, size2);
1027 TBM_TRACE_BO("after: bo1(%p) bo2(%p)\n", bo1, bo2);
1030 bo1->priv = bo2->priv;
1033 _tbm_bo_mutex_unlock();
1038 _tbm_set_last_result(TBM_BO_ERROR_SWAP_FAILED);
1039 TBM_ERR("error: bo1(%p) bo2(%p)\n", bo1, bo2);
1040 _tbm_bo_mutex_unlock();
1046 tbm_bo_add_user_data(tbm_bo bo, unsigned long key,
1047 tbm_data_free data_free_func)
1049 tbm_user_data *data;
1051 _tbm_bo_mutex_lock();
1053 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1055 /* check if the data according to the key exist if so, return false. */
1056 data = user_data_lookup(&bo->user_data_list, key);
1058 TBM_TRACE_BO("warning: user data already exist key(%ld)\n", key);
1059 _tbm_bo_mutex_unlock();
1063 data = user_data_create(key, data_free_func);
1065 TBM_ERR("error: bo(%p) key(%lu)\n", bo, key);
1066 _tbm_bo_mutex_unlock();
1070 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, data->data);
1072 LIST_ADD(&data->item_link, &bo->user_data_list);
1074 _tbm_bo_mutex_unlock();
1080 tbm_bo_delete_user_data(tbm_bo bo, unsigned long key)
1082 tbm_user_data *old_data;
1084 _tbm_bo_mutex_lock();
1086 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1088 if (LIST_IS_EMPTY(&bo->user_data_list)) {
1089 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1090 _tbm_bo_mutex_unlock();
1094 old_data = user_data_lookup(&bo->user_data_list, key);
1096 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1097 _tbm_bo_mutex_unlock();
1101 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1103 user_data_delete(old_data);
1105 _tbm_bo_mutex_unlock();
1111 tbm_bo_set_user_data(tbm_bo bo, unsigned long key, void *data)
1113 tbm_user_data *old_data;
1115 _tbm_bo_mutex_lock();
1117 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1119 if (LIST_IS_EMPTY(&bo->user_data_list)) {
1120 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1121 _tbm_bo_mutex_unlock();
1125 old_data = user_data_lookup(&bo->user_data_list, key);
1127 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1128 _tbm_bo_mutex_unlock();
1132 if (old_data->data && old_data->free_func)
1133 old_data->free_func(old_data->data);
1134 old_data->data = data;
1136 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1138 _tbm_bo_mutex_unlock();
1144 tbm_bo_get_user_data(tbm_bo bo, unsigned long key, void **data)
1146 tbm_user_data *old_data;
1148 _tbm_bo_mutex_lock();
1150 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1152 if (!data || LIST_IS_EMPTY(&bo->user_data_list)) {
1153 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1154 _tbm_bo_mutex_unlock();
1158 old_data = user_data_lookup(&bo->user_data_list, key);
1160 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1162 _tbm_bo_mutex_unlock();
1166 *data = old_data->data;
1168 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1170 _tbm_bo_mutex_unlock();
1176 tbm_bo_get_flags(tbm_bo bo)
1180 _tbm_bo_mutex_lock();
1182 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1186 TBM_TRACE_BO("bo(%p)\n", bo);
1188 _tbm_bo_mutex_unlock();
1193 /* LCOV_EXCL_START */
1194 /* internal function */
1196 _tbm_bo_set_surface(tbm_bo bo, tbm_surface_h surface)
1198 _tbm_bo_mutex_lock();
1200 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1202 bo->surface = surface;
1204 _tbm_bo_mutex_unlock();
1210 _tbm_bo_free(tbm_bo bo)
1212 /* destory the user_data_list */
1213 if (!LIST_IS_EMPTY(&bo->user_data_list)) {
1214 tbm_user_data *old_data = NULL, *tmp;
1216 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp,
1217 &bo->user_data_list, item_link) {
1218 TBM_DBG("free user_data\n");
1219 user_data_delete(old_data);
1223 while (bo->lock_cnt > 0) {
1224 TBM_ERR("error lock_cnt:%d\n", bo->lock_cnt);
1229 /* call the bo_free */
1230 if (bo->bufmgr->backend_module_data) {
1231 bo->bufmgr->bo_func->bo_free(bo->bo_data);
1234 bo->bufmgr->backend->bo_free(bo);
1238 bo->bufmgr->bo_cnt--;
1240 LIST_DEL(&bo->item_link);
1243 /* LCOV_EXCL_STOP */