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->backend_module_data) {
159 if (bo->bufmgr->bo_func->bo_lock) {
160 error = bo->bufmgr->bo_func->bo_lock(bo->bo_data, device, opt);
161 if (error != TBM_ERROR_NONE) {
162 TBM_WRN("fail to lock");
163 _tbm_set_last_result(error);
168 if (bo->bufmgr->backend->bo_lock) {
169 ret = bo->bufmgr->backend->bo_lock(bo, device, opt);
171 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
179 _bo_unlock(tbm_bo bo)
183 if (bo->bufmgr->backend_module_data) {
184 if (bo->bufmgr->bo_func->bo_unlock) {
185 error = bo->bufmgr->bo_func->bo_unlock(bo->bo_data);
186 if (error != TBM_ERROR_NONE) {
187 TBM_WRN("fail to unlock");
188 _tbm_set_last_result(error);
192 if (bo->bufmgr->backend->bo_unlock)
193 bo->bufmgr->backend->bo_unlock(bo);
198 _tbm_bo_lock(tbm_bo bo, int device, int opt)
205 /* do not try to lock the bo */
206 if (bo->bufmgr->bo_lock_type == TBM_BUFMGR_BO_LOCK_TYPE_NEVER)
209 if (bo->lock_cnt < 0) {
210 TBM_ERR("error bo:%p LOCK_CNT=%d\n",
217 switch (bo->bufmgr->bo_lock_type) {
218 case TBM_BUFMGR_BO_LOCK_TYPE_ONCE:
219 if (bo->lock_cnt == 0) {
220 _tbm_bufmgr_mutex_unlock();
221 ret = _bo_lock(bo, device, opt);
222 _tbm_bufmgr_mutex_lock();
228 case TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS:
229 _tbm_bufmgr_mutex_unlock();
230 ret = _bo_lock(bo, device, opt);
231 _tbm_bufmgr_mutex_lock();
236 TBM_ERR("error bo:%p bo_lock_type[%d] is wrong.\n",
237 bo, bo->bufmgr->bo_lock_type);
242 TBM_DBG(">> LOCK bo:%p(%d->%d)\n", bo, old, bo->lock_cnt);
248 _tbm_bo_unlock(tbm_bo bo)
252 /* do not try to unlock the bo */
253 if (bo->bufmgr->bo_lock_type == TBM_BUFMGR_BO_LOCK_TYPE_NEVER)
258 switch (bo->bufmgr->bo_lock_type) {
259 case TBM_BUFMGR_BO_LOCK_TYPE_ONCE:
260 if (bo->lock_cnt > 0) {
262 if (bo->lock_cnt == 0)
266 case TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS:
267 if (bo->lock_cnt > 0) {
273 TBM_ERR("error bo:%p bo_lock_type[%d] is wrong.\n",
274 bo, bo->bufmgr->bo_lock_type);
278 if (bo->lock_cnt < 0)
281 TBM_DBG(">> UNLOCK bo:%p(%d->%d)\n", bo, old, bo->lock_cnt);
285 _tbm_bo_magic_check(tbm_bo bo)
287 if (bo->magic != TBM_BO_MAGIC)
294 _tbm_bo_is_valid(tbm_bo bo)
297 TBM_ERR("error: bo is NULL.\n");
301 if (!_tbm_bo_magic_check(bo)) {
302 TBM_ERR("error: No valid bo(%p).\n", bo);
310 tbm_bo_alloc(tbm_bufmgr bufmgr, int size, int flags)
314 tbm_backend_bo_data *bo_data;
317 _tbm_bufmgr_mutex_lock();
318 _tbm_set_last_result(TBM_ERROR_NONE);
320 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
321 TBM_BO_RETURN_VAL_IF_FAIL(size > 0, NULL);
323 bo = calloc(1, sizeof(struct _tbm_bo));
325 /* LCOV_EXCL_START */
326 TBM_ERR("error: fail to create of tbm_bo size(%d) flag(%s)\n",
327 size, _tbm_flag_to_str(flags));
328 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
329 _tbm_bufmgr_mutex_unlock();
334 _tbm_util_check_bo_cnt(bufmgr);
338 if (bufmgr->backend_module_data) {
339 bo_data = bufmgr->bufmgr_func->bufmgr_alloc_bo(bufmgr->bufmgr_data, (unsigned int)size, flags, &error);
341 /* LCOV_EXCL_START */
342 TBM_ERR("error: fail to create of tbm_bo size(%d) flag(%s)\n",
343 size, _tbm_flag_to_str(flags));
344 _tbm_set_last_result(error);
346 _tbm_bufmgr_mutex_unlock();
350 bo->bo_data = bo_data;
352 bo_priv = bo->bufmgr->backend->bo_alloc(bo, size, flags);
354 /* LCOV_EXCL_START */
355 TBM_ERR("error: fail to create of tbm_bo size(%d) flag(%s)\n",
356 size, _tbm_flag_to_str(flags));
357 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
359 _tbm_bufmgr_mutex_unlock();
366 bo->bufmgr->bo_cnt++;
367 bo->magic = TBM_BO_MAGIC;
371 TBM_TRACE_BO("bo(%p) size(%d) refcnt(%d), flag(%s)\n", bo, size, bo->ref_cnt,
372 _tbm_flag_to_str(bo->flags));
374 LIST_INITHEAD(&bo->user_data_list);
376 LIST_ADD(&bo->item_link, &bo->bufmgr->bo_list);
378 _tbm_bufmgr_mutex_unlock();
384 tbm_bo_ref(tbm_bo bo)
386 _tbm_bufmgr_mutex_lock();
387 _tbm_set_last_result(TBM_ERROR_NONE);
389 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), NULL);
393 TBM_TRACE_BO("bo(%p) ref_cnt(%d)\n", bo, bo->ref_cnt);
395 _tbm_bufmgr_mutex_unlock();
401 tbm_bo_unref(tbm_bo bo)
403 _tbm_bufmgr_mutex_lock();
404 _tbm_set_last_result(TBM_ERROR_NONE);
406 TBM_BO_RETURN_IF_FAIL(_tbm_bo_is_valid(bo));
408 TBM_TRACE_BO("bo(%p) ref_cnt(%d)\n", bo, bo->ref_cnt - 1);
410 if (bo->ref_cnt <= 0) {
411 _tbm_bufmgr_mutex_unlock();
416 if (bo->ref_cnt == 0)
419 _tbm_bufmgr_mutex_unlock();
423 tbm_bo_map(tbm_bo bo, int device, int opt)
425 tbm_bo_handle bo_handle;
428 _tbm_bufmgr_mutex_lock();
429 _tbm_set_last_result(TBM_ERROR_NONE);
431 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) NULL);
433 if (!_tbm_bo_lock(bo, device, opt)) {
434 TBM_ERR("error: fail to lock bo:%p)\n", bo);
435 _tbm_bufmgr_mutex_unlock();
436 return (tbm_bo_handle) NULL;
439 if (bo->bufmgr->backend_module_data) {
440 bo_handle = bo->bufmgr->bo_func->bo_map(bo->bo_data, device, opt, &error);
441 if (bo_handle.ptr == NULL) {
442 /* LCOV_EXCL_START */
443 _tbm_set_last_result(error);
444 TBM_ERR("error: fail to map bo:%p error:%d\n", bo, error);
446 _tbm_bufmgr_mutex_unlock();
447 return (tbm_bo_handle) NULL;
451 bo_handle = bo->bufmgr->backend->bo_map(bo, device, opt);
452 if (bo_handle.ptr == NULL) {
453 /* LCOV_EXCL_START */
454 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
455 TBM_ERR("error: fail to map bo:%p\n", bo);
457 _tbm_bufmgr_mutex_unlock();
458 return (tbm_bo_handle) NULL;
463 /* increase the map_count */
466 TBM_TRACE_BO("bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
468 _tbm_bufmgr_mutex_unlock();
474 tbm_bo_unmap(tbm_bo bo)
479 _tbm_bufmgr_mutex_lock();
480 _tbm_set_last_result(TBM_ERROR_NONE);
482 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
483 TBM_BO_RETURN_VAL_IF_FAIL(bo->map_cnt > 0, 0);
485 if (bo->bufmgr->backend_module_data) {
486 error = bo->bufmgr->bo_func->bo_unmap(bo->bo_data);
487 if (error != TBM_ERROR_NONE) {
488 /* LCOV_EXCL_START */
489 TBM_ERR("error: bo(%p) map_cnt(%d) error(%d)\n", bo, bo->map_cnt, error);
490 _tbm_set_last_result(error);
492 _tbm_bufmgr_mutex_unlock();
497 ret = bo->bufmgr->backend->bo_unmap(bo);
499 /* LCOV_EXCL_START */
500 TBM_ERR("error: bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
501 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
502 _tbm_bufmgr_mutex_unlock();
508 /* decrease the map_count */
511 TBM_TRACE_BO("bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
515 _tbm_bufmgr_mutex_unlock();
521 tbm_bo_get_handle(tbm_bo bo, int device)
523 tbm_bo_handle bo_handle;
526 _tbm_bufmgr_mutex_lock();
527 _tbm_set_last_result(TBM_ERROR_NONE);
529 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) NULL);
531 if (bo->bufmgr->backend_module_data) {
532 bo_handle = bo->bufmgr->bo_func->bo_get_handle(bo->bo_data, device, &error);
533 if (bo_handle.ptr == NULL) {
534 /* LCOV_EXCL_START */
535 TBM_ERR("error: bo(%p) bo_handle(%p) error(%d)\n", bo, bo_handle.ptr, error);
536 _tbm_set_last_result(error);
537 _tbm_bufmgr_mutex_unlock();
538 return (tbm_bo_handle) NULL;
542 bo_handle = bo->bufmgr->backend->bo_get_handle(bo, device);
543 if (bo_handle.ptr == NULL) {
544 /* LCOV_EXCL_START */
545 TBM_ERR("error: bo(%p) bo_handle(%p)\n", bo, bo_handle.ptr);
546 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
547 _tbm_bufmgr_mutex_unlock();
548 return (tbm_bo_handle) NULL;
553 TBM_TRACE_BO("bo(%p) bo_handle(%p)\n", bo, bo_handle.ptr);
555 _tbm_bufmgr_mutex_unlock();
561 tbm_bo_export(tbm_bo bo)
566 _tbm_bufmgr_mutex_lock();
567 _tbm_set_last_result(TBM_ERROR_NONE);
569 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
571 if (bo->bufmgr->backend_module_data) {
572 if (!bo->bufmgr->bo_func->bo_export_key) {
573 /* LCOV_EXCL_START */
574 _tbm_bufmgr_mutex_unlock();
575 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
580 ret = bo->bufmgr->bo_func->bo_export_key(bo->bo_data, &error);
582 /* LCOV_EXCL_START */
583 TBM_ERR("error: bo(%p) tbm_key(%d) error(%d)\n", bo, ret, error);
584 _tbm_set_last_result(error);
585 _tbm_bufmgr_mutex_unlock();
590 if (!bo->bufmgr->backend->bo_export) {
591 /* LCOV_EXCL_START */
592 _tbm_bufmgr_mutex_unlock();
593 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
598 ret = bo->bufmgr->backend->bo_export(bo);
600 /* LCOV_EXCL_START */
601 TBM_ERR("error: bo(%p) tbm_key(%d)\n", bo, ret);
602 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
603 _tbm_bufmgr_mutex_unlock();
609 TBM_TRACE_BO("bo(%p) tbm_key(%u)\n", bo, ret);
611 _tbm_bufmgr_mutex_unlock();
617 tbm_bo_export_fd(tbm_bo bo)
622 _tbm_bufmgr_mutex_lock();
623 _tbm_set_last_result(TBM_ERROR_NONE);
625 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), -1);
627 if (bo->bufmgr->backend_module_data) {
628 if (!bo->bufmgr->bo_func->bo_export_fd) {
629 /* LCOV_EXCL_START */
630 _tbm_bufmgr_mutex_unlock();
631 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
636 ret = bo->bufmgr->bo_func->bo_export_fd(bo->bo_data, &error);
638 /* LCOV_EXCL_START */
639 TBM_ERR("error: bo(%p) tbm_fd(%d) error(%d)\n", bo, ret, error);
640 _tbm_set_last_result(error);
641 _tbm_bufmgr_mutex_unlock();
646 if (!bo->bufmgr->backend->bo_export_fd) {
647 /* LCOV_EXCL_START */
648 _tbm_bufmgr_mutex_unlock();
649 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
654 ret = bo->bufmgr->backend->bo_export_fd(bo);
656 /* LCOV_EXCL_START */
657 TBM_ERR("error: bo(%p) tbm_fd(%d)\n", bo, ret);
658 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
659 _tbm_bufmgr_mutex_unlock();
665 TBM_TRACE_BO("bo(%p) tbm_fd(%d)\n", bo, ret);
667 _tbm_bufmgr_mutex_unlock();
673 tbm_bo_import(tbm_bufmgr bufmgr, unsigned int key)
679 tbm_backend_bo_data *bo_data;
681 _tbm_bufmgr_mutex_lock();
682 _tbm_set_last_result(TBM_ERROR_NONE);
684 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
686 if (bufmgr->backend_module_data) {
687 if (!bufmgr->bufmgr_func->bufmgr_import_key) {
688 /* LCOV_EXCL_START */
689 _tbm_bufmgr_mutex_unlock();
690 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
695 if (!bufmgr->backend->bo_import) {
696 /* LCOV_EXCL_START */
697 _tbm_bufmgr_mutex_unlock();
698 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
704 _tbm_util_check_bo_cnt(bufmgr);
706 bo = calloc(1, sizeof(struct _tbm_bo));
708 /* LCOV_EXCL_START */
709 TBM_ERR("error: fail to import of tbm_bo by key(%d)\n", key);
710 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
711 _tbm_bufmgr_mutex_unlock();
718 if (bo->bufmgr->backend_module_data) {
719 bo_data = bo->bufmgr->bufmgr_func->bufmgr_import_key(bufmgr->bufmgr_data, key, &error);
721 /* LCOV_EXCL_START */
722 TBM_ERR("error: fail to import of tbm_bo by key(%d). error(%d)\n", key, error);
723 _tbm_set_last_result(error);
725 _tbm_bufmgr_mutex_unlock();
730 if (!LIST_IS_EMPTY(&bo->bufmgr->bo_list)) {
731 LIST_FOR_EACH_ENTRY(bo2, &bo->bufmgr->bo_list, item_link) {
732 if (bo2->bo_data == bo_data) {
733 TBM_TRACE_BO("find bo(%p) ref(%d) key(%d) flag(%s) in list\n",
734 bo2, bo2->ref_cnt, key,
735 _tbm_flag_to_str(bo2->flags));
738 _tbm_bufmgr_mutex_unlock();
743 bo->bo_data = bo_data;
745 bo_priv = bo->bufmgr->backend->bo_import(bo, key);
747 /* LCOV_EXCL_START */
748 TBM_ERR("error: fail to import of tbm_bo by key(%d)\n", key);
749 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
751 _tbm_bufmgr_mutex_unlock();
756 if (!LIST_IS_EMPTY(&bo->bufmgr->bo_list)) {
757 LIST_FOR_EACH_ENTRY(bo2, &bo->bufmgr->bo_list, item_link) {
758 if (bo2->priv == bo_priv) {
759 TBM_TRACE_BO("find bo(%p) ref(%d) key(%d) flag(%s) in list\n",
760 bo2, bo2->ref_cnt, key,
761 _tbm_flag_to_str(bo2->flags));
764 _tbm_bufmgr_mutex_unlock();
772 bo->bufmgr->bo_cnt++;
773 bo->magic = TBM_BO_MAGIC;
776 if (bo->bufmgr->backend_module_data) {
777 bo->flags = bo->bufmgr->bo_func->bo_get_memory_types(bo->bo_data, &error);
778 if (error != TBM_ERROR_NONE) {
779 TBM_ERR("fail to get the bo flags(memory_types)");
780 _tbm_set_last_result(error);
781 bo->flags = TBM_BO_DEFAULT;
784 if (bo->bufmgr->backend->bo_get_flags)
785 bo->flags = bo->bufmgr->backend->bo_get_flags(bo);
787 bo->flags = TBM_BO_DEFAULT;
790 TBM_TRACE_BO("import new bo(%p) ref(%d) key(%d) flag(%s) in list\n",
791 bo, bo->ref_cnt, key, _tbm_flag_to_str(bo->flags));
793 LIST_INITHEAD(&bo->user_data_list);
795 LIST_ADD(&bo->item_link, &bo->bufmgr->bo_list);
797 _tbm_bufmgr_mutex_unlock();
803 tbm_bo_import_fd(tbm_bufmgr bufmgr, tbm_fd fd)
808 tbm_backend_bo_data *bo_data;
811 _tbm_bufmgr_mutex_lock();
812 _tbm_set_last_result(TBM_ERROR_NONE);
814 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
816 if (bufmgr->backend_module_data) {
817 if (!bufmgr->bufmgr_func->bufmgr_import_fd) {
818 /* LCOV_EXCL_START */
819 _tbm_bufmgr_mutex_unlock();
820 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
825 if (!bufmgr->backend->bo_import_fd) {
826 /* LCOV_EXCL_START */
827 _tbm_bufmgr_mutex_unlock();
828 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
834 _tbm_util_check_bo_cnt(bufmgr);
836 bo = calloc(1, sizeof(struct _tbm_bo));
838 /* LCOV_EXCL_START */
839 TBM_ERR("error: fail to import tbm_bo by tbm_fd(%d)\n", fd);
840 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
841 _tbm_bufmgr_mutex_unlock();
848 if (bo->bufmgr->backend_module_data) {
849 bo_data = bo->bufmgr->bufmgr_func->bufmgr_import_fd(bufmgr->bufmgr_data, fd, &error);
851 /* LCOV_EXCL_START */
852 TBM_ERR("error: fail to import tbm_bo by tbm_fd(%d). error(%d)\n", fd, error);
853 _tbm_set_last_result(error);
855 _tbm_bufmgr_mutex_unlock();
860 if (!LIST_IS_EMPTY(&bo->bufmgr->bo_list)) {
861 LIST_FOR_EACH_ENTRY(bo2, &bo->bufmgr->bo_list, item_link) {
862 if (bo2->bo_data == bo_data) {
863 TBM_TRACE_BO("find bo(%p) ref(%d) fd(%d) flag(%s) in list\n",
864 bo2, bo2->ref_cnt, fd,
865 _tbm_flag_to_str(bo2->flags));
868 _tbm_bufmgr_mutex_unlock();
873 bo->bo_data = bo_data;
875 bo_priv = bo->bufmgr->backend->bo_import_fd(bo, fd);
877 /* LCOV_EXCL_START */
878 TBM_ERR("error: fail to import tbm_bo by tbm_fd(%d)\n", fd);
879 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
881 _tbm_bufmgr_mutex_unlock();
886 if (!LIST_IS_EMPTY(&bo->bufmgr->bo_list)) {
887 LIST_FOR_EACH_ENTRY(bo2, &bo->bufmgr->bo_list, item_link) {
888 if (bo2->priv == bo_priv) {
889 TBM_TRACE_BO("find bo(%p) ref(%d) fd(%d) flag(%s) in list\n",
890 bo2, bo2->ref_cnt, fd,
891 _tbm_flag_to_str(bo2->flags));
894 _tbm_bufmgr_mutex_unlock();
902 bo->bufmgr->bo_cnt++;
903 bo->magic = TBM_BO_MAGIC;
906 if (bo->bufmgr->backend_module_data) {
907 bo->flags = bo->bufmgr->bo_func->bo_get_memory_types(bo->bo_data, &error);
908 if (error != TBM_ERROR_NONE) {
909 TBM_ERR("fail to get the bo flags(memory_types)");
910 _tbm_set_last_result(error);
911 bo->flags = TBM_BO_DEFAULT;
914 if (bo->bufmgr->backend->bo_get_flags)
915 bo->flags = bo->bufmgr->backend->bo_get_flags(bo);
917 bo->flags = TBM_BO_DEFAULT;
920 TBM_TRACE_BO("import bo(%p) ref(%d) fd(%d) flag(%s)\n",
921 bo, bo->ref_cnt, fd, _tbm_flag_to_str(bo->flags));
923 LIST_INITHEAD(&bo->user_data_list);
925 LIST_ADD(&bo->item_link, &bo->bufmgr->bo_list);
927 _tbm_bufmgr_mutex_unlock();
933 tbm_bo_size(tbm_bo bo)
938 _tbm_bufmgr_mutex_lock();
939 _tbm_set_last_result(TBM_ERROR_NONE);
941 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
943 if (bo->bufmgr->backend_module_data) {
944 size = bo->bufmgr->bo_func->bo_get_size(bo->bo_data, &error);
945 if (error != TBM_ERROR_NONE) {
946 TBM_ERR("fail to get the size of the bo_data(%d).", error);
947 _tbm_set_last_result(TBM_ERROR_NONE);
950 size = bo->bufmgr->backend->bo_size(bo);
952 TBM_TRACE_BO("bo(%p) size(%d)\n", bo, size);
954 _tbm_bufmgr_mutex_unlock();
960 tbm_bo_locked(tbm_bo bo)
962 _tbm_bufmgr_mutex_lock();
963 _tbm_set_last_result(TBM_ERROR_NONE);
965 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
967 if (bo->bufmgr->bo_lock_type == TBM_BUFMGR_BO_LOCK_TYPE_NEVER) {
968 TBM_ERR("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
969 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
970 _tbm_bufmgr_mutex_unlock();
974 if (bo->lock_cnt > 0) {
975 TBM_TRACE_BO("error: bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
976 _tbm_bufmgr_mutex_unlock();
980 TBM_TRACE_BO("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
981 _tbm_bufmgr_mutex_unlock();
987 tbm_bo_swap(tbm_bo bo1, tbm_bo bo2)
989 tbm_error_e error1, error2;
990 int size1 = -1, size2 = -2;
993 _tbm_bufmgr_mutex_lock();
994 _tbm_set_last_result(TBM_ERROR_NONE);
996 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo1), 0);
997 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo2), 0);
999 TBM_TRACE_BO("before: bo1(%p) bo2(%p)\n", bo1, bo2);
1001 if (bo1->bufmgr->backend_module_data) {
1002 size1 = bo1->bufmgr->bo_func->bo_get_size(bo1->bo_data, &error1);
1003 if (error1 != TBM_ERROR_NONE) {
1004 TBM_ERR("fail to get the size of bo1.(%d)", error1);
1005 _tbm_set_last_result(error1);
1008 size2 = bo2->bufmgr->bo_func->bo_get_size(bo2->bo_data, &error2);
1009 if (error2 != TBM_ERROR_NONE) {
1010 TBM_ERR("fail to get the size of bo2.(%d)", error2);
1011 _tbm_set_last_result(error2);
1015 size1 = bo1->bufmgr->backend->bo_size(bo1);
1016 size2 = bo2->bufmgr->backend->bo_size(bo2);
1019 if (size1 != size2) {
1020 TBM_ERR("error: bo1 size(%d) and bo2 size(%d) is different.", size1, size2);
1021 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1025 TBM_TRACE_BO("after: bo1(%p) bo2(%p)\n", bo1, bo2);
1028 bo1->priv = bo2->priv;
1031 _tbm_bufmgr_mutex_unlock();
1036 TBM_ERR("error: bo1(%p) bo2(%p)\n", bo1, bo2);
1037 _tbm_bufmgr_mutex_unlock();
1043 tbm_bo_add_user_data(tbm_bo bo, unsigned long key,
1044 tbm_data_free data_free_func)
1046 tbm_user_data *data;
1048 _tbm_bufmgr_mutex_lock();
1049 _tbm_set_last_result(TBM_ERROR_NONE);
1051 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1053 /* check if the data according to the key exist if so, return false. */
1054 data = user_data_lookup(&bo->user_data_list, key);
1056 TBM_TRACE_BO("warning: user data already exist key(%ld)\n", key);
1057 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1058 _tbm_bufmgr_mutex_unlock();
1062 data = user_data_create(key, data_free_func);
1064 TBM_ERR("error: bo(%p) key(%lu)\n", bo, key);
1065 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1066 _tbm_bufmgr_mutex_unlock();
1070 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, data->data);
1072 LIST_ADD(&data->item_link, &bo->user_data_list);
1074 _tbm_bufmgr_mutex_unlock();
1080 tbm_bo_delete_user_data(tbm_bo bo, unsigned long key)
1082 tbm_user_data *old_data;
1084 _tbm_bufmgr_mutex_lock();
1085 _tbm_set_last_result(TBM_ERROR_NONE);
1087 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1089 if (LIST_IS_EMPTY(&bo->user_data_list)) {
1090 TBM_TRACE_BO("bo(%p) key(%lu)\n", bo, key);
1091 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1092 _tbm_bufmgr_mutex_unlock();
1096 old_data = user_data_lookup(&bo->user_data_list, key);
1098 TBM_TRACE_BO("bo(%p) key(%lu)\n", bo, key);
1099 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1100 _tbm_bufmgr_mutex_unlock();
1104 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1106 user_data_delete(old_data);
1108 _tbm_bufmgr_mutex_unlock();
1114 tbm_bo_set_user_data(tbm_bo bo, unsigned long key, void *data)
1116 tbm_user_data *old_data;
1118 _tbm_bufmgr_mutex_lock();
1119 _tbm_set_last_result(TBM_ERROR_NONE);
1121 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1123 if (LIST_IS_EMPTY(&bo->user_data_list)) {
1124 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1125 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1126 _tbm_bufmgr_mutex_unlock();
1130 old_data = user_data_lookup(&bo->user_data_list, key);
1132 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1133 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1134 _tbm_bufmgr_mutex_unlock();
1138 if (old_data->data && old_data->free_func)
1139 old_data->free_func(old_data->data);
1140 old_data->data = data;
1142 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1144 _tbm_bufmgr_mutex_unlock();
1150 tbm_bo_get_user_data(tbm_bo bo, unsigned long key, void **data)
1152 tbm_user_data *old_data;
1154 _tbm_bufmgr_mutex_lock();
1155 _tbm_set_last_result(TBM_ERROR_NONE);
1157 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1159 if (!data || LIST_IS_EMPTY(&bo->user_data_list)) {
1160 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1161 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1162 _tbm_bufmgr_mutex_unlock();
1166 old_data = user_data_lookup(&bo->user_data_list, key);
1169 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1170 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1171 _tbm_bufmgr_mutex_unlock();
1175 *data = old_data->data;
1177 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1179 _tbm_bufmgr_mutex_unlock();
1185 tbm_bo_get_flags(tbm_bo bo)
1189 _tbm_bufmgr_mutex_lock();
1191 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1195 TBM_TRACE_BO("bo(%p)\n", bo);
1197 _tbm_bufmgr_mutex_unlock();
1202 /* LCOV_EXCL_START */
1203 /* internal function */
1205 _tbm_bo_set_surface(tbm_bo bo, tbm_surface_h surface)
1207 _tbm_bufmgr_mutex_lock();
1209 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1211 bo->surface = surface;
1213 _tbm_bufmgr_mutex_unlock();
1219 _tbm_bo_free(tbm_bo bo)
1221 /* destory the user_data_list */
1222 if (!LIST_IS_EMPTY(&bo->user_data_list)) {
1223 tbm_user_data *old_data = NULL, *tmp;
1225 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp,
1226 &bo->user_data_list, item_link) {
1227 TBM_DBG("free user_data\n");
1228 user_data_delete(old_data);
1232 while (bo->lock_cnt > 0) {
1233 TBM_ERR("error lock_cnt:%d\n", bo->lock_cnt);
1238 /* call the bo_free */
1239 if (bo->bufmgr->backend_module_data) {
1240 bo->bufmgr->bo_func->bo_free(bo->bo_data);
1243 bo->bufmgr->backend->bo_free(bo);
1248 bo->bufmgr->bo_cnt--;
1250 LIST_DEL(&bo->item_link);
1253 /* LCOV_EXCL_STOP */