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");
92 user_data_lookup(struct list_head *user_data_list, unsigned long key)
94 tbm_user_data *old_data = NULL;
96 if (LIST_IS_EMPTY(user_data_list))
99 LIST_FOR_EACH_ENTRY(old_data, user_data_list, item_link) {
100 if (old_data->key == key)
108 user_data_create(unsigned long key, tbm_data_free data_free_func)
110 tbm_user_data *user_data;
112 user_data = calloc(1, sizeof(tbm_user_data));
114 /* LCOV_EXCL_START */
115 TBM_ERR("fail to allocate an user_date\n");
116 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
121 user_data->key = key;
122 user_data->free_func = data_free_func;
128 user_data_delete(tbm_user_data *user_data)
130 if (user_data->data && user_data->free_func)
131 user_data->free_func(user_data->data);
133 LIST_DEL(&user_data->item_link);
139 _bo_lock(tbm_bo bo, int device, int opt)
144 if (bo->bufmgr->use_hal_tbm) {
145 error = (tbm_error_e)hal_tbm_bo_lock((hal_tbm_bo *)bo->bo_data, device, opt);
146 if (error == TBM_ERROR_NOT_SUPPORTED) {
147 _tbm_set_last_result(TBM_ERROR_NONE);
149 if (error != TBM_ERROR_NONE) {
150 TBM_WRN("fail to lock");
151 _tbm_set_last_result(error);
155 } else if (bo->bufmgr->backend_module_data) {
156 if (bo->bufmgr->bo_func->bo_lock) {
157 error = bo->bufmgr->bo_func->bo_lock(bo->bo_data, device, opt);
158 if (error != TBM_ERROR_NONE) {
159 TBM_WRN("fail to lock");
160 _tbm_set_last_result(error);
165 if (bo->bufmgr->backend->bo_lock) {
166 ret = bo->bufmgr->backend->bo_lock(bo, device, opt);
168 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
176 _bo_unlock(tbm_bo bo)
180 if (bo->bufmgr->use_hal_tbm) {
181 error = (tbm_error_e)hal_tbm_bo_unlock((hal_tbm_bo *)bo->bo_data);
182 if (error == TBM_ERROR_NOT_SUPPORTED) {
183 _tbm_set_last_result(TBM_ERROR_NONE);
185 if (error != TBM_ERROR_NONE) {
186 TBM_WRN("fail to lock");
187 _tbm_set_last_result(error);
190 } else if (bo->bufmgr->backend_module_data) {
191 if (bo->bufmgr->bo_func->bo_unlock) {
192 error = bo->bufmgr->bo_func->bo_unlock(bo->bo_data);
193 if (error != TBM_ERROR_NONE) {
194 TBM_WRN("fail to unlock");
195 _tbm_set_last_result(error);
199 if (bo->bufmgr->backend->bo_unlock)
200 bo->bufmgr->backend->bo_unlock(bo);
205 _tbm_bo_lock(tbm_bo bo, int device, int opt)
212 /* do not try to lock the bo */
213 if (bo->bufmgr->bo_lock_type == TBM_BUFMGR_BO_LOCK_TYPE_NEVER)
216 if (bo->lock_cnt < 0) {
217 TBM_ERR("error bo:%p LOCK_CNT=%d\n",
224 switch (bo->bufmgr->bo_lock_type) {
225 case TBM_BUFMGR_BO_LOCK_TYPE_ONCE:
226 if (bo->lock_cnt == 0) {
227 _tbm_bufmgr_mutex_unlock();
228 ret = _bo_lock(bo, device, opt);
229 _tbm_bufmgr_mutex_lock();
235 case TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS:
236 _tbm_bufmgr_mutex_unlock();
237 ret = _bo_lock(bo, device, opt);
238 _tbm_bufmgr_mutex_lock();
243 TBM_ERR("error bo:%p bo_lock_type[%d] is wrong.\n",
244 bo, bo->bufmgr->bo_lock_type);
249 TBM_DBG(">> LOCK bo:%p(%d->%d)\n", bo, old, bo->lock_cnt);
255 _tbm_bo_unlock(tbm_bo bo)
259 /* do not try to unlock the bo */
260 if (bo->bufmgr->bo_lock_type == TBM_BUFMGR_BO_LOCK_TYPE_NEVER)
265 switch (bo->bufmgr->bo_lock_type) {
266 case TBM_BUFMGR_BO_LOCK_TYPE_ONCE:
267 if (bo->lock_cnt > 0) {
269 if (bo->lock_cnt == 0)
273 case TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS:
274 if (bo->lock_cnt > 0) {
280 TBM_ERR("error bo:%p bo_lock_type[%d] is wrong.\n",
281 bo, bo->bufmgr->bo_lock_type);
285 if (bo->lock_cnt < 0)
288 TBM_DBG(">> UNLOCK bo:%p(%d->%d)\n", bo, old, bo->lock_cnt);
292 _tbm_bo_magic_check(tbm_bo bo)
294 if (bo->magic != TBM_BO_MAGIC)
301 _tbm_bo_is_valid(tbm_bo bo)
304 TBM_ERR("error: bo is NULL.\n");
308 if (!_tbm_bo_magic_check(bo)) {
309 TBM_ERR("error: No valid bo(%p).\n", bo);
317 _tbm_bo_deinit(tbm_bo bo)
321 bo->bufmgr->bo_cnt--;
322 LIST_DEL(&bo->item_link);
326 tbm_bo_alloc(tbm_bufmgr bufmgr, int size, int flags)
331 _tbm_bufmgr_mutex_lock();
332 _tbm_set_last_result(TBM_ERROR_NONE);
334 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
335 TBM_BO_RETURN_VAL_IF_FAIL(size > 0, NULL);
337 bo = tbm_bufmgr_internal_alloc_bo(bufmgr, size, flags, &error);
339 /* LCOV_EXCL_START */
340 TBM_ERR("tbm_bufmgr_internal_alloc_bo failed. error:%d", error);
341 _tbm_set_last_result(error);
342 _tbm_bufmgr_mutex_unlock();
347 TBM_TRACE_BO("bo(%p) size(%d) refcnt(%d), flag(%s)\n", bo, size, bo->ref_cnt,
348 _tbm_flag_to_str(bo->flags));
350 _tbm_bufmgr_mutex_unlock();
356 tbm_bo_ref(tbm_bo bo)
358 _tbm_bufmgr_mutex_lock();
359 _tbm_set_last_result(TBM_ERROR_NONE);
361 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), NULL);
365 TBM_TRACE_BO("bo(%p) ref_cnt(%d)\n", bo, bo->ref_cnt);
367 _tbm_bufmgr_mutex_unlock();
373 tbm_bo_unref(tbm_bo bo)
375 _tbm_bufmgr_mutex_lock();
376 _tbm_set_last_result(TBM_ERROR_NONE);
378 TBM_BO_RETURN_IF_FAIL(_tbm_bo_is_valid(bo));
380 TBM_TRACE_BO("bo(%p) ref_cnt(%d)\n", bo, bo->ref_cnt - 1);
382 if (bo->ref_cnt <= 0) {
383 _tbm_bufmgr_mutex_unlock();
388 if (bo->ref_cnt == 0)
391 _tbm_bufmgr_mutex_unlock();
395 tbm_bo_map(tbm_bo bo, int device, int opt)
397 tbm_bo_handle bo_handle;
400 _tbm_bufmgr_mutex_lock();
401 _tbm_set_last_result(TBM_ERROR_NONE);
403 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) NULL);
405 if (!_tbm_bo_lock(bo, device, opt)) {
406 TBM_ERR("error: fail to lock bo:%p)\n", bo);
407 _tbm_bufmgr_mutex_unlock();
408 return (tbm_bo_handle) NULL;
411 if (bo->bufmgr->use_hal_tbm) {
412 hal_tbm_bo_handle hbo_handle;
413 hbo_handle = hal_tbm_bo_map((hal_tbm_bo *)bo->bo_data, device, opt, (hal_tbm_error *)&error);
414 if (hbo_handle.ptr == NULL) {
415 /* LCOV_EXCL_START */
416 _tbm_set_last_result(error);
417 TBM_ERR("error: bo(%p) bo_handle(%p) error(%d)\n", bo, hbo_handle.ptr, error);
421 memcpy(&bo_handle.ptr, &hbo_handle.ptr, sizeof(tbm_bo_handle));
422 } else if (bo->bufmgr->backend_module_data) {
423 bo_handle = bo->bufmgr->bo_func->bo_map(bo->bo_data, device, opt, &error);
424 if (bo_handle.ptr == NULL) {
425 /* LCOV_EXCL_START */
426 _tbm_set_last_result(error);
427 TBM_ERR("error: fail to map bo:%p error:%d\n", bo, error);
432 bo_handle = bo->bufmgr->backend->bo_map(bo, device, opt);
433 if (bo_handle.ptr == NULL) {
434 /* LCOV_EXCL_START */
435 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
436 TBM_ERR("error: fail to map bo:%p\n", bo);
442 /* increase the map_count */
445 TBM_TRACE_BO("bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
447 _tbm_bufmgr_mutex_unlock();
453 _tbm_bufmgr_mutex_unlock();
454 return (tbm_bo_handle) NULL;
458 tbm_bo_unmap(tbm_bo bo)
463 _tbm_bufmgr_mutex_lock();
464 _tbm_set_last_result(TBM_ERROR_NONE);
466 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
467 TBM_BO_RETURN_VAL_IF_FAIL(bo->map_cnt > 0, 0);
469 if (bo->bufmgr->use_hal_tbm) {
470 error = (hal_tbm_error)hal_tbm_bo_unmap((hal_tbm_bo *)bo->bo_data);
471 if (error != TBM_ERROR_NONE) {
472 /* LCOV_EXCL_START */
473 TBM_ERR("error: bo(%p) map_cnt(%d) error(%d)\n", bo, bo->map_cnt, error);
474 _tbm_set_last_result(error);
479 } else if (bo->bufmgr->backend_module_data) {
480 error = bo->bufmgr->bo_func->bo_unmap(bo->bo_data);
481 if (error != TBM_ERROR_NONE) {
482 /* LCOV_EXCL_START */
483 TBM_ERR("error: bo(%p) map_cnt(%d) error(%d)\n", bo, bo->map_cnt, error);
484 _tbm_set_last_result(error);
490 ret = bo->bufmgr->backend->bo_unmap(bo);
492 /* LCOV_EXCL_START */
493 TBM_ERR("error: bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
494 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
500 /* decrease the map_count */
503 TBM_TRACE_BO("bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
508 _tbm_bufmgr_mutex_unlock();
514 tbm_bo_get_handle(tbm_bo bo, int device)
516 tbm_bo_handle bo_handle;
519 _tbm_bufmgr_mutex_lock();
520 _tbm_set_last_result(TBM_ERROR_NONE);
522 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) NULL);
524 if (bo->bufmgr->use_hal_tbm) {
525 hal_tbm_bo_handle hbo_handle;
526 hbo_handle = hal_tbm_bo_get_handle((hal_tbm_bo *)bo->bo_data, device, (hal_tbm_error *)&error);
527 if (hbo_handle.ptr == NULL) {
528 /* LCOV_EXCL_START */
529 TBM_ERR("error: bo(%p) bo_handle(%p) error(%d)\n", bo, hbo_handle.ptr, error);
530 _tbm_set_last_result(error);
534 memcpy(&bo_handle.ptr, &hbo_handle.ptr, sizeof(tbm_bo_handle));
535 } else if (bo->bufmgr->backend_module_data) {
536 bo_handle = bo->bufmgr->bo_func->bo_get_handle(bo->bo_data, device, &error);
537 if (bo_handle.ptr == NULL) {
538 /* LCOV_EXCL_START */
539 TBM_ERR("error: bo(%p) bo_handle(%p) error(%d)\n", bo, bo_handle.ptr, error);
540 _tbm_set_last_result(error);
545 bo_handle = bo->bufmgr->backend->bo_get_handle(bo, device);
546 if (bo_handle.ptr == NULL) {
547 /* LCOV_EXCL_START */
548 TBM_ERR("error: bo(%p) bo_handle(%p)\n", bo, bo_handle.ptr);
549 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
555 TBM_TRACE_BO("bo(%p) bo_handle(%p)\n", bo, bo_handle.ptr);
557 _tbm_bufmgr_mutex_unlock();
562 _tbm_bufmgr_mutex_unlock();
563 return (tbm_bo_handle) NULL;
567 tbm_bo_export(tbm_bo bo)
572 _tbm_bufmgr_mutex_lock();
573 _tbm_set_last_result(TBM_ERROR_NONE);
575 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
577 if (bo->bufmgr->use_hal_tbm) {
578 ret = (hal_tbm_key)hal_tbm_bo_export_key((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
580 /* LCOV_EXCL_START */
581 TBM_ERR("error: bo(%p) tbm_key(%d) error(%d)\n", bo, ret, error);
582 _tbm_set_last_result(error);
586 } else if (bo->bufmgr->backend_module_data) {
587 if (!bo->bufmgr->bo_func->bo_export_key) {
588 /* LCOV_EXCL_START */
589 _tbm_bufmgr_mutex_unlock();
590 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
595 ret = bo->bufmgr->bo_func->bo_export_key(bo->bo_data, &error);
597 /* LCOV_EXCL_START */
598 TBM_ERR("error: bo(%p) tbm_key(%d) error(%d)\n", bo, ret, error);
599 _tbm_set_last_result(error);
604 if (!bo->bufmgr->backend->bo_export) {
605 /* LCOV_EXCL_START */
606 _tbm_bufmgr_mutex_unlock();
607 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
612 ret = bo->bufmgr->backend->bo_export(bo);
614 /* LCOV_EXCL_START */
615 TBM_ERR("error: bo(%p) tbm_key(%d)\n", bo, ret);
616 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
622 TBM_TRACE_BO("bo(%p) tbm_key(%u)\n", bo, ret);
625 _tbm_bufmgr_mutex_unlock();
631 tbm_bo_export_fd(tbm_bo bo)
636 _tbm_bufmgr_mutex_lock();
637 _tbm_set_last_result(TBM_ERROR_NONE);
639 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), -1);
641 if (bo->bufmgr->use_hal_tbm) {
642 ret = (hal_tbm_fd)hal_tbm_bo_export_fd((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
644 /* LCOV_EXCL_START */
645 TBM_ERR("error: bo(%p) tbm_fd(%d) error(%d)\n", bo, ret, error);
646 _tbm_set_last_result(error);
650 } else if (bo->bufmgr->backend_module_data) {
651 if (!bo->bufmgr->bo_func->bo_export_fd) {
652 /* LCOV_EXCL_START */
653 _tbm_bufmgr_mutex_unlock();
654 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
659 ret = bo->bufmgr->bo_func->bo_export_fd(bo->bo_data, &error);
661 /* LCOV_EXCL_START */
662 TBM_ERR("error: bo(%p) tbm_fd(%d) error(%d)\n", bo, ret, error);
663 _tbm_set_last_result(error);
668 if (!bo->bufmgr->backend->bo_export_fd) {
669 /* LCOV_EXCL_START */
670 _tbm_bufmgr_mutex_unlock();
671 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
676 ret = bo->bufmgr->backend->bo_export_fd(bo);
678 /* LCOV_EXCL_START */
679 TBM_ERR("error: bo(%p) tbm_fd(%d)\n", bo, ret);
680 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
686 TBM_TRACE_BO("bo(%p) tbm_fd(%d)\n", bo, ret);
689 _tbm_bufmgr_mutex_unlock();
695 tbm_bo_import(tbm_bufmgr bufmgr, unsigned int key)
700 _tbm_bufmgr_mutex_lock();
701 _tbm_set_last_result(TBM_ERROR_NONE);
703 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
705 bo = tbm_bufmgr_internal_import_bo_with_key(bufmgr, key, &error);
707 /* LCOV_EXCL_START */
708 TBM_ERR("tbm_bufmgr_internal_import_key failed. error:%d", error);
709 _tbm_set_last_result(error);
710 _tbm_bufmgr_mutex_unlock();
715 TBM_TRACE_BO("import new bo(%p) ref(%d) key(%d) flag(%s) in list\n",
716 bo, bo->ref_cnt, key, _tbm_flag_to_str(bo->flags));
718 _tbm_bufmgr_mutex_unlock();
724 tbm_bo_import_fd(tbm_bufmgr bufmgr, tbm_fd fd)
729 _tbm_bufmgr_mutex_lock();
730 _tbm_set_last_result(TBM_ERROR_NONE);
732 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
734 bo = tbm_bufmgr_internal_import_bo_with_fd(bufmgr, fd, &error);
736 /* LCOV_EXCL_START */
737 TBM_ERR("tbm_bufmgr_internal_import_fd failed. error:%d", error);
738 _tbm_set_last_result(error);
739 _tbm_bufmgr_mutex_unlock();
744 LIST_INITHEAD(&bo->user_data_list); // TODO: remove this. build-break when it is removed.
746 TBM_TRACE_BO("import bo(%p) ref(%d) fd(%d) flag(%s)\n",
747 bo, bo->ref_cnt, fd, _tbm_flag_to_str(bo->flags));
749 _tbm_bufmgr_mutex_unlock();
755 tbm_bo_size(tbm_bo bo)
760 _tbm_bufmgr_mutex_lock();
761 _tbm_set_last_result(TBM_ERROR_NONE);
763 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
765 if (bo->bufmgr->use_hal_tbm) {
766 size = hal_tbm_bo_get_size((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
767 if (error != TBM_ERROR_NONE) {
768 TBM_ERR("fail to get the size of the bo_data(%d).", error);
769 _tbm_set_last_result(TBM_ERROR_NONE);
771 } else if (bo->bufmgr->backend_module_data) {
772 size = bo->bufmgr->bo_func->bo_get_size(bo->bo_data, &error);
773 if (error != TBM_ERROR_NONE) {
774 TBM_ERR("fail to get the size of the bo_data(%d).", error);
775 _tbm_set_last_result(TBM_ERROR_NONE);
778 size = bo->bufmgr->backend->bo_size(bo);
780 TBM_TRACE_BO("bo(%p) size(%d)\n", bo, size);
782 _tbm_bufmgr_mutex_unlock();
788 tbm_bo_locked(tbm_bo bo)
790 _tbm_bufmgr_mutex_lock();
791 _tbm_set_last_result(TBM_ERROR_NONE);
793 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
795 if (bo->bufmgr->bo_lock_type == TBM_BUFMGR_BO_LOCK_TYPE_NEVER) {
796 TBM_ERR("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
797 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
798 _tbm_bufmgr_mutex_unlock();
802 if (bo->lock_cnt > 0) {
803 TBM_TRACE_BO("error: bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
804 _tbm_bufmgr_mutex_unlock();
808 TBM_TRACE_BO("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
809 _tbm_bufmgr_mutex_unlock();
815 tbm_bo_swap(tbm_bo bo1, tbm_bo bo2)
817 tbm_error_e error1, error2;
818 int size1 = -1, size2 = -2;
821 _tbm_bufmgr_mutex_lock();
822 _tbm_set_last_result(TBM_ERROR_NONE);
824 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo1), 0);
825 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo2), 0);
827 TBM_TRACE_BO("before: bo1(%p) bo2(%p)\n", bo1, bo2);
829 if (bo1->bufmgr->use_hal_tbm) {
830 size1 = hal_tbm_bo_get_size((hal_tbm_bo *)bo1->bo_data, (hal_tbm_error *)&error1);
831 if (error1 != TBM_ERROR_NONE) {
832 TBM_ERR("fail to get the size of bo1.(%d)", error1);
833 _tbm_set_last_result(error1);
836 size2 = hal_tbm_bo_get_size((hal_tbm_bo *)bo2->bo_data, (hal_tbm_error *)&error2);
837 if (error2 != TBM_ERROR_NONE) {
838 TBM_ERR("fail to get the size of bo1.(%d)", error2);
839 _tbm_set_last_result(error2);
842 } else if (bo1->bufmgr->backend_module_data) {
843 size1 = bo1->bufmgr->bo_func->bo_get_size(bo1->bo_data, &error1);
844 if (error1 != TBM_ERROR_NONE) {
845 TBM_ERR("fail to get the size of bo1.(%d)", error1);
846 _tbm_set_last_result(error1);
849 size2 = bo2->bufmgr->bo_func->bo_get_size(bo2->bo_data, &error2);
850 if (error2 != TBM_ERROR_NONE) {
851 TBM_ERR("fail to get the size of bo2.(%d)", error2);
852 _tbm_set_last_result(error2);
856 size1 = bo1->bufmgr->backend->bo_size(bo1);
857 size2 = bo2->bufmgr->backend->bo_size(bo2);
860 if (size1 != size2) {
861 TBM_ERR("error: bo1 size(%d) and bo2 size(%d) is different.", size1, size2);
862 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
866 TBM_TRACE_BO("after: bo1(%p) bo2(%p)\n", bo1, bo2);
869 bo1->priv = bo2->priv;
872 _tbm_bufmgr_mutex_unlock();
877 TBM_ERR("error: bo1(%p) bo2(%p)\n", bo1, bo2);
878 _tbm_bufmgr_mutex_unlock();
884 tbm_bo_add_user_data(tbm_bo bo, unsigned long key,
885 tbm_data_free data_free_func)
889 _tbm_bufmgr_mutex_lock();
890 _tbm_set_last_result(TBM_ERROR_NONE);
892 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
894 /* check if the data according to the key exist if so, return false. */
895 data = user_data_lookup(&bo->user_data_list, key);
897 TBM_TRACE_BO("warning: user data already exist key(%ld)\n", key);
898 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
899 _tbm_bufmgr_mutex_unlock();
903 data = user_data_create(key, data_free_func);
905 TBM_ERR("error: bo(%p) key(%lu)\n", bo, key);
906 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
907 _tbm_bufmgr_mutex_unlock();
911 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, data->data);
913 LIST_ADD(&data->item_link, &bo->user_data_list);
915 _tbm_bufmgr_mutex_unlock();
921 tbm_bo_delete_user_data(tbm_bo bo, unsigned long key)
923 tbm_user_data *old_data;
925 _tbm_bufmgr_mutex_lock();
926 _tbm_set_last_result(TBM_ERROR_NONE);
928 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
930 if (LIST_IS_EMPTY(&bo->user_data_list)) {
931 TBM_TRACE_BO("bo(%p) key(%lu)\n", bo, key);
932 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
933 _tbm_bufmgr_mutex_unlock();
937 old_data = user_data_lookup(&bo->user_data_list, key);
939 TBM_TRACE_BO("bo(%p) key(%lu)\n", bo, key);
940 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
941 _tbm_bufmgr_mutex_unlock();
945 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
947 user_data_delete(old_data);
949 _tbm_bufmgr_mutex_unlock();
955 tbm_bo_set_user_data(tbm_bo bo, unsigned long key, void *data)
957 tbm_user_data *old_data;
959 _tbm_bufmgr_mutex_lock();
960 _tbm_set_last_result(TBM_ERROR_NONE);
962 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
964 if (LIST_IS_EMPTY(&bo->user_data_list)) {
965 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
966 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
967 _tbm_bufmgr_mutex_unlock();
971 old_data = user_data_lookup(&bo->user_data_list, key);
973 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
974 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
975 _tbm_bufmgr_mutex_unlock();
979 if (old_data->data && old_data->free_func)
980 old_data->free_func(old_data->data);
981 old_data->data = data;
983 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
985 _tbm_bufmgr_mutex_unlock();
991 tbm_bo_get_user_data(tbm_bo bo, unsigned long key, void **data)
993 tbm_user_data *old_data;
995 _tbm_bufmgr_mutex_lock();
996 _tbm_set_last_result(TBM_ERROR_NONE);
998 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1000 if (!data || LIST_IS_EMPTY(&bo->user_data_list)) {
1001 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1002 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1003 _tbm_bufmgr_mutex_unlock();
1007 old_data = user_data_lookup(&bo->user_data_list, key);
1010 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1011 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1012 _tbm_bufmgr_mutex_unlock();
1016 *data = old_data->data;
1018 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1020 _tbm_bufmgr_mutex_unlock();
1026 tbm_bo_get_flags(tbm_bo bo)
1030 _tbm_bufmgr_mutex_lock();
1032 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1036 TBM_TRACE_BO("bo(%p)\n", bo);
1038 _tbm_bufmgr_mutex_unlock();
1043 /* LCOV_EXCL_START */
1044 /* internal function */
1046 _tbm_bo_set_surface(tbm_bo bo, tbm_surface_h surface)
1048 _tbm_bufmgr_mutex_lock();
1050 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1052 bo->surface = surface;
1054 _tbm_bufmgr_mutex_unlock();
1060 _tbm_bo_free(tbm_bo bo)
1062 /* destory the user_data_list */
1063 if (!LIST_IS_EMPTY(&bo->user_data_list)) {
1064 tbm_user_data *old_data = NULL, *tmp;
1066 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp,
1067 &bo->user_data_list, item_link) {
1068 TBM_DBG("free user_data\n");
1069 user_data_delete(old_data);
1073 while (bo->lock_cnt > 0) {
1074 TBM_ERR("error lock_cnt:%d\n", bo->lock_cnt);
1079 /* call the bo_free */
1080 if (bo->bufmgr->use_hal_tbm) {
1081 // call hal_tbm_bo_free when bo is created by tbm_bo_alloc api.
1082 if (!bo->get_from_hal_surface) {
1083 bo->get_from_hal_surface = 0;
1085 hal_tbm_bo_free(bo->bo_data);
1088 } else if (bo->bufmgr->backend_module_data) {
1089 bo->bufmgr->bo_func->bo_free(bo->bo_data);
1092 bo->bufmgr->backend->bo_free(bo);
1100 /* LCOV_EXCL_STOP */