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_set_last_result(*error);
436 _tbm_bo_init(bufmgr, bo, flags);
438 _tbm_bufmgr_mutex_unlock();
445 _tbm_bufmgr_mutex_unlock();
451 tbm_bo_alloc_with_bo_data(tbm_bufmgr bufmgr, tbm_backend_bo_data *bo_data, int flags)
453 tbm_bo bo, bo2 = NULL;
455 _tbm_bufmgr_mutex_lock();
456 _tbm_set_last_result(TBM_ERROR_NONE);
458 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
459 TBM_BO_RETURN_VAL_IF_FAIL(bo_data, NULL);
461 // return an existed bo if the bo is already created with the same bo_data.
462 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
463 LIST_FOR_EACH_ENTRY(bo2, &bufmgr->bo_list, item_link) {
464 if (bo2->bo_data == bo_data) {
465 TBM_ERR("find bo(%p) ref(%d) flag(%s) in list\n",
466 bo2, bo2->ref_cnt, _tbm_flag_to_str(bo2->flags));
468 _tbm_bufmgr_mutex_unlock();
474 bo = calloc(1, sizeof(struct _tbm_bo));
476 /* LCOV_EXCL_START */
477 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
478 _tbm_bufmgr_mutex_unlock();
483 _tbm_util_check_bo_cnt(bufmgr);
485 bo->get_from_hal_surface = 1;
486 bo->bo_data = bo_data;
488 _tbm_bo_init(bufmgr, bo, flags);
490 TBM_TRACE_BO("bo(%p) refcnt(%d), flag(%s)\n", bo, bo->ref_cnt, _tbm_flag_to_str(bo->flags));
492 _tbm_bufmgr_mutex_unlock();
500 tbm_bo_ref(tbm_bo bo)
502 _tbm_bufmgr_mutex_lock();
503 _tbm_set_last_result(TBM_ERROR_NONE);
505 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), NULL);
509 TBM_TRACE_BO("bo(%p) ref_cnt(%d)\n", bo, bo->ref_cnt);
511 _tbm_bufmgr_mutex_unlock();
517 tbm_bo_unref(tbm_bo bo)
519 _tbm_bufmgr_mutex_lock();
520 _tbm_set_last_result(TBM_ERROR_NONE);
522 TBM_BO_RETURN_IF_FAIL(_tbm_bo_is_valid(bo));
524 TBM_TRACE_BO("bo(%p) ref_cnt(%d)\n", bo, bo->ref_cnt - 1);
526 if (bo->ref_cnt <= 0) {
527 _tbm_bufmgr_mutex_unlock();
532 if (bo->ref_cnt == 0)
535 _tbm_bufmgr_mutex_unlock();
539 tbm_bo_map(tbm_bo bo, int device, int opt)
541 tbm_bo_handle bo_handle;
544 _tbm_bufmgr_mutex_lock();
545 _tbm_set_last_result(TBM_ERROR_NONE);
547 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) NULL);
549 if (!_tbm_bo_lock(bo, device, opt)) {
550 TBM_ERR("error: fail to lock bo:%p)\n", bo);
551 _tbm_bufmgr_mutex_unlock();
552 return (tbm_bo_handle) NULL;
555 if (bo->bufmgr->use_hal_tbm) {
556 hal_tbm_bo_handle hbo_handle;
557 hbo_handle = hal_tbm_bo_map((hal_tbm_bo *)bo->bo_data, device, opt, (hal_tbm_error *)&error);
558 if (hbo_handle.ptr == NULL) {
559 /* LCOV_EXCL_START */
560 _tbm_set_last_result(error);
561 TBM_ERR("error: bo(%p) bo_handle(%p) error(%d)\n", bo, hbo_handle.ptr, error);
565 memcpy(&bo_handle.ptr, &hbo_handle.ptr, sizeof(tbm_bo_handle));
566 } else if (bo->bufmgr->backend_module_data) {
567 bo_handle = bo->bufmgr->bo_func->bo_map(bo->bo_data, device, opt, &error);
568 if (bo_handle.ptr == NULL) {
569 /* LCOV_EXCL_START */
570 _tbm_set_last_result(error);
571 TBM_ERR("error: fail to map bo:%p error:%d\n", bo, error);
576 bo_handle = bo->bufmgr->backend->bo_map(bo, device, opt);
577 if (bo_handle.ptr == NULL) {
578 /* LCOV_EXCL_START */
579 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
580 TBM_ERR("error: fail to map bo:%p\n", bo);
586 /* increase the map_count */
589 TBM_TRACE_BO("bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
591 _tbm_bufmgr_mutex_unlock();
597 _tbm_bufmgr_mutex_unlock();
598 return (tbm_bo_handle) NULL;
602 tbm_bo_unmap(tbm_bo bo)
607 _tbm_bufmgr_mutex_lock();
608 _tbm_set_last_result(TBM_ERROR_NONE);
610 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
611 TBM_BO_RETURN_VAL_IF_FAIL(bo->map_cnt > 0, 0);
613 if (bo->bufmgr->use_hal_tbm) {
614 error = (hal_tbm_error)hal_tbm_bo_unmap((hal_tbm_bo *)bo->bo_data);
615 if (error != TBM_ERROR_NONE) {
616 /* LCOV_EXCL_START */
617 TBM_ERR("error: bo(%p) map_cnt(%d) error(%d)\n", bo, bo->map_cnt, error);
618 _tbm_set_last_result(error);
623 } else if (bo->bufmgr->backend_module_data) {
624 error = bo->bufmgr->bo_func->bo_unmap(bo->bo_data);
625 if (error != TBM_ERROR_NONE) {
626 /* LCOV_EXCL_START */
627 TBM_ERR("error: bo(%p) map_cnt(%d) error(%d)\n", bo, bo->map_cnt, error);
628 _tbm_set_last_result(error);
634 ret = bo->bufmgr->backend->bo_unmap(bo);
636 /* LCOV_EXCL_START */
637 TBM_ERR("error: bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
638 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
644 /* decrease the map_count */
647 TBM_TRACE_BO("bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
652 _tbm_bufmgr_mutex_unlock();
658 tbm_bo_get_handle(tbm_bo bo, int device)
660 tbm_bo_handle bo_handle;
663 _tbm_bufmgr_mutex_lock();
664 _tbm_set_last_result(TBM_ERROR_NONE);
666 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) NULL);
668 if (bo->bufmgr->use_hal_tbm) {
669 hal_tbm_bo_handle hbo_handle;
670 hbo_handle = hal_tbm_bo_get_handle((hal_tbm_bo *)bo->bo_data, device, (hal_tbm_error *)&error);
671 if (hbo_handle.ptr == NULL) {
672 /* LCOV_EXCL_START */
673 TBM_ERR("error: bo(%p) bo_handle(%p) error(%d)\n", bo, hbo_handle.ptr, error);
674 _tbm_set_last_result(error);
678 memcpy(&bo_handle.ptr, &hbo_handle.ptr, sizeof(tbm_bo_handle));
679 } else if (bo->bufmgr->backend_module_data) {
680 bo_handle = bo->bufmgr->bo_func->bo_get_handle(bo->bo_data, device, &error);
681 if (bo_handle.ptr == NULL) {
682 /* LCOV_EXCL_START */
683 TBM_ERR("error: bo(%p) bo_handle(%p) error(%d)\n", bo, bo_handle.ptr, error);
684 _tbm_set_last_result(error);
689 bo_handle = bo->bufmgr->backend->bo_get_handle(bo, device);
690 if (bo_handle.ptr == NULL) {
691 /* LCOV_EXCL_START */
692 TBM_ERR("error: bo(%p) bo_handle(%p)\n", bo, bo_handle.ptr);
693 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
699 TBM_TRACE_BO("bo(%p) bo_handle(%p)\n", bo, bo_handle.ptr);
701 _tbm_bufmgr_mutex_unlock();
706 _tbm_bufmgr_mutex_unlock();
707 return (tbm_bo_handle) NULL;
711 tbm_bo_export(tbm_bo bo)
716 _tbm_bufmgr_mutex_lock();
717 _tbm_set_last_result(TBM_ERROR_NONE);
719 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
721 if (bo->bufmgr->use_hal_tbm) {
722 ret = (hal_tbm_key)hal_tbm_bo_export_key((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
724 /* LCOV_EXCL_START */
725 TBM_ERR("error: bo(%p) tbm_key(%d) error(%d)\n", bo, ret, error);
726 _tbm_set_last_result(error);
730 } else if (bo->bufmgr->backend_module_data) {
731 if (!bo->bufmgr->bo_func->bo_export_key) {
732 /* LCOV_EXCL_START */
733 _tbm_bufmgr_mutex_unlock();
734 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
739 ret = bo->bufmgr->bo_func->bo_export_key(bo->bo_data, &error);
741 /* LCOV_EXCL_START */
742 TBM_ERR("error: bo(%p) tbm_key(%d) error(%d)\n", bo, ret, error);
743 _tbm_set_last_result(error);
748 if (!bo->bufmgr->backend->bo_export) {
749 /* LCOV_EXCL_START */
750 _tbm_bufmgr_mutex_unlock();
751 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
756 ret = bo->bufmgr->backend->bo_export(bo);
758 /* LCOV_EXCL_START */
759 TBM_ERR("error: bo(%p) tbm_key(%d)\n", bo, ret);
760 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
766 TBM_TRACE_BO("bo(%p) tbm_key(%u)\n", bo, ret);
769 _tbm_bufmgr_mutex_unlock();
775 tbm_bo_export_fd(tbm_bo bo)
780 _tbm_bufmgr_mutex_lock();
781 _tbm_set_last_result(TBM_ERROR_NONE);
783 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), -1);
785 if (bo->bufmgr->use_hal_tbm) {
786 ret = (hal_tbm_fd)hal_tbm_bo_export_fd((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
788 /* LCOV_EXCL_START */
789 TBM_ERR("error: bo(%p) tbm_fd(%d) error(%d)\n", bo, ret, error);
790 _tbm_set_last_result(error);
794 } else if (bo->bufmgr->backend_module_data) {
795 if (!bo->bufmgr->bo_func->bo_export_fd) {
796 /* LCOV_EXCL_START */
797 _tbm_bufmgr_mutex_unlock();
798 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
803 ret = bo->bufmgr->bo_func->bo_export_fd(bo->bo_data, &error);
805 /* LCOV_EXCL_START */
806 TBM_ERR("error: bo(%p) tbm_fd(%d) error(%d)\n", bo, ret, error);
807 _tbm_set_last_result(error);
812 if (!bo->bufmgr->backend->bo_export_fd) {
813 /* LCOV_EXCL_START */
814 _tbm_bufmgr_mutex_unlock();
815 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
820 ret = bo->bufmgr->backend->bo_export_fd(bo);
822 /* LCOV_EXCL_START */
823 TBM_ERR("error: bo(%p) tbm_fd(%d)\n", bo, ret);
824 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
830 TBM_TRACE_BO("bo(%p) tbm_fd(%d)\n", bo, ret);
833 _tbm_bufmgr_mutex_unlock();
839 tbm_bo_import(tbm_bufmgr bufmgr, unsigned int key)
841 tbm_bo bo, bo2 = NULL;
845 _tbm_bufmgr_mutex_lock();
846 _tbm_set_last_result(TBM_ERROR_NONE);
848 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
850 _tbm_util_check_bo_cnt(bufmgr);
852 bo = calloc(1, sizeof(struct _tbm_bo));
854 /* LCOV_EXCL_START */
855 TBM_ERR("error: fail to import of tbm_bo by key(%d)\n", key);
856 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
857 _tbm_bufmgr_mutex_unlock();
862 bo->bo_data = tbm_module_bufmgr_bo_import_key(bufmgr->module, bo, key, &error);
864 /* LCOV_EXCL_START */
865 TBM_ERR("tbm_module_bufmgr_bo_import_key failed. tbm_key:%d", key);
866 _tbm_set_last_result(error);
867 _tbm_bufmgr_mutex_unlock();
872 // return the existed bo2 if bo->bo_data and bo2->bo_data is the same
873 bo2 = tbm_bufmgr_internal_find_bo(bufmgr, bo);
875 TBM_TRACE_BO("find bo(%p) ref(%d) key(%d) flag(%s) in list",
876 bo2, bo2->ref_cnt, key, _tbm_flag_to_str(bo2->flags));
879 _tbm_bufmgr_mutex_unlock();
883 if (bufmgr->use_hal_tbm) {
884 flags = (tbm_bo_memory_type)hal_tbm_bo_get_memory_types((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
885 if (error != TBM_ERROR_NONE) {
886 TBM_ERR("fail to get the bo flags(memory_types)");
887 _tbm_set_last_result(error);
888 flags = TBM_BO_DEFAULT;
890 } else if (bufmgr->backend_module_data) {
891 flags = bufmgr->bo_func->bo_get_memory_types(bo->bo_data, &error);
892 if (error != TBM_ERROR_NONE) {
893 TBM_ERR("fail to get the bo flags(memory_types)");
894 _tbm_set_last_result(error);
895 flags = TBM_BO_DEFAULT;
898 if (bufmgr->backend->bo_get_flags)
899 flags = bufmgr->backend->bo_get_flags(bo);
901 flags = TBM_BO_DEFAULT;
904 _tbm_bo_init(bufmgr, bo, flags);
906 TBM_TRACE_BO("import new bo(%p) ref(%d) key(%d) flag(%s) in list\n",
907 bo, bo->ref_cnt, key, _tbm_flag_to_str(bo->flags));
909 _tbm_bufmgr_mutex_unlock();
915 tbm_bo_import_fd(tbm_bufmgr bufmgr, tbm_fd fd)
917 tbm_bo bo, bo2 = NULL;
921 _tbm_bufmgr_mutex_lock();
922 _tbm_set_last_result(TBM_ERROR_NONE);
924 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
926 _tbm_util_check_bo_cnt(bufmgr);
928 bo = calloc(1, sizeof(struct _tbm_bo));
930 /* LCOV_EXCL_START */
931 TBM_ERR("error: fail to import tbm_bo by tbm_fd(%d)\n", fd);
932 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
933 _tbm_bufmgr_mutex_unlock();
938 bo->bo_data = tbm_module_bufmgr_bo_import_fd(bufmgr->module, bo, fd, &error);
940 /* LCOV_EXCL_START */
941 TBM_ERR("tbm_module_bufmgr_bo_import_fd failed. tbm_fd:%d", fd);
942 _tbm_set_last_result(error);
943 _tbm_bufmgr_mutex_unlock();
948 // return the existed bo2 if bo->bo_data and bo2->bo_data is the same
949 bo2 = tbm_bufmgr_internal_find_bo(bufmgr, bo);
951 TBM_TRACE_BO("find bo(%p) ref(%d) fd(%d) flag(%s) in list",
952 bo2, bo2->ref_cnt, fd, _tbm_flag_to_str(bo2->flags));
955 _tbm_bufmgr_mutex_unlock();
959 if (bufmgr->use_hal_tbm) {
960 flags = (tbm_bo_memory_type)hal_tbm_bo_get_memory_types((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
961 if (error != TBM_ERROR_NONE) {
962 TBM_ERR("fail to get the bo flags(memory_types)");
963 _tbm_set_last_result(error);
964 flags = TBM_BO_DEFAULT;
966 } else if (bufmgr->backend_module_data) {
967 flags = bufmgr->bo_func->bo_get_memory_types(bo->bo_data, &error);
968 if (error != TBM_ERROR_NONE) {
969 TBM_ERR("fail to get the bo flags(memory_types)");
970 _tbm_set_last_result(error);
971 flags = TBM_BO_DEFAULT;
974 if (bufmgr->backend->bo_get_flags)
975 flags = bufmgr->backend->bo_get_flags(bo);
977 flags = TBM_BO_DEFAULT;
980 _tbm_bo_init(bufmgr, bo, flags);
982 TBM_TRACE_BO("import bo(%p) ref(%d) fd(%d) flag(%s)\n",
983 bo, bo->ref_cnt, fd, _tbm_flag_to_str(bo->flags));
985 _tbm_bufmgr_mutex_unlock();
991 tbm_bo_size(tbm_bo bo)
996 _tbm_bufmgr_mutex_lock();
997 _tbm_set_last_result(TBM_ERROR_NONE);
999 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1001 if (bo->bufmgr->use_hal_tbm) {
1002 size = hal_tbm_bo_get_size((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
1003 if (error != TBM_ERROR_NONE) {
1004 TBM_ERR("fail to get the size of the bo_data(%d).", error);
1005 _tbm_set_last_result(TBM_ERROR_NONE);
1007 } else if (bo->bufmgr->backend_module_data) {
1008 size = bo->bufmgr->bo_func->bo_get_size(bo->bo_data, &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);
1014 size = bo->bufmgr->backend->bo_size(bo);
1016 TBM_TRACE_BO("bo(%p) size(%d)\n", bo, size);
1018 _tbm_bufmgr_mutex_unlock();
1024 tbm_bo_locked(tbm_bo bo)
1026 _tbm_bufmgr_mutex_lock();
1027 _tbm_set_last_result(TBM_ERROR_NONE);
1029 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1031 if (bo->bufmgr->bo_lock_type == TBM_BUFMGR_BO_LOCK_TYPE_NEVER) {
1032 TBM_ERR("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
1033 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1034 _tbm_bufmgr_mutex_unlock();
1038 if (bo->lock_cnt > 0) {
1039 TBM_TRACE_BO("error: bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
1040 _tbm_bufmgr_mutex_unlock();
1044 TBM_TRACE_BO("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
1045 _tbm_bufmgr_mutex_unlock();
1051 tbm_bo_swap(tbm_bo bo1, tbm_bo bo2)
1053 tbm_error_e error1, error2;
1054 int size1 = -1, size2 = -2;
1057 _tbm_bufmgr_mutex_lock();
1058 _tbm_set_last_result(TBM_ERROR_NONE);
1060 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo1), 0);
1061 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo2), 0);
1063 TBM_TRACE_BO("before: bo1(%p) bo2(%p)\n", bo1, bo2);
1065 if (bo1->bufmgr->use_hal_tbm) {
1066 size1 = hal_tbm_bo_get_size((hal_tbm_bo *)bo1->bo_data, (hal_tbm_error *)&error1);
1067 if (error1 != TBM_ERROR_NONE) {
1068 TBM_ERR("fail to get the size of bo1.(%d)", error1);
1069 _tbm_set_last_result(error1);
1072 size2 = hal_tbm_bo_get_size((hal_tbm_bo *)bo2->bo_data, (hal_tbm_error *)&error2);
1073 if (error2 != TBM_ERROR_NONE) {
1074 TBM_ERR("fail to get the size of bo1.(%d)", error2);
1075 _tbm_set_last_result(error2);
1078 } else if (bo1->bufmgr->backend_module_data) {
1079 size1 = bo1->bufmgr->bo_func->bo_get_size(bo1->bo_data, &error1);
1080 if (error1 != TBM_ERROR_NONE) {
1081 TBM_ERR("fail to get the size of bo1.(%d)", error1);
1082 _tbm_set_last_result(error1);
1085 size2 = bo2->bufmgr->bo_func->bo_get_size(bo2->bo_data, &error2);
1086 if (error2 != TBM_ERROR_NONE) {
1087 TBM_ERR("fail to get the size of bo2.(%d)", error2);
1088 _tbm_set_last_result(error2);
1092 size1 = bo1->bufmgr->backend->bo_size(bo1);
1093 size2 = bo2->bufmgr->backend->bo_size(bo2);
1096 if (size1 != size2) {
1097 TBM_ERR("error: bo1 size(%d) and bo2 size(%d) is different.", size1, size2);
1098 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1102 TBM_TRACE_BO("after: bo1(%p) bo2(%p)\n", bo1, bo2);
1105 bo1->priv = bo2->priv;
1108 _tbm_bufmgr_mutex_unlock();
1113 TBM_ERR("error: bo1(%p) bo2(%p)\n", bo1, bo2);
1114 _tbm_bufmgr_mutex_unlock();
1120 tbm_bo_add_user_data(tbm_bo bo, unsigned long key,
1121 tbm_data_free data_free_func)
1123 tbm_user_data *data;
1125 _tbm_bufmgr_mutex_lock();
1126 _tbm_set_last_result(TBM_ERROR_NONE);
1128 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1130 /* check if the data according to the key exist if so, return false. */
1131 data = user_data_lookup(&bo->user_data_list, key);
1133 TBM_TRACE_BO("warning: user data already exist key(%ld)\n", key);
1134 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1135 _tbm_bufmgr_mutex_unlock();
1139 data = user_data_create(key, data_free_func);
1141 TBM_ERR("error: bo(%p) key(%lu)\n", bo, key);
1142 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1143 _tbm_bufmgr_mutex_unlock();
1147 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, data->data);
1149 LIST_ADD(&data->item_link, &bo->user_data_list);
1151 _tbm_bufmgr_mutex_unlock();
1157 tbm_bo_delete_user_data(tbm_bo bo, unsigned long key)
1159 tbm_user_data *old_data;
1161 _tbm_bufmgr_mutex_lock();
1162 _tbm_set_last_result(TBM_ERROR_NONE);
1164 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1166 if (LIST_IS_EMPTY(&bo->user_data_list)) {
1167 TBM_TRACE_BO("bo(%p) key(%lu)\n", bo, key);
1168 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1169 _tbm_bufmgr_mutex_unlock();
1173 old_data = user_data_lookup(&bo->user_data_list, key);
1175 TBM_TRACE_BO("bo(%p) key(%lu)\n", bo, key);
1176 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1177 _tbm_bufmgr_mutex_unlock();
1181 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1183 user_data_delete(old_data);
1185 _tbm_bufmgr_mutex_unlock();
1191 tbm_bo_set_user_data(tbm_bo bo, unsigned long key, void *data)
1193 tbm_user_data *old_data;
1195 _tbm_bufmgr_mutex_lock();
1196 _tbm_set_last_result(TBM_ERROR_NONE);
1198 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1200 if (LIST_IS_EMPTY(&bo->user_data_list)) {
1201 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1202 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1203 _tbm_bufmgr_mutex_unlock();
1207 old_data = user_data_lookup(&bo->user_data_list, key);
1209 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1210 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1211 _tbm_bufmgr_mutex_unlock();
1215 if (old_data->data && old_data->free_func)
1216 old_data->free_func(old_data->data);
1217 old_data->data = data;
1219 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1221 _tbm_bufmgr_mutex_unlock();
1227 tbm_bo_get_user_data(tbm_bo bo, unsigned long key, void **data)
1229 tbm_user_data *old_data;
1231 _tbm_bufmgr_mutex_lock();
1232 _tbm_set_last_result(TBM_ERROR_NONE);
1234 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1236 if (!data || LIST_IS_EMPTY(&bo->user_data_list)) {
1237 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1238 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1239 _tbm_bufmgr_mutex_unlock();
1243 old_data = user_data_lookup(&bo->user_data_list, key);
1246 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1247 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1248 _tbm_bufmgr_mutex_unlock();
1252 *data = old_data->data;
1254 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1256 _tbm_bufmgr_mutex_unlock();
1262 tbm_bo_get_flags(tbm_bo bo)
1266 _tbm_bufmgr_mutex_lock();
1268 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1272 TBM_TRACE_BO("bo(%p)\n", bo);
1274 _tbm_bufmgr_mutex_unlock();
1279 /* LCOV_EXCL_START */
1280 /* internal function */
1282 _tbm_bo_set_surface(tbm_bo bo, tbm_surface_h surface)
1284 _tbm_bufmgr_mutex_lock();
1286 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1288 bo->surface = surface;
1290 _tbm_bufmgr_mutex_unlock();
1296 _tbm_bo_free(tbm_bo bo)
1298 /* destory the user_data_list */
1299 if (!LIST_IS_EMPTY(&bo->user_data_list)) {
1300 tbm_user_data *old_data = NULL, *tmp;
1302 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp,
1303 &bo->user_data_list, item_link) {
1304 TBM_DBG("free user_data\n");
1305 user_data_delete(old_data);
1309 while (bo->lock_cnt > 0) {
1310 TBM_ERR("error lock_cnt:%d\n", bo->lock_cnt);
1315 /* call the bo_free */
1316 if (bo->bufmgr->use_hal_tbm) {
1317 // call hal_tbm_bo_free when bo is created by tbm_bo_alloc api.
1318 if (!bo->get_from_hal_surface) {
1319 bo->get_from_hal_surface = 0;
1321 hal_tbm_bo_free(bo->bo_data);
1324 } else if (bo->bufmgr->backend_module_data) {
1325 bo->bufmgr->bo_func->bo_free(bo->bo_data);
1328 bo->bufmgr->backend->bo_free(bo);
1336 /* LCOV_EXCL_STOP */