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->use_hal_tbm) {
157 error = (tbm_error_e)hal_tbm_bo_lock((hal_tbm_bo *)bo->bo_data, device, opt);
158 if (error == TBM_ERROR_NOT_SUPPORTED) {
159 _tbm_set_last_result(TBM_ERROR_NONE);
161 if (error != TBM_ERROR_NONE) {
162 TBM_WRN("fail to lock");
163 _tbm_set_last_result(error);
167 } else if (bo->bufmgr->backend_module_data) {
168 if (bo->bufmgr->bo_func->bo_lock) {
169 error = bo->bufmgr->bo_func->bo_lock(bo->bo_data, device, opt);
170 if (error != TBM_ERROR_NONE) {
171 TBM_WRN("fail to lock");
172 _tbm_set_last_result(error);
177 if (bo->bufmgr->backend->bo_lock) {
178 ret = bo->bufmgr->backend->bo_lock(bo, device, opt);
180 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
188 _bo_unlock(tbm_bo bo)
192 if (bo->bufmgr->use_hal_tbm) {
193 error = (tbm_error_e)hal_tbm_bo_unlock((hal_tbm_bo *)bo->bo_data);
194 if (error == TBM_ERROR_NOT_SUPPORTED) {
195 _tbm_set_last_result(TBM_ERROR_NONE);
197 if (error != TBM_ERROR_NONE) {
198 TBM_WRN("fail to lock");
199 _tbm_set_last_result(error);
202 } else if (bo->bufmgr->backend_module_data) {
203 if (bo->bufmgr->bo_func->bo_unlock) {
204 error = bo->bufmgr->bo_func->bo_unlock(bo->bo_data);
205 if (error != TBM_ERROR_NONE) {
206 TBM_WRN("fail to unlock");
207 _tbm_set_last_result(error);
211 if (bo->bufmgr->backend->bo_unlock)
212 bo->bufmgr->backend->bo_unlock(bo);
217 _tbm_bo_lock(tbm_bo bo, int device, int opt)
224 /* do not try to lock the bo */
225 if (bo->bufmgr->bo_lock_type == TBM_BUFMGR_BO_LOCK_TYPE_NEVER)
228 if (bo->lock_cnt < 0) {
229 TBM_ERR("error bo:%p LOCK_CNT=%d\n",
236 switch (bo->bufmgr->bo_lock_type) {
237 case TBM_BUFMGR_BO_LOCK_TYPE_ONCE:
238 if (bo->lock_cnt == 0) {
239 _tbm_bufmgr_mutex_unlock();
240 ret = _bo_lock(bo, device, opt);
241 _tbm_bufmgr_mutex_lock();
247 case TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS:
248 _tbm_bufmgr_mutex_unlock();
249 ret = _bo_lock(bo, device, opt);
250 _tbm_bufmgr_mutex_lock();
255 TBM_ERR("error bo:%p bo_lock_type[%d] is wrong.\n",
256 bo, bo->bufmgr->bo_lock_type);
261 TBM_DBG(">> LOCK bo:%p(%d->%d)\n", bo, old, bo->lock_cnt);
267 _tbm_bo_unlock(tbm_bo bo)
271 /* do not try to unlock the bo */
272 if (bo->bufmgr->bo_lock_type == TBM_BUFMGR_BO_LOCK_TYPE_NEVER)
277 switch (bo->bufmgr->bo_lock_type) {
278 case TBM_BUFMGR_BO_LOCK_TYPE_ONCE:
279 if (bo->lock_cnt > 0) {
281 if (bo->lock_cnt == 0)
285 case TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS:
286 if (bo->lock_cnt > 0) {
292 TBM_ERR("error bo:%p bo_lock_type[%d] is wrong.\n",
293 bo, bo->bufmgr->bo_lock_type);
297 if (bo->lock_cnt < 0)
300 TBM_DBG(">> UNLOCK bo:%p(%d->%d)\n", bo, old, bo->lock_cnt);
304 _tbm_bo_magic_check(tbm_bo bo)
306 if (bo->magic != TBM_BO_MAGIC)
313 _tbm_bo_is_valid(tbm_bo bo)
316 TBM_ERR("error: bo is NULL.\n");
320 if (!_tbm_bo_magic_check(bo)) {
321 TBM_ERR("error: No valid bo(%p).\n", bo);
329 _tbm_bo_init(tbm_bufmgr bufmgr, tbm_bo bo, int flags)
333 bo->magic = TBM_BO_MAGIC;
336 LIST_INITHEAD(&bo->user_data_list);
339 LIST_ADD(&bo->item_link, &bufmgr->bo_list);
343 _tbm_bo_deinit(tbm_bo bo)
347 bo->bufmgr->bo_cnt--;
348 LIST_DEL(&bo->item_link);
352 tbm_bo_alloc(tbm_bufmgr bufmgr, int size, int flags)
355 tbm_backend_bo_data *bo_data;
358 _tbm_bufmgr_mutex_lock();
359 _tbm_set_last_result(TBM_ERROR_NONE);
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_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
368 _tbm_bufmgr_mutex_unlock();
373 _tbm_util_check_bo_cnt(bufmgr);
375 bo_data = tbm_module_bufmgr_bo_alloc(bufmgr->module, bo, size, flags, &error);
376 if (!bo_data || error != TBM_ERROR_NONE) {
377 /* LCOV_EXCL_START */
378 TBM_ERR("tbm_module_bufmgr_bo_alloc failed. error:%d", error);
379 _tbm_set_last_result(error);
383 bo->bo_data = bo_data;
384 bo->priv = (void *)bo_data; // TODO: this will be DEPRECATED.
386 _tbm_bo_init(bufmgr, bo, flags);
388 TBM_TRACE_BO("bo(%p) size(%d) refcnt(%d), flag(%s)\n", bo, size, bo->ref_cnt,
389 _tbm_flag_to_str(bo->flags));
391 _tbm_bufmgr_mutex_unlock();
396 TBM_ERR("error: fail to create of tbm_bo size(%d) flag(%s)\n", size, _tbm_flag_to_str(flags));
398 _tbm_bufmgr_mutex_unlock();
403 tbm_bo_ref(tbm_bo bo)
405 _tbm_bufmgr_mutex_lock();
406 _tbm_set_last_result(TBM_ERROR_NONE);
408 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), NULL);
412 TBM_TRACE_BO("bo(%p) ref_cnt(%d)\n", bo, bo->ref_cnt);
414 _tbm_bufmgr_mutex_unlock();
420 tbm_bo_unref(tbm_bo bo)
422 _tbm_bufmgr_mutex_lock();
423 _tbm_set_last_result(TBM_ERROR_NONE);
425 TBM_BO_RETURN_IF_FAIL(_tbm_bo_is_valid(bo));
427 TBM_TRACE_BO("bo(%p) ref_cnt(%d)\n", bo, bo->ref_cnt - 1);
429 if (bo->ref_cnt <= 0) {
430 _tbm_bufmgr_mutex_unlock();
435 if (bo->ref_cnt == 0)
438 _tbm_bufmgr_mutex_unlock();
442 tbm_bo_map(tbm_bo bo, int device, int opt)
444 tbm_bo_handle bo_handle;
447 _tbm_bufmgr_mutex_lock();
448 _tbm_set_last_result(TBM_ERROR_NONE);
450 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) NULL);
452 if (!_tbm_bo_lock(bo, device, opt)) {
453 TBM_ERR("error: fail to lock bo:%p)\n", bo);
454 _tbm_bufmgr_mutex_unlock();
455 return (tbm_bo_handle) NULL;
458 if (bo->bufmgr->use_hal_tbm) {
459 hal_tbm_bo_handle hbo_handle;
460 hbo_handle = hal_tbm_bo_map((hal_tbm_bo *)bo->bo_data, device, opt, (hal_tbm_error *)&error);
461 if (hbo_handle.ptr == NULL) {
462 /* LCOV_EXCL_START */
463 _tbm_set_last_result(error);
464 TBM_ERR("error: bo(%p) bo_handle(%p) error(%d)\n", bo, hbo_handle.ptr, error);
468 memcpy(&bo_handle.ptr, &hbo_handle.ptr, sizeof(tbm_bo_handle));
469 } else if (bo->bufmgr->backend_module_data) {
470 bo_handle = bo->bufmgr->bo_func->bo_map(bo->bo_data, device, opt, &error);
471 if (bo_handle.ptr == NULL) {
472 /* LCOV_EXCL_START */
473 _tbm_set_last_result(error);
474 TBM_ERR("error: fail to map bo:%p error:%d\n", bo, error);
479 bo_handle = bo->bufmgr->backend->bo_map(bo, device, opt);
480 if (bo_handle.ptr == NULL) {
481 /* LCOV_EXCL_START */
482 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
483 TBM_ERR("error: fail to map bo:%p\n", bo);
489 /* increase the map_count */
492 TBM_TRACE_BO("bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
494 _tbm_bufmgr_mutex_unlock();
500 _tbm_bufmgr_mutex_unlock();
501 return (tbm_bo_handle) NULL;
505 tbm_bo_unmap(tbm_bo bo)
510 _tbm_bufmgr_mutex_lock();
511 _tbm_set_last_result(TBM_ERROR_NONE);
513 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
514 TBM_BO_RETURN_VAL_IF_FAIL(bo->map_cnt > 0, 0);
516 if (bo->bufmgr->use_hal_tbm) {
517 error = (hal_tbm_error)hal_tbm_bo_unmap((hal_tbm_bo *)bo->bo_data);
518 if (error != TBM_ERROR_NONE) {
519 /* LCOV_EXCL_START */
520 TBM_ERR("error: bo(%p) map_cnt(%d) error(%d)\n", bo, bo->map_cnt, error);
521 _tbm_set_last_result(error);
526 } else if (bo->bufmgr->backend_module_data) {
527 error = bo->bufmgr->bo_func->bo_unmap(bo->bo_data);
528 if (error != TBM_ERROR_NONE) {
529 /* LCOV_EXCL_START */
530 TBM_ERR("error: bo(%p) map_cnt(%d) error(%d)\n", bo, bo->map_cnt, error);
531 _tbm_set_last_result(error);
537 ret = bo->bufmgr->backend->bo_unmap(bo);
539 /* LCOV_EXCL_START */
540 TBM_ERR("error: bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
541 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
547 /* decrease the map_count */
550 TBM_TRACE_BO("bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
555 _tbm_bufmgr_mutex_unlock();
561 tbm_bo_get_handle(tbm_bo bo, int device)
563 tbm_bo_handle bo_handle;
566 _tbm_bufmgr_mutex_lock();
567 _tbm_set_last_result(TBM_ERROR_NONE);
569 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) NULL);
571 if (bo->bufmgr->use_hal_tbm) {
572 hal_tbm_bo_handle hbo_handle;
573 hbo_handle = hal_tbm_bo_get_handle((hal_tbm_bo *)bo->bo_data, device, (hal_tbm_error *)&error);
574 if (hbo_handle.ptr == NULL) {
575 /* LCOV_EXCL_START */
576 TBM_ERR("error: bo(%p) bo_handle(%p) error(%d)\n", bo, hbo_handle.ptr, error);
577 _tbm_set_last_result(error);
581 memcpy(&bo_handle.ptr, &hbo_handle.ptr, sizeof(tbm_bo_handle));
582 } else if (bo->bufmgr->backend_module_data) {
583 bo_handle = bo->bufmgr->bo_func->bo_get_handle(bo->bo_data, device, &error);
584 if (bo_handle.ptr == NULL) {
585 /* LCOV_EXCL_START */
586 TBM_ERR("error: bo(%p) bo_handle(%p) error(%d)\n", bo, bo_handle.ptr, error);
587 _tbm_set_last_result(error);
592 bo_handle = bo->bufmgr->backend->bo_get_handle(bo, device);
593 if (bo_handle.ptr == NULL) {
594 /* LCOV_EXCL_START */
595 TBM_ERR("error: bo(%p) bo_handle(%p)\n", bo, bo_handle.ptr);
596 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
602 TBM_TRACE_BO("bo(%p) bo_handle(%p)\n", bo, bo_handle.ptr);
604 _tbm_bufmgr_mutex_unlock();
609 _tbm_bufmgr_mutex_unlock();
610 return (tbm_bo_handle) NULL;
614 tbm_bo_export(tbm_bo bo)
619 _tbm_bufmgr_mutex_lock();
620 _tbm_set_last_result(TBM_ERROR_NONE);
622 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
624 if (bo->bufmgr->use_hal_tbm) {
625 ret = (hal_tbm_key)hal_tbm_bo_export_key((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
627 /* LCOV_EXCL_START */
628 TBM_ERR("error: bo(%p) tbm_key(%d) error(%d)\n", bo, ret, error);
629 _tbm_set_last_result(error);
633 } else if (bo->bufmgr->backend_module_data) {
634 if (!bo->bufmgr->bo_func->bo_export_key) {
635 /* LCOV_EXCL_START */
636 _tbm_bufmgr_mutex_unlock();
637 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
642 ret = bo->bufmgr->bo_func->bo_export_key(bo->bo_data, &error);
644 /* LCOV_EXCL_START */
645 TBM_ERR("error: bo(%p) tbm_key(%d) error(%d)\n", bo, ret, error);
646 _tbm_set_last_result(error);
651 if (!bo->bufmgr->backend->bo_export) {
652 /* LCOV_EXCL_START */
653 _tbm_bufmgr_mutex_unlock();
654 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
659 ret = bo->bufmgr->backend->bo_export(bo);
661 /* LCOV_EXCL_START */
662 TBM_ERR("error: bo(%p) tbm_key(%d)\n", bo, ret);
663 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
669 TBM_TRACE_BO("bo(%p) tbm_key(%u)\n", bo, ret);
672 _tbm_bufmgr_mutex_unlock();
678 tbm_bo_export_fd(tbm_bo bo)
683 _tbm_bufmgr_mutex_lock();
684 _tbm_set_last_result(TBM_ERROR_NONE);
686 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), -1);
688 if (bo->bufmgr->use_hal_tbm) {
689 ret = (hal_tbm_fd)hal_tbm_bo_export_fd((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
691 /* LCOV_EXCL_START */
692 TBM_ERR("error: bo(%p) tbm_fd(%d) error(%d)\n", bo, ret, error);
693 _tbm_set_last_result(error);
697 } else if (bo->bufmgr->backend_module_data) {
698 if (!bo->bufmgr->bo_func->bo_export_fd) {
699 /* LCOV_EXCL_START */
700 _tbm_bufmgr_mutex_unlock();
701 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
706 ret = bo->bufmgr->bo_func->bo_export_fd(bo->bo_data, &error);
708 /* LCOV_EXCL_START */
709 TBM_ERR("error: bo(%p) tbm_fd(%d) error(%d)\n", bo, ret, error);
710 _tbm_set_last_result(error);
715 if (!bo->bufmgr->backend->bo_export_fd) {
716 /* LCOV_EXCL_START */
717 _tbm_bufmgr_mutex_unlock();
718 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
723 ret = bo->bufmgr->backend->bo_export_fd(bo);
725 /* LCOV_EXCL_START */
726 TBM_ERR("error: bo(%p) tbm_fd(%d)\n", bo, ret);
727 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
733 TBM_TRACE_BO("bo(%p) tbm_fd(%d)\n", bo, ret);
736 _tbm_bufmgr_mutex_unlock();
742 tbm_bo_import(tbm_bufmgr bufmgr, unsigned int key)
744 tbm_bo bo, bo2 = NULL;
748 _tbm_bufmgr_mutex_lock();
749 _tbm_set_last_result(TBM_ERROR_NONE);
751 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
753 _tbm_util_check_bo_cnt(bufmgr);
755 bo = calloc(1, sizeof(struct _tbm_bo));
757 /* LCOV_EXCL_START */
758 TBM_ERR("error: fail to import of tbm_bo by key(%d)\n", key);
759 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
760 _tbm_bufmgr_mutex_unlock();
765 bo->bo_data = tbm_module_bufmgr_bo_import_key(bufmgr->module, bo, key, &error);
767 /* LCOV_EXCL_START */
768 TBM_ERR("tbm_module_bufmgr_bo_import_key failed. tbm_key:%d", key);
769 _tbm_set_last_result(error);
770 _tbm_bufmgr_mutex_unlock();
775 // return the existed bo2 if bo->bo_data and bo2->bo_data is the same
776 bo2 = tbm_bufmgr_internal_find_bo(bufmgr, bo);
778 TBM_TRACE_BO("find bo(%p) ref(%d) key(%d) flag(%s) in list",
779 bo2, bo2->ref_cnt, key, _tbm_flag_to_str(bo2->flags));
782 _tbm_bufmgr_mutex_unlock();
786 if (bufmgr->use_hal_tbm) {
787 flags = (tbm_bo_memory_type)hal_tbm_bo_get_memory_types((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
788 if (error != TBM_ERROR_NONE) {
789 TBM_ERR("fail to get the bo flags(memory_types)");
790 _tbm_set_last_result(error);
791 flags = TBM_BO_DEFAULT;
793 } else if (bufmgr->backend_module_data) {
794 flags = bufmgr->bo_func->bo_get_memory_types(bo->bo_data, &error);
795 if (error != TBM_ERROR_NONE) {
796 TBM_ERR("fail to get the bo flags(memory_types)");
797 _tbm_set_last_result(error);
798 flags = TBM_BO_DEFAULT;
801 if (bufmgr->backend->bo_get_flags)
802 flags = bufmgr->backend->bo_get_flags(bo);
804 flags = TBM_BO_DEFAULT;
807 _tbm_bo_init(bufmgr, bo, flags);
809 TBM_TRACE_BO("import new bo(%p) ref(%d) key(%d) flag(%s) in list\n",
810 bo, bo->ref_cnt, key, _tbm_flag_to_str(bo->flags));
812 _tbm_bufmgr_mutex_unlock();
818 tbm_bo_import_fd(tbm_bufmgr bufmgr, tbm_fd fd)
820 tbm_bo bo, bo2 = NULL;
824 _tbm_bufmgr_mutex_lock();
825 _tbm_set_last_result(TBM_ERROR_NONE);
827 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
829 _tbm_util_check_bo_cnt(bufmgr);
831 bo = calloc(1, sizeof(struct _tbm_bo));
833 /* LCOV_EXCL_START */
834 TBM_ERR("error: fail to import tbm_bo by tbm_fd(%d)\n", fd);
835 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
836 _tbm_bufmgr_mutex_unlock();
841 bo->bo_data = tbm_module_bufmgr_bo_import_fd(bufmgr->module, bo, fd, &error);
843 /* LCOV_EXCL_START */
844 TBM_ERR("tbm_module_bufmgr_bo_import_fd failed. tbm_fd:%d", fd);
845 _tbm_set_last_result(error);
846 _tbm_bufmgr_mutex_unlock();
851 // return the existed bo2 if bo->bo_data and bo2->bo_data is the same
852 bo2 = tbm_bufmgr_internal_find_bo(bufmgr, bo);
854 TBM_TRACE_BO("find bo(%p) ref(%d) fd(%d) flag(%s) in list",
855 bo2, bo2->ref_cnt, fd, _tbm_flag_to_str(bo2->flags));
858 _tbm_bufmgr_mutex_unlock();
862 if (bufmgr->use_hal_tbm) {
863 flags = (tbm_bo_memory_type)hal_tbm_bo_get_memory_types((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
864 if (error != TBM_ERROR_NONE) {
865 TBM_ERR("fail to get the bo flags(memory_types)");
866 _tbm_set_last_result(error);
867 flags = TBM_BO_DEFAULT;
869 } else if (bufmgr->backend_module_data) {
870 flags = bufmgr->bo_func->bo_get_memory_types(bo->bo_data, &error);
871 if (error != TBM_ERROR_NONE) {
872 TBM_ERR("fail to get the bo flags(memory_types)");
873 _tbm_set_last_result(error);
874 flags = TBM_BO_DEFAULT;
877 if (bufmgr->backend->bo_get_flags)
878 flags = bufmgr->backend->bo_get_flags(bo);
880 flags = TBM_BO_DEFAULT;
883 _tbm_bo_init(bufmgr, bo, flags);
885 TBM_TRACE_BO("import bo(%p) ref(%d) fd(%d) flag(%s)\n",
886 bo, bo->ref_cnt, fd, _tbm_flag_to_str(bo->flags));
888 _tbm_bufmgr_mutex_unlock();
894 tbm_bo_size(tbm_bo bo)
899 _tbm_bufmgr_mutex_lock();
900 _tbm_set_last_result(TBM_ERROR_NONE);
902 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
904 if (bo->bufmgr->use_hal_tbm) {
905 size = hal_tbm_bo_get_size((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
906 if (error != TBM_ERROR_NONE) {
907 TBM_ERR("fail to get the size of the bo_data(%d).", error);
908 _tbm_set_last_result(TBM_ERROR_NONE);
910 } else if (bo->bufmgr->backend_module_data) {
911 size = bo->bufmgr->bo_func->bo_get_size(bo->bo_data, &error);
912 if (error != TBM_ERROR_NONE) {
913 TBM_ERR("fail to get the size of the bo_data(%d).", error);
914 _tbm_set_last_result(TBM_ERROR_NONE);
917 size = bo->bufmgr->backend->bo_size(bo);
919 TBM_TRACE_BO("bo(%p) size(%d)\n", bo, size);
921 _tbm_bufmgr_mutex_unlock();
927 tbm_bo_locked(tbm_bo bo)
929 _tbm_bufmgr_mutex_lock();
930 _tbm_set_last_result(TBM_ERROR_NONE);
932 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
934 if (bo->bufmgr->bo_lock_type == TBM_BUFMGR_BO_LOCK_TYPE_NEVER) {
935 TBM_ERR("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
936 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
937 _tbm_bufmgr_mutex_unlock();
941 if (bo->lock_cnt > 0) {
942 TBM_TRACE_BO("error: bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
943 _tbm_bufmgr_mutex_unlock();
947 TBM_TRACE_BO("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
948 _tbm_bufmgr_mutex_unlock();
954 tbm_bo_swap(tbm_bo bo1, tbm_bo bo2)
956 tbm_error_e error1, error2;
957 int size1 = -1, size2 = -2;
960 _tbm_bufmgr_mutex_lock();
961 _tbm_set_last_result(TBM_ERROR_NONE);
963 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo1), 0);
964 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo2), 0);
966 TBM_TRACE_BO("before: bo1(%p) bo2(%p)\n", bo1, bo2);
968 if (bo1->bufmgr->use_hal_tbm) {
969 size1 = hal_tbm_bo_get_size((hal_tbm_bo *)bo1->bo_data, (hal_tbm_error *)&error1);
970 if (error1 != TBM_ERROR_NONE) {
971 TBM_ERR("fail to get the size of bo1.(%d)", error1);
972 _tbm_set_last_result(error1);
975 size2 = hal_tbm_bo_get_size((hal_tbm_bo *)bo2->bo_data, (hal_tbm_error *)&error2);
976 if (error2 != TBM_ERROR_NONE) {
977 TBM_ERR("fail to get the size of bo1.(%d)", error2);
978 _tbm_set_last_result(error2);
981 } else if (bo1->bufmgr->backend_module_data) {
982 size1 = bo1->bufmgr->bo_func->bo_get_size(bo1->bo_data, &error1);
983 if (error1 != TBM_ERROR_NONE) {
984 TBM_ERR("fail to get the size of bo1.(%d)", error1);
985 _tbm_set_last_result(error1);
988 size2 = bo2->bufmgr->bo_func->bo_get_size(bo2->bo_data, &error2);
989 if (error2 != TBM_ERROR_NONE) {
990 TBM_ERR("fail to get the size of bo2.(%d)", error2);
991 _tbm_set_last_result(error2);
995 size1 = bo1->bufmgr->backend->bo_size(bo1);
996 size2 = bo2->bufmgr->backend->bo_size(bo2);
999 if (size1 != size2) {
1000 TBM_ERR("error: bo1 size(%d) and bo2 size(%d) is different.", size1, size2);
1001 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1005 TBM_TRACE_BO("after: bo1(%p) bo2(%p)\n", bo1, bo2);
1008 bo1->priv = bo2->priv;
1011 _tbm_bufmgr_mutex_unlock();
1016 TBM_ERR("error: bo1(%p) bo2(%p)\n", bo1, bo2);
1017 _tbm_bufmgr_mutex_unlock();
1023 tbm_bo_add_user_data(tbm_bo bo, unsigned long key,
1024 tbm_data_free data_free_func)
1026 tbm_user_data *data;
1028 _tbm_bufmgr_mutex_lock();
1029 _tbm_set_last_result(TBM_ERROR_NONE);
1031 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1033 /* check if the data according to the key exist if so, return false. */
1034 data = user_data_lookup(&bo->user_data_list, key);
1036 TBM_TRACE_BO("warning: user data already exist key(%ld)\n", key);
1037 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1038 _tbm_bufmgr_mutex_unlock();
1042 data = user_data_create(key, data_free_func);
1044 TBM_ERR("error: bo(%p) key(%lu)\n", bo, key);
1045 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1046 _tbm_bufmgr_mutex_unlock();
1050 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, data->data);
1052 LIST_ADD(&data->item_link, &bo->user_data_list);
1054 _tbm_bufmgr_mutex_unlock();
1060 tbm_bo_delete_user_data(tbm_bo bo, unsigned long key)
1062 tbm_user_data *old_data;
1064 _tbm_bufmgr_mutex_lock();
1065 _tbm_set_last_result(TBM_ERROR_NONE);
1067 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1069 if (LIST_IS_EMPTY(&bo->user_data_list)) {
1070 TBM_TRACE_BO("bo(%p) key(%lu)\n", bo, key);
1071 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1072 _tbm_bufmgr_mutex_unlock();
1076 old_data = user_data_lookup(&bo->user_data_list, key);
1078 TBM_TRACE_BO("bo(%p) key(%lu)\n", bo, key);
1079 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1080 _tbm_bufmgr_mutex_unlock();
1084 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1086 user_data_delete(old_data);
1088 _tbm_bufmgr_mutex_unlock();
1094 tbm_bo_set_user_data(tbm_bo bo, unsigned long key, void *data)
1096 tbm_user_data *old_data;
1098 _tbm_bufmgr_mutex_lock();
1099 _tbm_set_last_result(TBM_ERROR_NONE);
1101 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1103 if (LIST_IS_EMPTY(&bo->user_data_list)) {
1104 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1105 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1106 _tbm_bufmgr_mutex_unlock();
1110 old_data = user_data_lookup(&bo->user_data_list, key);
1112 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1113 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1114 _tbm_bufmgr_mutex_unlock();
1118 if (old_data->data && old_data->free_func)
1119 old_data->free_func(old_data->data);
1120 old_data->data = data;
1122 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1124 _tbm_bufmgr_mutex_unlock();
1130 tbm_bo_get_user_data(tbm_bo bo, unsigned long key, void **data)
1132 tbm_user_data *old_data;
1134 _tbm_bufmgr_mutex_lock();
1135 _tbm_set_last_result(TBM_ERROR_NONE);
1137 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1139 if (!data || LIST_IS_EMPTY(&bo->user_data_list)) {
1140 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1141 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1142 _tbm_bufmgr_mutex_unlock();
1146 old_data = user_data_lookup(&bo->user_data_list, key);
1149 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1150 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1151 _tbm_bufmgr_mutex_unlock();
1155 *data = old_data->data;
1157 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1159 _tbm_bufmgr_mutex_unlock();
1165 tbm_bo_get_flags(tbm_bo bo)
1169 _tbm_bufmgr_mutex_lock();
1171 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1175 TBM_TRACE_BO("bo(%p)\n", bo);
1177 _tbm_bufmgr_mutex_unlock();
1182 /* LCOV_EXCL_START */
1183 /* internal function */
1185 _tbm_bo_set_surface(tbm_bo bo, tbm_surface_h surface)
1187 _tbm_bufmgr_mutex_lock();
1189 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1191 bo->surface = surface;
1193 _tbm_bufmgr_mutex_unlock();
1199 _tbm_bo_free(tbm_bo bo)
1201 /* destory the user_data_list */
1202 if (!LIST_IS_EMPTY(&bo->user_data_list)) {
1203 tbm_user_data *old_data = NULL, *tmp;
1205 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp,
1206 &bo->user_data_list, item_link) {
1207 TBM_DBG("free user_data\n");
1208 user_data_delete(old_data);
1212 while (bo->lock_cnt > 0) {
1213 TBM_ERR("error lock_cnt:%d\n", bo->lock_cnt);
1218 /* call the bo_free */
1219 if (bo->bufmgr->use_hal_tbm) {
1220 // call hal_tbm_bo_free when bo is created by tbm_bo_alloc api.
1221 if (!bo->get_from_hal_surface) {
1222 bo->get_from_hal_surface = 0;
1224 hal_tbm_bo_free(bo->bo_data);
1227 } else if (bo->bufmgr->backend_module_data) {
1228 bo->bufmgr->bo_func->bo_free(bo->bo_data);
1231 bo->bufmgr->backend->bo_free(bo);
1239 /* LCOV_EXCL_STOP */