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 bo_handle = tbm_module_bo_get_handle(bo->bufmgr->module, bo, bo->bo_data, device, &error);
525 if (bo_handle.ptr == NULL) {
526 /* LCOV_EXCL_START */
527 TBM_ERR("error: bo(%p) bo_handle(%p) error(%d)\n", bo, bo_handle.ptr, error);
528 _tbm_set_last_result(error);
529 _tbm_bufmgr_mutex_unlock();
530 return (tbm_bo_handle)NULL;
534 TBM_TRACE_BO("bo(%p) bo_handle(%p)\n", bo, bo_handle.ptr);
536 _tbm_bufmgr_mutex_unlock();
542 tbm_bo_export(tbm_bo bo)
547 _tbm_bufmgr_mutex_lock();
548 _tbm_set_last_result(TBM_ERROR_NONE);
550 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
552 if (bo->bufmgr->use_hal_tbm) {
553 ret = (hal_tbm_key)hal_tbm_bo_export_key((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
555 /* LCOV_EXCL_START */
556 TBM_ERR("error: bo(%p) tbm_key(%d) error(%d)\n", bo, ret, error);
557 _tbm_set_last_result(error);
561 } else if (bo->bufmgr->backend_module_data) {
562 if (!bo->bufmgr->bo_func->bo_export_key) {
563 /* LCOV_EXCL_START */
564 _tbm_bufmgr_mutex_unlock();
565 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
570 ret = bo->bufmgr->bo_func->bo_export_key(bo->bo_data, &error);
572 /* LCOV_EXCL_START */
573 TBM_ERR("error: bo(%p) tbm_key(%d) error(%d)\n", bo, ret, error);
574 _tbm_set_last_result(error);
579 if (!bo->bufmgr->backend->bo_export) {
580 /* LCOV_EXCL_START */
581 _tbm_bufmgr_mutex_unlock();
582 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
587 ret = bo->bufmgr->backend->bo_export(bo);
589 /* LCOV_EXCL_START */
590 TBM_ERR("error: bo(%p) tbm_key(%d)\n", bo, ret);
591 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
597 TBM_TRACE_BO("bo(%p) tbm_key(%u)\n", bo, ret);
600 _tbm_bufmgr_mutex_unlock();
606 tbm_bo_export_fd(tbm_bo bo)
611 _tbm_bufmgr_mutex_lock();
612 _tbm_set_last_result(TBM_ERROR_NONE);
614 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), -1);
616 if (bo->bufmgr->use_hal_tbm) {
617 ret = (hal_tbm_fd)hal_tbm_bo_export_fd((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
619 /* LCOV_EXCL_START */
620 TBM_ERR("error: bo(%p) tbm_fd(%d) error(%d)\n", bo, ret, error);
621 _tbm_set_last_result(error);
625 } else if (bo->bufmgr->backend_module_data) {
626 if (!bo->bufmgr->bo_func->bo_export_fd) {
627 /* LCOV_EXCL_START */
628 _tbm_bufmgr_mutex_unlock();
629 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
634 ret = bo->bufmgr->bo_func->bo_export_fd(bo->bo_data, &error);
636 /* LCOV_EXCL_START */
637 TBM_ERR("error: bo(%p) tbm_fd(%d) error(%d)\n", bo, ret, error);
638 _tbm_set_last_result(error);
643 if (!bo->bufmgr->backend->bo_export_fd) {
644 /* LCOV_EXCL_START */
645 _tbm_bufmgr_mutex_unlock();
646 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
651 ret = bo->bufmgr->backend->bo_export_fd(bo);
653 /* LCOV_EXCL_START */
654 TBM_ERR("error: bo(%p) tbm_fd(%d)\n", bo, ret);
655 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
661 TBM_TRACE_BO("bo(%p) tbm_fd(%d)\n", bo, ret);
664 _tbm_bufmgr_mutex_unlock();
670 tbm_bo_import(tbm_bufmgr bufmgr, unsigned int key)
675 _tbm_bufmgr_mutex_lock();
676 _tbm_set_last_result(TBM_ERROR_NONE);
678 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
680 bo = tbm_bufmgr_internal_import_bo_with_key(bufmgr, key, &error);
682 /* LCOV_EXCL_START */
683 TBM_ERR("tbm_bufmgr_internal_import_key failed. error:%d", error);
684 _tbm_set_last_result(error);
685 _tbm_bufmgr_mutex_unlock();
690 TBM_TRACE_BO("import new bo(%p) ref(%d) key(%d) flag(%s) in list\n",
691 bo, bo->ref_cnt, key, _tbm_flag_to_str(bo->flags));
693 _tbm_bufmgr_mutex_unlock();
699 tbm_bo_import_fd(tbm_bufmgr bufmgr, tbm_fd fd)
704 _tbm_bufmgr_mutex_lock();
705 _tbm_set_last_result(TBM_ERROR_NONE);
707 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
709 bo = tbm_bufmgr_internal_import_bo_with_fd(bufmgr, fd, &error);
711 /* LCOV_EXCL_START */
712 TBM_ERR("tbm_bufmgr_internal_import_fd failed. error:%d", error);
713 _tbm_set_last_result(error);
714 _tbm_bufmgr_mutex_unlock();
719 LIST_INITHEAD(&bo->user_data_list); // TODO: remove this. build-break when it is removed.
721 TBM_TRACE_BO("import bo(%p) ref(%d) fd(%d) flag(%s)\n",
722 bo, bo->ref_cnt, fd, _tbm_flag_to_str(bo->flags));
724 _tbm_bufmgr_mutex_unlock();
730 tbm_bo_size(tbm_bo bo)
735 _tbm_bufmgr_mutex_lock();
736 _tbm_set_last_result(TBM_ERROR_NONE);
738 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
740 size = tbm_module_bo_get_size(bo->bufmgr->module, bo, bo->bo_data, &error);
741 _tbm_set_last_result(error);
743 TBM_TRACE_BO("bo(%p) size(%d)\n", bo, size);
745 _tbm_bufmgr_mutex_unlock();
751 tbm_bo_locked(tbm_bo bo)
753 _tbm_bufmgr_mutex_lock();
754 _tbm_set_last_result(TBM_ERROR_NONE);
756 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
758 if (bo->bufmgr->bo_lock_type == TBM_BUFMGR_BO_LOCK_TYPE_NEVER) {
759 TBM_ERR("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
760 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
761 _tbm_bufmgr_mutex_unlock();
765 if (bo->lock_cnt > 0) {
766 TBM_TRACE_BO("error: bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
767 _tbm_bufmgr_mutex_unlock();
771 TBM_TRACE_BO("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
772 _tbm_bufmgr_mutex_unlock();
778 tbm_bo_swap(tbm_bo bo1, tbm_bo bo2)
780 tbm_error_e error1, error2;
781 int size1 = -1, size2 = -2;
784 _tbm_bufmgr_mutex_lock();
785 _tbm_set_last_result(TBM_ERROR_NONE);
787 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo1), 0);
788 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo2), 0);
790 TBM_TRACE_BO("before: bo1(%p) bo2(%p)\n", bo1, bo2);
792 size1 = tbm_module_bo_get_size(bo1->bufmgr->module, bo1, bo1->bo_data, &error1);
793 _tbm_set_last_result(error1);
794 size2 = tbm_module_bo_get_size(bo2->bufmgr->module, bo2, bo2->bo_data, &error2);
795 _tbm_set_last_result(error2);
797 if (size1 != size2) {
798 TBM_ERR("error: bo1 size(%d) and bo2 size(%d) is different.", size1, size2);
799 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
803 TBM_TRACE_BO("after: bo1(%p) bo2(%p)\n", bo1, bo2);
806 bo1->priv = bo2->priv;
809 _tbm_bufmgr_mutex_unlock();
814 TBM_ERR("error: bo1(%p) bo2(%p)\n", bo1, bo2);
815 _tbm_bufmgr_mutex_unlock();
821 tbm_bo_add_user_data(tbm_bo bo, unsigned long key,
822 tbm_data_free data_free_func)
826 _tbm_bufmgr_mutex_lock();
827 _tbm_set_last_result(TBM_ERROR_NONE);
829 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
831 /* check if the data according to the key exist if so, return false. */
832 data = user_data_lookup(&bo->user_data_list, key);
834 TBM_TRACE_BO("warning: user data already exist key(%ld)\n", key);
835 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
836 _tbm_bufmgr_mutex_unlock();
840 data = user_data_create(key, data_free_func);
842 TBM_ERR("error: bo(%p) key(%lu)\n", bo, key);
843 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
844 _tbm_bufmgr_mutex_unlock();
848 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, data->data);
850 LIST_ADD(&data->item_link, &bo->user_data_list);
852 _tbm_bufmgr_mutex_unlock();
858 tbm_bo_delete_user_data(tbm_bo bo, unsigned long key)
860 tbm_user_data *old_data;
862 _tbm_bufmgr_mutex_lock();
863 _tbm_set_last_result(TBM_ERROR_NONE);
865 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
867 if (LIST_IS_EMPTY(&bo->user_data_list)) {
868 TBM_TRACE_BO("bo(%p) key(%lu)\n", bo, key);
869 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
870 _tbm_bufmgr_mutex_unlock();
874 old_data = user_data_lookup(&bo->user_data_list, key);
876 TBM_TRACE_BO("bo(%p) key(%lu)\n", bo, key);
877 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
878 _tbm_bufmgr_mutex_unlock();
882 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
884 user_data_delete(old_data);
886 _tbm_bufmgr_mutex_unlock();
892 tbm_bo_set_user_data(tbm_bo bo, unsigned long key, void *data)
894 tbm_user_data *old_data;
896 _tbm_bufmgr_mutex_lock();
897 _tbm_set_last_result(TBM_ERROR_NONE);
899 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
901 if (LIST_IS_EMPTY(&bo->user_data_list)) {
902 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
903 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
904 _tbm_bufmgr_mutex_unlock();
908 old_data = user_data_lookup(&bo->user_data_list, key);
910 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
911 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
912 _tbm_bufmgr_mutex_unlock();
916 if (old_data->data && old_data->free_func)
917 old_data->free_func(old_data->data);
918 old_data->data = data;
920 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
922 _tbm_bufmgr_mutex_unlock();
928 tbm_bo_get_user_data(tbm_bo bo, unsigned long key, void **data)
930 tbm_user_data *old_data;
932 _tbm_bufmgr_mutex_lock();
933 _tbm_set_last_result(TBM_ERROR_NONE);
935 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
937 if (!data || LIST_IS_EMPTY(&bo->user_data_list)) {
938 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
939 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
940 _tbm_bufmgr_mutex_unlock();
944 old_data = user_data_lookup(&bo->user_data_list, key);
947 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
948 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
949 _tbm_bufmgr_mutex_unlock();
953 *data = old_data->data;
955 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
957 _tbm_bufmgr_mutex_unlock();
963 tbm_bo_get_flags(tbm_bo bo)
967 _tbm_bufmgr_mutex_lock();
969 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
973 TBM_TRACE_BO("bo(%p)\n", bo);
975 _tbm_bufmgr_mutex_unlock();
980 /* LCOV_EXCL_START */
981 /* internal function */
983 _tbm_bo_set_surface(tbm_bo bo, tbm_surface_h surface)
985 _tbm_bufmgr_mutex_lock();
987 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
989 bo->surface = surface;
991 _tbm_bufmgr_mutex_unlock();
997 _tbm_bo_free(tbm_bo bo)
999 /* destory the user_data_list */
1000 if (!LIST_IS_EMPTY(&bo->user_data_list)) {
1001 tbm_user_data *old_data = NULL, *tmp;
1003 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp,
1004 &bo->user_data_list, item_link) {
1005 TBM_DBG("free user_data\n");
1006 user_data_delete(old_data);
1010 while (bo->lock_cnt > 0) {
1011 TBM_ERR("error lock_cnt:%d\n", bo->lock_cnt);
1016 tbm_module_bo_free(bo->bufmgr->module, bo, bo->bo_data, bo->get_from_hal_surface);
1022 /* LCOV_EXCL_STOP */