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)
847 tbm_backend_bo_data *bo_data;
850 _tbm_bufmgr_mutex_lock();
851 _tbm_set_last_result(TBM_ERROR_NONE);
853 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
855 if (!bufmgr->use_hal_tbm) {
856 if (bufmgr->backend_module_data) {
857 if (!bufmgr->bufmgr_func->bufmgr_import_key) {
858 /* LCOV_EXCL_START */
859 _tbm_bufmgr_mutex_unlock();
860 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
865 if (!bufmgr->backend->bo_import) {
866 /* LCOV_EXCL_START */
867 _tbm_bufmgr_mutex_unlock();
868 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
875 _tbm_util_check_bo_cnt(bufmgr);
877 bo = calloc(1, sizeof(struct _tbm_bo));
879 /* LCOV_EXCL_START */
880 TBM_ERR("error: fail to import of tbm_bo by key(%d)\n", key);
881 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
882 _tbm_bufmgr_mutex_unlock();
887 if (bufmgr->use_hal_tbm) {
888 bo_data = (tbm_backend_bo_data *)hal_tbm_bufmgr_import_key(bufmgr->hal_bufmgr, key, (hal_tbm_error *)&error);
889 /* LCOV_EXCL_START */
891 TBM_ERR("error: fail to import of tbm_bo by key(%d). error(%d)\n", key, error);
892 _tbm_set_last_result(error);
896 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
897 LIST_FOR_EACH_ENTRY(bo2, &bufmgr->bo_list, item_link) {
898 if (bo2->bo_data == bo_data) {
899 TBM_TRACE_BO("find bo(%p) ref(%d) key(%d) flag(%s) in list\n",
900 bo2, bo2->ref_cnt, key,
901 _tbm_flag_to_str(bo2->flags));
904 _tbm_bufmgr_mutex_unlock();
909 bo->bo_data = bo_data;
910 } else if (bufmgr->backend_module_data) {
911 bo_data = bufmgr->bufmgr_func->bufmgr_import_key(bufmgr->bufmgr_data, key, &error);
913 /* LCOV_EXCL_START */
914 TBM_ERR("error: fail to import of tbm_bo by key(%d). error(%d)\n", key, error);
915 _tbm_set_last_result(error);
920 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
921 LIST_FOR_EACH_ENTRY(bo2, &bufmgr->bo_list, item_link) {
922 if (bo2->bo_data == bo_data) {
923 TBM_TRACE_BO("find bo(%p) ref(%d) key(%d) flag(%s) in list\n",
924 bo2, bo2->ref_cnt, key,
925 _tbm_flag_to_str(bo2->flags));
928 _tbm_bufmgr_mutex_unlock();
933 bo->bo_data = bo_data;
935 bo_priv = bufmgr->backend->bo_import(bo, key);
937 /* LCOV_EXCL_START */
938 TBM_ERR("error: fail to import of tbm_bo by key(%d)\n", key);
939 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
944 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
945 LIST_FOR_EACH_ENTRY(bo2, &bufmgr->bo_list, item_link) {
946 if (bo2->priv == bo_priv) {
947 TBM_TRACE_BO("find bo(%p) ref(%d) key(%d) flag(%s) in list\n",
948 bo2, bo2->ref_cnt, key,
949 _tbm_flag_to_str(bo2->flags));
952 _tbm_bufmgr_mutex_unlock();
960 if (bufmgr->use_hal_tbm) {
961 flags = (tbm_bo_memory_type)hal_tbm_bo_get_memory_types((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
962 if (error != TBM_ERROR_NONE) {
963 TBM_ERR("fail to get the bo flags(memory_types)");
964 _tbm_set_last_result(error);
965 flags = TBM_BO_DEFAULT;
967 } else if (bufmgr->backend_module_data) {
968 flags = bufmgr->bo_func->bo_get_memory_types(bo->bo_data, &error);
969 if (error != TBM_ERROR_NONE) {
970 TBM_ERR("fail to get the bo flags(memory_types)");
971 _tbm_set_last_result(error);
972 flags = TBM_BO_DEFAULT;
975 if (bufmgr->backend->bo_get_flags)
976 flags = bufmgr->backend->bo_get_flags(bo);
978 flags = TBM_BO_DEFAULT;
981 _tbm_bo_init(bufmgr, bo, flags);
983 TBM_TRACE_BO("import new bo(%p) ref(%d) key(%d) flag(%s) in list\n",
984 bo, bo->ref_cnt, key, _tbm_flag_to_str(bo->flags));
986 _tbm_bufmgr_mutex_unlock();
992 _tbm_bufmgr_mutex_unlock();
997 tbm_bo_import_fd(tbm_bufmgr bufmgr, tbm_fd fd)
1002 tbm_backend_bo_data *bo_data;
1006 _tbm_bufmgr_mutex_lock();
1007 _tbm_set_last_result(TBM_ERROR_NONE);
1009 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
1011 if (!bufmgr->use_hal_tbm) {
1012 if (bufmgr->backend_module_data) {
1013 if (!bufmgr->bufmgr_func->bufmgr_import_fd) {
1014 /* LCOV_EXCL_START */
1015 _tbm_bufmgr_mutex_unlock();
1016 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
1018 /* LCOV_EXCL_STOP */
1021 if (!bufmgr->backend->bo_import_fd) {
1022 /* LCOV_EXCL_START */
1023 _tbm_bufmgr_mutex_unlock();
1024 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
1026 /* LCOV_EXCL_STOP */
1031 _tbm_util_check_bo_cnt(bufmgr);
1033 bo = calloc(1, sizeof(struct _tbm_bo));
1035 /* LCOV_EXCL_START */
1036 TBM_ERR("error: fail to import tbm_bo by tbm_fd(%d)\n", fd);
1037 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1038 _tbm_bufmgr_mutex_unlock();
1040 /* LCOV_EXCL_STOP */
1043 if (bufmgr->use_hal_tbm) {
1044 bo_data = (tbm_backend_bo_data *)hal_tbm_bufmgr_import_fd(bufmgr->hal_bufmgr, (hal_tbm_fd)fd, (hal_tbm_error *)&error);
1045 /* LCOV_EXCL_START */
1047 TBM_ERR("error: fail to import tbm_bo by tbm_fd(%d). error(%d)\n", fd, error);
1048 _tbm_set_last_result(error);
1051 /* LCOV_EXCL_STOP */
1053 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
1054 LIST_FOR_EACH_ENTRY(bo2, &bufmgr->bo_list, item_link) {
1055 if (bo2->bo_data == bo_data) {
1056 TBM_TRACE_BO("find bo(%p) ref(%d) fd(%d) flag(%s) in list\n",
1057 bo2, bo2->ref_cnt, fd, _tbm_flag_to_str(bo2->flags));
1060 _tbm_bufmgr_mutex_unlock();
1065 bo->bo_data = bo_data;
1066 } else if (bufmgr->backend_module_data) {
1067 bo_data = bufmgr->bufmgr_func->bufmgr_import_fd(bufmgr->bufmgr_data, fd, &error);
1069 /* LCOV_EXCL_START */
1070 TBM_ERR("error: fail to import tbm_bo by tbm_fd(%d). error(%d)\n", fd, error);
1071 _tbm_set_last_result(error);
1073 /* LCOV_EXCL_STOP */
1076 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
1077 LIST_FOR_EACH_ENTRY(bo2, &bufmgr->bo_list, item_link) {
1078 if (bo2->bo_data == bo_data) {
1079 TBM_TRACE_BO("find bo(%p) ref(%d) fd(%d) flag(%s) in list\n",
1080 bo2, bo2->ref_cnt, fd, _tbm_flag_to_str(bo2->flags));
1083 _tbm_bufmgr_mutex_unlock();
1088 bo->bo_data = bo_data;
1090 bo_priv = bufmgr->backend->bo_import_fd(bo, fd);
1092 /* LCOV_EXCL_START */
1093 TBM_ERR("error: fail to import tbm_bo by tbm_fd(%d)\n", fd);
1094 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1096 /* LCOV_EXCL_STOP */
1099 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
1100 LIST_FOR_EACH_ENTRY(bo2, &bufmgr->bo_list, item_link) {
1101 if (bo2->priv == bo_priv) {
1102 TBM_TRACE_BO("find bo(%p) ref(%d) fd(%d) flag(%s) in list\n",
1103 bo2, bo2->ref_cnt, fd, _tbm_flag_to_str(bo2->flags));
1106 _tbm_bufmgr_mutex_unlock();
1114 if (bufmgr->use_hal_tbm) {
1115 flags = (tbm_bo_memory_type)hal_tbm_bo_get_memory_types((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
1116 if (error != TBM_ERROR_NONE) {
1117 TBM_ERR("fail to get the bo flags(memory_types)");
1118 _tbm_set_last_result(error);
1119 flags = TBM_BO_DEFAULT;
1121 } else if (bufmgr->backend_module_data) {
1122 flags = bufmgr->bo_func->bo_get_memory_types(bo->bo_data, &error);
1123 if (error != TBM_ERROR_NONE) {
1124 TBM_ERR("fail to get the bo flags(memory_types)");
1125 _tbm_set_last_result(error);
1126 flags = TBM_BO_DEFAULT;
1129 if (bufmgr->backend->bo_get_flags)
1130 flags = bufmgr->backend->bo_get_flags(bo);
1132 flags = TBM_BO_DEFAULT;
1135 _tbm_bo_init(bufmgr, bo, flags);
1137 TBM_TRACE_BO("import bo(%p) ref(%d) fd(%d) flag(%s)\n",
1138 bo, bo->ref_cnt, fd, _tbm_flag_to_str(bo->flags));
1140 _tbm_bufmgr_mutex_unlock();
1146 _tbm_bufmgr_mutex_unlock();
1151 tbm_bo_size(tbm_bo bo)
1156 _tbm_bufmgr_mutex_lock();
1157 _tbm_set_last_result(TBM_ERROR_NONE);
1159 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1161 if (bo->bufmgr->use_hal_tbm) {
1162 size = hal_tbm_bo_get_size((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
1163 if (error != TBM_ERROR_NONE) {
1164 TBM_ERR("fail to get the size of the bo_data(%d).", error);
1165 _tbm_set_last_result(TBM_ERROR_NONE);
1167 } else if (bo->bufmgr->backend_module_data) {
1168 size = bo->bufmgr->bo_func->bo_get_size(bo->bo_data, &error);
1169 if (error != TBM_ERROR_NONE) {
1170 TBM_ERR("fail to get the size of the bo_data(%d).", error);
1171 _tbm_set_last_result(TBM_ERROR_NONE);
1174 size = bo->bufmgr->backend->bo_size(bo);
1176 TBM_TRACE_BO("bo(%p) size(%d)\n", bo, size);
1178 _tbm_bufmgr_mutex_unlock();
1184 tbm_bo_locked(tbm_bo bo)
1186 _tbm_bufmgr_mutex_lock();
1187 _tbm_set_last_result(TBM_ERROR_NONE);
1189 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1191 if (bo->bufmgr->bo_lock_type == TBM_BUFMGR_BO_LOCK_TYPE_NEVER) {
1192 TBM_ERR("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
1193 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1194 _tbm_bufmgr_mutex_unlock();
1198 if (bo->lock_cnt > 0) {
1199 TBM_TRACE_BO("error: bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
1200 _tbm_bufmgr_mutex_unlock();
1204 TBM_TRACE_BO("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
1205 _tbm_bufmgr_mutex_unlock();
1211 tbm_bo_swap(tbm_bo bo1, tbm_bo bo2)
1213 tbm_error_e error1, error2;
1214 int size1 = -1, size2 = -2;
1217 _tbm_bufmgr_mutex_lock();
1218 _tbm_set_last_result(TBM_ERROR_NONE);
1220 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo1), 0);
1221 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo2), 0);
1223 TBM_TRACE_BO("before: bo1(%p) bo2(%p)\n", bo1, bo2);
1225 if (bo1->bufmgr->use_hal_tbm) {
1226 size1 = hal_tbm_bo_get_size((hal_tbm_bo *)bo1->bo_data, (hal_tbm_error *)&error1);
1227 if (error1 != TBM_ERROR_NONE) {
1228 TBM_ERR("fail to get the size of bo1.(%d)", error1);
1229 _tbm_set_last_result(error1);
1232 size2 = hal_tbm_bo_get_size((hal_tbm_bo *)bo2->bo_data, (hal_tbm_error *)&error2);
1233 if (error2 != TBM_ERROR_NONE) {
1234 TBM_ERR("fail to get the size of bo1.(%d)", error2);
1235 _tbm_set_last_result(error2);
1238 } else if (bo1->bufmgr->backend_module_data) {
1239 size1 = bo1->bufmgr->bo_func->bo_get_size(bo1->bo_data, &error1);
1240 if (error1 != TBM_ERROR_NONE) {
1241 TBM_ERR("fail to get the size of bo1.(%d)", error1);
1242 _tbm_set_last_result(error1);
1245 size2 = bo2->bufmgr->bo_func->bo_get_size(bo2->bo_data, &error2);
1246 if (error2 != TBM_ERROR_NONE) {
1247 TBM_ERR("fail to get the size of bo2.(%d)", error2);
1248 _tbm_set_last_result(error2);
1252 size1 = bo1->bufmgr->backend->bo_size(bo1);
1253 size2 = bo2->bufmgr->backend->bo_size(bo2);
1256 if (size1 != size2) {
1257 TBM_ERR("error: bo1 size(%d) and bo2 size(%d) is different.", size1, size2);
1258 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1262 TBM_TRACE_BO("after: bo1(%p) bo2(%p)\n", bo1, bo2);
1265 bo1->priv = bo2->priv;
1268 _tbm_bufmgr_mutex_unlock();
1273 TBM_ERR("error: bo1(%p) bo2(%p)\n", bo1, bo2);
1274 _tbm_bufmgr_mutex_unlock();
1280 tbm_bo_add_user_data(tbm_bo bo, unsigned long key,
1281 tbm_data_free data_free_func)
1283 tbm_user_data *data;
1285 _tbm_bufmgr_mutex_lock();
1286 _tbm_set_last_result(TBM_ERROR_NONE);
1288 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1290 /* check if the data according to the key exist if so, return false. */
1291 data = user_data_lookup(&bo->user_data_list, key);
1293 TBM_TRACE_BO("warning: user data already exist key(%ld)\n", key);
1294 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1295 _tbm_bufmgr_mutex_unlock();
1299 data = user_data_create(key, data_free_func);
1301 TBM_ERR("error: bo(%p) key(%lu)\n", bo, key);
1302 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1303 _tbm_bufmgr_mutex_unlock();
1307 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, data->data);
1309 LIST_ADD(&data->item_link, &bo->user_data_list);
1311 _tbm_bufmgr_mutex_unlock();
1317 tbm_bo_delete_user_data(tbm_bo bo, unsigned long key)
1319 tbm_user_data *old_data;
1321 _tbm_bufmgr_mutex_lock();
1322 _tbm_set_last_result(TBM_ERROR_NONE);
1324 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1326 if (LIST_IS_EMPTY(&bo->user_data_list)) {
1327 TBM_TRACE_BO("bo(%p) key(%lu)\n", bo, key);
1328 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1329 _tbm_bufmgr_mutex_unlock();
1333 old_data = user_data_lookup(&bo->user_data_list, key);
1335 TBM_TRACE_BO("bo(%p) key(%lu)\n", bo, key);
1336 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1337 _tbm_bufmgr_mutex_unlock();
1341 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1343 user_data_delete(old_data);
1345 _tbm_bufmgr_mutex_unlock();
1351 tbm_bo_set_user_data(tbm_bo bo, unsigned long key, void *data)
1353 tbm_user_data *old_data;
1355 _tbm_bufmgr_mutex_lock();
1356 _tbm_set_last_result(TBM_ERROR_NONE);
1358 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1360 if (LIST_IS_EMPTY(&bo->user_data_list)) {
1361 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1362 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1363 _tbm_bufmgr_mutex_unlock();
1367 old_data = user_data_lookup(&bo->user_data_list, key);
1369 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1370 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1371 _tbm_bufmgr_mutex_unlock();
1375 if (old_data->data && old_data->free_func)
1376 old_data->free_func(old_data->data);
1377 old_data->data = data;
1379 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1381 _tbm_bufmgr_mutex_unlock();
1387 tbm_bo_get_user_data(tbm_bo bo, unsigned long key, void **data)
1389 tbm_user_data *old_data;
1391 _tbm_bufmgr_mutex_lock();
1392 _tbm_set_last_result(TBM_ERROR_NONE);
1394 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1396 if (!data || LIST_IS_EMPTY(&bo->user_data_list)) {
1397 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1398 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1399 _tbm_bufmgr_mutex_unlock();
1403 old_data = user_data_lookup(&bo->user_data_list, key);
1406 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1407 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1408 _tbm_bufmgr_mutex_unlock();
1412 *data = old_data->data;
1414 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1416 _tbm_bufmgr_mutex_unlock();
1422 tbm_bo_get_flags(tbm_bo bo)
1426 _tbm_bufmgr_mutex_lock();
1428 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1432 TBM_TRACE_BO("bo(%p)\n", bo);
1434 _tbm_bufmgr_mutex_unlock();
1439 /* LCOV_EXCL_START */
1440 /* internal function */
1442 _tbm_bo_set_surface(tbm_bo bo, tbm_surface_h surface)
1444 _tbm_bufmgr_mutex_lock();
1446 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1448 bo->surface = surface;
1450 _tbm_bufmgr_mutex_unlock();
1456 _tbm_bo_free(tbm_bo bo)
1458 /* destory the user_data_list */
1459 if (!LIST_IS_EMPTY(&bo->user_data_list)) {
1460 tbm_user_data *old_data = NULL, *tmp;
1462 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp,
1463 &bo->user_data_list, item_link) {
1464 TBM_DBG("free user_data\n");
1465 user_data_delete(old_data);
1469 while (bo->lock_cnt > 0) {
1470 TBM_ERR("error lock_cnt:%d\n", bo->lock_cnt);
1475 /* call the bo_free */
1476 if (bo->bufmgr->use_hal_tbm) {
1477 // call hal_tbm_bo_free when bo is created by tbm_bo_alloc api.
1478 if (!bo->get_from_hal_surface) {
1479 bo->get_from_hal_surface = 0;
1481 hal_tbm_bo_free(bo->bo_data);
1484 } else if (bo->bufmgr->backend_module_data) {
1485 bo->bufmgr->bo_func->bo_free(bo->bo_data);
1488 bo->bufmgr->backend->bo_free(bo);
1496 /* LCOV_EXCL_STOP */