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)
357 _tbm_bufmgr_mutex_lock();
358 _tbm_set_last_result(TBM_ERROR_NONE);
360 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
361 TBM_BO_RETURN_VAL_IF_FAIL(size > 0, NULL);
363 bo = tbm_bufmgr_internal_alloc_bo(bufmgr, size, flags, &error);
365 /* LCOV_EXCL_START */
366 TBM_ERR("tbm_bufmgr_internal_alloc_bo failed. error:%d", error);
367 _tbm_set_last_result(error);
368 _tbm_bufmgr_mutex_unlock();
373 TBM_TRACE_BO("bo(%p) size(%d) refcnt(%d), flag(%s)\n", bo, size, bo->ref_cnt,
374 _tbm_flag_to_str(bo->flags));
376 _tbm_bufmgr_mutex_unlock();
382 tbm_bo_ref(tbm_bo bo)
384 _tbm_bufmgr_mutex_lock();
385 _tbm_set_last_result(TBM_ERROR_NONE);
387 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), NULL);
391 TBM_TRACE_BO("bo(%p) ref_cnt(%d)\n", bo, bo->ref_cnt);
393 _tbm_bufmgr_mutex_unlock();
399 tbm_bo_unref(tbm_bo bo)
401 _tbm_bufmgr_mutex_lock();
402 _tbm_set_last_result(TBM_ERROR_NONE);
404 TBM_BO_RETURN_IF_FAIL(_tbm_bo_is_valid(bo));
406 TBM_TRACE_BO("bo(%p) ref_cnt(%d)\n", bo, bo->ref_cnt - 1);
408 if (bo->ref_cnt <= 0) {
409 _tbm_bufmgr_mutex_unlock();
414 if (bo->ref_cnt == 0)
417 _tbm_bufmgr_mutex_unlock();
421 tbm_bo_map(tbm_bo bo, int device, int opt)
423 tbm_bo_handle bo_handle;
426 _tbm_bufmgr_mutex_lock();
427 _tbm_set_last_result(TBM_ERROR_NONE);
429 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) NULL);
431 if (!_tbm_bo_lock(bo, device, opt)) {
432 TBM_ERR("error: fail to lock bo:%p)\n", bo);
433 _tbm_bufmgr_mutex_unlock();
434 return (tbm_bo_handle) NULL;
437 if (bo->bufmgr->use_hal_tbm) {
438 hal_tbm_bo_handle hbo_handle;
439 hbo_handle = hal_tbm_bo_map((hal_tbm_bo *)bo->bo_data, device, opt, (hal_tbm_error *)&error);
440 if (hbo_handle.ptr == NULL) {
441 /* LCOV_EXCL_START */
442 _tbm_set_last_result(error);
443 TBM_ERR("error: bo(%p) bo_handle(%p) error(%d)\n", bo, hbo_handle.ptr, error);
447 memcpy(&bo_handle.ptr, &hbo_handle.ptr, sizeof(tbm_bo_handle));
448 } else if (bo->bufmgr->backend_module_data) {
449 bo_handle = bo->bufmgr->bo_func->bo_map(bo->bo_data, device, opt, &error);
450 if (bo_handle.ptr == NULL) {
451 /* LCOV_EXCL_START */
452 _tbm_set_last_result(error);
453 TBM_ERR("error: fail to map bo:%p error:%d\n", bo, error);
458 bo_handle = bo->bufmgr->backend->bo_map(bo, device, opt);
459 if (bo_handle.ptr == NULL) {
460 /* LCOV_EXCL_START */
461 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
462 TBM_ERR("error: fail to map bo:%p\n", bo);
468 /* increase the map_count */
471 TBM_TRACE_BO("bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
473 _tbm_bufmgr_mutex_unlock();
479 _tbm_bufmgr_mutex_unlock();
480 return (tbm_bo_handle) NULL;
484 tbm_bo_unmap(tbm_bo bo)
489 _tbm_bufmgr_mutex_lock();
490 _tbm_set_last_result(TBM_ERROR_NONE);
492 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
493 TBM_BO_RETURN_VAL_IF_FAIL(bo->map_cnt > 0, 0);
495 if (bo->bufmgr->use_hal_tbm) {
496 error = (hal_tbm_error)hal_tbm_bo_unmap((hal_tbm_bo *)bo->bo_data);
497 if (error != TBM_ERROR_NONE) {
498 /* LCOV_EXCL_START */
499 TBM_ERR("error: bo(%p) map_cnt(%d) error(%d)\n", bo, bo->map_cnt, error);
500 _tbm_set_last_result(error);
505 } else if (bo->bufmgr->backend_module_data) {
506 error = bo->bufmgr->bo_func->bo_unmap(bo->bo_data);
507 if (error != TBM_ERROR_NONE) {
508 /* LCOV_EXCL_START */
509 TBM_ERR("error: bo(%p) map_cnt(%d) error(%d)\n", bo, bo->map_cnt, error);
510 _tbm_set_last_result(error);
516 ret = bo->bufmgr->backend->bo_unmap(bo);
518 /* LCOV_EXCL_START */
519 TBM_ERR("error: bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
520 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
526 /* decrease the map_count */
529 TBM_TRACE_BO("bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
534 _tbm_bufmgr_mutex_unlock();
540 tbm_bo_get_handle(tbm_bo bo, int device)
542 tbm_bo_handle bo_handle;
545 _tbm_bufmgr_mutex_lock();
546 _tbm_set_last_result(TBM_ERROR_NONE);
548 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) NULL);
550 if (bo->bufmgr->use_hal_tbm) {
551 hal_tbm_bo_handle hbo_handle;
552 hbo_handle = hal_tbm_bo_get_handle((hal_tbm_bo *)bo->bo_data, device, (hal_tbm_error *)&error);
553 if (hbo_handle.ptr == NULL) {
554 /* LCOV_EXCL_START */
555 TBM_ERR("error: bo(%p) bo_handle(%p) error(%d)\n", bo, hbo_handle.ptr, error);
556 _tbm_set_last_result(error);
560 memcpy(&bo_handle.ptr, &hbo_handle.ptr, sizeof(tbm_bo_handle));
561 } else if (bo->bufmgr->backend_module_data) {
562 bo_handle = bo->bufmgr->bo_func->bo_get_handle(bo->bo_data, device, &error);
563 if (bo_handle.ptr == NULL) {
564 /* LCOV_EXCL_START */
565 TBM_ERR("error: bo(%p) bo_handle(%p) error(%d)\n", bo, bo_handle.ptr, error);
566 _tbm_set_last_result(error);
571 bo_handle = bo->bufmgr->backend->bo_get_handle(bo, device);
572 if (bo_handle.ptr == NULL) {
573 /* LCOV_EXCL_START */
574 TBM_ERR("error: bo(%p) bo_handle(%p)\n", bo, bo_handle.ptr);
575 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
581 TBM_TRACE_BO("bo(%p) bo_handle(%p)\n", bo, bo_handle.ptr);
583 _tbm_bufmgr_mutex_unlock();
588 _tbm_bufmgr_mutex_unlock();
589 return (tbm_bo_handle) NULL;
593 tbm_bo_export(tbm_bo bo)
598 _tbm_bufmgr_mutex_lock();
599 _tbm_set_last_result(TBM_ERROR_NONE);
601 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
603 if (bo->bufmgr->use_hal_tbm) {
604 ret = (hal_tbm_key)hal_tbm_bo_export_key((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
606 /* LCOV_EXCL_START */
607 TBM_ERR("error: bo(%p) tbm_key(%d) error(%d)\n", bo, ret, error);
608 _tbm_set_last_result(error);
612 } else if (bo->bufmgr->backend_module_data) {
613 if (!bo->bufmgr->bo_func->bo_export_key) {
614 /* LCOV_EXCL_START */
615 _tbm_bufmgr_mutex_unlock();
616 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
621 ret = bo->bufmgr->bo_func->bo_export_key(bo->bo_data, &error);
623 /* LCOV_EXCL_START */
624 TBM_ERR("error: bo(%p) tbm_key(%d) error(%d)\n", bo, ret, error);
625 _tbm_set_last_result(error);
630 if (!bo->bufmgr->backend->bo_export) {
631 /* LCOV_EXCL_START */
632 _tbm_bufmgr_mutex_unlock();
633 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
638 ret = bo->bufmgr->backend->bo_export(bo);
640 /* LCOV_EXCL_START */
641 TBM_ERR("error: bo(%p) tbm_key(%d)\n", bo, ret);
642 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
648 TBM_TRACE_BO("bo(%p) tbm_key(%u)\n", bo, ret);
651 _tbm_bufmgr_mutex_unlock();
657 tbm_bo_export_fd(tbm_bo bo)
662 _tbm_bufmgr_mutex_lock();
663 _tbm_set_last_result(TBM_ERROR_NONE);
665 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), -1);
667 if (bo->bufmgr->use_hal_tbm) {
668 ret = (hal_tbm_fd)hal_tbm_bo_export_fd((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
670 /* LCOV_EXCL_START */
671 TBM_ERR("error: bo(%p) tbm_fd(%d) error(%d)\n", bo, ret, error);
672 _tbm_set_last_result(error);
676 } else if (bo->bufmgr->backend_module_data) {
677 if (!bo->bufmgr->bo_func->bo_export_fd) {
678 /* LCOV_EXCL_START */
679 _tbm_bufmgr_mutex_unlock();
680 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
685 ret = bo->bufmgr->bo_func->bo_export_fd(bo->bo_data, &error);
687 /* LCOV_EXCL_START */
688 TBM_ERR("error: bo(%p) tbm_fd(%d) error(%d)\n", bo, ret, error);
689 _tbm_set_last_result(error);
694 if (!bo->bufmgr->backend->bo_export_fd) {
695 /* LCOV_EXCL_START */
696 _tbm_bufmgr_mutex_unlock();
697 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
702 ret = bo->bufmgr->backend->bo_export_fd(bo);
704 /* LCOV_EXCL_START */
705 TBM_ERR("error: bo(%p) tbm_fd(%d)\n", bo, ret);
706 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
712 TBM_TRACE_BO("bo(%p) tbm_fd(%d)\n", bo, ret);
715 _tbm_bufmgr_mutex_unlock();
721 tbm_bo_import(tbm_bufmgr bufmgr, unsigned int key)
723 tbm_bo bo, bo2 = NULL;
727 _tbm_bufmgr_mutex_lock();
728 _tbm_set_last_result(TBM_ERROR_NONE);
730 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
732 _tbm_util_check_bo_cnt(bufmgr);
734 bo = calloc(1, sizeof(struct _tbm_bo));
736 /* LCOV_EXCL_START */
737 TBM_ERR("error: fail to import of tbm_bo by key(%d)\n", key);
738 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
739 _tbm_bufmgr_mutex_unlock();
744 bo->bo_data = tbm_module_bufmgr_bo_import_key(bufmgr->module, bo, key, &error);
746 /* LCOV_EXCL_START */
747 TBM_ERR("tbm_module_bufmgr_bo_import_key failed. tbm_key:%d", key);
748 _tbm_set_last_result(error);
749 _tbm_bufmgr_mutex_unlock();
754 // return the existed bo2 if bo->bo_data and bo2->bo_data is the same
755 bo2 = tbm_bufmgr_internal_find_bo(bufmgr, bo);
757 TBM_TRACE_BO("find bo(%p) ref(%d) key(%d) flag(%s) in list",
758 bo2, bo2->ref_cnt, key, _tbm_flag_to_str(bo2->flags));
761 _tbm_bufmgr_mutex_unlock();
765 if (bufmgr->use_hal_tbm) {
766 flags = (tbm_bo_memory_type)hal_tbm_bo_get_memory_types((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
767 if (error != TBM_ERROR_NONE) {
768 TBM_ERR("fail to get the bo flags(memory_types)");
769 _tbm_set_last_result(error);
770 flags = TBM_BO_DEFAULT;
772 } else if (bufmgr->backend_module_data) {
773 flags = bufmgr->bo_func->bo_get_memory_types(bo->bo_data, &error);
774 if (error != TBM_ERROR_NONE) {
775 TBM_ERR("fail to get the bo flags(memory_types)");
776 _tbm_set_last_result(error);
777 flags = TBM_BO_DEFAULT;
780 if (bufmgr->backend->bo_get_flags)
781 flags = bufmgr->backend->bo_get_flags(bo);
783 flags = TBM_BO_DEFAULT;
786 _tbm_bo_init(bufmgr, bo, flags);
788 TBM_TRACE_BO("import new bo(%p) ref(%d) key(%d) flag(%s) in list\n",
789 bo, bo->ref_cnt, key, _tbm_flag_to_str(bo->flags));
791 _tbm_bufmgr_mutex_unlock();
797 tbm_bo_import_fd(tbm_bufmgr bufmgr, tbm_fd fd)
799 tbm_bo bo, bo2 = NULL;
803 _tbm_bufmgr_mutex_lock();
804 _tbm_set_last_result(TBM_ERROR_NONE);
806 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
808 _tbm_util_check_bo_cnt(bufmgr);
810 bo = calloc(1, sizeof(struct _tbm_bo));
812 /* LCOV_EXCL_START */
813 TBM_ERR("error: fail to import tbm_bo by tbm_fd(%d)\n", fd);
814 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
815 _tbm_bufmgr_mutex_unlock();
820 bo->bo_data = tbm_module_bufmgr_bo_import_fd(bufmgr->module, bo, fd, &error);
822 /* LCOV_EXCL_START */
823 TBM_ERR("tbm_module_bufmgr_bo_import_fd failed. tbm_fd:%d", fd);
824 _tbm_set_last_result(error);
825 _tbm_bufmgr_mutex_unlock();
830 // return the existed bo2 if bo->bo_data and bo2->bo_data is the same
831 bo2 = tbm_bufmgr_internal_find_bo(bufmgr, bo);
833 TBM_TRACE_BO("find bo(%p) ref(%d) fd(%d) flag(%s) in list",
834 bo2, bo2->ref_cnt, fd, _tbm_flag_to_str(bo2->flags));
837 _tbm_bufmgr_mutex_unlock();
841 if (bufmgr->use_hal_tbm) {
842 flags = (tbm_bo_memory_type)hal_tbm_bo_get_memory_types((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
843 if (error != TBM_ERROR_NONE) {
844 TBM_ERR("fail to get the bo flags(memory_types)");
845 _tbm_set_last_result(error);
846 flags = TBM_BO_DEFAULT;
848 } else if (bufmgr->backend_module_data) {
849 flags = bufmgr->bo_func->bo_get_memory_types(bo->bo_data, &error);
850 if (error != TBM_ERROR_NONE) {
851 TBM_ERR("fail to get the bo flags(memory_types)");
852 _tbm_set_last_result(error);
853 flags = TBM_BO_DEFAULT;
856 if (bufmgr->backend->bo_get_flags)
857 flags = bufmgr->backend->bo_get_flags(bo);
859 flags = TBM_BO_DEFAULT;
862 _tbm_bo_init(bufmgr, bo, flags);
864 TBM_TRACE_BO("import bo(%p) ref(%d) fd(%d) flag(%s)\n",
865 bo, bo->ref_cnt, fd, _tbm_flag_to_str(bo->flags));
867 _tbm_bufmgr_mutex_unlock();
873 tbm_bo_size(tbm_bo bo)
878 _tbm_bufmgr_mutex_lock();
879 _tbm_set_last_result(TBM_ERROR_NONE);
881 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
883 if (bo->bufmgr->use_hal_tbm) {
884 size = hal_tbm_bo_get_size((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
885 if (error != TBM_ERROR_NONE) {
886 TBM_ERR("fail to get the size of the bo_data(%d).", error);
887 _tbm_set_last_result(TBM_ERROR_NONE);
889 } else if (bo->bufmgr->backend_module_data) {
890 size = bo->bufmgr->bo_func->bo_get_size(bo->bo_data, &error);
891 if (error != TBM_ERROR_NONE) {
892 TBM_ERR("fail to get the size of the bo_data(%d).", error);
893 _tbm_set_last_result(TBM_ERROR_NONE);
896 size = bo->bufmgr->backend->bo_size(bo);
898 TBM_TRACE_BO("bo(%p) size(%d)\n", bo, size);
900 _tbm_bufmgr_mutex_unlock();
906 tbm_bo_locked(tbm_bo bo)
908 _tbm_bufmgr_mutex_lock();
909 _tbm_set_last_result(TBM_ERROR_NONE);
911 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
913 if (bo->bufmgr->bo_lock_type == TBM_BUFMGR_BO_LOCK_TYPE_NEVER) {
914 TBM_ERR("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
915 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
916 _tbm_bufmgr_mutex_unlock();
920 if (bo->lock_cnt > 0) {
921 TBM_TRACE_BO("error: bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
922 _tbm_bufmgr_mutex_unlock();
926 TBM_TRACE_BO("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
927 _tbm_bufmgr_mutex_unlock();
933 tbm_bo_swap(tbm_bo bo1, tbm_bo bo2)
935 tbm_error_e error1, error2;
936 int size1 = -1, size2 = -2;
939 _tbm_bufmgr_mutex_lock();
940 _tbm_set_last_result(TBM_ERROR_NONE);
942 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo1), 0);
943 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo2), 0);
945 TBM_TRACE_BO("before: bo1(%p) bo2(%p)\n", bo1, bo2);
947 if (bo1->bufmgr->use_hal_tbm) {
948 size1 = hal_tbm_bo_get_size((hal_tbm_bo *)bo1->bo_data, (hal_tbm_error *)&error1);
949 if (error1 != TBM_ERROR_NONE) {
950 TBM_ERR("fail to get the size of bo1.(%d)", error1);
951 _tbm_set_last_result(error1);
954 size2 = hal_tbm_bo_get_size((hal_tbm_bo *)bo2->bo_data, (hal_tbm_error *)&error2);
955 if (error2 != TBM_ERROR_NONE) {
956 TBM_ERR("fail to get the size of bo1.(%d)", error2);
957 _tbm_set_last_result(error2);
960 } else if (bo1->bufmgr->backend_module_data) {
961 size1 = bo1->bufmgr->bo_func->bo_get_size(bo1->bo_data, &error1);
962 if (error1 != TBM_ERROR_NONE) {
963 TBM_ERR("fail to get the size of bo1.(%d)", error1);
964 _tbm_set_last_result(error1);
967 size2 = bo2->bufmgr->bo_func->bo_get_size(bo2->bo_data, &error2);
968 if (error2 != TBM_ERROR_NONE) {
969 TBM_ERR("fail to get the size of bo2.(%d)", error2);
970 _tbm_set_last_result(error2);
974 size1 = bo1->bufmgr->backend->bo_size(bo1);
975 size2 = bo2->bufmgr->backend->bo_size(bo2);
978 if (size1 != size2) {
979 TBM_ERR("error: bo1 size(%d) and bo2 size(%d) is different.", size1, size2);
980 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
984 TBM_TRACE_BO("after: bo1(%p) bo2(%p)\n", bo1, bo2);
987 bo1->priv = bo2->priv;
990 _tbm_bufmgr_mutex_unlock();
995 TBM_ERR("error: bo1(%p) bo2(%p)\n", bo1, bo2);
996 _tbm_bufmgr_mutex_unlock();
1002 tbm_bo_add_user_data(tbm_bo bo, unsigned long key,
1003 tbm_data_free data_free_func)
1005 tbm_user_data *data;
1007 _tbm_bufmgr_mutex_lock();
1008 _tbm_set_last_result(TBM_ERROR_NONE);
1010 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1012 /* check if the data according to the key exist if so, return false. */
1013 data = user_data_lookup(&bo->user_data_list, key);
1015 TBM_TRACE_BO("warning: user data already exist key(%ld)\n", key);
1016 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1017 _tbm_bufmgr_mutex_unlock();
1021 data = user_data_create(key, data_free_func);
1023 TBM_ERR("error: bo(%p) key(%lu)\n", bo, key);
1024 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1025 _tbm_bufmgr_mutex_unlock();
1029 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, data->data);
1031 LIST_ADD(&data->item_link, &bo->user_data_list);
1033 _tbm_bufmgr_mutex_unlock();
1039 tbm_bo_delete_user_data(tbm_bo bo, unsigned long key)
1041 tbm_user_data *old_data;
1043 _tbm_bufmgr_mutex_lock();
1044 _tbm_set_last_result(TBM_ERROR_NONE);
1046 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1048 if (LIST_IS_EMPTY(&bo->user_data_list)) {
1049 TBM_TRACE_BO("bo(%p) key(%lu)\n", bo, key);
1050 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1051 _tbm_bufmgr_mutex_unlock();
1055 old_data = user_data_lookup(&bo->user_data_list, key);
1057 TBM_TRACE_BO("bo(%p) key(%lu)\n", bo, key);
1058 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1059 _tbm_bufmgr_mutex_unlock();
1063 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1065 user_data_delete(old_data);
1067 _tbm_bufmgr_mutex_unlock();
1073 tbm_bo_set_user_data(tbm_bo bo, unsigned long key, void *data)
1075 tbm_user_data *old_data;
1077 _tbm_bufmgr_mutex_lock();
1078 _tbm_set_last_result(TBM_ERROR_NONE);
1080 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1082 if (LIST_IS_EMPTY(&bo->user_data_list)) {
1083 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1084 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1085 _tbm_bufmgr_mutex_unlock();
1089 old_data = user_data_lookup(&bo->user_data_list, key);
1091 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1092 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1093 _tbm_bufmgr_mutex_unlock();
1097 if (old_data->data && old_data->free_func)
1098 old_data->free_func(old_data->data);
1099 old_data->data = data;
1101 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1103 _tbm_bufmgr_mutex_unlock();
1109 tbm_bo_get_user_data(tbm_bo bo, unsigned long key, void **data)
1111 tbm_user_data *old_data;
1113 _tbm_bufmgr_mutex_lock();
1114 _tbm_set_last_result(TBM_ERROR_NONE);
1116 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1118 if (!data || LIST_IS_EMPTY(&bo->user_data_list)) {
1119 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1120 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1121 _tbm_bufmgr_mutex_unlock();
1125 old_data = user_data_lookup(&bo->user_data_list, key);
1128 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1129 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1130 _tbm_bufmgr_mutex_unlock();
1134 *data = old_data->data;
1136 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1138 _tbm_bufmgr_mutex_unlock();
1144 tbm_bo_get_flags(tbm_bo bo)
1148 _tbm_bufmgr_mutex_lock();
1150 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1154 TBM_TRACE_BO("bo(%p)\n", bo);
1156 _tbm_bufmgr_mutex_unlock();
1161 /* LCOV_EXCL_START */
1162 /* internal function */
1164 _tbm_bo_set_surface(tbm_bo bo, tbm_surface_h surface)
1166 _tbm_bufmgr_mutex_lock();
1168 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1170 bo->surface = surface;
1172 _tbm_bufmgr_mutex_unlock();
1178 _tbm_bo_free(tbm_bo bo)
1180 /* destory the user_data_list */
1181 if (!LIST_IS_EMPTY(&bo->user_data_list)) {
1182 tbm_user_data *old_data = NULL, *tmp;
1184 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp,
1185 &bo->user_data_list, item_link) {
1186 TBM_DBG("free user_data\n");
1187 user_data_delete(old_data);
1191 while (bo->lock_cnt > 0) {
1192 TBM_ERR("error lock_cnt:%d\n", bo->lock_cnt);
1197 /* call the bo_free */
1198 if (bo->bufmgr->use_hal_tbm) {
1199 // call hal_tbm_bo_free when bo is created by tbm_bo_alloc api.
1200 if (!bo->get_from_hal_surface) {
1201 bo->get_from_hal_surface = 0;
1203 hal_tbm_bo_free(bo->bo_data);
1206 } else if (bo->bufmgr->backend_module_data) {
1207 bo->bufmgr->bo_func->bo_free(bo->bo_data);
1210 bo->bufmgr->backend->bo_free(bo);
1218 /* LCOV_EXCL_STOP */