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,};
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 _tbm_util_get_appname_from_pid(surf_pid, app_name);
783 _tbm_util_get_appname_brief(app_name);
785 snprintf(data, 255, "%-2d %-9p %-4d %-5u %-6u %-3u %-6u %-2d %-2d %-3d %-8s %-15s",
792 surf->info.size / 1024,
796 _tbm_surface_internal_format_to_str(surf->info.format) + 11,
799 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
800 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
803 strncat(data, " ", MAX_SIZE_N(title));
805 value = _tbm_surface_internal_get_debug_data(surf, debug_old_data->key);
807 strncat(data, value, MAX_SIZE_N(title));
809 strncat(data, "none", MAX_SIZE_N(title));
812 TBM_SNRPRINTF(str, len, c, "%s\n", data);
814 for (i = 0; i < surf->num_bos; i++) {
815 if (bufmgr->backend_module_data) {
816 size = bufmgr->bo_func->bo_get_size(surf->bos[i]->bo_data, &error);
817 if (error != TBM_ERROR_NONE)
818 TBM_WRN("fail to get the size of bo.");
820 size = bufmgr->backend->bo_size(surf->bos[i]);
821 TBM_SNRPRINTF(str, len, c, " bo:%-12p %-26d%-10d\n",
823 surf->bos[i]->ref_cnt,
828 TBM_SNRPRINTF(str, len, c, " no tbm_surfaces.\n");
829 TBM_SNRPRINTF(str, len, c, "\n");
831 TBM_SNRPRINTF(str, len, c, "[tbm_bo information]\n");
832 TBM_SNRPRINTF(str, len, c, "no bo refcnt size lock_cnt map_cnt flags surface name\n");
834 /* show the tbm_bo information in bo_list */
835 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
840 LIST_FOR_EACH_ENTRY(bo, &bufmgr->bo_list, item_link) {
841 if (bufmgr->backend_module_data) {
842 size = bufmgr->bo_func->bo_get_size(bo->bo_data, &error);
843 if (error != TBM_ERROR_NONE)
844 TBM_WRN("fail to get the size of bo.");
845 key = bufmgr->bo_func->bo_export_key(bo->bo_data, &error);
846 if (error != TBM_ERROR_NONE)
847 TBM_WRN("fail to get the tdm_key of bo.");
849 size = bufmgr->backend->bo_size(bo);
850 key = bufmgr->backend->bo_export(bo);
852 TBM_SNRPRINTF(str, len, c, "%-4d%-11p %-4d %-6d %-5d %-4u %-3d %-11p %-4d\n",
864 TBM_SNRPRINTF(str, len, c, "no tbm_bos.\n");
865 TBM_SNRPRINTF(str, len, c, "\n");
867 TBM_SNRPRINTF(str, len, c, "===============================================================\n");
869 pthread_mutex_unlock(&gLock);
875 tbm_bufmgr_debug_show(tbm_bufmgr bufmgr)
878 str = tbm_bufmgr_debug_tbm_info_get(bufmgr);
886 tbm_bufmgr_debug_trace(tbm_bufmgr bufmgr, int onoff)
888 _tbm_bufmgr_mutex_lock();
889 _tbm_set_last_result(TBM_ERROR_NONE);
891 TBM_BUFMGR_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
892 TBM_BUFMGR_RETURN_IF_FAIL(bufmgr == gBufMgr);
895 TBM_LOG_D("bufmgr=%p onoff=%d\n", bufmgr, onoff);
899 _tbm_bufmgr_mutex_unlock();
903 tbm_bufmgr_debug_set_trace_mask(tbm_bufmgr bufmgr, tbm_bufmgr_debug_trace_mask mask, int set)
905 _tbm_bufmgr_mutex_lock();
906 _tbm_set_last_result(TBM_ERROR_NONE);
908 TBM_BUFMGR_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
909 TBM_BUFMGR_RETURN_IF_FAIL(bufmgr == gBufMgr);
914 TBM_INFO("bufmgr=%p sets the trace_mask=%d\n", bufmgr, mask);
915 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_BO)
916 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_BO");
917 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL)
918 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL");
919 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE)
920 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE");
921 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE)
922 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE");
923 } else if (set == 0) {
926 TBM_INFO("bufmgr=%p unsets the trace_mask=%d\n", bufmgr, mask);
927 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_BO)
928 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_BO");
929 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL)
930 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL");
931 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE)
932 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE");
933 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE)
934 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE");
936 TBM_WRN("set value is wrong.(set=%d)", set);
939 _tbm_bufmgr_mutex_unlock();
943 tbm_bufmgr_debug_dump_set_scale(double scale)
945 pthread_mutex_lock(&gLock);
946 _tbm_set_last_result(TBM_ERROR_NONE);
947 scale_factor = scale;
948 pthread_mutex_unlock(&gLock);
952 tbm_bufmgr_debug_get_ref_count(void)
956 pthread_mutex_lock(&gLock);
958 _tbm_set_last_result(TBM_ERROR_NONE);
960 refcnt = (gBufMgr) ? gBufMgr->ref_count : 0;
962 pthread_mutex_unlock(&gLock);
968 tbm_bufmgr_debug_queue_dump(char *path, int count, int onoff)
970 pthread_mutex_lock(&gLock);
971 _tbm_set_last_result(TBM_ERROR_NONE);
974 TBM_DBG("count=%d onoff=%d\n", count, onoff);
976 tbm_surface_internal_dump_end();
981 TBM_ERR("path is null");
982 pthread_mutex_unlock(&gLock);
985 TBM_DBG("path=%s count=%d onoff=%d\n", path, count, onoff);
987 if (_tbm_util_get_max_surface_size(&w, &h) == 0) {
988 TBM_ERR("Fail to get tbm_surface size.\n");
989 pthread_mutex_unlock(&gLock);
993 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
999 pthread_mutex_unlock(&gLock);
1005 tbm_bufmgr_debug_dump_all(char *path)
1007 int w, h, count = 0;
1008 tbm_surface_h surface = NULL;
1010 pthread_mutex_lock(&gLock);
1011 _tbm_set_last_result(TBM_ERROR_NONE);
1014 TBM_ERR("path is null.\n");
1015 pthread_mutex_unlock(&gLock);
1019 TBM_DBG("path=%s\n", path);
1021 count = _tbm_util_get_max_surface_size(&w, &h);
1023 TBM_ERR("No tbm_surface.\n");
1024 pthread_mutex_unlock(&gLock);
1028 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
1031 LIST_FOR_EACH_ENTRY(surface, &gBufMgr->surf_list, item_link)
1032 tbm_surface_internal_dump_buffer(surface, "dump_all");
1034 tbm_surface_internal_dump_end();
1036 pthread_mutex_unlock(&gLock);
1041 /* internal function */
1043 _tbm_bufmgr_get_bufmgr(void)
1049 tbm_bufmgr_bind_native_display(tbm_bufmgr bufmgr, void *native_display)
1054 _tbm_bufmgr_mutex_lock();
1055 _tbm_set_last_result(TBM_ERROR_NONE);
1057 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1059 if (bufmgr->backend_module_data) {
1060 if (!bufmgr->bufmgr_func->bufmgr_bind_native_display) {
1061 TBM_WRN("skip: tbm_bufmgr(%p) native_display(%p)\n",
1062 bufmgr, native_display);
1063 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
1064 _tbm_bufmgr_mutex_unlock();
1068 error = bufmgr->bufmgr_func->bufmgr_bind_native_display(bufmgr->bufmgr_data, (tbm_native_display *)native_display);
1069 if (error != TBM_ERROR_NONE) {
1070 TBM_ERR("error: tbm_bufmgr(%p) native_display(%p) error(%d)\n",
1071 bufmgr, native_display, error);
1072 _tbm_set_last_result(error);
1073 _tbm_bufmgr_mutex_unlock();
1078 if (!bufmgr->backend->bufmgr_bind_native_display) {
1079 TBM_WRN("skip: tbm_bufmgr(%p) native_display(%p)\n",
1080 bufmgr, native_display);
1081 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
1082 _tbm_bufmgr_mutex_unlock();
1086 ret = bufmgr->backend->bufmgr_bind_native_display(bufmgr, native_display);
1088 TBM_ERR("error: tbm_bufmgr(%p) native_display(%p)\n",
1089 bufmgr, native_display);
1090 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1091 _tbm_bufmgr_mutex_unlock();
1096 TBM_INFO("tbm_bufmgr(%p) native_display(%p)\n", bufmgr, native_display);
1098 _tbm_bufmgr_mutex_unlock();
1104 tbm_bufmgr_server_init(void)
1108 bufmgr = _tbm_bufmgr_init(-1, 1);
1114 tbm_bufmgr_set_bo_lock_type(tbm_bufmgr bufmgr, tbm_bufmgr_bo_lock_type bo_lock_type)
1116 _tbm_bufmgr_mutex_lock();
1117 _tbm_set_last_result(TBM_ERROR_NONE);
1119 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1120 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, 0);
1122 pthread_mutex_lock(&gLock);
1123 gBufMgr->bo_lock_type = bo_lock_type;
1124 pthread_mutex_unlock(&gLock);
1126 TBM_INFO("The bo_lock_type of the bo is %d\n", bo_lock_type);
1128 _tbm_bufmgr_mutex_unlock();
1134 int tbm_bufmgr_get_fd_limit(void)
1138 if (getrlimit(RLIMIT_NOFILE, &lim))
1141 return (int)lim.rlim_cur;
1144 tbm_bufmgr tbm_bufmgr_get(void)
1148 /* LCOV_EXCL_STOP */