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 #define TBM_BO_MAGIC 0xBF011234
40 #define TBM_BO_RETURN_IF_FAIL(cond) {\
42 TBM_ERR("'%s' failed.\n", #cond);\
43 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
44 _tbm_bufmgr_mutex_unlock();\
49 #define TBM_BO_RETURN_VAL_IF_FAIL(cond, val) {\
51 TBM_ERR("'%s' failed.\n", #cond);\
52 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
53 _tbm_bufmgr_mutex_unlock();\
59 _tbm_flag_to_str(int f)
63 if (f == TBM_BO_DEFAULT)
64 snprintf(str, 255, "DEFAULT");
68 if (f & TBM_BO_SCANOUT)
69 c += snprintf(&str[c], 255-c, "SCANOUT");
71 if (f & TBM_BO_NONCACHABLE) {
72 if (c >= 0 && c < 255)
73 c += snprintf(&str[c], 255-c, ", ");
75 if (c >= 0 && c < 255)
76 c += snprintf(&str[c], 255-c, "NONCACHABLE,");
80 if (c >= 0 && c < 255)
81 c += snprintf(&str[c], 255-c, ", ");
83 if (c >= 0 && c < 255)
84 c += snprintf(&str[c], 255-c, "WC");
92 _tbm_util_check_bo_cnt(tbm_bufmgr bufmgr)
94 static int last_chk_bo_cnt = 0;
96 if ((bufmgr->bo_cnt >= 500) && ((bufmgr->bo_cnt % 20) == 0) &&
97 (bufmgr->bo_cnt > last_chk_bo_cnt)) {
98 TBM_DBG("============TBM BO CNT DEBUG: bo_cnt=%d\n", bufmgr->bo_cnt);
99 tbm_bufmgr_debug_show(bufmgr);
100 last_chk_bo_cnt = bufmgr->bo_cnt;
106 user_data_lookup(struct list_head *user_data_list, unsigned long key)
108 tbm_user_data *old_data = NULL;
110 if (LIST_IS_EMPTY(user_data_list))
113 LIST_FOR_EACH_ENTRY(old_data, user_data_list, item_link) {
114 if (old_data->key == key)
122 user_data_create(unsigned long key, tbm_data_free data_free_func)
124 tbm_user_data *user_data;
126 user_data = calloc(1, sizeof(tbm_user_data));
128 /* LCOV_EXCL_START */
129 TBM_ERR("fail to allocate an user_date\n");
130 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
135 user_data->key = key;
136 user_data->free_func = data_free_func;
142 user_data_delete(tbm_user_data *user_data)
144 if (user_data->data && user_data->free_func)
145 user_data->free_func(user_data->data);
147 LIST_DEL(&user_data->item_link);
153 _bo_lock(tbm_bo bo, int device, int opt)
158 if (bo->bufmgr->use_hal_tbm) {
159 error = (tbm_error_e)hal_tbm_bo_lock((hal_tbm_bo *)bo->bo_data, device, opt);
160 if (error == TBM_ERROR_NOT_SUPPORTED) {
161 _tbm_set_last_result(TBM_ERROR_NONE);
163 if (error != TBM_ERROR_NONE) {
164 TBM_WRN("fail to lock");
165 _tbm_set_last_result(error);
169 } else if (bo->bufmgr->backend_module_data) {
170 if (bo->bufmgr->bo_func->bo_lock) {
171 error = bo->bufmgr->bo_func->bo_lock(bo->bo_data, device, opt);
172 if (error != TBM_ERROR_NONE) {
173 TBM_WRN("fail to lock");
174 _tbm_set_last_result(error);
179 if (bo->bufmgr->backend->bo_lock) {
180 ret = bo->bufmgr->backend->bo_lock(bo, device, opt);
182 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
190 _bo_unlock(tbm_bo bo)
194 if (bo->bufmgr->use_hal_tbm) {
195 error = (tbm_error_e)hal_tbm_bo_unlock((hal_tbm_bo *)bo->bo_data);
196 if (error == TBM_ERROR_NOT_SUPPORTED) {
197 _tbm_set_last_result(TBM_ERROR_NONE);
199 if (error != TBM_ERROR_NONE) {
200 TBM_WRN("fail to lock");
201 _tbm_set_last_result(error);
204 } else if (bo->bufmgr->backend_module_data) {
205 if (bo->bufmgr->bo_func->bo_unlock) {
206 error = bo->bufmgr->bo_func->bo_unlock(bo->bo_data);
207 if (error != TBM_ERROR_NONE) {
208 TBM_WRN("fail to unlock");
209 _tbm_set_last_result(error);
213 if (bo->bufmgr->backend->bo_unlock)
214 bo->bufmgr->backend->bo_unlock(bo);
219 _tbm_bo_lock(tbm_bo bo, int device, int opt)
226 /* do not try to lock the bo */
227 if (bo->bufmgr->bo_lock_type == TBM_BUFMGR_BO_LOCK_TYPE_NEVER)
230 if (bo->lock_cnt < 0) {
231 TBM_ERR("error bo:%p LOCK_CNT=%d\n",
238 switch (bo->bufmgr->bo_lock_type) {
239 case TBM_BUFMGR_BO_LOCK_TYPE_ONCE:
240 if (bo->lock_cnt == 0) {
241 _tbm_bufmgr_mutex_unlock();
242 ret = _bo_lock(bo, device, opt);
243 _tbm_bufmgr_mutex_lock();
249 case TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS:
250 _tbm_bufmgr_mutex_unlock();
251 ret = _bo_lock(bo, device, opt);
252 _tbm_bufmgr_mutex_lock();
257 TBM_ERR("error bo:%p bo_lock_type[%d] is wrong.\n",
258 bo, bo->bufmgr->bo_lock_type);
263 TBM_DBG(">> LOCK bo:%p(%d->%d)\n", bo, old, bo->lock_cnt);
269 _tbm_bo_unlock(tbm_bo bo)
273 /* do not try to unlock the bo */
274 if (bo->bufmgr->bo_lock_type == TBM_BUFMGR_BO_LOCK_TYPE_NEVER)
279 switch (bo->bufmgr->bo_lock_type) {
280 case TBM_BUFMGR_BO_LOCK_TYPE_ONCE:
281 if (bo->lock_cnt > 0) {
283 if (bo->lock_cnt == 0)
287 case TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS:
288 if (bo->lock_cnt > 0) {
294 TBM_ERR("error bo:%p bo_lock_type[%d] is wrong.\n",
295 bo, bo->bufmgr->bo_lock_type);
299 if (bo->lock_cnt < 0)
302 TBM_DBG(">> UNLOCK bo:%p(%d->%d)\n", bo, old, bo->lock_cnt);
306 _tbm_bo_magic_check(tbm_bo bo)
308 if (bo->magic != TBM_BO_MAGIC)
315 _tbm_bo_is_valid(tbm_bo bo)
318 TBM_ERR("error: bo is NULL.\n");
322 if (!_tbm_bo_magic_check(bo)) {
323 TBM_ERR("error: No valid bo(%p).\n", bo);
331 _tbm_bo_init(tbm_bufmgr bufmgr, tbm_bo bo, int flags)
335 bo->magic = TBM_BO_MAGIC;
338 LIST_INITHEAD(&bo->user_data_list);
341 LIST_ADD(&bo->item_link, &bufmgr->bo_list);
345 _tbm_bo_deinit(tbm_bo bo)
349 bo->bufmgr->bo_cnt--;
350 LIST_DEL(&bo->item_link);
354 tbm_bo_alloc(tbm_bufmgr bufmgr, int size, int flags)
357 tbm_backend_bo_data *bo_data;
360 _tbm_bufmgr_mutex_lock();
361 _tbm_set_last_result(TBM_ERROR_NONE);
363 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
364 TBM_BO_RETURN_VAL_IF_FAIL(size > 0, NULL);
366 bo = calloc(1, sizeof(struct _tbm_bo));
368 /* LCOV_EXCL_START */
369 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
370 _tbm_bufmgr_mutex_unlock();
375 _tbm_util_check_bo_cnt(bufmgr);
377 bo_data = tbm_module_bufmgr_bo_alloc(bufmgr->module, bo, size, flags, &error);
378 if (!bo_data || error != TBM_ERROR_NONE) {
379 /* LCOV_EXCL_START */
380 TBM_ERR("tbm_module_bufmgr_bo_alloc failed. error:%d", error);
381 _tbm_set_last_result(error);
385 bo->bo_data = bo_data;
386 bo->priv = (void *)bo_data; // TODO: this will be DEPRECATED.
388 _tbm_bo_init(bufmgr, bo, flags);
390 TBM_TRACE_BO("bo(%p) size(%d) refcnt(%d), flag(%s)\n", bo, size, bo->ref_cnt,
391 _tbm_flag_to_str(bo->flags));
393 _tbm_bufmgr_mutex_unlock();
398 TBM_ERR("error: fail to create of tbm_bo size(%d) flag(%s)\n", size, _tbm_flag_to_str(flags));
400 _tbm_bufmgr_mutex_unlock();
404 /* LCOV_EXCL_START */
406 tbm_bo_alloc_with_format(tbm_bufmgr bufmgr, int format, int bo_idx, int width,
407 int height, int bpp, tbm_bo_memory_type flags, tbm_error_e *error)
411 _tbm_bufmgr_mutex_lock();
412 _tbm_set_last_result(TBM_ERROR_NONE);
414 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
416 bo = calloc(1, sizeof(struct _tbm_bo));
418 /* LCOV_EXCL_START */
419 TBM_ERR("error: fail to tbm_bo_alloc_with_format fmt(%s) idx(%d) w(%d) h(%d) mem_types(%s)\n",
420 FOURCC_STR(format), bo_idx, width, height, _tbm_flag_to_str(flags));
421 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
426 _tbm_util_check_bo_cnt(bufmgr);
428 bo->bo_data = tbm_module_bufmgr_bo_alloc_with_format(bufmgr->module, format, bo_idx, width, height, bpp, flags, error);
430 /* LCOV_EXCL_START */
431 TBM_ERR("tbm_module_bufmgr_bo_alloc_with_format failed. fmt:%d idx:%d wxh:%dx%d mem_types:%s\n",
432 format, bo_idx, width, height, _tbm_flag_to_str(flags));
433 _tbm_set_last_result(*error);
438 _tbm_bo_init(bufmgr, bo, flags);
440 _tbm_bufmgr_mutex_unlock();
447 _tbm_bufmgr_mutex_unlock();
453 tbm_bo_alloc_with_bo_data(tbm_bufmgr bufmgr, tbm_backend_bo_data *bo_data, int flags)
455 tbm_bo bo, bo2 = NULL;
457 _tbm_bufmgr_mutex_lock();
458 _tbm_set_last_result(TBM_ERROR_NONE);
460 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
461 TBM_BO_RETURN_VAL_IF_FAIL(bo_data, NULL);
463 // return an existed bo if the bo is already created with the same bo_data.
464 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
465 LIST_FOR_EACH_ENTRY(bo2, &bufmgr->bo_list, item_link) {
466 if (bo2->bo_data == bo_data) {
467 TBM_ERR("find bo(%p) ref(%d) flag(%s) in list\n",
468 bo2, bo2->ref_cnt, _tbm_flag_to_str(bo2->flags));
470 _tbm_bufmgr_mutex_unlock();
476 bo = calloc(1, sizeof(struct _tbm_bo));
478 /* LCOV_EXCL_START */
479 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
480 _tbm_bufmgr_mutex_unlock();
485 _tbm_util_check_bo_cnt(bufmgr);
487 bo->get_from_hal_surface = 1;
488 bo->bo_data = bo_data;
490 _tbm_bo_init(bufmgr, bo, flags);
492 TBM_TRACE_BO("bo(%p) refcnt(%d), flag(%s)\n", bo, bo->ref_cnt, _tbm_flag_to_str(bo->flags));
494 _tbm_bufmgr_mutex_unlock();
502 tbm_bo_ref(tbm_bo bo)
504 _tbm_bufmgr_mutex_lock();
505 _tbm_set_last_result(TBM_ERROR_NONE);
507 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), NULL);
511 TBM_TRACE_BO("bo(%p) ref_cnt(%d)\n", bo, bo->ref_cnt);
513 _tbm_bufmgr_mutex_unlock();
519 tbm_bo_unref(tbm_bo bo)
521 _tbm_bufmgr_mutex_lock();
522 _tbm_set_last_result(TBM_ERROR_NONE);
524 TBM_BO_RETURN_IF_FAIL(_tbm_bo_is_valid(bo));
526 TBM_TRACE_BO("bo(%p) ref_cnt(%d)\n", bo, bo->ref_cnt - 1);
528 if (bo->ref_cnt <= 0) {
529 _tbm_bufmgr_mutex_unlock();
534 if (bo->ref_cnt == 0)
537 _tbm_bufmgr_mutex_unlock();
541 tbm_bo_map(tbm_bo bo, int device, int opt)
543 tbm_bo_handle bo_handle;
546 _tbm_bufmgr_mutex_lock();
547 _tbm_set_last_result(TBM_ERROR_NONE);
549 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) NULL);
551 if (!_tbm_bo_lock(bo, device, opt)) {
552 TBM_ERR("error: fail to lock bo:%p)\n", bo);
553 _tbm_bufmgr_mutex_unlock();
554 return (tbm_bo_handle) NULL;
557 if (bo->bufmgr->use_hal_tbm) {
558 hal_tbm_bo_handle hbo_handle;
559 hbo_handle = hal_tbm_bo_map((hal_tbm_bo *)bo->bo_data, device, opt, (hal_tbm_error *)&error);
560 if (hbo_handle.ptr == NULL) {
561 /* LCOV_EXCL_START */
562 _tbm_set_last_result(error);
563 TBM_ERR("error: bo(%p) bo_handle(%p) error(%d)\n", bo, hbo_handle.ptr, error);
567 memcpy(&bo_handle.ptr, &hbo_handle.ptr, sizeof(tbm_bo_handle));
568 } else if (bo->bufmgr->backend_module_data) {
569 bo_handle = bo->bufmgr->bo_func->bo_map(bo->bo_data, device, opt, &error);
570 if (bo_handle.ptr == NULL) {
571 /* LCOV_EXCL_START */
572 _tbm_set_last_result(error);
573 TBM_ERR("error: fail to map bo:%p error:%d\n", bo, error);
578 bo_handle = bo->bufmgr->backend->bo_map(bo, device, opt);
579 if (bo_handle.ptr == NULL) {
580 /* LCOV_EXCL_START */
581 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
582 TBM_ERR("error: fail to map bo:%p\n", bo);
588 /* increase the map_count */
591 TBM_TRACE_BO("bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
593 _tbm_bufmgr_mutex_unlock();
599 _tbm_bufmgr_mutex_unlock();
600 return (tbm_bo_handle) NULL;
604 tbm_bo_unmap(tbm_bo bo)
609 _tbm_bufmgr_mutex_lock();
610 _tbm_set_last_result(TBM_ERROR_NONE);
612 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
613 TBM_BO_RETURN_VAL_IF_FAIL(bo->map_cnt > 0, 0);
615 if (bo->bufmgr->use_hal_tbm) {
616 error = (hal_tbm_error)hal_tbm_bo_unmap((hal_tbm_bo *)bo->bo_data);
617 if (error != TBM_ERROR_NONE) {
618 /* LCOV_EXCL_START */
619 TBM_ERR("error: bo(%p) map_cnt(%d) error(%d)\n", bo, bo->map_cnt, error);
620 _tbm_set_last_result(error);
625 } else if (bo->bufmgr->backend_module_data) {
626 error = bo->bufmgr->bo_func->bo_unmap(bo->bo_data);
627 if (error != TBM_ERROR_NONE) {
628 /* LCOV_EXCL_START */
629 TBM_ERR("error: bo(%p) map_cnt(%d) error(%d)\n", bo, bo->map_cnt, error);
630 _tbm_set_last_result(error);
636 ret = bo->bufmgr->backend->bo_unmap(bo);
638 /* LCOV_EXCL_START */
639 TBM_ERR("error: bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
640 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
646 /* decrease the map_count */
649 TBM_TRACE_BO("bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
654 _tbm_bufmgr_mutex_unlock();
660 tbm_bo_get_handle(tbm_bo bo, int device)
662 tbm_bo_handle bo_handle;
665 _tbm_bufmgr_mutex_lock();
666 _tbm_set_last_result(TBM_ERROR_NONE);
668 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) NULL);
670 if (bo->bufmgr->use_hal_tbm) {
671 hal_tbm_bo_handle hbo_handle;
672 hbo_handle = hal_tbm_bo_get_handle((hal_tbm_bo *)bo->bo_data, device, (hal_tbm_error *)&error);
673 if (hbo_handle.ptr == NULL) {
674 /* LCOV_EXCL_START */
675 TBM_ERR("error: bo(%p) bo_handle(%p) error(%d)\n", bo, hbo_handle.ptr, error);
676 _tbm_set_last_result(error);
680 memcpy(&bo_handle.ptr, &hbo_handle.ptr, sizeof(tbm_bo_handle));
681 } else if (bo->bufmgr->backend_module_data) {
682 bo_handle = bo->bufmgr->bo_func->bo_get_handle(bo->bo_data, device, &error);
683 if (bo_handle.ptr == NULL) {
684 /* LCOV_EXCL_START */
685 TBM_ERR("error: bo(%p) bo_handle(%p) error(%d)\n", bo, bo_handle.ptr, error);
686 _tbm_set_last_result(error);
691 bo_handle = bo->bufmgr->backend->bo_get_handle(bo, device);
692 if (bo_handle.ptr == NULL) {
693 /* LCOV_EXCL_START */
694 TBM_ERR("error: bo(%p) bo_handle(%p)\n", bo, bo_handle.ptr);
695 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
701 TBM_TRACE_BO("bo(%p) bo_handle(%p)\n", bo, bo_handle.ptr);
703 _tbm_bufmgr_mutex_unlock();
708 _tbm_bufmgr_mutex_unlock();
709 return (tbm_bo_handle) NULL;
713 tbm_bo_export(tbm_bo bo)
718 _tbm_bufmgr_mutex_lock();
719 _tbm_set_last_result(TBM_ERROR_NONE);
721 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
723 if (bo->bufmgr->use_hal_tbm) {
724 ret = (hal_tbm_key)hal_tbm_bo_export_key((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
726 /* LCOV_EXCL_START */
727 TBM_ERR("error: bo(%p) tbm_key(%d) error(%d)\n", bo, ret, error);
728 _tbm_set_last_result(error);
732 } else if (bo->bufmgr->backend_module_data) {
733 if (!bo->bufmgr->bo_func->bo_export_key) {
734 /* LCOV_EXCL_START */
735 _tbm_bufmgr_mutex_unlock();
736 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
741 ret = bo->bufmgr->bo_func->bo_export_key(bo->bo_data, &error);
743 /* LCOV_EXCL_START */
744 TBM_ERR("error: bo(%p) tbm_key(%d) error(%d)\n", bo, ret, error);
745 _tbm_set_last_result(error);
750 if (!bo->bufmgr->backend->bo_export) {
751 /* LCOV_EXCL_START */
752 _tbm_bufmgr_mutex_unlock();
753 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
758 ret = bo->bufmgr->backend->bo_export(bo);
760 /* LCOV_EXCL_START */
761 TBM_ERR("error: bo(%p) tbm_key(%d)\n", bo, ret);
762 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
768 TBM_TRACE_BO("bo(%p) tbm_key(%u)\n", bo, ret);
771 _tbm_bufmgr_mutex_unlock();
777 tbm_bo_export_fd(tbm_bo bo)
782 _tbm_bufmgr_mutex_lock();
783 _tbm_set_last_result(TBM_ERROR_NONE);
785 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), -1);
787 if (bo->bufmgr->use_hal_tbm) {
788 ret = (hal_tbm_fd)hal_tbm_bo_export_fd((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
790 /* LCOV_EXCL_START */
791 TBM_ERR("error: bo(%p) tbm_fd(%d) error(%d)\n", bo, ret, error);
792 _tbm_set_last_result(error);
796 } else if (bo->bufmgr->backend_module_data) {
797 if (!bo->bufmgr->bo_func->bo_export_fd) {
798 /* LCOV_EXCL_START */
799 _tbm_bufmgr_mutex_unlock();
800 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
805 ret = bo->bufmgr->bo_func->bo_export_fd(bo->bo_data, &error);
807 /* LCOV_EXCL_START */
808 TBM_ERR("error: bo(%p) tbm_fd(%d) error(%d)\n", bo, ret, error);
809 _tbm_set_last_result(error);
814 if (!bo->bufmgr->backend->bo_export_fd) {
815 /* LCOV_EXCL_START */
816 _tbm_bufmgr_mutex_unlock();
817 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
822 ret = bo->bufmgr->backend->bo_export_fd(bo);
824 /* LCOV_EXCL_START */
825 TBM_ERR("error: bo(%p) tbm_fd(%d)\n", bo, ret);
826 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
832 TBM_TRACE_BO("bo(%p) tbm_fd(%d)\n", bo, ret);
835 _tbm_bufmgr_mutex_unlock();
841 tbm_bo_import(tbm_bufmgr bufmgr, unsigned int key)
843 tbm_bo bo, bo2 = NULL;
847 _tbm_bufmgr_mutex_lock();
848 _tbm_set_last_result(TBM_ERROR_NONE);
850 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
852 _tbm_util_check_bo_cnt(bufmgr);
854 bo = calloc(1, sizeof(struct _tbm_bo));
856 /* LCOV_EXCL_START */
857 TBM_ERR("error: fail to import of tbm_bo by key(%d)\n", key);
858 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
859 _tbm_bufmgr_mutex_unlock();
864 bo->bo_data = tbm_module_bufmgr_bo_import_key(bufmgr->module, bo, key, &error);
866 /* LCOV_EXCL_START */
867 TBM_ERR("tbm_module_bufmgr_bo_import_key failed. tbm_key:%d", key);
868 _tbm_set_last_result(error);
869 _tbm_bufmgr_mutex_unlock();
874 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
875 LIST_FOR_EACH_ENTRY(bo2, &bufmgr->bo_list, item_link) {
876 if (bo2->bo_data == bo->bo_data) {
877 TBM_TRACE_BO("find bo(%p) ref(%d) key(%d) flag(%s) in list",
878 bo2, bo2->ref_cnt, key, _tbm_flag_to_str(bo2->flags));
881 _tbm_bufmgr_mutex_unlock();
887 if (bufmgr->use_hal_tbm) {
888 flags = (tbm_bo_memory_type)hal_tbm_bo_get_memory_types((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
889 if (error != TBM_ERROR_NONE) {
890 TBM_ERR("fail to get the bo flags(memory_types)");
891 _tbm_set_last_result(error);
892 flags = TBM_BO_DEFAULT;
894 } else if (bufmgr->backend_module_data) {
895 flags = bufmgr->bo_func->bo_get_memory_types(bo->bo_data, &error);
896 if (error != TBM_ERROR_NONE) {
897 TBM_ERR("fail to get the bo flags(memory_types)");
898 _tbm_set_last_result(error);
899 flags = TBM_BO_DEFAULT;
902 if (bufmgr->backend->bo_get_flags)
903 flags = bufmgr->backend->bo_get_flags(bo);
905 flags = TBM_BO_DEFAULT;
908 _tbm_bo_init(bufmgr, bo, flags);
910 TBM_TRACE_BO("import new bo(%p) ref(%d) key(%d) flag(%s) in list\n",
911 bo, bo->ref_cnt, key, _tbm_flag_to_str(bo->flags));
913 _tbm_bufmgr_mutex_unlock();
919 tbm_bo_import_fd(tbm_bufmgr bufmgr, tbm_fd fd)
921 tbm_bo bo, bo2 = NULL;
925 _tbm_bufmgr_mutex_lock();
926 _tbm_set_last_result(TBM_ERROR_NONE);
928 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
930 _tbm_util_check_bo_cnt(bufmgr);
932 bo = calloc(1, sizeof(struct _tbm_bo));
934 /* LCOV_EXCL_START */
935 TBM_ERR("error: fail to import tbm_bo by tbm_fd(%d)\n", fd);
936 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
937 _tbm_bufmgr_mutex_unlock();
942 bo->bo_data = tbm_module_bufmgr_bo_import_fd(bufmgr->module, bo, fd, &error);
944 /* LCOV_EXCL_START */
945 TBM_ERR("tbm_module_bufmgr_bo_import_fd failed. tbm_fd:%d", fd);
946 _tbm_set_last_result(error);
947 _tbm_bufmgr_mutex_unlock();
952 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
953 LIST_FOR_EACH_ENTRY(bo2, &bufmgr->bo_list, item_link) {
954 if (bo2->bo_data == bo->bo_data) {
955 TBM_TRACE_BO("find bo(%p) ref(%d) fd(%d) flag(%s) in list\n",
956 bo2, bo2->ref_cnt, fd, _tbm_flag_to_str(bo2->flags));
959 _tbm_bufmgr_mutex_unlock();
965 if (bufmgr->use_hal_tbm) {
966 flags = (tbm_bo_memory_type)hal_tbm_bo_get_memory_types((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
967 if (error != TBM_ERROR_NONE) {
968 TBM_ERR("fail to get the bo flags(memory_types)");
969 _tbm_set_last_result(error);
970 flags = TBM_BO_DEFAULT;
972 } else if (bufmgr->backend_module_data) {
973 flags = bufmgr->bo_func->bo_get_memory_types(bo->bo_data, &error);
974 if (error != TBM_ERROR_NONE) {
975 TBM_ERR("fail to get the bo flags(memory_types)");
976 _tbm_set_last_result(error);
977 flags = TBM_BO_DEFAULT;
980 if (bufmgr->backend->bo_get_flags)
981 flags = bufmgr->backend->bo_get_flags(bo);
983 flags = TBM_BO_DEFAULT;
986 _tbm_bo_init(bufmgr, bo, flags);
988 TBM_TRACE_BO("import bo(%p) ref(%d) fd(%d) flag(%s)\n",
989 bo, bo->ref_cnt, fd, _tbm_flag_to_str(bo->flags));
991 _tbm_bufmgr_mutex_unlock();
997 tbm_bo_size(tbm_bo bo)
1002 _tbm_bufmgr_mutex_lock();
1003 _tbm_set_last_result(TBM_ERROR_NONE);
1005 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1007 if (bo->bufmgr->use_hal_tbm) {
1008 size = hal_tbm_bo_get_size((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
1009 if (error != TBM_ERROR_NONE) {
1010 TBM_ERR("fail to get the size of the bo_data(%d).", error);
1011 _tbm_set_last_result(TBM_ERROR_NONE);
1013 } else if (bo->bufmgr->backend_module_data) {
1014 size = bo->bufmgr->bo_func->bo_get_size(bo->bo_data, &error);
1015 if (error != TBM_ERROR_NONE) {
1016 TBM_ERR("fail to get the size of the bo_data(%d).", error);
1017 _tbm_set_last_result(TBM_ERROR_NONE);
1020 size = bo->bufmgr->backend->bo_size(bo);
1022 TBM_TRACE_BO("bo(%p) size(%d)\n", bo, size);
1024 _tbm_bufmgr_mutex_unlock();
1030 tbm_bo_locked(tbm_bo bo)
1032 _tbm_bufmgr_mutex_lock();
1033 _tbm_set_last_result(TBM_ERROR_NONE);
1035 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1037 if (bo->bufmgr->bo_lock_type == TBM_BUFMGR_BO_LOCK_TYPE_NEVER) {
1038 TBM_ERR("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
1039 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1040 _tbm_bufmgr_mutex_unlock();
1044 if (bo->lock_cnt > 0) {
1045 TBM_TRACE_BO("error: bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
1046 _tbm_bufmgr_mutex_unlock();
1050 TBM_TRACE_BO("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
1051 _tbm_bufmgr_mutex_unlock();
1057 tbm_bo_swap(tbm_bo bo1, tbm_bo bo2)
1059 tbm_error_e error1, error2;
1060 int size1 = -1, size2 = -2;
1063 _tbm_bufmgr_mutex_lock();
1064 _tbm_set_last_result(TBM_ERROR_NONE);
1066 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo1), 0);
1067 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo2), 0);
1069 TBM_TRACE_BO("before: bo1(%p) bo2(%p)\n", bo1, bo2);
1071 if (bo1->bufmgr->use_hal_tbm) {
1072 size1 = hal_tbm_bo_get_size((hal_tbm_bo *)bo1->bo_data, (hal_tbm_error *)&error1);
1073 if (error1 != TBM_ERROR_NONE) {
1074 TBM_ERR("fail to get the size of bo1.(%d)", error1);
1075 _tbm_set_last_result(error1);
1078 size2 = hal_tbm_bo_get_size((hal_tbm_bo *)bo2->bo_data, (hal_tbm_error *)&error2);
1079 if (error2 != TBM_ERROR_NONE) {
1080 TBM_ERR("fail to get the size of bo1.(%d)", error2);
1081 _tbm_set_last_result(error2);
1084 } else if (bo1->bufmgr->backend_module_data) {
1085 size1 = bo1->bufmgr->bo_func->bo_get_size(bo1->bo_data, &error1);
1086 if (error1 != TBM_ERROR_NONE) {
1087 TBM_ERR("fail to get the size of bo1.(%d)", error1);
1088 _tbm_set_last_result(error1);
1091 size2 = bo2->bufmgr->bo_func->bo_get_size(bo2->bo_data, &error2);
1092 if (error2 != TBM_ERROR_NONE) {
1093 TBM_ERR("fail to get the size of bo2.(%d)", error2);
1094 _tbm_set_last_result(error2);
1098 size1 = bo1->bufmgr->backend->bo_size(bo1);
1099 size2 = bo2->bufmgr->backend->bo_size(bo2);
1102 if (size1 != size2) {
1103 TBM_ERR("error: bo1 size(%d) and bo2 size(%d) is different.", size1, size2);
1104 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1108 TBM_TRACE_BO("after: bo1(%p) bo2(%p)\n", bo1, bo2);
1111 bo1->priv = bo2->priv;
1114 _tbm_bufmgr_mutex_unlock();
1119 TBM_ERR("error: bo1(%p) bo2(%p)\n", bo1, bo2);
1120 _tbm_bufmgr_mutex_unlock();
1126 tbm_bo_add_user_data(tbm_bo bo, unsigned long key,
1127 tbm_data_free data_free_func)
1129 tbm_user_data *data;
1131 _tbm_bufmgr_mutex_lock();
1132 _tbm_set_last_result(TBM_ERROR_NONE);
1134 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1136 /* check if the data according to the key exist if so, return false. */
1137 data = user_data_lookup(&bo->user_data_list, key);
1139 TBM_TRACE_BO("warning: user data already exist key(%ld)\n", key);
1140 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1141 _tbm_bufmgr_mutex_unlock();
1145 data = user_data_create(key, data_free_func);
1147 TBM_ERR("error: bo(%p) key(%lu)\n", bo, key);
1148 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1149 _tbm_bufmgr_mutex_unlock();
1153 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, data->data);
1155 LIST_ADD(&data->item_link, &bo->user_data_list);
1157 _tbm_bufmgr_mutex_unlock();
1163 tbm_bo_delete_user_data(tbm_bo bo, unsigned long key)
1165 tbm_user_data *old_data;
1167 _tbm_bufmgr_mutex_lock();
1168 _tbm_set_last_result(TBM_ERROR_NONE);
1170 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1172 if (LIST_IS_EMPTY(&bo->user_data_list)) {
1173 TBM_TRACE_BO("bo(%p) key(%lu)\n", bo, key);
1174 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1175 _tbm_bufmgr_mutex_unlock();
1179 old_data = user_data_lookup(&bo->user_data_list, key);
1181 TBM_TRACE_BO("bo(%p) key(%lu)\n", bo, key);
1182 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1183 _tbm_bufmgr_mutex_unlock();
1187 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1189 user_data_delete(old_data);
1191 _tbm_bufmgr_mutex_unlock();
1197 tbm_bo_set_user_data(tbm_bo bo, unsigned long key, void *data)
1199 tbm_user_data *old_data;
1201 _tbm_bufmgr_mutex_lock();
1202 _tbm_set_last_result(TBM_ERROR_NONE);
1204 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1206 if (LIST_IS_EMPTY(&bo->user_data_list)) {
1207 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1208 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1209 _tbm_bufmgr_mutex_unlock();
1213 old_data = user_data_lookup(&bo->user_data_list, key);
1215 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1216 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1217 _tbm_bufmgr_mutex_unlock();
1221 if (old_data->data && old_data->free_func)
1222 old_data->free_func(old_data->data);
1223 old_data->data = data;
1225 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1227 _tbm_bufmgr_mutex_unlock();
1233 tbm_bo_get_user_data(tbm_bo bo, unsigned long key, void **data)
1235 tbm_user_data *old_data;
1237 _tbm_bufmgr_mutex_lock();
1238 _tbm_set_last_result(TBM_ERROR_NONE);
1240 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1242 if (!data || LIST_IS_EMPTY(&bo->user_data_list)) {
1243 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1244 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1245 _tbm_bufmgr_mutex_unlock();
1249 old_data = user_data_lookup(&bo->user_data_list, key);
1252 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1253 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1254 _tbm_bufmgr_mutex_unlock();
1258 *data = old_data->data;
1260 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1262 _tbm_bufmgr_mutex_unlock();
1268 tbm_bo_get_flags(tbm_bo bo)
1272 _tbm_bufmgr_mutex_lock();
1274 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1278 TBM_TRACE_BO("bo(%p)\n", bo);
1280 _tbm_bufmgr_mutex_unlock();
1285 /* LCOV_EXCL_START */
1286 /* internal function */
1288 _tbm_bo_set_surface(tbm_bo bo, tbm_surface_h surface)
1290 _tbm_bufmgr_mutex_lock();
1292 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1294 bo->surface = surface;
1296 _tbm_bufmgr_mutex_unlock();
1302 _tbm_bo_free(tbm_bo bo)
1304 /* destory the user_data_list */
1305 if (!LIST_IS_EMPTY(&bo->user_data_list)) {
1306 tbm_user_data *old_data = NULL, *tmp;
1308 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp,
1309 &bo->user_data_list, item_link) {
1310 TBM_DBG("free user_data\n");
1311 user_data_delete(old_data);
1315 while (bo->lock_cnt > 0) {
1316 TBM_ERR("error lock_cnt:%d\n", bo->lock_cnt);
1321 /* call the bo_free */
1322 if (bo->bufmgr->use_hal_tbm) {
1323 // call hal_tbm_bo_free when bo is created by tbm_bo_alloc api.
1324 if (!bo->get_from_hal_surface) {
1325 bo->get_from_hal_surface = 0;
1327 hal_tbm_bo_free(bo->bo_data);
1330 } else if (bo->bufmgr->backend_module_data) {
1331 bo->bufmgr->bo_func->bo_free(bo->bo_data);
1334 bo->bufmgr->backend->bo_free(bo);
1342 /* LCOV_EXCL_STOP */