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 **************************************************************************/
34 #include "tbm_bufmgr.h"
35 #include "tbm_bufmgr_int.h"
36 #include "tbm_bufmgr_backend.h"
39 #include <sys/resource.h>
50 static pthread_mutex_t gLock = PTHREAD_MUTEX_INITIALIZER;
51 static pthread_mutex_t tbm_bufmgr_lock = PTHREAD_MUTEX_INITIALIZER;
52 static double scale_factor = 0;
53 static void _tbm_bufmgr_mutex_unlock(void);
55 //#define TBM_BUFMGR_INIT_TIME
57 #define PREFIX_LIB "libtbm_"
58 #define SUFFIX_LIB ".so"
59 #define DEFAULT_LIB PREFIX_LIB"default"SUFFIX_LIB
61 /* values to indicate unspecified fields in XF86ModReqInfo. */
62 #define MAJOR_UNSPEC 0xFF
63 #define MINOR_UNSPEC 0xFF
64 #define PATCH_UNSPEC 0xFFFF
65 #define ABI_VERS_UNSPEC 0xFFFFFFFF
67 #define MODULE_VERSION_NUMERIC(maj, min, patch) \
68 ((((maj) & 0xFF) << 24) | (((min) & 0xFF) << 16) | (patch & 0xFFFF))
69 #define GET_MODULE_MAJOR_VERSION(vers) (((vers) >> 24) & 0xFF)
70 #define GET_MODULE_MINOR_VERSION(vers) (((vers) >> 16) & 0xFF)
71 #define GET_MODULE_PATCHLEVEL(vers) ((vers) & 0xFFFF)
73 #define MAX_SIZE_N(dest) (sizeof(dest) - strlen(dest) - 1)
76 #define TBM_BUFMGR_RETURN_IF_FAIL(cond) {\
78 TBM_ERR("'%s' failed.\n", #cond);\
79 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
80 _tbm_bufmgr_mutex_unlock();\
85 #define TBM_BUFMGR_RETURN_VAL_IF_FAIL(cond, val) {\
87 TBM_ERR("'%s' failed.\n", #cond);\
88 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
89 _tbm_bufmgr_mutex_unlock();\
96 _tbm_bufmgr_mutex_init(void)
98 static bool tbm_bufmgr_mutex_init = false;
100 if (tbm_bufmgr_mutex_init)
103 if (pthread_mutex_init(&tbm_bufmgr_lock, NULL)) {
104 TBM_ERR("fail: Cannot pthread_mutex_init for tbm_bufmgr_lock.\n");
108 tbm_bufmgr_mutex_init = true;
114 _tbm_bufmgr_mutex_lock(void)
116 if (!_tbm_bufmgr_mutex_init()) {
117 TBM_ERR("fail: _tbm_bufmgr_mutex_init()\n");
121 pthread_mutex_lock(&tbm_bufmgr_lock);
125 _tbm_bufmgr_mutex_unlock(void)
127 pthread_mutex_unlock(&tbm_bufmgr_lock);
131 _tbm_util_get_max_surface_size(int *w, int *h)
133 tbm_surface_info_s info;
134 tbm_surface_h surface = NULL;
140 if (gBufMgr == NULL || LIST_IS_EMPTY(&gBufMgr->surf_list))
143 LIST_FOR_EACH_ENTRY(surface, &gBufMgr->surf_list, item_link) {
144 if (tbm_surface_get_info(surface, &info) == TBM_SURFACE_ERROR_NONE) {
148 if (*h < info.height)
157 _tbm_util_get_appname_brief(char *brief)
161 char temp[255] = {0,};
162 char *saveptr = NULL;
164 token = strtok_r(brief, delim, &saveptr);
166 while (token != NULL) {
167 memset(temp, 0x00, 255 * sizeof(char));
168 strncpy(temp, token, 254 * sizeof(char));
169 token = strtok_r(NULL, delim, &saveptr);
172 snprintf(brief, sizeof(temp), "%s", temp);
176 _tbm_util_get_appname_from_pid(long pid, char *str)
178 char fn_cmdline[255] = {0, }, cmdline[255];
182 if (pid <= 0) return;
184 snprintf(fn_cmdline, sizeof(fn_cmdline), "/proc/%ld/cmdline", pid);
186 fp = fopen(fn_cmdline, "r");
188 TBM_ERR("cannot file open %s\n", fn_cmdline);
192 if (!fgets(cmdline, 255, fp)) {
193 TBM_ERR("fail to get appname for pid(%ld)\n", pid);
200 len = strlen(cmdline);
202 memset(cmdline, 0x00, 255);
206 snprintf(str, sizeof(cmdline), "%s", cmdline);
210 _check_version(TBMModuleVersionInfo *data)
212 int backend_module_major, backend_module_minor;
213 int tbm_backend_major, tbm_backend_minor;
215 backend_module_major = GET_ABI_MAJOR(data->abiversion);
216 backend_module_minor = GET_ABI_MINOR(data->abiversion);
218 TBM_DBG("TBM module %s: vendor=\"%s\" ABI=%d,%d\n",
219 data->modname ? data->modname : "UNKNOWN!",
220 data->vendor ? data->vendor : "UNKNOWN!", backend_module_major, backend_module_minor);
222 tbm_backend_major = GET_ABI_MAJOR(TBM_ABI_VERSION);
223 tbm_backend_minor = GET_ABI_MINOR(TBM_ABI_VERSION);
225 TBM_DBG("TBM ABI version %d.%d\n",
226 tbm_backend_major, tbm_backend_minor);
228 if (backend_module_major != tbm_backend_major) {
229 TBM_ERR("TBM module ABI major ver(%d) doesn't match the TBM's ver(%d)\n",
230 backend_module_major, tbm_backend_major);
232 } else if (backend_module_minor > tbm_backend_minor) {
233 TBM_ERR("TBM module ABI minor ver(%d) is newer than the TBM's ver(%d)\n",
234 backend_module_minor, tbm_backend_minor);
242 _tbm_backend_check_bufmgr_func(tbm_backend_bufmgr_func *bufmgr_func)
244 TBM_RETURN_VAL_IF_FAIL(bufmgr_func, 0); /* mandatory symbol */
245 TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_get_capabilities, 0); /* mandatory symbol */
246 TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_bind_native_display, 0); /* mandatory symbol */
247 TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_get_supported_formats, 0); /* mandatory symbol */
248 TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_get_plane_data, 0); /* mandatory symbol */
249 TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_alloc_bo, 0); /* mandatory symbol */
250 if (!bufmgr_func->bufmgr_alloc_bo_with_format)
251 TBM_DBG("No bufmgr_func->bufmgr_alloc_bo_with_format.");
252 TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_import_fd, 0); /* mandatory symbol */
253 if (!bufmgr_func->bufmgr_import_key)
254 TBM_DBG("No bufmgr_func->bo_export_key.");
260 _tbm_backend_check_bufmgr_bo(tbm_backend_bo_func *bo_func)
262 TBM_RETURN_VAL_IF_FAIL(bo_func, 0); /* mandatory symbol */
263 TBM_RETURN_VAL_IF_FAIL(bo_func->bo_free, 0); /* mandatory symbol */
264 TBM_RETURN_VAL_IF_FAIL(bo_func->bo_get_size, 0); /* mandatory symbol */
265 TBM_RETURN_VAL_IF_FAIL(bo_func->bo_get_memory_types, 0); /* mandatory symbol */
266 TBM_RETURN_VAL_IF_FAIL(bo_func->bo_get_handle, 0); /* mandatory symbol */
267 TBM_RETURN_VAL_IF_FAIL(bo_func->bo_map, 0); /* mandatory symbol */
268 TBM_RETURN_VAL_IF_FAIL(bo_func->bo_unmap, 0); /* mandatory symbol */
269 if (!bo_func->bo_lock)
270 TBM_DBG("No bo_func->bo_lock.");
271 if (!bo_func->bo_unlock)
272 TBM_DBG("No bo_func->bo_unlock.");
273 TBM_RETURN_VAL_IF_FAIL(bo_func->bo_export_fd, 0); /* mandatory symbol */
274 if (!bo_func->bo_export_key)
275 TBM_INFO("No bo_func->bo_export_key.");
281 _tbm_backend_load_module(tbm_bufmgr bufmgr, const char *file)
283 char path[PATH_MAX] = {0, };
284 void *module_data = NULL;
285 tbm_backend_module *backend_module_data = NULL;
286 tbm_backend_bufmgr_data *bufmgr_data = NULL;
287 int backend_module_major, backend_module_minor;
288 int tbm_backend_major, tbm_backend_minor;
291 snprintf(path, sizeof(path), BUFMGR_MODULE_DIR "/%s", file);
293 module_data = dlopen(path, RTLD_LAZY);
295 TBM_ERR("failed to load module: %s(%s)\n", dlerror(), file);
299 backend_module_data = dlsym(module_data, "tbm_backend_module_data");
300 if (!backend_module_data) {
301 TBM_ERR("Error: module does not have data object.\n");
305 tbm_backend_major = GET_ABI_MAJOR(TBM_BACKEND_ABI_LATEST_VERSION);
306 tbm_backend_minor = GET_ABI_MINOR(TBM_BACKEND_ABI_LATEST_VERSION);
307 TBM_INFO("TBM Backend ABI version %d.%d\n", tbm_backend_major, tbm_backend_minor);
309 backend_module_major = GET_ABI_MAJOR(backend_module_data->abi_version);
310 backend_module_minor = GET_ABI_MINOR(backend_module_data->abi_version);
312 TBM_INFO("TBM module %s: vendor=\"%s\" Backend ABI version=%d.%d\n",
313 backend_module_data->name ? backend_module_data->name : "UNKNOWN!",
314 backend_module_data->vendor ? backend_module_data->vendor : "UNKNOWN!",
315 backend_module_major, backend_module_minor);
317 if (backend_module_major > tbm_backend_major) {
318 TBM_ERR("TBM module ABI major ver(%d) is newer than the TBM's ver(%d)\n",
319 backend_module_major, tbm_backend_major);
321 } else if (backend_module_minor > tbm_backend_minor) {
322 TBM_ERR("TBM module ABI minor ver(%d) is newer than the TBM's ver(%d)\n",
323 backend_module_minor, tbm_backend_minor);
327 if (!backend_module_data->init) {
328 TBM_ERR("Error: module does not supply init symbol.\n");
332 if (!backend_module_data->deinit) {
333 TBM_ERR("Error: module does not supply deinit symbol.\n");
337 bufmgr_data = backend_module_data->init(bufmgr, &error);
339 TBM_ERR("Fail to init module(%s)\n", file);
343 /* check the mandatory symbols of the backend module */
344 if (!_tbm_backend_check_bufmgr_func(bufmgr->bufmgr_func)) {
345 TBM_ERR("Fail to check the bufmgr_func symboles.");
349 if (!_tbm_backend_check_bufmgr_bo(bufmgr->bo_func)) {
350 TBM_ERR("Fail to check the bufmgr_bo symboles.");
354 /* get the capability */
355 bufmgr->capabilities = bufmgr->bufmgr_func->bufmgr_get_capabilities(bufmgr_data, &error);
356 if (bufmgr->capabilities == TBM_BUFMGR_CAPABILITY_NONE) {
357 TBM_ERR("The capabilities of the backend module is TBM_BUFMGR_CAPABILITY_NONE.");
358 TBM_ERR("TBM_BUFMGR_CAPABILITY_SHARE_FD is the essential capability.");
362 if (!(bufmgr->capabilities & TBM_BUFMGR_CAPABILITY_SHARE_FD)) {
363 TBM_ERR("The capabilities of the backend module had no TBM_BUFMGR_CAPABILITY_SHARE_FD.");
364 TBM_ERR("The tbm backend has to get TBM_BUFMGR_CAPABILITY_SHARE_FD. ");
368 bufmgr->module_data = module_data;
369 bufmgr->backend_module_data = backend_module_data;
370 bufmgr->bufmgr_data = bufmgr_data;
372 TBM_DBG("Success to load module(%s)\n", file);
378 bufmgr->backend_module_data->deinit(bufmgr_data);
380 dlclose(module_data);
386 _tbm_bufmgr_load_module(tbm_bufmgr bufmgr, int fd, const char *file)
388 char path[PATH_MAX] = {0, };
389 TBMModuleVersionInfo *vers;
390 TBMModuleData *initdata;
394 snprintf(path, sizeof(path), BUFMGR_MODULE_DIR "/%s", file);
396 module_data = dlopen(path, RTLD_LAZY);
398 TBM_ERR("failed to load module: %s(%s)\n", dlerror(), file);
402 initdata = dlsym(module_data, "tbmModuleData");
404 TBM_ERR("Error: module does not have data object.\n");
408 vers = initdata->vers;
410 TBM_ERR("Error: module does not supply version information.\n");
414 init = initdata->init;
416 TBM_ERR("Error: module does not supply init symbol.\n");
420 if (!_check_version(vers)) {
421 TBM_ERR("Fail to check version.\n");
425 if (!init(bufmgr, fd)) {
426 TBM_ERR("Fail to init module(%s)\n", file);
430 if (!bufmgr->backend || !bufmgr->backend->priv) {
431 TBM_ERR("Error: module(%s) wrong operation. Check backend or backend's priv.\n", file);
435 bufmgr->module_data = module_data;
437 TBM_DBG("Success to load module(%s)\n", file);
442 dlclose(module_data);
447 _tbm_load_module(tbm_bufmgr bufmgr, int fd)
449 struct dirent **namelist;
452 /* try to load the new backend module */
453 ret = _tbm_backend_load_module(bufmgr, DEFAULT_LIB);
457 /* try to load the old(deprecated) backend mdoule */
458 ret = _tbm_bufmgr_load_module(bufmgr, fd, DEFAULT_LIB);
462 /* load bufmgr priv from configured path */
463 n = scandir(BUFMGR_MODULE_DIR, &namelist, 0, alphasort);
465 TBM_ERR("no files : %s\n", BUFMGR_MODULE_DIR);
470 if (!ret && strstr(namelist[n]->d_name, PREFIX_LIB)) {
471 const char *p = strstr(namelist[n]->d_name, SUFFIX_LIB);
473 if (p && !strcmp(p, SUFFIX_LIB)) {
474 ret = _tbm_backend_load_module(bufmgr, namelist[n]->d_name);
476 ret = _tbm_bufmgr_load_module(bufmgr, fd,
477 namelist[n]->d_name);
491 _tbm_bufmgr_init(int fd, int server)
493 #ifdef TBM_BUFMGR_INIT_TIME
494 struct timeval start_tv, end_tv;
498 #ifdef TBM_BUFMGR_INIT_TIME
499 /* get the start tv */
500 gettimeofday(&start_tv, NULL);
503 /* LCOV_EXCL_START */
505 env = getenv("TBM_DLOG");
508 TBM_DBG("TBM_DLOG=%s\n", env);
514 env = getenv("TBM_TRACE");
516 trace_mask = atoi(env);
517 TBM_DBG("TBM_TRACE=%s\n", env);
522 pthread_mutex_lock(&gLock);
524 _tbm_set_last_result(TBM_ERROR_NONE);
527 TBM_WRN("!!!!!WARNING:: The tbm_bufmgr_init DOSE NOT use argument fd ANYMORE.\n");
528 TBM_WRN("!!!!!WARNING:: IT WILL BE CHANGED like tbm_bufmgr_init(int fd) --> tbm_bufmgr_init(void).\n");
532 /* initialize buffer manager */
534 gBufMgr->ref_count++;
535 TBM_DBG("reuse tbm_bufmgr(%p) ref_count(%d) fd(%d)\n", gBufMgr, gBufMgr->ref_count, gBufMgr->fd);
536 pthread_mutex_unlock(&gLock);
540 TBM_DBG("bufmgr init\n");
542 /* allocate bufmgr */
543 gBufMgr = calloc(1, sizeof(struct _tbm_bufmgr));
545 TBM_ERR("error: fail to alloc bufmgr fd(%d)\n", fd);
546 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
547 pthread_mutex_unlock(&gLock);
553 /* set the display_server flag before loading the backend module */
555 TBM_INFO("The tbm_bufmgr(%p) is used by display server. Need to bind the native_display.\n", gBufMgr);
556 gBufMgr->display_server = 1;
559 /* load bufmgr priv from env */
560 if (!_tbm_load_module(gBufMgr, gBufMgr->fd)) {
561 TBM_ERR("error : Fail to load bufmgr backend\n");
562 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
565 pthread_mutex_unlock(&gLock);
571 gBufMgr->ref_count = 1;
573 TBM_INFO("create tizen bufmgr:%p ref_count:%d\n",
574 gBufMgr, gBufMgr->ref_count);
576 /* setup the bo_lock_type */
577 env = getenv("BUFMGR_LOCK_TYPE");
578 if (env && !strcmp(env, "always"))
579 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS;
580 else if (env && !strcmp(env, "none"))
581 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_NEVER;
582 else if (env && !strcmp(env, "once"))
583 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ONCE;
585 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS;
587 TBM_DBG("BUFMGR_LOCK_TYPE=%s\n", env ? env : "default:once");
589 /* intialize bo_list */
590 LIST_INITHEAD(&gBufMgr->bo_list);
592 /* intialize surf_list */
593 LIST_INITHEAD(&gBufMgr->surf_list);
595 /* intialize surf_queue_list */
596 LIST_INITHEAD(&gBufMgr->surf_queue_list);
598 /* intialize debug_key_list */
599 LIST_INITHEAD(&gBufMgr->debug_key_list);
601 #ifdef TBM_BUFMGR_INIT_TIME
603 gettimeofday(&end_tv, NULL);
604 TBM_INFO("tbm_bufmgr_init time: %ld ms", ((end_tv.tv_sec * 1000 + end_tv.tv_usec / 1000) - (start_tv.tv_sec * 1000 + start_tv.tv_usec / 1000)));
607 pthread_mutex_unlock(&gLock);
613 tbm_bufmgr_init(int fd)
617 bufmgr = _tbm_bufmgr_init(fd, 0);
623 tbm_bufmgr_deinit(tbm_bufmgr bufmgr)
625 TBM_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
627 _tbm_bufmgr_mutex_lock();
628 pthread_mutex_lock(&gLock);
629 _tbm_set_last_result(TBM_ERROR_NONE);
632 TBM_ERR("gBufmgr already destroy: bufmgr:%p\n", bufmgr);
633 pthread_mutex_unlock(&gLock);
634 _tbm_bufmgr_mutex_unlock();
639 if (bufmgr->ref_count > 0) {
640 TBM_DBG("reduce a ref_count(%d) of tbm_bufmgr(%p)\n", bufmgr->ref_count, bufmgr);
641 pthread_mutex_unlock(&gLock);
642 _tbm_bufmgr_mutex_unlock();
646 /* destroy bo_list */
647 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
648 tbm_bo bo = NULL, tmp;
650 LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &bufmgr->bo_list, item_link) {
651 TBM_ERR("Un-freed bo(%p, ref:%d)\n", bo, bo->ref_cnt);
654 LIST_DELINIT(&bufmgr->bo_list);
657 /* destroy surf_list */
658 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
659 tbm_surface_h surf = NULL, tmp;
661 LIST_FOR_EACH_ENTRY_SAFE(surf, tmp, &bufmgr->surf_list, item_link) {
662 TBM_ERR("Un-freed surf(%p, ref:%d)\n", surf, surf->refcnt);
663 tbm_surface_destroy(surf);
665 LIST_DELINIT(&bufmgr->surf_list);
668 if (bufmgr->backend_module_data) {
669 /* deinit and backend destroys the backend func and data */
670 bufmgr->backend_module_data->deinit(bufmgr->bufmgr_data);
671 bufmgr->bo_func = NULL;
672 bufmgr->bufmgr_func = NULL;
673 bufmgr->bufmgr_data = NULL;
674 bufmgr->backend_module_data = NULL;
676 /* destroy bufmgr priv */
677 bufmgr->backend->bufmgr_deinit(bufmgr->backend->priv);
678 bufmgr->backend->priv = NULL;
679 tbm_backend_free(bufmgr->backend);
680 bufmgr->backend = NULL;
683 TBM_INFO("destroy tbm_bufmgr(%p)\n", bufmgr);
685 dlclose(bufmgr->module_data);
693 pthread_mutex_unlock(&gLock);
694 _tbm_bufmgr_mutex_unlock();
698 tbm_bufmgr_get_capability(tbm_bufmgr bufmgr)
700 unsigned int capabilities = TBM_BUFMGR_CAPABILITY_NONE;
702 _tbm_bufmgr_mutex_lock();
703 _tbm_set_last_result(TBM_ERROR_NONE);
705 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), TBM_BUFMGR_CAPABILITY_NONE);
706 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, TBM_BUFMGR_CAPABILITY_NONE);
708 capabilities = bufmgr->capabilities;
710 _tbm_bufmgr_mutex_unlock();
715 /* LCOV_EXCL_START */
717 tbm_bufmgr_debug_tbm_info_get(tbm_bufmgr bufmgr)
719 char app_name[255] = {0,}, title[512] = {0,};
720 tbm_surface_debug_data *debug_old_data = NULL;
728 pthread_mutex_lock(&gLock);
729 _tbm_set_last_result(TBM_ERROR_NONE);
731 if (!TBM_BUFMGR_IS_VALID(bufmgr) || (bufmgr != gBufMgr)) {
732 TBM_ERR("invalid bufmgr\n");
733 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
734 pthread_mutex_unlock(&gLock);
740 TBM_ERR("Fail to allocate the string.\n");
741 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
742 pthread_mutex_unlock(&gLock);
746 TBM_SNRPRINTF(str, len, c, "\n");
747 pid = syscall(SYS_getpid);
748 _tbm_util_get_appname_from_pid(pid, app_name);
749 _tbm_util_get_appname_brief(app_name);
750 TBM_SNRPRINTF(str, len, c, "============TBM DEBUG: %s(%ld)===========================\n",
753 snprintf(title, 255, "%s", "no surface refcnt width height bpp size n_b n_p flags format app_name ");
755 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
756 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
757 strncat(title, " ", MAX_SIZE_N(title));
758 strncat(title, debug_old_data->key, MAX_SIZE_N(title));
762 TBM_SNRPRINTF(str, len, c, "[tbm_surface information]\n");
763 TBM_SNRPRINTF(str, len, c, "%s\n", title);
765 /* show the tbm_surface information in surf_list */
766 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
767 tbm_surface_h surf = NULL;
770 LIST_FOR_EACH_ENTRY(surf, &bufmgr->surf_list, item_link) {
771 char data[512] = {0,};
772 unsigned int surf_pid = 0;
775 surf_pid = _tbm_surface_internal_get_debug_pid(surf);
777 /* if pid is null, set the self_pid */
778 surf_pid = syscall(SYS_getpid);;
781 memset(app_name, 0x0, 255 * sizeof(char));
782 if (geteuid() == 0) {
783 _tbm_util_get_appname_from_pid(surf_pid, app_name);
784 _tbm_util_get_appname_brief(app_name);
786 snprintf(app_name, sizeof(app_name), "%d", surf_pid);
789 snprintf(data, 255, "%-2d %-9p %-4d %-5u %-6u %-3u %-6u %-2d %-2d %-3d %-8s %-15s",
796 surf->info.size / 1024,
800 _tbm_surface_internal_format_to_str(surf->info.format) + 11,
803 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
804 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
807 strncat(data, " ", MAX_SIZE_N(title));
809 value = _tbm_surface_internal_get_debug_data(surf, debug_old_data->key);
811 strncat(data, value, MAX_SIZE_N(title));
813 strncat(data, "none", MAX_SIZE_N(title));
816 TBM_SNRPRINTF(str, len, c, "%s\n", data);
818 for (i = 0; i < surf->num_bos; i++) {
819 if (bufmgr->backend_module_data) {
820 size = bufmgr->bo_func->bo_get_size(surf->bos[i]->bo_data, &error);
821 if (error != TBM_ERROR_NONE)
822 TBM_WRN("fail to get the size of bo.");
824 size = bufmgr->backend->bo_size(surf->bos[i]);
825 TBM_SNRPRINTF(str, len, c, " bo:%-12p %-26d%-10d\n",
827 surf->bos[i]->ref_cnt,
832 TBM_SNRPRINTF(str, len, c, " no tbm_surfaces.\n");
833 TBM_SNRPRINTF(str, len, c, "\n");
835 TBM_SNRPRINTF(str, len, c, "[tbm_bo information]\n");
836 TBM_SNRPRINTF(str, len, c, "no bo refcnt size lock_cnt map_cnt flags surface name\n");
838 /* show the tbm_bo information in bo_list */
839 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
844 LIST_FOR_EACH_ENTRY(bo, &bufmgr->bo_list, item_link) {
845 if (bufmgr->backend_module_data) {
846 size = bufmgr->bo_func->bo_get_size(bo->bo_data, &error);
847 if (error != TBM_ERROR_NONE)
848 TBM_WRN("fail to get the size of bo.");
849 key = bufmgr->bo_func->bo_export_key(bo->bo_data, &error);
850 if (error != TBM_ERROR_NONE)
851 TBM_WRN("fail to get the tdm_key of bo.");
853 size = bufmgr->backend->bo_size(bo);
854 key = bufmgr->backend->bo_export(bo);
856 TBM_SNRPRINTF(str, len, c, "%-4d%-11p %-4d %-6d %-5d %-4u %-3d %-11p %-4d\n",
868 TBM_SNRPRINTF(str, len, c, "no tbm_bos.\n");
869 TBM_SNRPRINTF(str, len, c, "\n");
871 TBM_SNRPRINTF(str, len, c, "===============================================================\n");
873 pthread_mutex_unlock(&gLock);
879 tbm_bufmgr_debug_show(tbm_bufmgr bufmgr)
882 str = tbm_bufmgr_debug_tbm_info_get(bufmgr);
890 tbm_bufmgr_debug_trace(tbm_bufmgr bufmgr, int onoff)
892 _tbm_bufmgr_mutex_lock();
893 _tbm_set_last_result(TBM_ERROR_NONE);
895 TBM_BUFMGR_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
896 TBM_BUFMGR_RETURN_IF_FAIL(bufmgr == gBufMgr);
899 TBM_LOG_D("bufmgr=%p onoff=%d\n", bufmgr, onoff);
903 _tbm_bufmgr_mutex_unlock();
907 tbm_bufmgr_debug_set_trace_mask(tbm_bufmgr bufmgr, tbm_bufmgr_debug_trace_mask mask, int set)
909 _tbm_bufmgr_mutex_lock();
910 _tbm_set_last_result(TBM_ERROR_NONE);
912 TBM_BUFMGR_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
913 TBM_BUFMGR_RETURN_IF_FAIL(bufmgr == gBufMgr);
918 TBM_INFO("bufmgr=%p sets the trace_mask=%d\n", bufmgr, mask);
919 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_BO)
920 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_BO");
921 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL)
922 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL");
923 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE)
924 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE");
925 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE)
926 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE");
927 } else if (set == 0) {
930 TBM_INFO("bufmgr=%p unsets the trace_mask=%d\n", bufmgr, mask);
931 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_BO)
932 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_BO");
933 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL)
934 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL");
935 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE)
936 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE");
937 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE)
938 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE");
940 TBM_WRN("set value is wrong.(set=%d)", set);
943 _tbm_bufmgr_mutex_unlock();
947 tbm_bufmgr_debug_dump_set_scale(double scale)
949 pthread_mutex_lock(&gLock);
950 _tbm_set_last_result(TBM_ERROR_NONE);
951 scale_factor = scale;
952 pthread_mutex_unlock(&gLock);
956 tbm_bufmgr_debug_get_ref_count(void)
960 pthread_mutex_lock(&gLock);
962 _tbm_set_last_result(TBM_ERROR_NONE);
964 refcnt = (gBufMgr) ? gBufMgr->ref_count : 0;
966 pthread_mutex_unlock(&gLock);
972 tbm_bufmgr_debug_queue_dump(char *path, int count, int onoff)
974 pthread_mutex_lock(&gLock);
975 _tbm_set_last_result(TBM_ERROR_NONE);
978 TBM_DBG("count=%d onoff=%d\n", count, onoff);
980 tbm_surface_internal_dump_end();
985 TBM_ERR("path is null");
986 pthread_mutex_unlock(&gLock);
989 TBM_DBG("path=%s count=%d onoff=%d\n", path, count, onoff);
991 if (_tbm_util_get_max_surface_size(&w, &h) == 0) {
992 TBM_ERR("Fail to get tbm_surface size.\n");
993 pthread_mutex_unlock(&gLock);
997 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
1003 pthread_mutex_unlock(&gLock);
1009 tbm_bufmgr_debug_dump_all(char *path)
1011 int w, h, count = 0;
1012 tbm_surface_h surface = NULL;
1014 pthread_mutex_lock(&gLock);
1015 _tbm_set_last_result(TBM_ERROR_NONE);
1018 TBM_ERR("path is null.\n");
1019 pthread_mutex_unlock(&gLock);
1023 TBM_DBG("path=%s\n", path);
1025 count = _tbm_util_get_max_surface_size(&w, &h);
1027 TBM_ERR("No tbm_surface.\n");
1028 pthread_mutex_unlock(&gLock);
1032 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
1035 LIST_FOR_EACH_ENTRY(surface, &gBufMgr->surf_list, item_link)
1036 tbm_surface_internal_dump_buffer(surface, "dump_all");
1038 tbm_surface_internal_dump_end();
1040 pthread_mutex_unlock(&gLock);
1045 /* internal function */
1047 _tbm_bufmgr_get_bufmgr(void)
1053 tbm_bufmgr_bind_native_display(tbm_bufmgr bufmgr, void *native_display)
1058 _tbm_bufmgr_mutex_lock();
1059 _tbm_set_last_result(TBM_ERROR_NONE);
1061 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1063 if (bufmgr->backend_module_data) {
1064 if (!bufmgr->bufmgr_func->bufmgr_bind_native_display) {
1065 TBM_WRN("skip: tbm_bufmgr(%p) native_display(%p)\n",
1066 bufmgr, native_display);
1067 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
1068 _tbm_bufmgr_mutex_unlock();
1072 error = bufmgr->bufmgr_func->bufmgr_bind_native_display(bufmgr->bufmgr_data, (tbm_native_display *)native_display);
1073 if (error != TBM_ERROR_NONE) {
1074 TBM_ERR("error: tbm_bufmgr(%p) native_display(%p) error(%d)\n",
1075 bufmgr, native_display, error);
1076 _tbm_set_last_result(error);
1077 _tbm_bufmgr_mutex_unlock();
1082 if (!bufmgr->backend->bufmgr_bind_native_display) {
1083 TBM_WRN("skip: tbm_bufmgr(%p) native_display(%p)\n",
1084 bufmgr, native_display);
1085 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
1086 _tbm_bufmgr_mutex_unlock();
1090 ret = bufmgr->backend->bufmgr_bind_native_display(bufmgr, native_display);
1092 TBM_ERR("error: tbm_bufmgr(%p) native_display(%p)\n",
1093 bufmgr, native_display);
1094 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1095 _tbm_bufmgr_mutex_unlock();
1100 TBM_INFO("tbm_bufmgr(%p) native_display(%p)\n", bufmgr, native_display);
1102 _tbm_bufmgr_mutex_unlock();
1108 tbm_bufmgr_server_init(void)
1112 bufmgr = _tbm_bufmgr_init(-1, 1);
1118 tbm_bufmgr_set_bo_lock_type(tbm_bufmgr bufmgr, tbm_bufmgr_bo_lock_type bo_lock_type)
1120 _tbm_bufmgr_mutex_lock();
1121 _tbm_set_last_result(TBM_ERROR_NONE);
1123 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1124 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, 0);
1126 pthread_mutex_lock(&gLock);
1127 gBufMgr->bo_lock_type = bo_lock_type;
1128 pthread_mutex_unlock(&gLock);
1130 TBM_INFO("The bo_lock_type of the bo is %d\n", bo_lock_type);
1132 _tbm_bufmgr_mutex_unlock();
1138 int tbm_bufmgr_get_fd_limit(void)
1142 if (getrlimit(RLIMIT_NOFILE, &lim))
1145 return (int)lim.rlim_cur;
1148 tbm_bufmgr tbm_bufmgr_get(void)
1152 /* LCOV_EXCL_STOP */