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 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);
373 TBM_STDOUT_INFO("Success to load module(%s)", file);
379 bufmgr->backend_module_data->deinit(bufmgr_data);
381 dlclose(module_data);
387 _tbm_bufmgr_load_module(tbm_bufmgr bufmgr, int fd, const char *file)
389 char path[PATH_MAX] = {0, };
390 TBMModuleVersionInfo *vers;
391 TBMModuleData *initdata;
395 snprintf(path, sizeof(path), BUFMGR_MODULE_DIR "/%s", file);
397 module_data = dlopen(path, RTLD_LAZY);
399 TBM_ERR("failed to load module: %s(%s)\n", dlerror(), file);
403 initdata = dlsym(module_data, "tbmModuleData");
405 TBM_ERR("Error: module does not have data object.\n");
409 vers = initdata->vers;
411 TBM_ERR("Error: module does not supply version information.\n");
415 init = initdata->init;
417 TBM_ERR("Error: module does not supply init symbol.\n");
421 if (!_check_version(vers)) {
422 TBM_ERR("Fail to check version.\n");
426 if (!init(bufmgr, fd)) {
427 TBM_ERR("Fail to init module(%s)\n", file);
431 if (!bufmgr->backend || !bufmgr->backend->priv) {
432 TBM_ERR("Error: module(%s) wrong operation. Check backend or backend's priv.\n", file);
436 bufmgr->module_data = module_data;
438 TBM_DBG("Success to load module(%s)\n", file);
443 dlclose(module_data);
448 _tbm_load_module(tbm_bufmgr bufmgr, int fd)
450 struct dirent **namelist;
453 /* try to load the new backend module */
454 ret = _tbm_backend_load_module(bufmgr, DEFAULT_LIB);
458 /* try to load the old(deprecated) backend mdoule */
459 ret = _tbm_bufmgr_load_module(bufmgr, fd, DEFAULT_LIB);
463 /* load bufmgr priv from configured path */
464 n = scandir(BUFMGR_MODULE_DIR, &namelist, 0, alphasort);
466 TBM_ERR("no files : %s\n", BUFMGR_MODULE_DIR);
471 if (!ret && strstr(namelist[n]->d_name, PREFIX_LIB)) {
472 const char *p = strstr(namelist[n]->d_name, SUFFIX_LIB);
474 if (p && !strcmp(p, SUFFIX_LIB)) {
475 ret = _tbm_backend_load_module(bufmgr, namelist[n]->d_name);
477 ret = _tbm_bufmgr_load_module(bufmgr, fd,
478 namelist[n]->d_name);
492 _tbm_bufmgr_init(int fd, int server)
494 #ifdef TBM_BUFMGR_INIT_TIME
495 struct timeval start_tv, end_tv;
499 #ifdef TBM_BUFMGR_INIT_TIME
500 /* get the start tv */
501 gettimeofday(&start_tv, NULL);
504 /* LCOV_EXCL_START */
506 env = getenv("TBM_DLOG");
509 TBM_DBG("TBM_DLOG=%s\n", env);
515 env = getenv("TBM_TRACE");
517 trace_mask = atoi(env);
518 TBM_DBG("TBM_TRACE=%s\n", env);
523 pthread_mutex_lock(&gLock);
525 _tbm_set_last_result(TBM_ERROR_NONE);
528 TBM_WRN("!!!!!WARNING:: The tbm_bufmgr_init DOSE NOT use argument fd ANYMORE.\n");
529 TBM_WRN("!!!!!WARNING:: IT WILL BE CHANGED like tbm_bufmgr_init(int fd) --> tbm_bufmgr_init(void).\n");
533 /* initialize buffer manager */
535 gBufMgr->ref_count++;
536 TBM_DBG("reuse tbm_bufmgr(%p) ref_count(%d) fd(%d)\n", gBufMgr, gBufMgr->ref_count, gBufMgr->fd);
537 pthread_mutex_unlock(&gLock);
541 TBM_DBG("bufmgr init\n");
543 /* allocate bufmgr */
544 gBufMgr = calloc(1, sizeof(struct _tbm_bufmgr));
546 TBM_ERR("error: fail to alloc bufmgr fd(%d)\n", fd);
547 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
548 pthread_mutex_unlock(&gLock);
554 /* set the display_server flag before loading the backend module */
556 TBM_INFO("The tbm_bufmgr(%p) is used by display server. Need to bind the native_display.\n", gBufMgr);
557 gBufMgr->display_server = 1;
560 /* load bufmgr priv from env */
561 TBM_STDOUT_INFO("loading backend module");
562 if (!_tbm_load_module(gBufMgr, gBufMgr->fd)) {
563 TBM_ERR("error : Fail to load bufmgr backend\n");
564 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
567 pthread_mutex_unlock(&gLock);
571 TBM_STDOUT_INFO("loading backend module done");
574 gBufMgr->ref_count = 1;
576 TBM_INFO("create tizen bufmgr:%p ref_count:%d\n",
577 gBufMgr, gBufMgr->ref_count);
579 /* setup the bo_lock_type */
580 env = getenv("BUFMGR_LOCK_TYPE");
581 if (env && !strcmp(env, "always"))
582 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS;
583 else if (env && !strcmp(env, "none"))
584 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_NEVER;
585 else if (env && !strcmp(env, "once"))
586 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ONCE;
588 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS;
590 TBM_DBG("BUFMGR_LOCK_TYPE=%s\n", env ? env : "default:once");
592 /* intialize bo_list */
593 LIST_INITHEAD(&gBufMgr->bo_list);
595 /* intialize surf_list */
596 LIST_INITHEAD(&gBufMgr->surf_list);
598 /* intialize surf_queue_list */
599 LIST_INITHEAD(&gBufMgr->surf_queue_list);
601 /* intialize debug_key_list */
602 LIST_INITHEAD(&gBufMgr->debug_key_list);
604 #ifdef TBM_BUFMGR_INIT_TIME
606 gettimeofday(&end_tv, NULL);
607 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)));
610 pthread_mutex_unlock(&gLock);
616 tbm_bufmgr_init(int fd)
620 bufmgr = _tbm_bufmgr_init(fd, 0);
626 tbm_bufmgr_deinit(tbm_bufmgr bufmgr)
628 TBM_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
630 _tbm_bufmgr_mutex_lock();
631 pthread_mutex_lock(&gLock);
632 _tbm_set_last_result(TBM_ERROR_NONE);
635 TBM_ERR("gBufmgr already destroy: bufmgr:%p\n", bufmgr);
636 pthread_mutex_unlock(&gLock);
637 _tbm_bufmgr_mutex_unlock();
642 if (bufmgr->ref_count > 0) {
643 TBM_DBG("reduce a ref_count(%d) of tbm_bufmgr(%p)\n", bufmgr->ref_count, bufmgr);
644 pthread_mutex_unlock(&gLock);
645 _tbm_bufmgr_mutex_unlock();
649 /* destroy bo_list */
650 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
651 tbm_bo bo = NULL, tmp;
653 LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &bufmgr->bo_list, item_link) {
654 TBM_ERR("Un-freed bo(%p, ref:%d)\n", bo, bo->ref_cnt);
657 LIST_DELINIT(&bufmgr->bo_list);
660 /* destroy surf_list */
661 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
662 tbm_surface_h surf = NULL, tmp;
664 LIST_FOR_EACH_ENTRY_SAFE(surf, tmp, &bufmgr->surf_list, item_link) {
665 TBM_ERR("Un-freed surf(%p, ref:%d)\n", surf, surf->refcnt);
666 tbm_surface_destroy(surf);
668 LIST_DELINIT(&bufmgr->surf_list);
671 if (bufmgr->backend_module_data) {
672 /* deinit and backend destroys the backend func and data */
673 bufmgr->backend_module_data->deinit(bufmgr->bufmgr_data);
674 bufmgr->bo_func = NULL;
675 bufmgr->bufmgr_func = NULL;
676 bufmgr->bufmgr_data = NULL;
677 bufmgr->backend_module_data = NULL;
679 /* destroy bufmgr priv */
680 bufmgr->backend->bufmgr_deinit(bufmgr->backend->priv);
681 bufmgr->backend->priv = NULL;
682 tbm_backend_free(bufmgr->backend);
683 bufmgr->backend = NULL;
686 TBM_INFO("destroy tbm_bufmgr(%p)\n", bufmgr);
688 dlclose(bufmgr->module_data);
696 pthread_mutex_unlock(&gLock);
697 _tbm_bufmgr_mutex_unlock();
701 tbm_bufmgr_get_capability(tbm_bufmgr bufmgr)
703 unsigned int capabilities = TBM_BUFMGR_CAPABILITY_NONE;
705 _tbm_bufmgr_mutex_lock();
706 _tbm_set_last_result(TBM_ERROR_NONE);
708 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), TBM_BUFMGR_CAPABILITY_NONE);
709 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, TBM_BUFMGR_CAPABILITY_NONE);
711 capabilities = bufmgr->capabilities;
713 _tbm_bufmgr_mutex_unlock();
718 /* LCOV_EXCL_START */
720 tbm_bufmgr_debug_tbm_info_get(tbm_bufmgr bufmgr)
722 char app_name[255] = {0,}, title[512] = {0,};
723 tbm_surface_debug_data *debug_old_data = NULL;
731 pthread_mutex_lock(&gLock);
732 _tbm_set_last_result(TBM_ERROR_NONE);
734 if (!TBM_BUFMGR_IS_VALID(bufmgr) || (bufmgr != gBufMgr)) {
735 TBM_ERR("invalid bufmgr\n");
736 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
737 pthread_mutex_unlock(&gLock);
743 TBM_ERR("Fail to allocate the string.\n");
744 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
745 pthread_mutex_unlock(&gLock);
749 TBM_SNRPRINTF(str, len, c, "\n");
750 pid = syscall(SYS_getpid);
751 _tbm_util_get_appname_from_pid(pid, app_name);
752 _tbm_util_get_appname_brief(app_name);
753 TBM_SNRPRINTF(str, len, c, "============TBM DEBUG: %s(%ld)===========================\n",
756 snprintf(title, 255, "%s", "no surface refcnt width height bpp size n_b n_p flags format app_name ");
758 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
759 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
760 strncat(title, " ", MAX_SIZE_N(title));
761 strncat(title, debug_old_data->key, MAX_SIZE_N(title));
765 TBM_SNRPRINTF(str, len, c, "[tbm_surface information]\n");
766 TBM_SNRPRINTF(str, len, c, "%s\n", title);
768 /* show the tbm_surface information in surf_list */
769 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
770 tbm_surface_h surf = NULL;
773 LIST_FOR_EACH_ENTRY(surf, &bufmgr->surf_list, item_link) {
774 char data[512] = {0,};
775 unsigned int surf_pid = 0;
778 surf_pid = _tbm_surface_internal_get_debug_pid(surf);
780 /* if pid is null, set the self_pid */
781 surf_pid = syscall(SYS_getpid);;
784 memset(app_name, 0x0, 255 * sizeof(char));
785 if (geteuid() == 0) {
786 _tbm_util_get_appname_from_pid(surf_pid, app_name);
787 _tbm_util_get_appname_brief(app_name);
789 snprintf(app_name, sizeof(app_name), "%d", surf_pid);
792 snprintf(data, 255, "%-2d %-9p %-4d %-5u %-6u %-3u %-6u %-2d %-2d %-3d %-8s %-15s",
799 surf->info.size / 1024,
803 _tbm_surface_internal_format_to_str(surf->info.format) + 11,
806 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
807 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
810 strncat(data, " ", MAX_SIZE_N(title));
812 value = _tbm_surface_internal_get_debug_data(surf, debug_old_data->key);
814 strncat(data, value, MAX_SIZE_N(title));
816 strncat(data, "none", MAX_SIZE_N(title));
819 TBM_SNRPRINTF(str, len, c, "%s\n", data);
821 for (i = 0; i < surf->num_bos; i++) {
822 if (bufmgr->backend_module_data) {
823 size = bufmgr->bo_func->bo_get_size(surf->bos[i]->bo_data, &error);
824 if (error != TBM_ERROR_NONE)
825 TBM_WRN("fail to get the size of bo.");
827 size = bufmgr->backend->bo_size(surf->bos[i]);
828 TBM_SNRPRINTF(str, len, c, " bo:%-12p %-26d%-10d\n",
830 surf->bos[i]->ref_cnt,
835 TBM_SNRPRINTF(str, len, c, " no tbm_surfaces.\n");
836 TBM_SNRPRINTF(str, len, c, "\n");
838 TBM_SNRPRINTF(str, len, c, "[tbm_bo information]\n");
839 TBM_SNRPRINTF(str, len, c, "no bo refcnt size lock_cnt map_cnt flags surface name\n");
841 /* show the tbm_bo information in bo_list */
842 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
847 LIST_FOR_EACH_ENTRY(bo, &bufmgr->bo_list, item_link) {
848 if (bufmgr->backend_module_data) {
849 size = bufmgr->bo_func->bo_get_size(bo->bo_data, &error);
850 if (error != TBM_ERROR_NONE)
851 TBM_WRN("fail to get the size of bo.");
852 key = bufmgr->bo_func->bo_export_key(bo->bo_data, &error);
853 if (error != TBM_ERROR_NONE)
854 TBM_WRN("fail to get the tdm_key of bo.");
856 size = bufmgr->backend->bo_size(bo);
857 key = bufmgr->backend->bo_export(bo);
859 TBM_SNRPRINTF(str, len, c, "%-4d%-11p %-4d %-6d %-5d %-4u %-3d %-11p %-4d\n",
871 TBM_SNRPRINTF(str, len, c, "no tbm_bos.\n");
872 TBM_SNRPRINTF(str, len, c, "\n");
874 TBM_SNRPRINTF(str, len, c, "===============================================================\n");
876 pthread_mutex_unlock(&gLock);
882 tbm_bufmgr_debug_show(tbm_bufmgr bufmgr)
885 str = tbm_bufmgr_debug_tbm_info_get(bufmgr);
893 tbm_bufmgr_debug_trace(tbm_bufmgr bufmgr, int onoff)
895 _tbm_bufmgr_mutex_lock();
896 _tbm_set_last_result(TBM_ERROR_NONE);
898 TBM_BUFMGR_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
899 TBM_BUFMGR_RETURN_IF_FAIL(bufmgr == gBufMgr);
902 TBM_LOG_D("bufmgr=%p onoff=%d\n", bufmgr, onoff);
906 _tbm_bufmgr_mutex_unlock();
910 tbm_bufmgr_debug_set_trace_mask(tbm_bufmgr bufmgr, tbm_bufmgr_debug_trace_mask mask, int set)
912 _tbm_bufmgr_mutex_lock();
913 _tbm_set_last_result(TBM_ERROR_NONE);
915 TBM_BUFMGR_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
916 TBM_BUFMGR_RETURN_IF_FAIL(bufmgr == gBufMgr);
921 TBM_INFO("bufmgr=%p sets the trace_mask=%d\n", bufmgr, mask);
922 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_BO)
923 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_BO");
924 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL)
925 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL");
926 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE)
927 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE");
928 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE)
929 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE");
930 } else if (set == 0) {
933 TBM_INFO("bufmgr=%p unsets the trace_mask=%d\n", bufmgr, mask);
934 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_BO)
935 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_BO");
936 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL)
937 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL");
938 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE)
939 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE");
940 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE)
941 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE");
943 TBM_WRN("set value is wrong.(set=%d)", set);
946 _tbm_bufmgr_mutex_unlock();
950 tbm_bufmgr_debug_dump_set_scale(double scale)
952 pthread_mutex_lock(&gLock);
953 _tbm_set_last_result(TBM_ERROR_NONE);
954 scale_factor = scale;
955 pthread_mutex_unlock(&gLock);
959 tbm_bufmgr_debug_get_ref_count(void)
963 pthread_mutex_lock(&gLock);
965 _tbm_set_last_result(TBM_ERROR_NONE);
967 refcnt = (gBufMgr) ? gBufMgr->ref_count : 0;
969 pthread_mutex_unlock(&gLock);
975 tbm_bufmgr_debug_queue_dump(char *path, int count, int onoff)
977 pthread_mutex_lock(&gLock);
978 _tbm_set_last_result(TBM_ERROR_NONE);
981 TBM_DBG("count=%d onoff=%d\n", count, onoff);
983 tbm_surface_internal_dump_end();
988 TBM_ERR("path is null");
989 pthread_mutex_unlock(&gLock);
992 TBM_DBG("path=%s count=%d onoff=%d\n", path, count, onoff);
994 if (_tbm_util_get_max_surface_size(&w, &h) == 0) {
995 TBM_ERR("Fail to get tbm_surface size.\n");
996 pthread_mutex_unlock(&gLock);
1000 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
1006 pthread_mutex_unlock(&gLock);
1012 tbm_bufmgr_debug_dump_all(char *path)
1014 int w, h, count = 0;
1015 tbm_surface_h surface = NULL;
1017 pthread_mutex_lock(&gLock);
1018 _tbm_set_last_result(TBM_ERROR_NONE);
1021 TBM_ERR("path is null.\n");
1022 pthread_mutex_unlock(&gLock);
1026 TBM_DBG("path=%s\n", path);
1028 count = _tbm_util_get_max_surface_size(&w, &h);
1030 TBM_ERR("No tbm_surface.\n");
1031 pthread_mutex_unlock(&gLock);
1035 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
1038 LIST_FOR_EACH_ENTRY(surface, &gBufMgr->surf_list, item_link)
1039 tbm_surface_internal_dump_buffer(surface, "dump_all");
1041 tbm_surface_internal_dump_end();
1043 pthread_mutex_unlock(&gLock);
1048 /* internal function */
1050 _tbm_bufmgr_get_bufmgr(void)
1056 tbm_bufmgr_bind_native_display(tbm_bufmgr bufmgr, void *native_display)
1061 _tbm_bufmgr_mutex_lock();
1062 _tbm_set_last_result(TBM_ERROR_NONE);
1064 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1066 if (bufmgr->backend_module_data) {
1067 if (!bufmgr->bufmgr_func->bufmgr_bind_native_display) {
1068 TBM_WRN("skip: tbm_bufmgr(%p) native_display(%p)\n",
1069 bufmgr, native_display);
1070 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
1071 _tbm_bufmgr_mutex_unlock();
1075 error = bufmgr->bufmgr_func->bufmgr_bind_native_display(bufmgr->bufmgr_data, (tbm_native_display *)native_display);
1076 if (error != TBM_ERROR_NONE) {
1077 TBM_ERR("error: tbm_bufmgr(%p) native_display(%p) error(%d)\n",
1078 bufmgr, native_display, error);
1079 _tbm_set_last_result(error);
1080 _tbm_bufmgr_mutex_unlock();
1085 if (!bufmgr->backend->bufmgr_bind_native_display) {
1086 TBM_WRN("skip: tbm_bufmgr(%p) native_display(%p)\n",
1087 bufmgr, native_display);
1088 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
1089 _tbm_bufmgr_mutex_unlock();
1093 ret = bufmgr->backend->bufmgr_bind_native_display(bufmgr, native_display);
1095 TBM_ERR("error: tbm_bufmgr(%p) native_display(%p)\n",
1096 bufmgr, native_display);
1097 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1098 _tbm_bufmgr_mutex_unlock();
1103 TBM_INFO("tbm_bufmgr(%p) native_display(%p)\n", bufmgr, native_display);
1105 _tbm_bufmgr_mutex_unlock();
1111 tbm_bufmgr_server_init(void)
1115 bufmgr = _tbm_bufmgr_init(-1, 1);
1121 tbm_bufmgr_set_bo_lock_type(tbm_bufmgr bufmgr, tbm_bufmgr_bo_lock_type bo_lock_type)
1123 _tbm_bufmgr_mutex_lock();
1124 _tbm_set_last_result(TBM_ERROR_NONE);
1126 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1127 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, 0);
1129 pthread_mutex_lock(&gLock);
1130 gBufMgr->bo_lock_type = bo_lock_type;
1131 pthread_mutex_unlock(&gLock);
1133 TBM_INFO("The bo_lock_type of the bo is %d\n", bo_lock_type);
1135 _tbm_bufmgr_mutex_unlock();
1141 int tbm_bufmgr_get_fd_limit(void)
1145 if (getrlimit(RLIMIT_NOFILE, &lim))
1148 return (int)lim.rlim_cur;
1151 tbm_bufmgr tbm_bufmgr_get(void)
1155 /* LCOV_EXCL_STOP */