1 /**************************************************************************
5 Copyright 2012 Samsung Electronics co., Ltd. All Rights Reserved.
7 Contact: SooChan Lim <sc1.lim@samsung.com>, Sangjin Lee <lsj119@samsung.com>
8 Boram Park <boram1288.park@samsung.com>, Changyeon Lee <cyeon.lee@samsung.com>
10 Permission is hereby granted, free of charge, to any person obtaining a
11 copy of this software and associated documentation files (the
12 "Software"), to deal in the Software without restriction, including
13 without limitation the rights to use, copy, modify, merge, publish,
14 distribute, sub license, and/or sell copies of the Software, and to
15 permit persons to whom the Software is furnished to do so, subject to
16 the following conditions:
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial portions
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
25 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 **************************************************************************/
33 #include "tbm_bufmgr.h"
34 #include "tbm_bufmgr_int.h"
38 #define TBM_BO_RETURN_IF_FAIL(cond) {\
40 TBM_ERR("'%s' failed.\n", #cond);\
41 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
42 _tbm_bufmgr_mutex_unlock();\
47 #define TBM_BO_RETURN_VAL_IF_FAIL(cond, val) {\
49 TBM_ERR("'%s' failed.\n", #cond);\
50 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
51 _tbm_bufmgr_mutex_unlock();\
57 _tbm_flag_to_str(int f)
61 if (f == TBM_BO_DEFAULT)
62 snprintf(str, 255, "DEFAULT");
66 if (f & TBM_BO_SCANOUT)
67 c += snprintf(&str[c], 255-c, "SCANOUT");
69 if (f & TBM_BO_NONCACHABLE) {
70 if (c >= 0 && c < 255)
71 c += snprintf(&str[c], 255-c, ", ");
73 if (c >= 0 && c < 255)
74 c += snprintf(&str[c], 255-c, "NONCACHABLE,");
78 if (c >= 0 && c < 255)
79 c += snprintf(&str[c], 255-c, ", ");
81 if (c >= 0 && c < 255)
82 c += snprintf(&str[c], 255-c, "WC");
90 _tbm_util_check_bo_cnt(tbm_bufmgr bufmgr)
92 static int last_chk_bo_cnt = 0;
94 if ((bufmgr->bo_cnt >= 500) && ((bufmgr->bo_cnt % 20) == 0) &&
95 (bufmgr->bo_cnt > last_chk_bo_cnt)) {
96 TBM_DBG("============TBM BO CNT DEBUG: bo_cnt=%d\n", bufmgr->bo_cnt);
97 tbm_bufmgr_debug_show(bufmgr);
98 last_chk_bo_cnt = bufmgr->bo_cnt;
104 user_data_lookup(struct list_head *user_data_list, unsigned long key)
106 tbm_user_data *old_data = NULL;
108 if (LIST_IS_EMPTY(user_data_list))
111 LIST_FOR_EACH_ENTRY(old_data, user_data_list, item_link) {
112 if (old_data->key == key)
120 user_data_create(unsigned long key, tbm_data_free data_free_func)
122 tbm_user_data *user_data;
124 user_data = calloc(1, sizeof(tbm_user_data));
126 /* LCOV_EXCL_START */
127 TBM_ERR("fail to allocate an user_date\n");
128 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
133 user_data->key = key;
134 user_data->free_func = data_free_func;
140 user_data_delete(tbm_user_data *user_data)
142 if (user_data->data && user_data->free_func)
143 user_data->free_func(user_data->data);
145 LIST_DEL(&user_data->item_link);
151 _bo_lock(tbm_bo bo, int device, int opt)
156 if (bo->bufmgr->use_hal_tbm) {
157 error = (tbm_error_e)hal_tbm_bo_lock((hal_tbm_bo *)bo->bo_data, device, opt);
158 if (error == TBM_ERROR_NOT_SUPPORTED) {
159 _tbm_set_last_result(TBM_ERROR_NONE);
161 if (error != TBM_ERROR_NONE) {
162 TBM_WRN("fail to lock");
163 _tbm_set_last_result(error);
167 } else if (bo->bufmgr->backend_module_data) {
168 if (bo->bufmgr->bo_func->bo_lock) {
169 error = bo->bufmgr->bo_func->bo_lock(bo->bo_data, device, opt);
170 if (error != TBM_ERROR_NONE) {
171 TBM_WRN("fail to lock");
172 _tbm_set_last_result(error);
177 if (bo->bufmgr->backend->bo_lock) {
178 ret = bo->bufmgr->backend->bo_lock(bo, device, opt);
180 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
188 _bo_unlock(tbm_bo bo)
192 if (bo->bufmgr->use_hal_tbm) {
193 error = (tbm_error_e)hal_tbm_bo_unlock((hal_tbm_bo *)bo->bo_data);
194 if (error == TBM_ERROR_NOT_SUPPORTED) {
195 _tbm_set_last_result(TBM_ERROR_NONE);
197 if (error != TBM_ERROR_NONE) {
198 TBM_WRN("fail to lock");
199 _tbm_set_last_result(error);
202 } else if (bo->bufmgr->backend_module_data) {
203 if (bo->bufmgr->bo_func->bo_unlock) {
204 error = bo->bufmgr->bo_func->bo_unlock(bo->bo_data);
205 if (error != TBM_ERROR_NONE) {
206 TBM_WRN("fail to unlock");
207 _tbm_set_last_result(error);
211 if (bo->bufmgr->backend->bo_unlock)
212 bo->bufmgr->backend->bo_unlock(bo);
217 _tbm_bo_lock(tbm_bo bo, int device, int opt)
224 /* do not try to lock the bo */
225 if (bo->bufmgr->bo_lock_type == TBM_BUFMGR_BO_LOCK_TYPE_NEVER)
228 if (bo->lock_cnt < 0) {
229 TBM_ERR("error bo:%p LOCK_CNT=%d\n",
236 switch (bo->bufmgr->bo_lock_type) {
237 case TBM_BUFMGR_BO_LOCK_TYPE_ONCE:
238 if (bo->lock_cnt == 0) {
239 _tbm_bufmgr_mutex_unlock();
240 ret = _bo_lock(bo, device, opt);
241 _tbm_bufmgr_mutex_lock();
247 case TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS:
248 _tbm_bufmgr_mutex_unlock();
249 ret = _bo_lock(bo, device, opt);
250 _tbm_bufmgr_mutex_lock();
255 TBM_ERR("error bo:%p bo_lock_type[%d] is wrong.\n",
256 bo, bo->bufmgr->bo_lock_type);
261 TBM_DBG(">> LOCK bo:%p(%d->%d)\n", bo, old, bo->lock_cnt);
267 _tbm_bo_unlock(tbm_bo bo)
271 /* do not try to unlock the bo */
272 if (bo->bufmgr->bo_lock_type == TBM_BUFMGR_BO_LOCK_TYPE_NEVER)
277 switch (bo->bufmgr->bo_lock_type) {
278 case TBM_BUFMGR_BO_LOCK_TYPE_ONCE:
279 if (bo->lock_cnt > 0) {
281 if (bo->lock_cnt == 0)
285 case TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS:
286 if (bo->lock_cnt > 0) {
292 TBM_ERR("error bo:%p bo_lock_type[%d] is wrong.\n",
293 bo, bo->bufmgr->bo_lock_type);
297 if (bo->lock_cnt < 0)
300 TBM_DBG(">> UNLOCK bo:%p(%d->%d)\n", bo, old, bo->lock_cnt);
304 _tbm_bo_magic_check(tbm_bo bo)
306 if (bo->magic != TBM_BO_MAGIC)
313 _tbm_bo_is_valid(tbm_bo bo)
316 TBM_ERR("error: bo is NULL.\n");
320 if (!_tbm_bo_magic_check(bo)) {
321 TBM_ERR("error: No valid bo(%p).\n", bo);
329 _tbm_bo_init(tbm_bufmgr bufmgr, tbm_bo bo, int flags)
333 bo->magic = TBM_BO_MAGIC;
336 LIST_INITHEAD(&bo->user_data_list);
339 LIST_ADD(&bo->item_link, &bufmgr->bo_list);
343 _tbm_bo_deinit(tbm_bo bo)
347 bo->bufmgr->bo_cnt--;
348 LIST_DEL(&bo->item_link);
352 tbm_bo_alloc(tbm_bufmgr bufmgr, int size, int flags)
355 tbm_backend_bo_data *bo_data;
358 _tbm_bufmgr_mutex_lock();
359 _tbm_set_last_result(TBM_ERROR_NONE);
361 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
362 TBM_BO_RETURN_VAL_IF_FAIL(size > 0, NULL);
364 bo = calloc(1, sizeof(struct _tbm_bo));
366 /* LCOV_EXCL_START */
367 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
368 _tbm_bufmgr_mutex_unlock();
373 _tbm_util_check_bo_cnt(bufmgr);
375 bo_data = tbm_module_bufmgr_bo_alloc(bufmgr->module, bo, size, flags, &error);
376 if (!bo_data || error != TBM_ERROR_NONE) {
377 /* LCOV_EXCL_START */
378 TBM_ERR("tbm_module_bufmgr_bo_alloc failed. error:%d", error);
379 _tbm_set_last_result(error);
383 bo->bo_data = bo_data;
384 bo->priv = (void *)bo_data; // TODO: this will be DEPRECATED.
386 _tbm_bo_init(bufmgr, bo, flags);
388 TBM_TRACE_BO("bo(%p) size(%d) refcnt(%d), flag(%s)\n", bo, size, bo->ref_cnt,
389 _tbm_flag_to_str(bo->flags));
391 _tbm_bufmgr_mutex_unlock();
396 TBM_ERR("error: fail to create of tbm_bo size(%d) flag(%s)\n", size, _tbm_flag_to_str(flags));
398 _tbm_bufmgr_mutex_unlock();
402 /* LCOV_EXCL_START */
404 tbm_bo_alloc_with_bo_data(tbm_bufmgr bufmgr, tbm_backend_bo_data *bo_data, int flags)
406 tbm_bo bo, bo2 = NULL;
408 _tbm_bufmgr_mutex_lock();
409 _tbm_set_last_result(TBM_ERROR_NONE);
411 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
412 TBM_BO_RETURN_VAL_IF_FAIL(bo_data, NULL);
414 // return an existed bo if the bo is already created with the same bo_data.
415 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
416 LIST_FOR_EACH_ENTRY(bo2, &bufmgr->bo_list, item_link) {
417 if (bo2->bo_data == bo_data) {
418 TBM_ERR("find bo(%p) ref(%d) flag(%s) in list\n",
419 bo2, bo2->ref_cnt, _tbm_flag_to_str(bo2->flags));
421 _tbm_bufmgr_mutex_unlock();
427 bo = calloc(1, sizeof(struct _tbm_bo));
429 /* LCOV_EXCL_START */
430 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
431 _tbm_bufmgr_mutex_unlock();
436 _tbm_util_check_bo_cnt(bufmgr);
438 bo->get_from_hal_surface = 1;
439 bo->bo_data = bo_data;
441 _tbm_bo_init(bufmgr, bo, flags);
443 TBM_TRACE_BO("bo(%p) refcnt(%d), flag(%s)\n", bo, bo->ref_cnt, _tbm_flag_to_str(bo->flags));
445 _tbm_bufmgr_mutex_unlock();
453 tbm_bo_ref(tbm_bo bo)
455 _tbm_bufmgr_mutex_lock();
456 _tbm_set_last_result(TBM_ERROR_NONE);
458 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), NULL);
462 TBM_TRACE_BO("bo(%p) ref_cnt(%d)\n", bo, bo->ref_cnt);
464 _tbm_bufmgr_mutex_unlock();
470 tbm_bo_unref(tbm_bo bo)
472 _tbm_bufmgr_mutex_lock();
473 _tbm_set_last_result(TBM_ERROR_NONE);
475 TBM_BO_RETURN_IF_FAIL(_tbm_bo_is_valid(bo));
477 TBM_TRACE_BO("bo(%p) ref_cnt(%d)\n", bo, bo->ref_cnt - 1);
479 if (bo->ref_cnt <= 0) {
480 _tbm_bufmgr_mutex_unlock();
485 if (bo->ref_cnt == 0)
488 _tbm_bufmgr_mutex_unlock();
492 tbm_bo_map(tbm_bo bo, int device, int opt)
494 tbm_bo_handle bo_handle;
497 _tbm_bufmgr_mutex_lock();
498 _tbm_set_last_result(TBM_ERROR_NONE);
500 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) NULL);
502 if (!_tbm_bo_lock(bo, device, opt)) {
503 TBM_ERR("error: fail to lock bo:%p)\n", bo);
504 _tbm_bufmgr_mutex_unlock();
505 return (tbm_bo_handle) NULL;
508 if (bo->bufmgr->use_hal_tbm) {
509 hal_tbm_bo_handle hbo_handle;
510 hbo_handle = hal_tbm_bo_map((hal_tbm_bo *)bo->bo_data, device, opt, (hal_tbm_error *)&error);
511 if (hbo_handle.ptr == NULL) {
512 /* LCOV_EXCL_START */
513 _tbm_set_last_result(error);
514 TBM_ERR("error: bo(%p) bo_handle(%p) error(%d)\n", bo, hbo_handle.ptr, error);
518 memcpy(&bo_handle.ptr, &hbo_handle.ptr, sizeof(tbm_bo_handle));
519 } else if (bo->bufmgr->backend_module_data) {
520 bo_handle = bo->bufmgr->bo_func->bo_map(bo->bo_data, device, opt, &error);
521 if (bo_handle.ptr == NULL) {
522 /* LCOV_EXCL_START */
523 _tbm_set_last_result(error);
524 TBM_ERR("error: fail to map bo:%p error:%d\n", bo, error);
529 bo_handle = bo->bufmgr->backend->bo_map(bo, device, opt);
530 if (bo_handle.ptr == NULL) {
531 /* LCOV_EXCL_START */
532 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
533 TBM_ERR("error: fail to map bo:%p\n", bo);
539 /* increase the map_count */
542 TBM_TRACE_BO("bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
544 _tbm_bufmgr_mutex_unlock();
550 _tbm_bufmgr_mutex_unlock();
551 return (tbm_bo_handle) NULL;
555 tbm_bo_unmap(tbm_bo bo)
560 _tbm_bufmgr_mutex_lock();
561 _tbm_set_last_result(TBM_ERROR_NONE);
563 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
564 TBM_BO_RETURN_VAL_IF_FAIL(bo->map_cnt > 0, 0);
566 if (bo->bufmgr->use_hal_tbm) {
567 error = (hal_tbm_error)hal_tbm_bo_unmap((hal_tbm_bo *)bo->bo_data);
568 if (error != TBM_ERROR_NONE) {
569 /* LCOV_EXCL_START */
570 TBM_ERR("error: bo(%p) map_cnt(%d) error(%d)\n", bo, bo->map_cnt, error);
571 _tbm_set_last_result(error);
576 } else if (bo->bufmgr->backend_module_data) {
577 error = bo->bufmgr->bo_func->bo_unmap(bo->bo_data);
578 if (error != TBM_ERROR_NONE) {
579 /* LCOV_EXCL_START */
580 TBM_ERR("error: bo(%p) map_cnt(%d) error(%d)\n", bo, bo->map_cnt, error);
581 _tbm_set_last_result(error);
587 ret = bo->bufmgr->backend->bo_unmap(bo);
589 /* LCOV_EXCL_START */
590 TBM_ERR("error: bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
591 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
597 /* decrease the map_count */
600 TBM_TRACE_BO("bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
605 _tbm_bufmgr_mutex_unlock();
611 tbm_bo_get_handle(tbm_bo bo, int device)
613 tbm_bo_handle bo_handle;
616 _tbm_bufmgr_mutex_lock();
617 _tbm_set_last_result(TBM_ERROR_NONE);
619 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) NULL);
621 if (bo->bufmgr->use_hal_tbm) {
622 hal_tbm_bo_handle hbo_handle;
623 hbo_handle = hal_tbm_bo_get_handle((hal_tbm_bo *)bo->bo_data, device, (hal_tbm_error *)&error);
624 if (hbo_handle.ptr == NULL) {
625 /* LCOV_EXCL_START */
626 TBM_ERR("error: bo(%p) bo_handle(%p) error(%d)\n", bo, hbo_handle.ptr, error);
627 _tbm_set_last_result(error);
631 memcpy(&bo_handle.ptr, &hbo_handle.ptr, sizeof(tbm_bo_handle));
632 } else if (bo->bufmgr->backend_module_data) {
633 bo_handle = bo->bufmgr->bo_func->bo_get_handle(bo->bo_data, device, &error);
634 if (bo_handle.ptr == NULL) {
635 /* LCOV_EXCL_START */
636 TBM_ERR("error: bo(%p) bo_handle(%p) error(%d)\n", bo, bo_handle.ptr, error);
637 _tbm_set_last_result(error);
642 bo_handle = bo->bufmgr->backend->bo_get_handle(bo, device);
643 if (bo_handle.ptr == NULL) {
644 /* LCOV_EXCL_START */
645 TBM_ERR("error: bo(%p) bo_handle(%p)\n", bo, bo_handle.ptr);
646 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
652 TBM_TRACE_BO("bo(%p) bo_handle(%p)\n", bo, bo_handle.ptr);
654 _tbm_bufmgr_mutex_unlock();
659 _tbm_bufmgr_mutex_unlock();
660 return (tbm_bo_handle) NULL;
664 tbm_bo_export(tbm_bo bo)
669 _tbm_bufmgr_mutex_lock();
670 _tbm_set_last_result(TBM_ERROR_NONE);
672 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
674 if (bo->bufmgr->use_hal_tbm) {
675 ret = (hal_tbm_key)hal_tbm_bo_export_key((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
677 /* LCOV_EXCL_START */
678 TBM_ERR("error: bo(%p) tbm_key(%d) error(%d)\n", bo, ret, error);
679 _tbm_set_last_result(error);
683 } else if (bo->bufmgr->backend_module_data) {
684 if (!bo->bufmgr->bo_func->bo_export_key) {
685 /* LCOV_EXCL_START */
686 _tbm_bufmgr_mutex_unlock();
687 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
692 ret = bo->bufmgr->bo_func->bo_export_key(bo->bo_data, &error);
694 /* LCOV_EXCL_START */
695 TBM_ERR("error: bo(%p) tbm_key(%d) error(%d)\n", bo, ret, error);
696 _tbm_set_last_result(error);
701 if (!bo->bufmgr->backend->bo_export) {
702 /* LCOV_EXCL_START */
703 _tbm_bufmgr_mutex_unlock();
704 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
709 ret = bo->bufmgr->backend->bo_export(bo);
711 /* LCOV_EXCL_START */
712 TBM_ERR("error: bo(%p) tbm_key(%d)\n", bo, ret);
713 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
719 TBM_TRACE_BO("bo(%p) tbm_key(%u)\n", bo, ret);
722 _tbm_bufmgr_mutex_unlock();
728 tbm_bo_export_fd(tbm_bo bo)
733 _tbm_bufmgr_mutex_lock();
734 _tbm_set_last_result(TBM_ERROR_NONE);
736 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), -1);
738 if (bo->bufmgr->use_hal_tbm) {
739 ret = (hal_tbm_fd)hal_tbm_bo_export_fd((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
741 /* LCOV_EXCL_START */
742 TBM_ERR("error: bo(%p) tbm_fd(%d) error(%d)\n", bo, ret, error);
743 _tbm_set_last_result(error);
747 } else if (bo->bufmgr->backend_module_data) {
748 if (!bo->bufmgr->bo_func->bo_export_fd) {
749 /* LCOV_EXCL_START */
750 _tbm_bufmgr_mutex_unlock();
751 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
756 ret = bo->bufmgr->bo_func->bo_export_fd(bo->bo_data, &error);
758 /* LCOV_EXCL_START */
759 TBM_ERR("error: bo(%p) tbm_fd(%d) error(%d)\n", bo, ret, error);
760 _tbm_set_last_result(error);
765 if (!bo->bufmgr->backend->bo_export_fd) {
766 /* LCOV_EXCL_START */
767 _tbm_bufmgr_mutex_unlock();
768 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
773 ret = bo->bufmgr->backend->bo_export_fd(bo);
775 /* LCOV_EXCL_START */
776 TBM_ERR("error: bo(%p) tbm_fd(%d)\n", bo, ret);
777 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
783 TBM_TRACE_BO("bo(%p) tbm_fd(%d)\n", bo, ret);
786 _tbm_bufmgr_mutex_unlock();
792 tbm_bo_import(tbm_bufmgr bufmgr, unsigned int key)
794 tbm_bo bo, bo2 = NULL;
798 _tbm_bufmgr_mutex_lock();
799 _tbm_set_last_result(TBM_ERROR_NONE);
801 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
803 _tbm_util_check_bo_cnt(bufmgr);
805 bo = calloc(1, sizeof(struct _tbm_bo));
807 /* LCOV_EXCL_START */
808 TBM_ERR("error: fail to import of tbm_bo by key(%d)\n", key);
809 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
810 _tbm_bufmgr_mutex_unlock();
815 bo->bo_data = tbm_module_bufmgr_bo_import_key(bufmgr->module, bo, key, &error);
817 /* LCOV_EXCL_START */
818 TBM_ERR("tbm_module_bufmgr_bo_import_key failed. tbm_key:%d", key);
819 _tbm_set_last_result(error);
820 _tbm_bufmgr_mutex_unlock();
825 // return the existed bo2 if bo->bo_data and bo2->bo_data is the same
826 bo2 = tbm_bufmgr_internal_find_bo(bufmgr, bo);
828 TBM_TRACE_BO("find bo(%p) ref(%d) key(%d) flag(%s) in list",
829 bo2, bo2->ref_cnt, key, _tbm_flag_to_str(bo2->flags));
832 _tbm_bufmgr_mutex_unlock();
836 if (bufmgr->use_hal_tbm) {
837 flags = (tbm_bo_memory_type)hal_tbm_bo_get_memory_types((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
838 if (error != TBM_ERROR_NONE) {
839 TBM_ERR("fail to get the bo flags(memory_types)");
840 _tbm_set_last_result(error);
841 flags = TBM_BO_DEFAULT;
843 } else if (bufmgr->backend_module_data) {
844 flags = bufmgr->bo_func->bo_get_memory_types(bo->bo_data, &error);
845 if (error != TBM_ERROR_NONE) {
846 TBM_ERR("fail to get the bo flags(memory_types)");
847 _tbm_set_last_result(error);
848 flags = TBM_BO_DEFAULT;
851 if (bufmgr->backend->bo_get_flags)
852 flags = bufmgr->backend->bo_get_flags(bo);
854 flags = TBM_BO_DEFAULT;
857 _tbm_bo_init(bufmgr, bo, flags);
859 TBM_TRACE_BO("import new bo(%p) ref(%d) key(%d) flag(%s) in list\n",
860 bo, bo->ref_cnt, key, _tbm_flag_to_str(bo->flags));
862 _tbm_bufmgr_mutex_unlock();
868 tbm_bo_import_fd(tbm_bufmgr bufmgr, tbm_fd fd)
870 tbm_bo bo, bo2 = NULL;
874 _tbm_bufmgr_mutex_lock();
875 _tbm_set_last_result(TBM_ERROR_NONE);
877 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
879 _tbm_util_check_bo_cnt(bufmgr);
881 bo = calloc(1, sizeof(struct _tbm_bo));
883 /* LCOV_EXCL_START */
884 TBM_ERR("error: fail to import tbm_bo by tbm_fd(%d)\n", fd);
885 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
886 _tbm_bufmgr_mutex_unlock();
891 bo->bo_data = tbm_module_bufmgr_bo_import_fd(bufmgr->module, bo, fd, &error);
893 /* LCOV_EXCL_START */
894 TBM_ERR("tbm_module_bufmgr_bo_import_fd failed. tbm_fd:%d", fd);
895 _tbm_set_last_result(error);
896 _tbm_bufmgr_mutex_unlock();
901 // return the existed bo2 if bo->bo_data and bo2->bo_data is the same
902 bo2 = tbm_bufmgr_internal_find_bo(bufmgr, bo);
904 TBM_TRACE_BO("find bo(%p) ref(%d) fd(%d) flag(%s) in list",
905 bo2, bo2->ref_cnt, fd, _tbm_flag_to_str(bo2->flags));
908 _tbm_bufmgr_mutex_unlock();
912 if (bufmgr->use_hal_tbm) {
913 flags = (tbm_bo_memory_type)hal_tbm_bo_get_memory_types((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
914 if (error != TBM_ERROR_NONE) {
915 TBM_ERR("fail to get the bo flags(memory_types)");
916 _tbm_set_last_result(error);
917 flags = TBM_BO_DEFAULT;
919 } else if (bufmgr->backend_module_data) {
920 flags = bufmgr->bo_func->bo_get_memory_types(bo->bo_data, &error);
921 if (error != TBM_ERROR_NONE) {
922 TBM_ERR("fail to get the bo flags(memory_types)");
923 _tbm_set_last_result(error);
924 flags = TBM_BO_DEFAULT;
927 if (bufmgr->backend->bo_get_flags)
928 flags = bufmgr->backend->bo_get_flags(bo);
930 flags = TBM_BO_DEFAULT;
933 _tbm_bo_init(bufmgr, bo, flags);
935 TBM_TRACE_BO("import bo(%p) ref(%d) fd(%d) flag(%s)\n",
936 bo, bo->ref_cnt, fd, _tbm_flag_to_str(bo->flags));
938 _tbm_bufmgr_mutex_unlock();
944 tbm_bo_size(tbm_bo bo)
949 _tbm_bufmgr_mutex_lock();
950 _tbm_set_last_result(TBM_ERROR_NONE);
952 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
954 if (bo->bufmgr->use_hal_tbm) {
955 size = hal_tbm_bo_get_size((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
956 if (error != TBM_ERROR_NONE) {
957 TBM_ERR("fail to get the size of the bo_data(%d).", error);
958 _tbm_set_last_result(TBM_ERROR_NONE);
960 } else if (bo->bufmgr->backend_module_data) {
961 size = bo->bufmgr->bo_func->bo_get_size(bo->bo_data, &error);
962 if (error != TBM_ERROR_NONE) {
963 TBM_ERR("fail to get the size of the bo_data(%d).", error);
964 _tbm_set_last_result(TBM_ERROR_NONE);
967 size = bo->bufmgr->backend->bo_size(bo);
969 TBM_TRACE_BO("bo(%p) size(%d)\n", bo, size);
971 _tbm_bufmgr_mutex_unlock();
977 tbm_bo_locked(tbm_bo bo)
979 _tbm_bufmgr_mutex_lock();
980 _tbm_set_last_result(TBM_ERROR_NONE);
982 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
984 if (bo->bufmgr->bo_lock_type == TBM_BUFMGR_BO_LOCK_TYPE_NEVER) {
985 TBM_ERR("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
986 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
987 _tbm_bufmgr_mutex_unlock();
991 if (bo->lock_cnt > 0) {
992 TBM_TRACE_BO("error: bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
993 _tbm_bufmgr_mutex_unlock();
997 TBM_TRACE_BO("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
998 _tbm_bufmgr_mutex_unlock();
1004 tbm_bo_swap(tbm_bo bo1, tbm_bo bo2)
1006 tbm_error_e error1, error2;
1007 int size1 = -1, size2 = -2;
1010 _tbm_bufmgr_mutex_lock();
1011 _tbm_set_last_result(TBM_ERROR_NONE);
1013 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo1), 0);
1014 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo2), 0);
1016 TBM_TRACE_BO("before: bo1(%p) bo2(%p)\n", bo1, bo2);
1018 if (bo1->bufmgr->use_hal_tbm) {
1019 size1 = hal_tbm_bo_get_size((hal_tbm_bo *)bo1->bo_data, (hal_tbm_error *)&error1);
1020 if (error1 != TBM_ERROR_NONE) {
1021 TBM_ERR("fail to get the size of bo1.(%d)", error1);
1022 _tbm_set_last_result(error1);
1025 size2 = hal_tbm_bo_get_size((hal_tbm_bo *)bo2->bo_data, (hal_tbm_error *)&error2);
1026 if (error2 != TBM_ERROR_NONE) {
1027 TBM_ERR("fail to get the size of bo1.(%d)", error2);
1028 _tbm_set_last_result(error2);
1031 } else if (bo1->bufmgr->backend_module_data) {
1032 size1 = bo1->bufmgr->bo_func->bo_get_size(bo1->bo_data, &error1);
1033 if (error1 != TBM_ERROR_NONE) {
1034 TBM_ERR("fail to get the size of bo1.(%d)", error1);
1035 _tbm_set_last_result(error1);
1038 size2 = bo2->bufmgr->bo_func->bo_get_size(bo2->bo_data, &error2);
1039 if (error2 != TBM_ERROR_NONE) {
1040 TBM_ERR("fail to get the size of bo2.(%d)", error2);
1041 _tbm_set_last_result(error2);
1045 size1 = bo1->bufmgr->backend->bo_size(bo1);
1046 size2 = bo2->bufmgr->backend->bo_size(bo2);
1049 if (size1 != size2) {
1050 TBM_ERR("error: bo1 size(%d) and bo2 size(%d) is different.", size1, size2);
1051 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1055 TBM_TRACE_BO("after: bo1(%p) bo2(%p)\n", bo1, bo2);
1058 bo1->priv = bo2->priv;
1061 _tbm_bufmgr_mutex_unlock();
1066 TBM_ERR("error: bo1(%p) bo2(%p)\n", bo1, bo2);
1067 _tbm_bufmgr_mutex_unlock();
1073 tbm_bo_add_user_data(tbm_bo bo, unsigned long key,
1074 tbm_data_free data_free_func)
1076 tbm_user_data *data;
1078 _tbm_bufmgr_mutex_lock();
1079 _tbm_set_last_result(TBM_ERROR_NONE);
1081 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1083 /* check if the data according to the key exist if so, return false. */
1084 data = user_data_lookup(&bo->user_data_list, key);
1086 TBM_TRACE_BO("warning: user data already exist key(%ld)\n", key);
1087 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1088 _tbm_bufmgr_mutex_unlock();
1092 data = user_data_create(key, data_free_func);
1094 TBM_ERR("error: bo(%p) key(%lu)\n", bo, key);
1095 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1096 _tbm_bufmgr_mutex_unlock();
1100 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, data->data);
1102 LIST_ADD(&data->item_link, &bo->user_data_list);
1104 _tbm_bufmgr_mutex_unlock();
1110 tbm_bo_delete_user_data(tbm_bo bo, unsigned long key)
1112 tbm_user_data *old_data;
1114 _tbm_bufmgr_mutex_lock();
1115 _tbm_set_last_result(TBM_ERROR_NONE);
1117 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1119 if (LIST_IS_EMPTY(&bo->user_data_list)) {
1120 TBM_TRACE_BO("bo(%p) key(%lu)\n", bo, key);
1121 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1122 _tbm_bufmgr_mutex_unlock();
1126 old_data = user_data_lookup(&bo->user_data_list, key);
1128 TBM_TRACE_BO("bo(%p) key(%lu)\n", bo, key);
1129 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1130 _tbm_bufmgr_mutex_unlock();
1134 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1136 user_data_delete(old_data);
1138 _tbm_bufmgr_mutex_unlock();
1144 tbm_bo_set_user_data(tbm_bo bo, unsigned long key, void *data)
1146 tbm_user_data *old_data;
1148 _tbm_bufmgr_mutex_lock();
1149 _tbm_set_last_result(TBM_ERROR_NONE);
1151 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1153 if (LIST_IS_EMPTY(&bo->user_data_list)) {
1154 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1155 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1156 _tbm_bufmgr_mutex_unlock();
1160 old_data = user_data_lookup(&bo->user_data_list, key);
1162 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1163 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1164 _tbm_bufmgr_mutex_unlock();
1168 if (old_data->data && old_data->free_func)
1169 old_data->free_func(old_data->data);
1170 old_data->data = data;
1172 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1174 _tbm_bufmgr_mutex_unlock();
1180 tbm_bo_get_user_data(tbm_bo bo, unsigned long key, void **data)
1182 tbm_user_data *old_data;
1184 _tbm_bufmgr_mutex_lock();
1185 _tbm_set_last_result(TBM_ERROR_NONE);
1187 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1189 if (!data || LIST_IS_EMPTY(&bo->user_data_list)) {
1190 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1191 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1192 _tbm_bufmgr_mutex_unlock();
1196 old_data = user_data_lookup(&bo->user_data_list, key);
1199 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1200 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1201 _tbm_bufmgr_mutex_unlock();
1205 *data = old_data->data;
1207 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1209 _tbm_bufmgr_mutex_unlock();
1215 tbm_bo_get_flags(tbm_bo bo)
1219 _tbm_bufmgr_mutex_lock();
1221 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1225 TBM_TRACE_BO("bo(%p)\n", bo);
1227 _tbm_bufmgr_mutex_unlock();
1232 /* LCOV_EXCL_START */
1233 /* internal function */
1235 _tbm_bo_set_surface(tbm_bo bo, tbm_surface_h surface)
1237 _tbm_bufmgr_mutex_lock();
1239 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1241 bo->surface = surface;
1243 _tbm_bufmgr_mutex_unlock();
1249 _tbm_bo_free(tbm_bo bo)
1251 /* destory the user_data_list */
1252 if (!LIST_IS_EMPTY(&bo->user_data_list)) {
1253 tbm_user_data *old_data = NULL, *tmp;
1255 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp,
1256 &bo->user_data_list, item_link) {
1257 TBM_DBG("free user_data\n");
1258 user_data_delete(old_data);
1262 while (bo->lock_cnt > 0) {
1263 TBM_ERR("error lock_cnt:%d\n", bo->lock_cnt);
1268 /* call the bo_free */
1269 if (bo->bufmgr->use_hal_tbm) {
1270 // call hal_tbm_bo_free when bo is created by tbm_bo_alloc api.
1271 if (!bo->get_from_hal_surface) {
1272 bo->get_from_hal_surface = 0;
1274 hal_tbm_bo_free(bo->bo_data);
1277 } else if (bo->bufmgr->backend_module_data) {
1278 bo->bufmgr->bo_func->bo_free(bo->bo_data);
1281 bo->bufmgr->backend->bo_free(bo);
1289 /* LCOV_EXCL_STOP */