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)
999 tbm_bo bo, bo2 = NULL;
1003 _tbm_bufmgr_mutex_lock();
1004 _tbm_set_last_result(TBM_ERROR_NONE);
1006 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
1008 _tbm_util_check_bo_cnt(bufmgr);
1010 bo = calloc(1, sizeof(struct _tbm_bo));
1012 /* LCOV_EXCL_START */
1013 TBM_ERR("error: fail to import tbm_bo by tbm_fd(%d)\n", fd);
1014 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1015 _tbm_bufmgr_mutex_unlock();
1017 /* LCOV_EXCL_STOP */
1020 bo->bo_data = tbm_module_bufmgr_bo_import_fd(bufmgr->module, bo, fd, &error);
1022 /* LCOV_EXCL_START */
1023 TBM_ERR("tbm_module_bufmgr_bo_import_fd failed. tbm_fd:%d", fd);
1024 _tbm_set_last_result(error);
1025 _tbm_bufmgr_mutex_unlock();
1027 /* LCOV_EXCL_STOP */
1030 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
1031 LIST_FOR_EACH_ENTRY(bo2, &bufmgr->bo_list, item_link) {
1032 if (bo2->bo_data == bo->bo_data) {
1033 TBM_TRACE_BO("find bo(%p) ref(%d) fd(%d) flag(%s) in list\n",
1034 bo2, bo2->ref_cnt, fd, _tbm_flag_to_str(bo2->flags));
1037 _tbm_bufmgr_mutex_unlock();
1043 if (bufmgr->use_hal_tbm) {
1044 flags = (tbm_bo_memory_type)hal_tbm_bo_get_memory_types((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
1045 if (error != TBM_ERROR_NONE) {
1046 TBM_ERR("fail to get the bo flags(memory_types)");
1047 _tbm_set_last_result(error);
1048 flags = TBM_BO_DEFAULT;
1050 } else if (bufmgr->backend_module_data) {
1051 flags = bufmgr->bo_func->bo_get_memory_types(bo->bo_data, &error);
1052 if (error != TBM_ERROR_NONE) {
1053 TBM_ERR("fail to get the bo flags(memory_types)");
1054 _tbm_set_last_result(error);
1055 flags = TBM_BO_DEFAULT;
1058 if (bufmgr->backend->bo_get_flags)
1059 flags = bufmgr->backend->bo_get_flags(bo);
1061 flags = TBM_BO_DEFAULT;
1064 _tbm_bo_init(bufmgr, bo, flags);
1066 TBM_TRACE_BO("import bo(%p) ref(%d) fd(%d) flag(%s)\n",
1067 bo, bo->ref_cnt, fd, _tbm_flag_to_str(bo->flags));
1069 _tbm_bufmgr_mutex_unlock();
1075 tbm_bo_size(tbm_bo bo)
1080 _tbm_bufmgr_mutex_lock();
1081 _tbm_set_last_result(TBM_ERROR_NONE);
1083 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1085 if (bo->bufmgr->use_hal_tbm) {
1086 size = hal_tbm_bo_get_size((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
1087 if (error != TBM_ERROR_NONE) {
1088 TBM_ERR("fail to get the size of the bo_data(%d).", error);
1089 _tbm_set_last_result(TBM_ERROR_NONE);
1091 } else if (bo->bufmgr->backend_module_data) {
1092 size = bo->bufmgr->bo_func->bo_get_size(bo->bo_data, &error);
1093 if (error != TBM_ERROR_NONE) {
1094 TBM_ERR("fail to get the size of the bo_data(%d).", error);
1095 _tbm_set_last_result(TBM_ERROR_NONE);
1098 size = bo->bufmgr->backend->bo_size(bo);
1100 TBM_TRACE_BO("bo(%p) size(%d)\n", bo, size);
1102 _tbm_bufmgr_mutex_unlock();
1108 tbm_bo_locked(tbm_bo bo)
1110 _tbm_bufmgr_mutex_lock();
1111 _tbm_set_last_result(TBM_ERROR_NONE);
1113 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1115 if (bo->bufmgr->bo_lock_type == TBM_BUFMGR_BO_LOCK_TYPE_NEVER) {
1116 TBM_ERR("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
1117 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1118 _tbm_bufmgr_mutex_unlock();
1122 if (bo->lock_cnt > 0) {
1123 TBM_TRACE_BO("error: bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
1124 _tbm_bufmgr_mutex_unlock();
1128 TBM_TRACE_BO("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
1129 _tbm_bufmgr_mutex_unlock();
1135 tbm_bo_swap(tbm_bo bo1, tbm_bo bo2)
1137 tbm_error_e error1, error2;
1138 int size1 = -1, size2 = -2;
1141 _tbm_bufmgr_mutex_lock();
1142 _tbm_set_last_result(TBM_ERROR_NONE);
1144 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo1), 0);
1145 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo2), 0);
1147 TBM_TRACE_BO("before: bo1(%p) bo2(%p)\n", bo1, bo2);
1149 if (bo1->bufmgr->use_hal_tbm) {
1150 size1 = hal_tbm_bo_get_size((hal_tbm_bo *)bo1->bo_data, (hal_tbm_error *)&error1);
1151 if (error1 != TBM_ERROR_NONE) {
1152 TBM_ERR("fail to get the size of bo1.(%d)", error1);
1153 _tbm_set_last_result(error1);
1156 size2 = hal_tbm_bo_get_size((hal_tbm_bo *)bo2->bo_data, (hal_tbm_error *)&error2);
1157 if (error2 != TBM_ERROR_NONE) {
1158 TBM_ERR("fail to get the size of bo1.(%d)", error2);
1159 _tbm_set_last_result(error2);
1162 } else if (bo1->bufmgr->backend_module_data) {
1163 size1 = bo1->bufmgr->bo_func->bo_get_size(bo1->bo_data, &error1);
1164 if (error1 != TBM_ERROR_NONE) {
1165 TBM_ERR("fail to get the size of bo1.(%d)", error1);
1166 _tbm_set_last_result(error1);
1169 size2 = bo2->bufmgr->bo_func->bo_get_size(bo2->bo_data, &error2);
1170 if (error2 != TBM_ERROR_NONE) {
1171 TBM_ERR("fail to get the size of bo2.(%d)", error2);
1172 _tbm_set_last_result(error2);
1176 size1 = bo1->bufmgr->backend->bo_size(bo1);
1177 size2 = bo2->bufmgr->backend->bo_size(bo2);
1180 if (size1 != size2) {
1181 TBM_ERR("error: bo1 size(%d) and bo2 size(%d) is different.", size1, size2);
1182 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1186 TBM_TRACE_BO("after: bo1(%p) bo2(%p)\n", bo1, bo2);
1189 bo1->priv = bo2->priv;
1192 _tbm_bufmgr_mutex_unlock();
1197 TBM_ERR("error: bo1(%p) bo2(%p)\n", bo1, bo2);
1198 _tbm_bufmgr_mutex_unlock();
1204 tbm_bo_add_user_data(tbm_bo bo, unsigned long key,
1205 tbm_data_free data_free_func)
1207 tbm_user_data *data;
1209 _tbm_bufmgr_mutex_lock();
1210 _tbm_set_last_result(TBM_ERROR_NONE);
1212 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1214 /* check if the data according to the key exist if so, return false. */
1215 data = user_data_lookup(&bo->user_data_list, key);
1217 TBM_TRACE_BO("warning: user data already exist key(%ld)\n", key);
1218 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1219 _tbm_bufmgr_mutex_unlock();
1223 data = user_data_create(key, data_free_func);
1225 TBM_ERR("error: bo(%p) key(%lu)\n", bo, key);
1226 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1227 _tbm_bufmgr_mutex_unlock();
1231 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, data->data);
1233 LIST_ADD(&data->item_link, &bo->user_data_list);
1235 _tbm_bufmgr_mutex_unlock();
1241 tbm_bo_delete_user_data(tbm_bo bo, unsigned long key)
1243 tbm_user_data *old_data;
1245 _tbm_bufmgr_mutex_lock();
1246 _tbm_set_last_result(TBM_ERROR_NONE);
1248 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1250 if (LIST_IS_EMPTY(&bo->user_data_list)) {
1251 TBM_TRACE_BO("bo(%p) key(%lu)\n", bo, key);
1252 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1253 _tbm_bufmgr_mutex_unlock();
1257 old_data = user_data_lookup(&bo->user_data_list, key);
1259 TBM_TRACE_BO("bo(%p) key(%lu)\n", bo, key);
1260 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1261 _tbm_bufmgr_mutex_unlock();
1265 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1267 user_data_delete(old_data);
1269 _tbm_bufmgr_mutex_unlock();
1275 tbm_bo_set_user_data(tbm_bo bo, unsigned long key, void *data)
1277 tbm_user_data *old_data;
1279 _tbm_bufmgr_mutex_lock();
1280 _tbm_set_last_result(TBM_ERROR_NONE);
1282 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1284 if (LIST_IS_EMPTY(&bo->user_data_list)) {
1285 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1286 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1287 _tbm_bufmgr_mutex_unlock();
1291 old_data = user_data_lookup(&bo->user_data_list, key);
1293 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1294 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1295 _tbm_bufmgr_mutex_unlock();
1299 if (old_data->data && old_data->free_func)
1300 old_data->free_func(old_data->data);
1301 old_data->data = data;
1303 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1305 _tbm_bufmgr_mutex_unlock();
1311 tbm_bo_get_user_data(tbm_bo bo, unsigned long key, void **data)
1313 tbm_user_data *old_data;
1315 _tbm_bufmgr_mutex_lock();
1316 _tbm_set_last_result(TBM_ERROR_NONE);
1318 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1320 if (!data || LIST_IS_EMPTY(&bo->user_data_list)) {
1321 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1322 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1323 _tbm_bufmgr_mutex_unlock();
1327 old_data = user_data_lookup(&bo->user_data_list, key);
1330 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1331 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1332 _tbm_bufmgr_mutex_unlock();
1336 *data = old_data->data;
1338 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1340 _tbm_bufmgr_mutex_unlock();
1346 tbm_bo_get_flags(tbm_bo bo)
1350 _tbm_bufmgr_mutex_lock();
1352 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1356 TBM_TRACE_BO("bo(%p)\n", bo);
1358 _tbm_bufmgr_mutex_unlock();
1363 /* LCOV_EXCL_START */
1364 /* internal function */
1366 _tbm_bo_set_surface(tbm_bo bo, tbm_surface_h surface)
1368 _tbm_bufmgr_mutex_lock();
1370 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1372 bo->surface = surface;
1374 _tbm_bufmgr_mutex_unlock();
1380 _tbm_bo_free(tbm_bo bo)
1382 /* destory the user_data_list */
1383 if (!LIST_IS_EMPTY(&bo->user_data_list)) {
1384 tbm_user_data *old_data = NULL, *tmp;
1386 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp,
1387 &bo->user_data_list, item_link) {
1388 TBM_DBG("free user_data\n");
1389 user_data_delete(old_data);
1393 while (bo->lock_cnt > 0) {
1394 TBM_ERR("error lock_cnt:%d\n", bo->lock_cnt);
1399 /* call the bo_free */
1400 if (bo->bufmgr->use_hal_tbm) {
1401 // call hal_tbm_bo_free when bo is created by tbm_bo_alloc api.
1402 if (!bo->get_from_hal_surface) {
1403 bo->get_from_hal_surface = 0;
1405 hal_tbm_bo_free(bo->bo_data);
1408 } else if (bo->bufmgr->backend_module_data) {
1409 bo->bufmgr->bo_func->bo_free(bo->bo_data);
1412 bo->bufmgr->backend->bo_free(bo);
1420 /* LCOV_EXCL_STOP */