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();\
97 _tbm_bufmgr_mutex_lock(void)
99 pthread_mutex_lock(&tbm_bufmgr_lock);
103 _tbm_bufmgr_mutex_unlock(void)
105 pthread_mutex_unlock(&tbm_bufmgr_lock);
109 _tbm_util_get_max_surface_size(int *w, int *h)
111 tbm_surface_info_s info;
112 tbm_surface_h surface = NULL;
118 if (gBufMgr == NULL || LIST_IS_EMPTY(&gBufMgr->surf_list))
121 LIST_FOR_EACH_ENTRY(surface, &gBufMgr->surf_list, item_link) {
122 if (tbm_surface_get_info(surface, &info) == TBM_SURFACE_ERROR_NONE) {
126 if (*h < info.height)
135 _tbm_util_get_appname_brief(char *brief)
139 char temp[255] = {0,};
140 char *saveptr = NULL;
142 token = strtok_r(brief, delim, &saveptr);
144 while (token != NULL) {
145 memset(temp, 0x00, 255 * sizeof(char));
146 strncpy(temp, token, 254 * sizeof(char));
147 token = strtok_r(NULL, delim, &saveptr);
150 snprintf(brief, sizeof(temp), "%s", temp);
154 _tbm_util_get_appname_from_pid(long pid, char *str)
156 char fn_cmdline[255] = {0, }, cmdline[255];
160 if (pid <= 0) return;
162 snprintf(fn_cmdline, sizeof(fn_cmdline), "/proc/%ld/cmdline", pid);
164 fp = fopen(fn_cmdline, "r");
166 TBM_ERR("cannot file open %s\n", fn_cmdline);
170 if (!fgets(cmdline, 255, fp)) {
171 TBM_ERR("fail to get appname for pid(%ld)\n", pid);
178 len = strlen(cmdline);
180 memset(cmdline, 0x00, 255);
184 snprintf(str, sizeof(cmdline), "%s", cmdline);
188 _check_version(TBMModuleVersionInfo *data)
190 int backend_module_major, backend_module_minor;
191 int tbm_backend_major, tbm_backend_minor;
193 backend_module_major = GET_ABI_MAJOR(data->abiversion);
194 backend_module_minor = GET_ABI_MINOR(data->abiversion);
196 TBM_DBG("TBM module %s: vendor=\"%s\" ABI=%d,%d\n",
197 data->modname ? data->modname : "UNKNOWN!",
198 data->vendor ? data->vendor : "UNKNOWN!", backend_module_major, backend_module_minor);
200 tbm_backend_major = GET_ABI_MAJOR(TBM_ABI_VERSION);
201 tbm_backend_minor = GET_ABI_MINOR(TBM_ABI_VERSION);
203 TBM_DBG("TBM ABI version %d.%d\n",
204 tbm_backend_major, tbm_backend_minor);
206 if (backend_module_major != tbm_backend_major) {
207 TBM_ERR("TBM module ABI major ver(%d) doesn't match the TBM's ver(%d)\n",
208 backend_module_major, tbm_backend_major);
210 } else if (backend_module_minor > tbm_backend_minor) {
211 TBM_ERR("TBM module ABI minor ver(%d) is newer than the TBM's ver(%d)\n",
212 backend_module_minor, tbm_backend_minor);
220 _tbm_backend_check_bufmgr_func(tbm_backend_bufmgr_func *bufmgr_func)
222 TBM_RETURN_VAL_IF_FAIL(bufmgr_func, 0); /* mandatory symbol */
223 TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_get_capabilities, 0); /* mandatory symbol */
224 TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_bind_native_display, 0); /* mandatory symbol */
225 TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_get_supported_formats, 0); /* mandatory symbol */
226 TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_get_plane_data, 0); /* mandatory symbol */
227 TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_alloc_bo, 0); /* mandatory symbol */
228 if (!bufmgr_func->bufmgr_alloc_bo_with_format)
229 TBM_DBG("No bufmgr_func->bufmgr_alloc_bo_with_format.");
230 TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_import_fd, 0); /* mandatory symbol */
231 if (!bufmgr_func->bufmgr_import_key)
232 TBM_DBG("No bufmgr_func->bo_export_key.");
238 _tbm_backend_check_bufmgr_bo(tbm_backend_bo_func *bo_func)
240 TBM_RETURN_VAL_IF_FAIL(bo_func, 0); /* mandatory symbol */
241 TBM_RETURN_VAL_IF_FAIL(bo_func->bo_free, 0); /* mandatory symbol */
242 TBM_RETURN_VAL_IF_FAIL(bo_func->bo_get_size, 0); /* mandatory symbol */
243 TBM_RETURN_VAL_IF_FAIL(bo_func->bo_get_memory_types, 0); /* mandatory symbol */
244 TBM_RETURN_VAL_IF_FAIL(bo_func->bo_get_handle, 0); /* mandatory symbol */
245 TBM_RETURN_VAL_IF_FAIL(bo_func->bo_map, 0); /* mandatory symbol */
246 TBM_RETURN_VAL_IF_FAIL(bo_func->bo_unmap, 0); /* mandatory symbol */
247 if (!bo_func->bo_lock)
248 TBM_DBG("No bo_func->bo_lock.");
249 if (!bo_func->bo_unlock)
250 TBM_DBG("No bo_func->bo_unlock.");
251 TBM_RETURN_VAL_IF_FAIL(bo_func->bo_export_fd, 0); /* mandatory symbol */
252 if (!bo_func->bo_export_key)
253 TBM_INFO("No bo_func->bo_export_key.");
259 _tbm_backend_load_module(tbm_bufmgr bufmgr, const char *file)
261 char path[PATH_MAX] = {0, };
262 void *module_data = NULL;
263 tbm_backend_module *backend_module_data = NULL;
264 tbm_backend_bufmgr_data *bufmgr_data = NULL;
265 int backend_module_major, backend_module_minor;
266 int tbm_backend_major, tbm_backend_minor;
269 snprintf(path, sizeof(path), BUFMGR_MODULE_DIR "/%s", file);
271 module_data = dlopen(path, RTLD_LAZY);
273 TBM_ERR("failed to load module: %s(%s)\n", dlerror(), file);
277 backend_module_data = dlsym(module_data, "tbm_backend_module_data");
278 if (!backend_module_data) {
279 TBM_ERR("Error: module does not have data object.\n");
283 tbm_backend_major = GET_ABI_MAJOR(TBM_BACKEND_ABI_LATEST_VERSION);
284 tbm_backend_minor = GET_ABI_MINOR(TBM_BACKEND_ABI_LATEST_VERSION);
285 TBM_INFO("TBM Backend ABI version %d.%d\n", tbm_backend_major, tbm_backend_minor);
287 backend_module_major = GET_ABI_MAJOR(backend_module_data->abi_version);
288 backend_module_minor = GET_ABI_MINOR(backend_module_data->abi_version);
290 TBM_INFO("TBM module %s: vendor=\"%s\" Backend ABI version=%d.%d\n",
291 backend_module_data->name ? backend_module_data->name : "UNKNOWN!",
292 backend_module_data->vendor ? backend_module_data->vendor : "UNKNOWN!",
293 backend_module_major, backend_module_minor);
295 if (backend_module_major > tbm_backend_major) {
296 TBM_ERR("TBM module ABI major ver(%d) is newer than the TBM's ver(%d)\n",
297 backend_module_major, tbm_backend_major);
299 } else if (backend_module_minor > tbm_backend_minor) {
300 TBM_ERR("TBM module ABI minor ver(%d) is newer than the TBM's ver(%d)\n",
301 backend_module_minor, tbm_backend_minor);
305 if (!backend_module_data->init) {
306 TBM_ERR("Error: module does not supply init symbol.\n");
310 if (!backend_module_data->deinit) {
311 TBM_ERR("Error: module does not supply deinit symbol.\n");
315 bufmgr_data = backend_module_data->init(bufmgr, &error);
317 TBM_ERR("Fail to init module(%s)\n", file);
321 /* check the mandatory symbols of the backend module */
322 if (!_tbm_backend_check_bufmgr_func(bufmgr->bufmgr_func)) {
323 TBM_ERR("Fail to check the bufmgr_func symboles.");
327 if (!_tbm_backend_check_bufmgr_bo(bufmgr->bo_func)) {
328 TBM_ERR("Fail to check the bufmgr_bo symboles.");
332 /* get the capability */
333 bufmgr->capabilities = bufmgr->bufmgr_func->bufmgr_get_capabilities(bufmgr_data, &error);
334 if (bufmgr->capabilities == TBM_BUFMGR_CAPABILITY_NONE) {
335 TBM_ERR("The capabilities of the backend module is TBM_BUFMGR_CAPABILITY_NONE.");
336 TBM_ERR("TBM_BUFMGR_CAPABILITY_SHARE_FD is the essential capability.");
340 if (!(bufmgr->capabilities & TBM_BUFMGR_CAPABILITY_SHARE_FD)) {
341 TBM_ERR("The capabilities of the backend module had no TBM_BUFMGR_CAPABILITY_SHARE_FD.");
342 TBM_ERR("The tbm backend has to get TBM_BUFMGR_CAPABILITY_SHARE_FD. ");
346 bufmgr->module_data = module_data;
347 bufmgr->backend_module_data = backend_module_data;
348 bufmgr->bufmgr_data = bufmgr_data;
350 TBM_DBG("Success to load module(%s)\n", file);
351 TBM_STDOUT_INFO("Success to load module(%s)", file);
357 bufmgr->backend_module_data->deinit(bufmgr_data);
359 dlclose(module_data);
365 _tbm_bufmgr_load_module(tbm_bufmgr bufmgr, int fd, const char *file)
367 char path[PATH_MAX] = {0, };
368 TBMModuleVersionInfo *vers;
369 TBMModuleData *initdata;
373 snprintf(path, sizeof(path), BUFMGR_MODULE_DIR "/%s", file);
375 module_data = dlopen(path, RTLD_LAZY);
377 TBM_ERR("failed to load module: %s(%s)\n", dlerror(), file);
381 initdata = dlsym(module_data, "tbmModuleData");
383 TBM_ERR("Error: module does not have data object.\n");
387 vers = initdata->vers;
389 TBM_ERR("Error: module does not supply version information.\n");
393 init = initdata->init;
395 TBM_ERR("Error: module does not supply init symbol.\n");
399 if (!_check_version(vers)) {
400 TBM_ERR("Fail to check version.\n");
404 if (!init(bufmgr, fd)) {
405 TBM_ERR("Fail to init module(%s)\n", file);
409 if (!bufmgr->backend || !bufmgr->backend->priv) {
410 TBM_ERR("Error: module(%s) wrong operation. Check backend or backend's priv.\n", file);
414 bufmgr->module_data = module_data;
416 TBM_DBG("Success to load module(%s)\n", file);
421 dlclose(module_data);
426 _tbm_load_module(tbm_bufmgr bufmgr, int fd)
428 struct dirent **namelist;
431 /* try to load the new backend module */
432 ret = _tbm_backend_load_module(bufmgr, DEFAULT_LIB);
436 /* try to load the old(deprecated) backend mdoule */
437 ret = _tbm_bufmgr_load_module(bufmgr, fd, DEFAULT_LIB);
441 /* load bufmgr priv from configured path */
442 n = scandir(BUFMGR_MODULE_DIR, &namelist, 0, alphasort);
444 TBM_ERR("no files : %s\n", BUFMGR_MODULE_DIR);
449 if (!ret && strstr(namelist[n]->d_name, PREFIX_LIB)) {
450 const char *p = strstr(namelist[n]->d_name, SUFFIX_LIB);
452 if (p && !strcmp(p, SUFFIX_LIB)) {
453 ret = _tbm_backend_load_module(bufmgr, namelist[n]->d_name);
455 ret = _tbm_bufmgr_load_module(bufmgr, fd,
456 namelist[n]->d_name);
470 _tbm_bufmgr_init(int fd, int server)
472 #ifdef TBM_BUFMGR_INIT_TIME
473 struct timeval start_tv, end_tv;
477 #ifdef TBM_BUFMGR_INIT_TIME
478 /* get the start tv */
479 gettimeofday(&start_tv, NULL);
482 /* LCOV_EXCL_START */
484 env = getenv("TBM_DLOG");
487 TBM_DBG("TBM_DLOG=%s\n", env);
493 env = getenv("TBM_TRACE");
495 trace_mask = atoi(env);
496 TBM_DBG("TBM_TRACE=%s\n", env);
501 pthread_mutex_lock(&gLock);
503 _tbm_set_last_result(TBM_ERROR_NONE);
506 TBM_WRN("!!!!!WARNING:: The tbm_bufmgr_init DOSE NOT use argument fd ANYMORE.\n");
507 TBM_WRN("!!!!!WARNING:: IT WILL BE CHANGED like tbm_bufmgr_init(int fd) --> tbm_bufmgr_init(void).\n");
511 /* initialize buffer manager */
513 gBufMgr->ref_count++;
514 TBM_DBG("reuse tbm_bufmgr(%p) ref_count(%d) fd(%d)\n", gBufMgr, gBufMgr->ref_count, gBufMgr->fd);
515 pthread_mutex_unlock(&gLock);
519 TBM_DBG("bufmgr init\n");
521 /* allocate bufmgr */
522 gBufMgr = calloc(1, sizeof(struct _tbm_bufmgr));
524 TBM_ERR("error: fail to alloc bufmgr fd(%d)\n", fd);
525 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
526 pthread_mutex_unlock(&gLock);
532 /* set the display_server flag before loading the backend module */
534 TBM_INFO("The tbm_bufmgr(%p) is used by display server. Need to bind the native_display.\n", gBufMgr);
535 gBufMgr->display_server = 1;
538 /* load bufmgr priv from env */
539 TBM_STDOUT_INFO("loading backend module");
540 if (!_tbm_load_module(gBufMgr, gBufMgr->fd)) {
541 TBM_ERR("error : Fail to load bufmgr backend\n");
542 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
545 pthread_mutex_unlock(&gLock);
549 TBM_STDOUT_INFO("loading backend module done");
552 gBufMgr->ref_count = 1;
554 TBM_INFO("create tizen bufmgr:%p ref_count:%d\n",
555 gBufMgr, gBufMgr->ref_count);
557 /* setup the bo_lock_type */
558 env = getenv("BUFMGR_LOCK_TYPE");
559 if (env && !strcmp(env, "always"))
560 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS;
561 else if (env && !strcmp(env, "none"))
562 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_NEVER;
563 else if (env && !strcmp(env, "once"))
564 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ONCE;
566 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS;
568 TBM_DBG("BUFMGR_LOCK_TYPE=%s\n", env ? env : "default:once");
570 /* intialize bo_list */
571 LIST_INITHEAD(&gBufMgr->bo_list);
573 /* intialize surf_list */
574 LIST_INITHEAD(&gBufMgr->surf_list);
576 /* intialize surf_queue_list */
577 LIST_INITHEAD(&gBufMgr->surf_queue_list);
579 /* intialize debug_key_list */
580 LIST_INITHEAD(&gBufMgr->debug_key_list);
582 #ifdef TBM_BUFMGR_INIT_TIME
584 gettimeofday(&end_tv, NULL);
585 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)));
588 pthread_mutex_unlock(&gLock);
594 tbm_bufmgr_init(int fd)
598 bufmgr = _tbm_bufmgr_init(fd, 0);
604 tbm_bufmgr_deinit(tbm_bufmgr bufmgr)
606 TBM_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
608 _tbm_bufmgr_mutex_lock();
609 pthread_mutex_lock(&gLock);
610 _tbm_set_last_result(TBM_ERROR_NONE);
613 TBM_ERR("gBufmgr already destroy: bufmgr:%p\n", bufmgr);
614 pthread_mutex_unlock(&gLock);
615 _tbm_bufmgr_mutex_unlock();
620 if (bufmgr->ref_count > 0) {
621 TBM_DBG("reduce a ref_count(%d) of tbm_bufmgr(%p)\n", bufmgr->ref_count, bufmgr);
622 pthread_mutex_unlock(&gLock);
623 _tbm_bufmgr_mutex_unlock();
627 /* destroy bo_list */
628 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
629 tbm_bo bo = NULL, tmp;
631 LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &bufmgr->bo_list, item_link) {
632 TBM_ERR("Un-freed bo(%p, ref:%d)\n", bo, bo->ref_cnt);
635 LIST_DELINIT(&bufmgr->bo_list);
638 /* destroy surf_list */
639 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
640 tbm_surface_h surf = NULL, tmp;
642 LIST_FOR_EACH_ENTRY_SAFE(surf, tmp, &bufmgr->surf_list, item_link) {
643 TBM_ERR("Un-freed surf(%p, ref:%d)\n", surf, surf->refcnt);
644 tbm_surface_destroy(surf);
646 LIST_DELINIT(&bufmgr->surf_list);
649 if (bufmgr->backend_module_data) {
650 /* deinit and backend destroys the backend func and data */
651 bufmgr->backend_module_data->deinit(bufmgr->bufmgr_data);
652 bufmgr->bo_func = NULL;
653 bufmgr->bufmgr_func = NULL;
654 bufmgr->bufmgr_data = NULL;
655 bufmgr->backend_module_data = NULL;
657 /* destroy bufmgr priv */
658 bufmgr->backend->bufmgr_deinit(bufmgr->backend->priv);
659 bufmgr->backend->priv = NULL;
660 tbm_backend_free(bufmgr->backend);
661 bufmgr->backend = NULL;
664 TBM_INFO("destroy tbm_bufmgr(%p)\n", bufmgr);
666 dlclose(bufmgr->module_data);
674 pthread_mutex_unlock(&gLock);
675 _tbm_bufmgr_mutex_unlock();
679 tbm_bufmgr_get_capability(tbm_bufmgr bufmgr)
681 unsigned int capabilities = TBM_BUFMGR_CAPABILITY_NONE;
683 _tbm_bufmgr_mutex_lock();
684 _tbm_set_last_result(TBM_ERROR_NONE);
686 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), TBM_BUFMGR_CAPABILITY_NONE);
687 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, TBM_BUFMGR_CAPABILITY_NONE);
689 capabilities = bufmgr->capabilities;
691 _tbm_bufmgr_mutex_unlock();
696 /* LCOV_EXCL_START */
698 tbm_bufmgr_debug_tbm_info_get(tbm_bufmgr bufmgr)
700 char app_name[255] = {0,}, title[512] = {0,};
701 tbm_surface_debug_data *debug_old_data = NULL;
709 pthread_mutex_lock(&gLock);
710 _tbm_set_last_result(TBM_ERROR_NONE);
712 if (!TBM_BUFMGR_IS_VALID(bufmgr) || (bufmgr != gBufMgr)) {
713 TBM_ERR("invalid bufmgr\n");
714 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
715 pthread_mutex_unlock(&gLock);
721 TBM_ERR("Fail to allocate the string.\n");
722 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
723 pthread_mutex_unlock(&gLock);
727 TBM_SNRPRINTF(str, len, c, "\n");
728 pid = syscall(SYS_getpid);
729 _tbm_util_get_appname_from_pid(pid, app_name);
730 _tbm_util_get_appname_brief(app_name);
731 TBM_SNRPRINTF(str, len, c, "============TBM DEBUG: %s(%ld)===========================\n",
734 snprintf(title, 255, "%s", "no surface refcnt width height bpp size n_b n_p flags format app_name ");
736 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
737 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
738 strncat(title, " ", MAX_SIZE_N(title));
739 strncat(title, debug_old_data->key, MAX_SIZE_N(title));
743 TBM_SNRPRINTF(str, len, c, "[tbm_surface information]\n");
744 TBM_SNRPRINTF(str, len, c, "%s\n", title);
746 /* show the tbm_surface information in surf_list */
747 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
748 tbm_surface_h surf = NULL;
751 LIST_FOR_EACH_ENTRY(surf, &bufmgr->surf_list, item_link) {
752 char data[512] = {0,};
753 unsigned int surf_pid = 0;
756 surf_pid = _tbm_surface_internal_get_debug_pid(surf);
758 /* if pid is null, set the self_pid */
759 surf_pid = syscall(SYS_getpid);;
762 memset(app_name, 0x0, 255 * sizeof(char));
763 if (geteuid() == 0) {
764 _tbm_util_get_appname_from_pid(surf_pid, app_name);
765 _tbm_util_get_appname_brief(app_name);
767 snprintf(app_name, sizeof(app_name), "%d", surf_pid);
770 snprintf(data, 255, "%-2d %-9p %-4d %-5u %-6u %-3u %-6u %-2d %-2d %-3d %-8s %-15s",
777 surf->info.size / 1024,
781 _tbm_surface_internal_format_to_str(surf->info.format) + 11,
784 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
785 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
788 strncat(data, " ", MAX_SIZE_N(title));
790 value = _tbm_surface_internal_get_debug_data(surf, debug_old_data->key);
792 strncat(data, value, MAX_SIZE_N(title));
794 strncat(data, "none", MAX_SIZE_N(title));
797 TBM_SNRPRINTF(str, len, c, "%s\n", data);
799 for (i = 0; i < surf->num_bos; i++) {
800 if (bufmgr->backend_module_data) {
801 size = bufmgr->bo_func->bo_get_size(surf->bos[i]->bo_data, &error);
802 if (error != TBM_ERROR_NONE)
803 TBM_WRN("fail to get the size of bo.");
805 size = bufmgr->backend->bo_size(surf->bos[i]);
806 TBM_SNRPRINTF(str, len, c, " bo:%-12p %-26d%-10d\n",
808 surf->bos[i]->ref_cnt,
813 TBM_SNRPRINTF(str, len, c, " no tbm_surfaces.\n");
814 TBM_SNRPRINTF(str, len, c, "\n");
816 TBM_SNRPRINTF(str, len, c, "[tbm_bo information]\n");
817 TBM_SNRPRINTF(str, len, c, "no bo refcnt size lock_cnt map_cnt flags surface name\n");
819 /* show the tbm_bo information in bo_list */
820 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
825 LIST_FOR_EACH_ENTRY(bo, &bufmgr->bo_list, item_link) {
826 if (bufmgr->backend_module_data) {
827 size = bufmgr->bo_func->bo_get_size(bo->bo_data, &error);
828 if (error != TBM_ERROR_NONE)
829 TBM_WRN("fail to get the size of bo.");
830 key = bufmgr->bo_func->bo_export_key(bo->bo_data, &error);
831 if (error != TBM_ERROR_NONE)
832 TBM_WRN("fail to get the tdm_key of bo.");
834 size = bufmgr->backend->bo_size(bo);
835 key = bufmgr->backend->bo_export(bo);
837 TBM_SNRPRINTF(str, len, c, "%-4d%-11p %-4d %-6d %-5d %-4u %-3d %-11p %-4d\n",
849 TBM_SNRPRINTF(str, len, c, "no tbm_bos.\n");
850 TBM_SNRPRINTF(str, len, c, "\n");
852 TBM_SNRPRINTF(str, len, c, "===============================================================\n");
854 pthread_mutex_unlock(&gLock);
860 tbm_bufmgr_debug_show(tbm_bufmgr bufmgr)
863 str = tbm_bufmgr_debug_tbm_info_get(bufmgr);
871 tbm_bufmgr_debug_trace(tbm_bufmgr bufmgr, int onoff)
873 _tbm_bufmgr_mutex_lock();
874 _tbm_set_last_result(TBM_ERROR_NONE);
876 TBM_BUFMGR_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
877 TBM_BUFMGR_RETURN_IF_FAIL(bufmgr == gBufMgr);
880 TBM_LOG_D("bufmgr=%p onoff=%d\n", bufmgr, onoff);
884 _tbm_bufmgr_mutex_unlock();
888 tbm_bufmgr_debug_set_trace_mask(tbm_bufmgr bufmgr, tbm_bufmgr_debug_trace_mask mask, int set)
890 _tbm_bufmgr_mutex_lock();
891 _tbm_set_last_result(TBM_ERROR_NONE);
893 TBM_BUFMGR_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
894 TBM_BUFMGR_RETURN_IF_FAIL(bufmgr == gBufMgr);
899 TBM_INFO("bufmgr=%p sets the trace_mask=%d\n", bufmgr, mask);
900 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_BO)
901 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_BO");
902 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL)
903 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL");
904 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE)
905 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE");
906 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE)
907 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE");
908 } else if (set == 0) {
911 TBM_INFO("bufmgr=%p unsets the trace_mask=%d\n", bufmgr, mask);
912 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_BO)
913 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_BO");
914 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL)
915 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL");
916 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE)
917 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE");
918 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE)
919 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE");
921 TBM_WRN("set value is wrong.(set=%d)", set);
924 _tbm_bufmgr_mutex_unlock();
928 tbm_bufmgr_debug_dump_set_scale(double scale)
930 pthread_mutex_lock(&gLock);
931 _tbm_set_last_result(TBM_ERROR_NONE);
932 scale_factor = scale;
933 pthread_mutex_unlock(&gLock);
937 tbm_bufmgr_debug_get_ref_count(void)
941 pthread_mutex_lock(&gLock);
943 _tbm_set_last_result(TBM_ERROR_NONE);
945 refcnt = (gBufMgr) ? gBufMgr->ref_count : 0;
947 pthread_mutex_unlock(&gLock);
953 tbm_bufmgr_debug_queue_dump(char *path, int count, int onoff)
955 pthread_mutex_lock(&gLock);
956 _tbm_set_last_result(TBM_ERROR_NONE);
959 TBM_DBG("count=%d onoff=%d\n", count, onoff);
961 tbm_surface_internal_dump_end();
966 TBM_ERR("path is null");
967 pthread_mutex_unlock(&gLock);
970 TBM_DBG("path=%s count=%d onoff=%d\n", path, count, onoff);
972 if (_tbm_util_get_max_surface_size(&w, &h) == 0) {
973 TBM_ERR("Fail to get tbm_surface size.\n");
974 pthread_mutex_unlock(&gLock);
978 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
984 pthread_mutex_unlock(&gLock);
990 tbm_bufmgr_debug_dump_all(char *path)
993 tbm_surface_h surface = NULL;
995 pthread_mutex_lock(&gLock);
996 _tbm_set_last_result(TBM_ERROR_NONE);
999 TBM_ERR("path is null.\n");
1000 pthread_mutex_unlock(&gLock);
1004 TBM_DBG("path=%s\n", path);
1006 count = _tbm_util_get_max_surface_size(&w, &h);
1008 TBM_ERR("No tbm_surface.\n");
1009 pthread_mutex_unlock(&gLock);
1013 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
1016 LIST_FOR_EACH_ENTRY(surface, &gBufMgr->surf_list, item_link)
1017 tbm_surface_internal_dump_buffer(surface, "dump_all");
1019 tbm_surface_internal_dump_end();
1021 pthread_mutex_unlock(&gLock);
1026 /* internal function */
1028 _tbm_bufmgr_get_bufmgr(void)
1034 tbm_bufmgr_bind_native_display(tbm_bufmgr bufmgr, void *native_display)
1039 _tbm_bufmgr_mutex_lock();
1040 _tbm_set_last_result(TBM_ERROR_NONE);
1042 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1044 if (bufmgr->backend_module_data) {
1045 if (!bufmgr->bufmgr_func->bufmgr_bind_native_display) {
1046 TBM_WRN("skip: tbm_bufmgr(%p) native_display(%p)\n",
1047 bufmgr, native_display);
1048 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
1049 _tbm_bufmgr_mutex_unlock();
1053 error = bufmgr->bufmgr_func->bufmgr_bind_native_display(bufmgr->bufmgr_data, (tbm_native_display *)native_display);
1054 if (error != TBM_ERROR_NONE) {
1055 TBM_ERR("error: tbm_bufmgr(%p) native_display(%p) error(%d)\n",
1056 bufmgr, native_display, error);
1057 _tbm_set_last_result(error);
1058 _tbm_bufmgr_mutex_unlock();
1063 if (!bufmgr->backend->bufmgr_bind_native_display) {
1064 TBM_WRN("skip: tbm_bufmgr(%p) native_display(%p)\n",
1065 bufmgr, native_display);
1066 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
1067 _tbm_bufmgr_mutex_unlock();
1071 ret = bufmgr->backend->bufmgr_bind_native_display(bufmgr, native_display);
1073 TBM_ERR("error: tbm_bufmgr(%p) native_display(%p)\n",
1074 bufmgr, native_display);
1075 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1076 _tbm_bufmgr_mutex_unlock();
1081 TBM_INFO("tbm_bufmgr(%p) native_display(%p)\n", bufmgr, native_display);
1083 _tbm_bufmgr_mutex_unlock();
1089 tbm_bufmgr_server_init(void)
1093 bufmgr = _tbm_bufmgr_init(-1, 1);
1099 tbm_bufmgr_set_bo_lock_type(tbm_bufmgr bufmgr, tbm_bufmgr_bo_lock_type bo_lock_type)
1101 _tbm_bufmgr_mutex_lock();
1102 _tbm_set_last_result(TBM_ERROR_NONE);
1104 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1105 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, 0);
1107 pthread_mutex_lock(&gLock);
1108 gBufMgr->bo_lock_type = bo_lock_type;
1109 pthread_mutex_unlock(&gLock);
1111 TBM_INFO("The bo_lock_type of the bo is %d\n", bo_lock_type);
1113 _tbm_bufmgr_mutex_unlock();
1119 int tbm_bufmgr_get_fd_limit(void)
1123 if (getrlimit(RLIMIT_NOFILE, &lim))
1126 return (int)lim.rlim_cur;
1129 tbm_bufmgr tbm_bufmgr_get(void)
1133 /* LCOV_EXCL_STOP */