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"
38 #define TBM_BO_RETURN_IF_FAIL(cond) {\
40 TBM_ERR("'%s' failed.\n", #cond);\
41 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
42 _tbm_bufmgr_mutex_unlock();\
47 #define TBM_BO_RETURN_VAL_IF_FAIL(cond, val) {\
49 TBM_ERR("'%s' failed.\n", #cond);\
50 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
51 _tbm_bufmgr_mutex_unlock();\
57 _tbm_flag_to_str(int f)
61 if (f == TBM_BO_DEFAULT)
62 snprintf(str, 255, "DEFAULT");
66 if (f & TBM_BO_SCANOUT)
67 c += snprintf(&str[c], 255-c, "SCANOUT");
69 if (f & TBM_BO_NONCACHABLE) {
70 if (c >= 0 && c < 255)
71 c += snprintf(&str[c], 255-c, ", ");
73 if (c >= 0 && c < 255)
74 c += snprintf(&str[c], 255-c, "NONCACHABLE,");
78 if (c >= 0 && c < 255)
79 c += snprintf(&str[c], 255-c, ", ");
81 if (c >= 0 && c < 255)
82 c += snprintf(&str[c], 255-c, "WC");
90 _tbm_util_check_bo_cnt(tbm_bufmgr bufmgr)
92 static int last_chk_bo_cnt = 0;
94 if ((bufmgr->bo_cnt >= 500) && ((bufmgr->bo_cnt % 20) == 0) &&
95 (bufmgr->bo_cnt > last_chk_bo_cnt)) {
96 TBM_DBG("============TBM BO CNT DEBUG: bo_cnt=%d\n", bufmgr->bo_cnt);
97 tbm_bufmgr_debug_show(bufmgr);
98 last_chk_bo_cnt = bufmgr->bo_cnt;
104 user_data_lookup(struct list_head *user_data_list, unsigned long key)
106 tbm_user_data *old_data = NULL;
108 if (LIST_IS_EMPTY(user_data_list))
111 LIST_FOR_EACH_ENTRY(old_data, user_data_list, item_link) {
112 if (old_data->key == key)
120 user_data_create(unsigned long key, tbm_data_free data_free_func)
122 tbm_user_data *user_data;
124 user_data = calloc(1, sizeof(tbm_user_data));
126 /* LCOV_EXCL_START */
127 TBM_ERR("fail to allocate an user_date\n");
128 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
133 user_data->key = key;
134 user_data->free_func = data_free_func;
140 user_data_delete(tbm_user_data *user_data)
142 if (user_data->data && user_data->free_func)
143 user_data->free_func(user_data->data);
145 LIST_DEL(&user_data->item_link);
151 _bo_lock(tbm_bo bo, int device, int opt)
156 if (bo->bufmgr->backend_module_data) {
157 if (bo->bufmgr->bo_func->bo_lock) {
158 error = bo->bufmgr->bo_func->bo_lock(bo->bo_data, device, opt);
159 if (error != TBM_ERROR_NONE) {
160 TBM_WRN("fail to lock");
161 _tbm_set_last_result(error);
166 if (bo->bufmgr->backend->bo_lock) {
167 ret = bo->bufmgr->backend->bo_lock(bo, device, opt);
169 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
177 _bo_unlock(tbm_bo bo)
181 if (bo->bufmgr->backend_module_data) {
182 if (bo->bufmgr->bo_func->bo_unlock) {
183 error = bo->bufmgr->bo_func->bo_unlock(bo->bo_data);
184 if (error != TBM_ERROR_NONE) {
185 TBM_WRN("fail to unlock");
186 _tbm_set_last_result(error);
190 if (bo->bufmgr->backend->bo_unlock)
191 bo->bufmgr->backend->bo_unlock(bo);
196 _tbm_bo_lock(tbm_bo bo, int device, int opt)
203 /* do not try to lock the bo */
204 if (bo->bufmgr->bo_lock_type == TBM_BUFMGR_BO_LOCK_TYPE_NEVER)
207 if (bo->lock_cnt < 0) {
208 TBM_ERR("error bo:%p LOCK_CNT=%d\n",
215 switch (bo->bufmgr->bo_lock_type) {
216 case TBM_BUFMGR_BO_LOCK_TYPE_ONCE:
217 if (bo->lock_cnt == 0) {
218 _tbm_bufmgr_mutex_unlock();
219 ret = _bo_lock(bo, device, opt);
220 _tbm_bufmgr_mutex_lock();
226 case TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS:
227 _tbm_bufmgr_mutex_unlock();
228 ret = _bo_lock(bo, device, opt);
229 _tbm_bufmgr_mutex_lock();
234 TBM_ERR("error bo:%p bo_lock_type[%d] is wrong.\n",
235 bo, bo->bufmgr->bo_lock_type);
240 TBM_DBG(">> LOCK bo:%p(%d->%d)\n", bo, old, bo->lock_cnt);
246 _tbm_bo_unlock(tbm_bo bo)
250 /* do not try to unlock the bo */
251 if (bo->bufmgr->bo_lock_type == TBM_BUFMGR_BO_LOCK_TYPE_NEVER)
256 switch (bo->bufmgr->bo_lock_type) {
257 case TBM_BUFMGR_BO_LOCK_TYPE_ONCE:
258 if (bo->lock_cnt > 0) {
260 if (bo->lock_cnt == 0)
264 case TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS:
265 if (bo->lock_cnt > 0) {
271 TBM_ERR("error bo:%p bo_lock_type[%d] is wrong.\n",
272 bo, bo->bufmgr->bo_lock_type);
276 if (bo->lock_cnt < 0)
279 TBM_DBG(">> UNLOCK bo:%p(%d->%d)\n", bo, old, bo->lock_cnt);
283 _tbm_bo_is_valid(tbm_bo bo)
285 tbm_bufmgr bufmgr = NULL;
286 tbm_bo old_data = NULL;
289 TBM_ERR("error: bo is NULL.\n");
293 bufmgr = tbm_bufmgr_get();
294 if (bufmgr == NULL) {
295 TBM_ERR("error: bufmgr is NULL.\n");
299 if (LIST_IS_EMPTY(&bufmgr->bo_list)) {
300 TBM_ERR("error: bo->bo->bufmgr->bo_list is EMPTY.\n");
304 LIST_FOR_EACH_ENTRY(old_data, &bufmgr->bo_list, item_link) {
309 TBM_ERR("error: No valid bo(%p).\n", bo);
315 tbm_bo_alloc(tbm_bufmgr bufmgr, int size, int flags)
319 tbm_backend_bo_data *bo_data;
322 _tbm_bufmgr_mutex_lock();
323 _tbm_set_last_result(TBM_ERROR_NONE);
325 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
326 TBM_BO_RETURN_VAL_IF_FAIL(size > 0, NULL);
328 bo = calloc(1, sizeof(struct _tbm_bo));
330 /* LCOV_EXCL_START */
331 TBM_ERR("error: fail to create of tbm_bo size(%d) flag(%s)\n",
332 size, _tbm_flag_to_str(flags));
333 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
334 _tbm_bufmgr_mutex_unlock();
339 _tbm_util_check_bo_cnt(bufmgr);
343 if (bufmgr->backend_module_data) {
344 bo_data = bufmgr->bufmgr_func->bufmgr_alloc_bo(bufmgr->bufmgr_data, (unsigned int)size, flags, &error);
346 /* LCOV_EXCL_START */
347 TBM_ERR("error: fail to create of tbm_bo size(%d) flag(%s)\n",
348 size, _tbm_flag_to_str(flags));
349 _tbm_set_last_result(error);
351 _tbm_bufmgr_mutex_unlock();
355 bo->bo_data = bo_data;
357 bo_priv = bo->bufmgr->backend->bo_alloc(bo, size, flags);
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_ERROR_INVALID_OPERATION);
364 _tbm_bufmgr_mutex_unlock();
371 bo->bufmgr->bo_cnt++;
375 TBM_TRACE_BO("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_bufmgr_mutex_unlock();
388 tbm_bo_ref(tbm_bo bo)
390 _tbm_bufmgr_mutex_lock();
391 _tbm_set_last_result(TBM_ERROR_NONE);
393 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), NULL);
397 TBM_TRACE_BO("bo(%p) ref_cnt(%d)\n", bo, bo->ref_cnt);
399 _tbm_bufmgr_mutex_unlock();
405 tbm_bo_unref(tbm_bo bo)
407 _tbm_bufmgr_mutex_lock();
408 _tbm_set_last_result(TBM_ERROR_NONE);
410 TBM_BO_RETURN_IF_FAIL(_tbm_bo_is_valid(bo));
412 TBM_TRACE_BO("bo(%p) ref_cnt(%d)\n", bo, bo->ref_cnt - 1);
414 if (bo->ref_cnt <= 0) {
415 _tbm_bufmgr_mutex_unlock();
420 if (bo->ref_cnt == 0)
423 _tbm_bufmgr_mutex_unlock();
427 tbm_bo_map(tbm_bo bo, int device, int opt)
429 tbm_bo_handle bo_handle;
432 _tbm_bufmgr_mutex_lock();
433 _tbm_set_last_result(TBM_ERROR_NONE);
435 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) NULL);
437 if (!_tbm_bo_lock(bo, device, opt)) {
438 TBM_ERR("error: fail to lock bo:%p)\n", bo);
439 _tbm_bufmgr_mutex_unlock();
440 return (tbm_bo_handle) NULL;
443 if (bo->bufmgr->backend_module_data) {
444 bo_handle = bo->bufmgr->bo_func->bo_map(bo->bo_data, device, opt, &error);
445 if (bo_handle.ptr == NULL) {
446 /* LCOV_EXCL_START */
447 _tbm_set_last_result(error);
448 TBM_ERR("error: fail to map bo:%p error:%d\n", bo, error);
450 _tbm_bufmgr_mutex_unlock();
451 return (tbm_bo_handle) NULL;
455 bo_handle = bo->bufmgr->backend->bo_map(bo, device, opt);
456 if (bo_handle.ptr == NULL) {
457 /* LCOV_EXCL_START */
458 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
459 TBM_ERR("error: fail to map bo:%p\n", bo);
461 _tbm_bufmgr_mutex_unlock();
462 return (tbm_bo_handle) NULL;
467 /* increase the map_count */
470 TBM_TRACE_BO("bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
472 _tbm_bufmgr_mutex_unlock();
478 tbm_bo_unmap(tbm_bo bo)
483 _tbm_bufmgr_mutex_lock();
484 _tbm_set_last_result(TBM_ERROR_NONE);
486 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
487 TBM_BO_RETURN_VAL_IF_FAIL(bo->map_cnt > 0, 0);
489 if (bo->bufmgr->backend_module_data) {
490 error = bo->bufmgr->bo_func->bo_unmap(bo->bo_data);
491 if (error != TBM_ERROR_NONE) {
492 /* LCOV_EXCL_START */
493 TBM_ERR("error: bo(%p) map_cnt(%d) error(%d)\n", bo, bo->map_cnt, error);
494 _tbm_set_last_result(error);
496 _tbm_bufmgr_mutex_unlock();
501 ret = bo->bufmgr->backend->bo_unmap(bo);
503 /* LCOV_EXCL_START */
504 TBM_ERR("error: bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
505 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
506 _tbm_bufmgr_mutex_unlock();
512 /* decrease the map_count */
515 TBM_TRACE_BO("bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
519 _tbm_bufmgr_mutex_unlock();
525 tbm_bo_get_handle(tbm_bo bo, int device)
527 tbm_bo_handle bo_handle;
530 _tbm_bufmgr_mutex_lock();
531 _tbm_set_last_result(TBM_ERROR_NONE);
533 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) NULL);
535 if (bo->bufmgr->backend_module_data) {
536 bo_handle = bo->bufmgr->bo_func->bo_get_handle(bo->bo_data, device, &error);
537 if (bo_handle.ptr == NULL) {
538 /* LCOV_EXCL_START */
539 TBM_ERR("error: bo(%p) bo_handle(%p) error(%d)\n", bo, bo_handle.ptr, error);
540 _tbm_set_last_result(error);
541 _tbm_bufmgr_mutex_unlock();
542 return (tbm_bo_handle) NULL;
546 bo_handle = bo->bufmgr->backend->bo_get_handle(bo, device);
547 if (bo_handle.ptr == NULL) {
548 /* LCOV_EXCL_START */
549 TBM_ERR("error: bo(%p) bo_handle(%p)\n", bo, bo_handle.ptr);
550 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
551 _tbm_bufmgr_mutex_unlock();
552 return (tbm_bo_handle) NULL;
557 TBM_TRACE_BO("bo(%p) bo_handle(%p)\n", bo, bo_handle.ptr);
559 _tbm_bufmgr_mutex_unlock();
565 tbm_bo_export(tbm_bo bo)
570 _tbm_bufmgr_mutex_lock();
571 _tbm_set_last_result(TBM_ERROR_NONE);
573 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
575 if (bo->bufmgr->backend_module_data) {
576 if (!bo->bufmgr->bo_func->bo_export_key) {
577 /* LCOV_EXCL_START */
578 _tbm_bufmgr_mutex_unlock();
579 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
584 ret = bo->bufmgr->bo_func->bo_export_key(bo->bo_data, &error);
586 /* LCOV_EXCL_START */
587 TBM_ERR("error: bo(%p) tbm_key(%d) error(%d)\n", bo, ret, error);
588 _tbm_set_last_result(error);
589 _tbm_bufmgr_mutex_unlock();
594 if (!bo->bufmgr->backend->bo_export) {
595 /* LCOV_EXCL_START */
596 _tbm_bufmgr_mutex_unlock();
597 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
602 ret = bo->bufmgr->backend->bo_export(bo);
604 /* LCOV_EXCL_START */
605 TBM_ERR("error: bo(%p) tbm_key(%d)\n", bo, ret);
606 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
607 _tbm_bufmgr_mutex_unlock();
613 TBM_TRACE_BO("bo(%p) tbm_key(%u)\n", bo, ret);
615 _tbm_bufmgr_mutex_unlock();
621 tbm_bo_export_fd(tbm_bo bo)
626 _tbm_bufmgr_mutex_lock();
627 _tbm_set_last_result(TBM_ERROR_NONE);
629 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), -1);
631 if (bo->bufmgr->backend_module_data) {
632 if (!bo->bufmgr->bo_func->bo_export_fd) {
633 /* LCOV_EXCL_START */
634 _tbm_bufmgr_mutex_unlock();
635 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
640 ret = bo->bufmgr->bo_func->bo_export_fd(bo->bo_data, &error);
642 /* LCOV_EXCL_START */
643 TBM_ERR("error: bo(%p) tbm_fd(%d) error(%d)\n", bo, ret, error);
644 _tbm_set_last_result(error);
645 _tbm_bufmgr_mutex_unlock();
650 if (!bo->bufmgr->backend->bo_export_fd) {
651 /* LCOV_EXCL_START */
652 _tbm_bufmgr_mutex_unlock();
653 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
658 ret = bo->bufmgr->backend->bo_export_fd(bo);
660 /* LCOV_EXCL_START */
661 TBM_ERR("error: bo(%p) tbm_fd(%d)\n", bo, ret);
662 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
663 _tbm_bufmgr_mutex_unlock();
669 TBM_TRACE_BO("bo(%p) tbm_fd(%d)\n", bo, ret);
671 _tbm_bufmgr_mutex_unlock();
677 tbm_bo_import(tbm_bufmgr bufmgr, unsigned int key)
683 tbm_backend_bo_data *bo_data;
685 _tbm_bufmgr_mutex_lock();
686 _tbm_set_last_result(TBM_ERROR_NONE);
688 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
690 if (bufmgr->backend_module_data) {
691 if (!bufmgr->bufmgr_func->bufmgr_import_key) {
692 /* LCOV_EXCL_START */
693 _tbm_bufmgr_mutex_unlock();
694 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
699 if (!bufmgr->backend->bo_import) {
700 /* LCOV_EXCL_START */
701 _tbm_bufmgr_mutex_unlock();
702 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
708 _tbm_util_check_bo_cnt(bufmgr);
710 bo = calloc(1, sizeof(struct _tbm_bo));
712 /* LCOV_EXCL_START */
713 TBM_ERR("error: fail to import of tbm_bo by key(%d)\n", key);
714 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
715 _tbm_bufmgr_mutex_unlock();
722 if (bo->bufmgr->backend_module_data) {
723 bo_data = bo->bufmgr->bufmgr_func->bufmgr_import_key(bufmgr->bufmgr_data, key, &error);
725 /* LCOV_EXCL_START */
726 TBM_ERR("error: fail to import of tbm_bo by key(%d). error(%d)\n", key, error);
727 _tbm_set_last_result(error);
729 _tbm_bufmgr_mutex_unlock();
734 if (!LIST_IS_EMPTY(&bo->bufmgr->bo_list)) {
735 LIST_FOR_EACH_ENTRY(bo2, &bo->bufmgr->bo_list, item_link) {
736 if (bo2->bo_data == bo_data) {
737 TBM_TRACE_BO("find bo(%p) ref(%d) key(%d) flag(%s) in list\n",
738 bo2, bo2->ref_cnt, key,
739 _tbm_flag_to_str(bo2->flags));
742 _tbm_bufmgr_mutex_unlock();
747 bo->bo_data = bo_data;
749 bo_priv = bo->bufmgr->backend->bo_import(bo, key);
751 /* LCOV_EXCL_START */
752 TBM_ERR("error: fail to import of tbm_bo by key(%d)\n", key);
753 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
755 _tbm_bufmgr_mutex_unlock();
760 if (!LIST_IS_EMPTY(&bo->bufmgr->bo_list)) {
761 LIST_FOR_EACH_ENTRY(bo2, &bo->bufmgr->bo_list, item_link) {
762 if (bo2->priv == bo_priv) {
763 TBM_TRACE_BO("find bo(%p) ref(%d) key(%d) flag(%s) in list\n",
764 bo2, bo2->ref_cnt, key,
765 _tbm_flag_to_str(bo2->flags));
768 _tbm_bufmgr_mutex_unlock();
776 bo->bufmgr->bo_cnt++;
779 if (bo->bufmgr->backend_module_data) {
780 bo->flags = bo->bufmgr->bo_func->bo_get_memory_types(bo->bo_data, &error);
781 if (error != TBM_ERROR_NONE) {
782 TBM_ERR("fail to get the bo flags(memory_types)");
783 _tbm_set_last_result(error);
784 bo->flags = TBM_BO_DEFAULT;
787 if (bo->bufmgr->backend->bo_get_flags)
788 bo->flags = bo->bufmgr->backend->bo_get_flags(bo);
790 bo->flags = TBM_BO_DEFAULT;
793 TBM_TRACE_BO("import new bo(%p) ref(%d) key(%d) flag(%s) in list\n",
794 bo, bo->ref_cnt, key, _tbm_flag_to_str(bo->flags));
796 LIST_INITHEAD(&bo->user_data_list);
798 LIST_ADD(&bo->item_link, &bo->bufmgr->bo_list);
800 _tbm_bufmgr_mutex_unlock();
806 tbm_bo_import_fd(tbm_bufmgr bufmgr, tbm_fd fd)
811 tbm_backend_bo_data *bo_data;
814 _tbm_bufmgr_mutex_lock();
815 _tbm_set_last_result(TBM_ERROR_NONE);
817 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
819 if (bufmgr->backend_module_data) {
820 if (!bufmgr->bufmgr_func->bufmgr_import_fd) {
821 /* LCOV_EXCL_START */
822 _tbm_bufmgr_mutex_unlock();
823 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
828 if (!bufmgr->backend->bo_import_fd) {
829 /* LCOV_EXCL_START */
830 _tbm_bufmgr_mutex_unlock();
831 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
837 _tbm_util_check_bo_cnt(bufmgr);
839 bo = calloc(1, sizeof(struct _tbm_bo));
841 /* LCOV_EXCL_START */
842 TBM_ERR("error: fail to import tbm_bo by tbm_fd(%d)\n", fd);
843 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
844 _tbm_bufmgr_mutex_unlock();
851 if (bo->bufmgr->backend_module_data) {
852 bo_data = bo->bufmgr->bufmgr_func->bufmgr_import_fd(bufmgr->bufmgr_data, fd, &error);
854 /* LCOV_EXCL_START */
855 TBM_ERR("error: fail to import tbm_bo by tbm_fd(%d). error(%d)\n", fd, error);
856 _tbm_set_last_result(error);
858 _tbm_bufmgr_mutex_unlock();
863 if (!LIST_IS_EMPTY(&bo->bufmgr->bo_list)) {
864 LIST_FOR_EACH_ENTRY(bo2, &bo->bufmgr->bo_list, item_link) {
865 if (bo2->bo_data == bo_data) {
866 TBM_TRACE_BO("find bo(%p) ref(%d) fd(%d) flag(%s) in list\n",
867 bo2, bo2->ref_cnt, fd,
868 _tbm_flag_to_str(bo2->flags));
871 _tbm_bufmgr_mutex_unlock();
876 bo->bo_data = bo_data;
878 bo_priv = bo->bufmgr->backend->bo_import_fd(bo, fd);
880 /* LCOV_EXCL_START */
881 TBM_ERR("error: fail to import tbm_bo by tbm_fd(%d)\n", fd);
882 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
884 _tbm_bufmgr_mutex_unlock();
889 if (!LIST_IS_EMPTY(&bo->bufmgr->bo_list)) {
890 LIST_FOR_EACH_ENTRY(bo2, &bo->bufmgr->bo_list, item_link) {
891 if (bo2->priv == bo_priv) {
892 TBM_TRACE_BO("find bo(%p) ref(%d) fd(%d) flag(%s) in list\n",
893 bo2, bo2->ref_cnt, fd,
894 _tbm_flag_to_str(bo2->flags));
897 _tbm_bufmgr_mutex_unlock();
905 bo->bufmgr->bo_cnt++;
908 if (bo->bufmgr->backend_module_data) {
909 bo->flags = bo->bufmgr->bo_func->bo_get_memory_types(bo->bo_data, &error);
910 if (error != TBM_ERROR_NONE) {
911 TBM_ERR("fail to get the bo flags(memory_types)");
912 _tbm_set_last_result(error);
913 bo->flags = TBM_BO_DEFAULT;
916 if (bo->bufmgr->backend->bo_get_flags)
917 bo->flags = bo->bufmgr->backend->bo_get_flags(bo);
919 bo->flags = TBM_BO_DEFAULT;
922 TBM_TRACE_BO("import bo(%p) ref(%d) fd(%d) flag(%s)\n",
923 bo, bo->ref_cnt, fd, _tbm_flag_to_str(bo->flags));
925 LIST_INITHEAD(&bo->user_data_list);
927 LIST_ADD(&bo->item_link, &bo->bufmgr->bo_list);
929 _tbm_bufmgr_mutex_unlock();
935 tbm_bo_size(tbm_bo bo)
940 _tbm_bufmgr_mutex_lock();
941 _tbm_set_last_result(TBM_ERROR_NONE);
943 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
945 if (bo->bufmgr->backend_module_data) {
946 size = bo->bufmgr->bo_func->bo_get_size(bo->bo_data, &error);
947 if (error != TBM_ERROR_NONE) {
948 TBM_ERR("fail to get the size of the bo_data(%d).", error);
949 _tbm_set_last_result(TBM_ERROR_NONE);
952 size = bo->bufmgr->backend->bo_size(bo);
954 TBM_TRACE_BO("bo(%p) size(%d)\n", bo, size);
956 _tbm_bufmgr_mutex_unlock();
962 tbm_bo_locked(tbm_bo bo)
964 _tbm_bufmgr_mutex_lock();
965 _tbm_set_last_result(TBM_ERROR_NONE);
967 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
969 if (bo->bufmgr->bo_lock_type == TBM_BUFMGR_BO_LOCK_TYPE_NEVER) {
970 TBM_ERR("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
971 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
972 _tbm_bufmgr_mutex_unlock();
976 if (bo->lock_cnt > 0) {
977 TBM_TRACE_BO("error: bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
978 _tbm_bufmgr_mutex_unlock();
982 TBM_TRACE_BO("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
983 _tbm_bufmgr_mutex_unlock();
989 tbm_bo_swap(tbm_bo bo1, tbm_bo bo2)
991 tbm_error_e error1, error2;
992 int size1 = -1, size2 = -2;
995 _tbm_bufmgr_mutex_lock();
996 _tbm_set_last_result(TBM_ERROR_NONE);
998 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo1), 0);
999 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo2), 0);
1001 TBM_TRACE_BO("before: bo1(%p) bo2(%p)\n", bo1, bo2);
1003 if (bo1->bufmgr->backend_module_data) {
1004 size1 = bo1->bufmgr->bo_func->bo_get_size(bo1->bo_data, &error1);
1005 if (error1 != TBM_ERROR_NONE) {
1006 TBM_ERR("fail to get the size of bo1.(%d)", error1);
1007 _tbm_set_last_result(error1);
1010 size2 = bo2->bufmgr->bo_func->bo_get_size(bo2->bo_data, &error2);
1011 if (error2 != TBM_ERROR_NONE) {
1012 TBM_ERR("fail to get the size of bo2.(%d)", error2);
1013 _tbm_set_last_result(error2);
1017 size1 = bo1->bufmgr->backend->bo_size(bo1);
1018 size2 = bo2->bufmgr->backend->bo_size(bo2);
1021 if (size1 != size2) {
1022 TBM_ERR("error: bo1 size(%d) and bo2 size(%d) is different.", size1, size2);
1023 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1027 TBM_TRACE_BO("after: bo1(%p) bo2(%p)\n", bo1, bo2);
1030 bo1->priv = bo2->priv;
1033 _tbm_bufmgr_mutex_unlock();
1038 TBM_ERR("error: bo1(%p) bo2(%p)\n", bo1, bo2);
1039 _tbm_bufmgr_mutex_unlock();
1045 tbm_bo_add_user_data(tbm_bo bo, unsigned long key,
1046 tbm_data_free data_free_func)
1048 tbm_user_data *data;
1050 _tbm_bufmgr_mutex_lock();
1051 _tbm_set_last_result(TBM_ERROR_NONE);
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_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1060 _tbm_bufmgr_mutex_unlock();
1064 data = user_data_create(key, data_free_func);
1066 TBM_ERR("error: bo(%p) key(%lu)\n", bo, key);
1067 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1068 _tbm_bufmgr_mutex_unlock();
1072 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, data->data);
1074 LIST_ADD(&data->item_link, &bo->user_data_list);
1076 _tbm_bufmgr_mutex_unlock();
1082 tbm_bo_delete_user_data(tbm_bo bo, unsigned long key)
1084 tbm_user_data *old_data;
1086 _tbm_bufmgr_mutex_lock();
1087 _tbm_set_last_result(TBM_ERROR_NONE);
1089 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1091 if (LIST_IS_EMPTY(&bo->user_data_list)) {
1092 TBM_TRACE_BO("bo(%p) key(%lu)\n", bo, key);
1093 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1094 _tbm_bufmgr_mutex_unlock();
1098 old_data = user_data_lookup(&bo->user_data_list, key);
1100 TBM_TRACE_BO("bo(%p) key(%lu)\n", bo, key);
1101 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1102 _tbm_bufmgr_mutex_unlock();
1106 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1108 user_data_delete(old_data);
1110 _tbm_bufmgr_mutex_unlock();
1116 tbm_bo_set_user_data(tbm_bo bo, unsigned long key, void *data)
1118 tbm_user_data *old_data;
1120 _tbm_bufmgr_mutex_lock();
1121 _tbm_set_last_result(TBM_ERROR_NONE);
1123 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1125 if (LIST_IS_EMPTY(&bo->user_data_list)) {
1126 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1127 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1128 _tbm_bufmgr_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_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1136 _tbm_bufmgr_mutex_unlock();
1140 if (old_data->data && old_data->free_func)
1141 old_data->free_func(old_data->data);
1142 old_data->data = data;
1144 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1146 _tbm_bufmgr_mutex_unlock();
1152 tbm_bo_get_user_data(tbm_bo bo, unsigned long key, void **data)
1154 tbm_user_data *old_data;
1156 _tbm_bufmgr_mutex_lock();
1157 _tbm_set_last_result(TBM_ERROR_NONE);
1159 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1161 if (!data || LIST_IS_EMPTY(&bo->user_data_list)) {
1162 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1163 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1164 _tbm_bufmgr_mutex_unlock();
1168 old_data = user_data_lookup(&bo->user_data_list, key);
1171 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1172 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1173 _tbm_bufmgr_mutex_unlock();
1177 *data = old_data->data;
1179 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1181 _tbm_bufmgr_mutex_unlock();
1187 tbm_bo_get_flags(tbm_bo bo)
1191 _tbm_bufmgr_mutex_lock();
1193 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1197 TBM_TRACE_BO("bo(%p)\n", bo);
1199 _tbm_bufmgr_mutex_unlock();
1204 /* LCOV_EXCL_START */
1205 /* internal function */
1207 _tbm_bo_set_surface(tbm_bo bo, tbm_surface_h surface)
1209 _tbm_bufmgr_mutex_lock();
1211 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1213 bo->surface = surface;
1215 _tbm_bufmgr_mutex_unlock();
1221 _tbm_bo_free(tbm_bo bo)
1223 /* destory the user_data_list */
1224 if (!LIST_IS_EMPTY(&bo->user_data_list)) {
1225 tbm_user_data *old_data = NULL, *tmp;
1227 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp,
1228 &bo->user_data_list, item_link) {
1229 TBM_DBG("free user_data\n");
1230 user_data_delete(old_data);
1234 while (bo->lock_cnt > 0) {
1235 TBM_ERR("error lock_cnt:%d\n", bo->lock_cnt);
1240 /* call the bo_free */
1241 if (bo->bufmgr->backend_module_data) {
1242 bo->bufmgr->bo_func->bo_free(bo->bo_data);
1245 bo->bufmgr->backend->bo_free(bo);
1249 bo->bufmgr->bo_cnt--;
1251 LIST_DEL(&bo->item_link);
1254 /* LCOV_EXCL_STOP */