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_init(tbm_bufmgr bufmgr, tbm_bo bo, int flags)
314 bo->magic = TBM_BO_MAGIC;
317 LIST_INITHEAD(&bo->user_data_list);
320 LIST_ADD(&bo->item_link, &bufmgr->bo_list);
324 _tbm_bo_deinit(tbm_bo bo)
328 bo->bufmgr->bo_cnt--;
329 LIST_DEL(&bo->item_link);
333 tbm_bo_alloc(tbm_bufmgr bufmgr, int size, int flags)
337 tbm_backend_bo_data *bo_data;
340 _tbm_bufmgr_mutex_lock();
341 _tbm_set_last_result(TBM_ERROR_NONE);
343 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
344 TBM_BO_RETURN_VAL_IF_FAIL(size > 0, NULL);
346 bo = calloc(1, sizeof(struct _tbm_bo));
348 /* LCOV_EXCL_START */
349 TBM_ERR("error: fail to create of tbm_bo size(%d) flag(%s)\n",
350 size, _tbm_flag_to_str(flags));
351 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
352 _tbm_bufmgr_mutex_unlock();
357 _tbm_util_check_bo_cnt(bufmgr);
359 if (bufmgr->backend_module_data) {
360 bo_data = bufmgr->bufmgr_func->bufmgr_alloc_bo(bufmgr->bufmgr_data, (unsigned int)size, flags, &error);
362 /* LCOV_EXCL_START */
363 TBM_ERR("error: fail to create of tbm_bo size(%d) flag(%s)\n",
364 size, _tbm_flag_to_str(flags));
365 _tbm_set_last_result(error);
367 _tbm_bufmgr_mutex_unlock();
371 bo->bo_data = bo_data;
373 bo_priv = bufmgr->backend->bo_alloc(bo, size, flags);
375 /* LCOV_EXCL_START */
376 TBM_ERR("error: fail to create of tbm_bo size(%d) flag(%s)\n",
377 size, _tbm_flag_to_str(flags));
378 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
380 _tbm_bufmgr_mutex_unlock();
387 _tbm_bo_init(bufmgr, bo, flags);
389 TBM_TRACE_BO("bo(%p) size(%d) refcnt(%d), flag(%s)\n", bo, size, bo->ref_cnt,
390 _tbm_flag_to_str(bo->flags));
392 _tbm_bufmgr_mutex_unlock();
397 /* LCOV_EXCL_START */
399 tbm_bo_alloc_with_format(tbm_bufmgr bufmgr, int format, int bo_idx, int width,
400 int height, tbm_bo_memory_type flags, tbm_error_e *error)
403 tbm_backend_bo_data *bo_data;
405 _tbm_bufmgr_mutex_lock();
406 _tbm_set_last_result(TBM_ERROR_NONE);
408 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
410 bo = calloc(1, sizeof(struct _tbm_bo));
412 TBM_ERR("error: fail to tbm_bo_alloc_with_format fmt(%s) idx(%d) w(%d) h(%d) mem_types(%s)\n",
413 FOURCC_STR(format), bo_idx, width, height, _tbm_flag_to_str(flags));
414 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
415 _tbm_bufmgr_mutex_unlock();
419 _tbm_util_check_bo_cnt(bufmgr);
421 if (!bufmgr->backend_module_data || !bufmgr->bufmgr_func->bufmgr_alloc_bo_with_format) {
422 /* LCOV_EXCL_START */
423 TBM_ERR("error: not supported tbm_bo_alloc_with_format\n");
424 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
426 _tbm_bufmgr_mutex_unlock();
431 bo_data = bufmgr->bufmgr_func->bufmgr_alloc_bo_with_format(bufmgr->bufmgr_data, format, bo_idx,
432 width, height, flags, error);
434 TBM_ERR("error: fail to tbm_bo_alloc_with_format fmt(%s) idx(%d) w(%d) h(%d) mem_types(%s)\n",
435 FOURCC_STR(format), bo_idx, width, height, _tbm_flag_to_str(flags));
436 _tbm_set_last_result(*error);
438 _tbm_bufmgr_mutex_unlock();
442 bo->bo_data = bo_data;
443 _tbm_bo_init(bufmgr, bo, flags);
445 _tbm_bufmgr_mutex_unlock();
451 tbm_bo_alloc_with_tiled_format(tbm_bufmgr bufmgr, int width, int height, int bpp, int format,
452 tbm_bo_memory_type flags, int bo_idx, tbm_error_e *error)
455 tbm_backend_bo_data *bo_data;
457 _tbm_bufmgr_mutex_lock();
458 _tbm_set_last_result(TBM_ERROR_NONE);
460 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
462 bo = calloc(1, sizeof(struct _tbm_bo));
464 TBM_ERR("error: fail to tbm_bo_alloc_with_tiled_format fmt(%s) idx(%d) w(%d) h(%d) flags(%s)\n",
465 FOURCC_STR(format), bo_idx, width, height, _tbm_flag_to_str(flags));
466 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
467 _tbm_bufmgr_mutex_unlock();
471 _tbm_util_check_bo_cnt(bufmgr);
473 if (!bufmgr->backend_module_data || !bufmgr->bufmgr_func->bufmgr_alloc_bo_with_tiled_format) {
474 TBM_ERR("error: not supported tbm_bo_alloc_with_tiled_format\n");
475 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
477 _tbm_bufmgr_mutex_unlock();
481 bo_data = bufmgr->bufmgr_func->bufmgr_alloc_bo_with_tiled_format(bufmgr->bufmgr_data, width, height,
482 bpp, format, flags, bo_idx, error);
484 TBM_ERR("error: fail to tbm_bo_alloc_with_tiled_format fmt(%s) idx(%d) w(%d) h(%d) flags(%s)\n",
485 FOURCC_STR(format), bo_idx, width, height, _tbm_flag_to_str(flags));
486 _tbm_set_last_result(*error);
488 _tbm_bufmgr_mutex_unlock();
492 bo->bo_data = bo_data;
493 _tbm_bo_init(bufmgr, bo, flags);
495 _tbm_bufmgr_mutex_unlock();
501 tbm_bo_alloc_with_surface(tbm_bufmgr bufmgr, int width, int height, int format, int flags, int bo_idx)
506 _tbm_bufmgr_mutex_lock();
507 _tbm_set_last_result(TBM_ERROR_NONE);
509 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
511 bo = calloc(1, sizeof(struct _tbm_bo));
513 TBM_ERR("error: fail to tbm_bo_alloc_with_surface fmt(%s) idx(%d) w(%d) h(%d) flags(%s)\n",
514 FOURCC_STR(format), bo_idx, width, height, _tbm_flag_to_str(flags));
515 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
516 _tbm_bufmgr_mutex_unlock();
520 _tbm_util_check_bo_cnt(bufmgr);
522 if (!bufmgr->backend->surface_bo_alloc) {
523 TBM_ERR("error: not supported tbm_bo_alloc_with_surface\n");
524 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
526 _tbm_bufmgr_mutex_unlock();
530 bo_priv = bufmgr->backend->surface_bo_alloc(bo, width, height, format, flags, bo_idx);
532 TBM_ERR("error: fail to tbm_bo_alloc_with_surface fmt(%s) idx(%d) w(%d) h(%d) flags(%s)\n",
533 FOURCC_STR(format), bo_idx, width, height, _tbm_flag_to_str(flags));
534 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
536 _tbm_bufmgr_mutex_unlock();
541 _tbm_bo_init(bufmgr, bo, flags);
543 _tbm_bufmgr_mutex_unlock();
550 tbm_bo_ref(tbm_bo bo)
552 _tbm_bufmgr_mutex_lock();
553 _tbm_set_last_result(TBM_ERROR_NONE);
555 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), NULL);
559 TBM_TRACE_BO("bo(%p) ref_cnt(%d)\n", bo, bo->ref_cnt);
561 _tbm_bufmgr_mutex_unlock();
567 tbm_bo_unref(tbm_bo bo)
569 _tbm_bufmgr_mutex_lock();
570 _tbm_set_last_result(TBM_ERROR_NONE);
572 TBM_BO_RETURN_IF_FAIL(_tbm_bo_is_valid(bo));
574 TBM_TRACE_BO("bo(%p) ref_cnt(%d)\n", bo, bo->ref_cnt - 1);
576 if (bo->ref_cnt <= 0) {
577 _tbm_bufmgr_mutex_unlock();
582 if (bo->ref_cnt == 0)
585 _tbm_bufmgr_mutex_unlock();
589 tbm_bo_map(tbm_bo bo, int device, int opt)
591 tbm_bo_handle bo_handle;
594 _tbm_bufmgr_mutex_lock();
595 _tbm_set_last_result(TBM_ERROR_NONE);
597 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) NULL);
599 if (!_tbm_bo_lock(bo, device, opt)) {
600 TBM_ERR("error: fail to lock bo:%p)\n", bo);
601 _tbm_bufmgr_mutex_unlock();
602 return (tbm_bo_handle) NULL;
605 if (bo->bufmgr->backend_module_data) {
606 bo_handle = bo->bufmgr->bo_func->bo_map(bo->bo_data, device, opt, &error);
607 if (bo_handle.ptr == NULL) {
608 /* LCOV_EXCL_START */
609 _tbm_set_last_result(error);
610 TBM_ERR("error: fail to map bo:%p error:%d\n", bo, error);
612 _tbm_bufmgr_mutex_unlock();
613 return (tbm_bo_handle) NULL;
617 bo_handle = bo->bufmgr->backend->bo_map(bo, device, opt);
618 if (bo_handle.ptr == NULL) {
619 /* LCOV_EXCL_START */
620 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
621 TBM_ERR("error: fail to map bo:%p\n", bo);
623 _tbm_bufmgr_mutex_unlock();
624 return (tbm_bo_handle) NULL;
629 /* increase the map_count */
632 TBM_TRACE_BO("bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
634 _tbm_bufmgr_mutex_unlock();
640 tbm_bo_unmap(tbm_bo bo)
645 _tbm_bufmgr_mutex_lock();
646 _tbm_set_last_result(TBM_ERROR_NONE);
648 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
649 TBM_BO_RETURN_VAL_IF_FAIL(bo->map_cnt > 0, 0);
651 if (bo->bufmgr->backend_module_data) {
652 error = bo->bufmgr->bo_func->bo_unmap(bo->bo_data);
653 if (error != TBM_ERROR_NONE) {
654 /* LCOV_EXCL_START */
655 TBM_ERR("error: bo(%p) map_cnt(%d) error(%d)\n", bo, bo->map_cnt, error);
656 _tbm_set_last_result(error);
658 _tbm_bufmgr_mutex_unlock();
663 ret = bo->bufmgr->backend->bo_unmap(bo);
665 /* LCOV_EXCL_START */
666 TBM_ERR("error: bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
667 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
668 _tbm_bufmgr_mutex_unlock();
674 /* decrease the map_count */
677 TBM_TRACE_BO("bo(%p) map_cnt(%d)\n", bo, bo->map_cnt);
681 _tbm_bufmgr_mutex_unlock();
687 tbm_bo_get_handle(tbm_bo bo, int device)
689 tbm_bo_handle bo_handle;
692 _tbm_bufmgr_mutex_lock();
693 _tbm_set_last_result(TBM_ERROR_NONE);
695 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), (tbm_bo_handle) NULL);
697 if (bo->bufmgr->backend_module_data) {
698 bo_handle = bo->bufmgr->bo_func->bo_get_handle(bo->bo_data, device, &error);
699 if (bo_handle.ptr == NULL) {
700 /* LCOV_EXCL_START */
701 TBM_ERR("error: bo(%p) bo_handle(%p) error(%d)\n", bo, bo_handle.ptr, error);
702 _tbm_set_last_result(error);
703 _tbm_bufmgr_mutex_unlock();
704 return (tbm_bo_handle) NULL;
708 bo_handle = bo->bufmgr->backend->bo_get_handle(bo, device);
709 if (bo_handle.ptr == NULL) {
710 /* LCOV_EXCL_START */
711 TBM_ERR("error: bo(%p) bo_handle(%p)\n", bo, bo_handle.ptr);
712 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
713 _tbm_bufmgr_mutex_unlock();
714 return (tbm_bo_handle) NULL;
719 TBM_TRACE_BO("bo(%p) bo_handle(%p)\n", bo, bo_handle.ptr);
721 _tbm_bufmgr_mutex_unlock();
727 tbm_bo_export(tbm_bo bo)
732 _tbm_bufmgr_mutex_lock();
733 _tbm_set_last_result(TBM_ERROR_NONE);
735 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
737 if (bo->bufmgr->backend_module_data) {
738 if (!bo->bufmgr->bo_func->bo_export_key) {
739 /* LCOV_EXCL_START */
740 _tbm_bufmgr_mutex_unlock();
741 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
746 ret = bo->bufmgr->bo_func->bo_export_key(bo->bo_data, &error);
748 /* LCOV_EXCL_START */
749 TBM_ERR("error: bo(%p) tbm_key(%d) error(%d)\n", bo, ret, error);
750 _tbm_set_last_result(error);
751 _tbm_bufmgr_mutex_unlock();
756 if (!bo->bufmgr->backend->bo_export) {
757 /* LCOV_EXCL_START */
758 _tbm_bufmgr_mutex_unlock();
759 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
764 ret = bo->bufmgr->backend->bo_export(bo);
766 /* LCOV_EXCL_START */
767 TBM_ERR("error: bo(%p) tbm_key(%d)\n", bo, ret);
768 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
769 _tbm_bufmgr_mutex_unlock();
775 TBM_TRACE_BO("bo(%p) tbm_key(%u)\n", bo, ret);
777 _tbm_bufmgr_mutex_unlock();
783 tbm_bo_export_fd(tbm_bo bo)
788 _tbm_bufmgr_mutex_lock();
789 _tbm_set_last_result(TBM_ERROR_NONE);
791 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), -1);
793 if (bo->bufmgr->backend_module_data) {
794 if (!bo->bufmgr->bo_func->bo_export_fd) {
795 /* LCOV_EXCL_START */
796 _tbm_bufmgr_mutex_unlock();
797 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
802 ret = bo->bufmgr->bo_func->bo_export_fd(bo->bo_data, &error);
804 /* LCOV_EXCL_START */
805 TBM_ERR("error: bo(%p) tbm_fd(%d) error(%d)\n", bo, ret, error);
806 _tbm_set_last_result(error);
807 _tbm_bufmgr_mutex_unlock();
812 if (!bo->bufmgr->backend->bo_export_fd) {
813 /* LCOV_EXCL_START */
814 _tbm_bufmgr_mutex_unlock();
815 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
820 ret = bo->bufmgr->backend->bo_export_fd(bo);
822 /* LCOV_EXCL_START */
823 TBM_ERR("error: bo(%p) tbm_fd(%d)\n", bo, ret);
824 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
825 _tbm_bufmgr_mutex_unlock();
831 TBM_TRACE_BO("bo(%p) tbm_fd(%d)\n", bo, ret);
833 _tbm_bufmgr_mutex_unlock();
839 tbm_bo_import(tbm_bufmgr bufmgr, unsigned int key)
845 tbm_backend_bo_data *bo_data;
848 _tbm_bufmgr_mutex_lock();
849 _tbm_set_last_result(TBM_ERROR_NONE);
851 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
853 if (bufmgr->backend_module_data) {
854 if (!bufmgr->bufmgr_func->bufmgr_import_key) {
855 /* LCOV_EXCL_START */
856 _tbm_bufmgr_mutex_unlock();
857 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
862 if (!bufmgr->backend->bo_import) {
863 /* LCOV_EXCL_START */
864 _tbm_bufmgr_mutex_unlock();
865 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
871 _tbm_util_check_bo_cnt(bufmgr);
873 bo = calloc(1, sizeof(struct _tbm_bo));
875 /* LCOV_EXCL_START */
876 TBM_ERR("error: fail to import of tbm_bo by key(%d)\n", key);
877 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
878 _tbm_bufmgr_mutex_unlock();
883 if (bufmgr->backend_module_data) {
884 bo_data = bufmgr->bufmgr_func->bufmgr_import_key(bufmgr->bufmgr_data, key, &error);
886 /* LCOV_EXCL_START */
887 TBM_ERR("error: fail to import of tbm_bo by key(%d). error(%d)\n", key, error);
888 _tbm_set_last_result(error);
890 _tbm_bufmgr_mutex_unlock();
895 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
896 LIST_FOR_EACH_ENTRY(bo2, &bufmgr->bo_list, item_link) {
897 if (bo2->bo_data == bo_data) {
898 TBM_TRACE_BO("find bo(%p) ref(%d) key(%d) flag(%s) in list\n",
899 bo2, bo2->ref_cnt, key,
900 _tbm_flag_to_str(bo2->flags));
903 _tbm_bufmgr_mutex_unlock();
908 bo->bo_data = bo_data;
910 bo_priv = bufmgr->backend->bo_import(bo, key);
912 /* LCOV_EXCL_START */
913 TBM_ERR("error: fail to import of tbm_bo by key(%d)\n", key);
914 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
916 _tbm_bufmgr_mutex_unlock();
921 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
922 LIST_FOR_EACH_ENTRY(bo2, &bufmgr->bo_list, item_link) {
923 if (bo2->priv == bo_priv) {
924 TBM_TRACE_BO("find bo(%p) ref(%d) key(%d) flag(%s) in list\n",
925 bo2, bo2->ref_cnt, key,
926 _tbm_flag_to_str(bo2->flags));
929 _tbm_bufmgr_mutex_unlock();
937 if (bufmgr->backend_module_data) {
938 flags = bufmgr->bo_func->bo_get_memory_types(bo->bo_data, &error);
939 if (error != TBM_ERROR_NONE) {
940 TBM_ERR("fail to get the bo flags(memory_types)");
941 _tbm_set_last_result(error);
942 flags = TBM_BO_DEFAULT;
945 if (bufmgr->backend->bo_get_flags)
946 flags = bufmgr->backend->bo_get_flags(bo);
948 flags = TBM_BO_DEFAULT;
951 _tbm_bo_init(bufmgr, bo, flags);
953 TBM_TRACE_BO("import new bo(%p) ref(%d) key(%d) flag(%s) in list\n",
954 bo, bo->ref_cnt, key, _tbm_flag_to_str(bo->flags));
956 _tbm_bufmgr_mutex_unlock();
962 tbm_bo_import_fd(tbm_bufmgr bufmgr, tbm_fd fd)
967 tbm_backend_bo_data *bo_data;
971 _tbm_bufmgr_mutex_lock();
972 _tbm_set_last_result(TBM_ERROR_NONE);
974 TBM_BO_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
976 if (bufmgr->backend_module_data) {
977 if (!bufmgr->bufmgr_func->bufmgr_import_fd) {
978 /* LCOV_EXCL_START */
979 _tbm_bufmgr_mutex_unlock();
980 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
985 if (!bufmgr->backend->bo_import_fd) {
986 /* LCOV_EXCL_START */
987 _tbm_bufmgr_mutex_unlock();
988 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
994 _tbm_util_check_bo_cnt(bufmgr);
996 bo = calloc(1, sizeof(struct _tbm_bo));
998 /* LCOV_EXCL_START */
999 TBM_ERR("error: fail to import tbm_bo by tbm_fd(%d)\n", fd);
1000 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1001 _tbm_bufmgr_mutex_unlock();
1003 /* LCOV_EXCL_STOP */
1006 if (bufmgr->backend_module_data) {
1007 bo_data = bufmgr->bufmgr_func->bufmgr_import_fd(bufmgr->bufmgr_data, fd, &error);
1009 /* LCOV_EXCL_START */
1010 TBM_ERR("error: fail to import tbm_bo by tbm_fd(%d). error(%d)\n", fd, error);
1011 _tbm_set_last_result(error);
1013 _tbm_bufmgr_mutex_unlock();
1015 /* LCOV_EXCL_STOP */
1018 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
1019 LIST_FOR_EACH_ENTRY(bo2, &bufmgr->bo_list, item_link) {
1020 if (bo2->bo_data == bo_data) {
1021 TBM_TRACE_BO("find bo(%p) ref(%d) fd(%d) flag(%s) in list\n",
1022 bo2, bo2->ref_cnt, fd,
1023 _tbm_flag_to_str(bo2->flags));
1026 _tbm_bufmgr_mutex_unlock();
1031 bo->bo_data = bo_data;
1033 bo_priv = bufmgr->backend->bo_import_fd(bo, fd);
1035 /* LCOV_EXCL_START */
1036 TBM_ERR("error: fail to import tbm_bo by tbm_fd(%d)\n", fd);
1037 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1039 _tbm_bufmgr_mutex_unlock();
1041 /* LCOV_EXCL_STOP */
1044 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
1045 LIST_FOR_EACH_ENTRY(bo2, &bufmgr->bo_list, item_link) {
1046 if (bo2->priv == bo_priv) {
1047 TBM_TRACE_BO("find bo(%p) ref(%d) fd(%d) flag(%s) in list\n",
1048 bo2, bo2->ref_cnt, fd,
1049 _tbm_flag_to_str(bo2->flags));
1052 _tbm_bufmgr_mutex_unlock();
1060 if (bufmgr->backend_module_data) {
1061 flags = bufmgr->bo_func->bo_get_memory_types(bo->bo_data, &error);
1062 if (error != TBM_ERROR_NONE) {
1063 TBM_ERR("fail to get the bo flags(memory_types)");
1064 _tbm_set_last_result(error);
1065 flags = TBM_BO_DEFAULT;
1068 if (bufmgr->backend->bo_get_flags)
1069 flags = bufmgr->backend->bo_get_flags(bo);
1071 flags = TBM_BO_DEFAULT;
1074 _tbm_bo_init(bufmgr, bo, flags);
1076 TBM_TRACE_BO("import bo(%p) ref(%d) fd(%d) flag(%s)\n",
1077 bo, bo->ref_cnt, fd, _tbm_flag_to_str(bo->flags));
1079 _tbm_bufmgr_mutex_unlock();
1085 tbm_bo_size(tbm_bo bo)
1090 _tbm_bufmgr_mutex_lock();
1091 _tbm_set_last_result(TBM_ERROR_NONE);
1093 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1095 if (bo->bufmgr->backend_module_data) {
1096 size = bo->bufmgr->bo_func->bo_get_size(bo->bo_data, &error);
1097 if (error != TBM_ERROR_NONE) {
1098 TBM_ERR("fail to get the size of the bo_data(%d).", error);
1099 _tbm_set_last_result(TBM_ERROR_NONE);
1102 size = bo->bufmgr->backend->bo_size(bo);
1104 TBM_TRACE_BO("bo(%p) size(%d)\n", bo, size);
1106 _tbm_bufmgr_mutex_unlock();
1112 tbm_bo_locked(tbm_bo bo)
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 (bo->bufmgr->bo_lock_type == TBM_BUFMGR_BO_LOCK_TYPE_NEVER) {
1120 TBM_ERR("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
1121 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1122 _tbm_bufmgr_mutex_unlock();
1126 if (bo->lock_cnt > 0) {
1127 TBM_TRACE_BO("error: bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
1128 _tbm_bufmgr_mutex_unlock();
1132 TBM_TRACE_BO("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
1133 _tbm_bufmgr_mutex_unlock();
1139 tbm_bo_swap(tbm_bo bo1, tbm_bo bo2)
1141 tbm_error_e error1, error2;
1142 int size1 = -1, size2 = -2;
1145 _tbm_bufmgr_mutex_lock();
1146 _tbm_set_last_result(TBM_ERROR_NONE);
1148 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo1), 0);
1149 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo2), 0);
1151 TBM_TRACE_BO("before: bo1(%p) bo2(%p)\n", bo1, bo2);
1153 if (bo1->bufmgr->backend_module_data) {
1154 size1 = bo1->bufmgr->bo_func->bo_get_size(bo1->bo_data, &error1);
1155 if (error1 != TBM_ERROR_NONE) {
1156 TBM_ERR("fail to get the size of bo1.(%d)", error1);
1157 _tbm_set_last_result(error1);
1160 size2 = bo2->bufmgr->bo_func->bo_get_size(bo2->bo_data, &error2);
1161 if (error2 != TBM_ERROR_NONE) {
1162 TBM_ERR("fail to get the size of bo2.(%d)", error2);
1163 _tbm_set_last_result(error2);
1167 size1 = bo1->bufmgr->backend->bo_size(bo1);
1168 size2 = bo2->bufmgr->backend->bo_size(bo2);
1171 if (size1 != size2) {
1172 TBM_ERR("error: bo1 size(%d) and bo2 size(%d) is different.", size1, size2);
1173 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1177 TBM_TRACE_BO("after: bo1(%p) bo2(%p)\n", bo1, bo2);
1180 bo1->priv = bo2->priv;
1183 _tbm_bufmgr_mutex_unlock();
1188 TBM_ERR("error: bo1(%p) bo2(%p)\n", bo1, bo2);
1189 _tbm_bufmgr_mutex_unlock();
1195 tbm_bo_add_user_data(tbm_bo bo, unsigned long key,
1196 tbm_data_free data_free_func)
1198 tbm_user_data *data;
1200 _tbm_bufmgr_mutex_lock();
1201 _tbm_set_last_result(TBM_ERROR_NONE);
1203 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1205 /* check if the data according to the key exist if so, return false. */
1206 data = user_data_lookup(&bo->user_data_list, key);
1208 TBM_TRACE_BO("warning: user data already exist key(%ld)\n", key);
1209 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1210 _tbm_bufmgr_mutex_unlock();
1214 data = user_data_create(key, data_free_func);
1216 TBM_ERR("error: bo(%p) key(%lu)\n", bo, key);
1217 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1218 _tbm_bufmgr_mutex_unlock();
1222 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, data->data);
1224 LIST_ADD(&data->item_link, &bo->user_data_list);
1226 _tbm_bufmgr_mutex_unlock();
1232 tbm_bo_delete_user_data(tbm_bo bo, unsigned long key)
1234 tbm_user_data *old_data;
1236 _tbm_bufmgr_mutex_lock();
1237 _tbm_set_last_result(TBM_ERROR_NONE);
1239 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1241 if (LIST_IS_EMPTY(&bo->user_data_list)) {
1242 TBM_TRACE_BO("bo(%p) key(%lu)\n", bo, key);
1243 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1244 _tbm_bufmgr_mutex_unlock();
1248 old_data = user_data_lookup(&bo->user_data_list, key);
1250 TBM_TRACE_BO("bo(%p) key(%lu)\n", bo, key);
1251 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1252 _tbm_bufmgr_mutex_unlock();
1256 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1258 user_data_delete(old_data);
1260 _tbm_bufmgr_mutex_unlock();
1266 tbm_bo_set_user_data(tbm_bo bo, unsigned long key, void *data)
1268 tbm_user_data *old_data;
1270 _tbm_bufmgr_mutex_lock();
1271 _tbm_set_last_result(TBM_ERROR_NONE);
1273 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1275 if (LIST_IS_EMPTY(&bo->user_data_list)) {
1276 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1277 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1278 _tbm_bufmgr_mutex_unlock();
1282 old_data = user_data_lookup(&bo->user_data_list, key);
1284 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1285 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1286 _tbm_bufmgr_mutex_unlock();
1290 if (old_data->data && old_data->free_func)
1291 old_data->free_func(old_data->data);
1292 old_data->data = data;
1294 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1296 _tbm_bufmgr_mutex_unlock();
1302 tbm_bo_get_user_data(tbm_bo bo, unsigned long key, void **data)
1304 tbm_user_data *old_data;
1306 _tbm_bufmgr_mutex_lock();
1307 _tbm_set_last_result(TBM_ERROR_NONE);
1309 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1311 if (!data || LIST_IS_EMPTY(&bo->user_data_list)) {
1312 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1313 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1314 _tbm_bufmgr_mutex_unlock();
1318 old_data = user_data_lookup(&bo->user_data_list, key);
1321 TBM_TRACE_BO("error: bo(%p) key(%lu)\n", bo, key);
1322 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
1323 _tbm_bufmgr_mutex_unlock();
1327 *data = old_data->data;
1329 TBM_TRACE_BO("bo(%p) key(%lu) data(%p)\n", bo, key, old_data->data);
1331 _tbm_bufmgr_mutex_unlock();
1337 tbm_bo_get_flags(tbm_bo bo)
1341 _tbm_bufmgr_mutex_lock();
1343 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1347 TBM_TRACE_BO("bo(%p)\n", bo);
1349 _tbm_bufmgr_mutex_unlock();
1354 /* LCOV_EXCL_START */
1355 /* internal function */
1357 _tbm_bo_set_surface(tbm_bo bo, tbm_surface_h surface)
1359 _tbm_bufmgr_mutex_lock();
1361 TBM_BO_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
1363 bo->surface = surface;
1365 _tbm_bufmgr_mutex_unlock();
1371 _tbm_bo_free(tbm_bo bo)
1373 /* destory the user_data_list */
1374 if (!LIST_IS_EMPTY(&bo->user_data_list)) {
1375 tbm_user_data *old_data = NULL, *tmp;
1377 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp,
1378 &bo->user_data_list, item_link) {
1379 TBM_DBG("free user_data\n");
1380 user_data_delete(old_data);
1384 while (bo->lock_cnt > 0) {
1385 TBM_ERR("error lock_cnt:%d\n", bo->lock_cnt);
1390 /* call the bo_free */
1391 if (bo->bufmgr->backend_module_data) {
1392 bo->bufmgr->bo_func->bo_free(bo->bo_data);
1395 bo->bufmgr->backend->bo_free(bo);
1403 /* LCOV_EXCL_STOP */