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_INFO("Success to load module(%s)\n", file);
356 bufmgr->backend_module_data->deinit(bufmgr_data);
358 dlclose(module_data);
364 _tbm_bufmgr_load_module(tbm_bufmgr bufmgr, int fd, const char *file)
366 char path[PATH_MAX] = {0, };
367 TBMModuleVersionInfo *vers;
368 TBMModuleData *initdata;
372 snprintf(path, sizeof(path), BUFMGR_MODULE_DIR "/%s", file);
374 module_data = dlopen(path, RTLD_LAZY);
376 TBM_ERR("failed to load module: %s(%s)\n", dlerror(), file);
380 initdata = dlsym(module_data, "tbmModuleData");
382 TBM_ERR("Error: module does not have data object.\n");
386 vers = initdata->vers;
388 TBM_ERR("Error: module does not supply version information.\n");
392 init = initdata->init;
394 TBM_ERR("Error: module does not supply init symbol.\n");
398 if (!_check_version(vers)) {
399 TBM_ERR("Fail to check version.\n");
403 if (!init(bufmgr, fd)) {
404 TBM_ERR("Fail to init module(%s)\n", file);
408 if (!bufmgr->backend || !bufmgr->backend->priv) {
409 TBM_ERR("Error: module(%s) wrong operation. Check backend or backend's priv.\n", file);
413 bufmgr->module_data = module_data;
415 TBM_DBG("Success to load module(%s)\n", file);
420 dlclose(module_data);
425 _tbm_load_module(tbm_bufmgr bufmgr, int fd)
427 struct dirent **namelist;
430 /* try to load the new backend module */
431 ret = _tbm_backend_load_module(bufmgr, DEFAULT_LIB);
435 /* try to load the old(deprecated) backend mdoule */
436 ret = _tbm_bufmgr_load_module(bufmgr, fd, DEFAULT_LIB);
440 /* load bufmgr priv from configured path */
441 n = scandir(BUFMGR_MODULE_DIR, &namelist, 0, alphasort);
443 TBM_ERR("no files : %s\n", BUFMGR_MODULE_DIR);
448 if (!ret && strstr(namelist[n]->d_name, PREFIX_LIB)) {
449 const char *p = strstr(namelist[n]->d_name, SUFFIX_LIB);
451 if (p && !strcmp(p, SUFFIX_LIB)) {
452 ret = _tbm_backend_load_module(bufmgr, namelist[n]->d_name);
454 ret = _tbm_bufmgr_load_module(bufmgr, fd,
455 namelist[n]->d_name);
469 _tbm_bufmgr_init(int fd, int server)
471 #ifdef TBM_BUFMGR_INIT_TIME
472 struct timeval start_tv, end_tv;
476 #ifdef TBM_BUFMGR_INIT_TIME
477 /* get the start tv */
478 gettimeofday(&start_tv, NULL);
483 /* LCOV_EXCL_START */
485 env = getenv("TBM_TRACE");
487 trace_mask = atoi(env);
488 TBM_DBG("TBM_TRACE=%s\n", env);
493 pthread_mutex_lock(&gLock);
495 _tbm_set_last_result(TBM_ERROR_NONE);
498 TBM_WRN("!!!!!WARNING:: The tbm_bufmgr_init DOSE NOT use argument fd ANYMORE.\n");
499 TBM_WRN("!!!!!WARNING:: IT WILL BE CHANGED like tbm_bufmgr_init(int fd) --> tbm_bufmgr_init(void).\n");
503 /* initialize buffer manager */
505 gBufMgr->ref_count++;
506 TBM_DBG("reuse tbm_bufmgr(%p) ref_count(%d) fd(%d)\n", gBufMgr, gBufMgr->ref_count, gBufMgr->fd);
507 pthread_mutex_unlock(&gLock);
511 TBM_DBG("bufmgr init\n");
513 /* allocate bufmgr */
514 gBufMgr = calloc(1, sizeof(struct _tbm_bufmgr));
516 TBM_ERR("error: fail to alloc bufmgr fd(%d)\n", fd);
517 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
518 pthread_mutex_unlock(&gLock);
524 /* set the display_server flag before loading the backend module */
526 TBM_INFO("The tbm_bufmgr(%p) is used by display server. Need to bind the native_display.\n", gBufMgr);
527 gBufMgr->display_server = 1;
530 /* load bufmgr priv from env */
531 if (!_tbm_load_module(gBufMgr, gBufMgr->fd)) {
532 TBM_ERR("error : Fail to load bufmgr backend\n");
533 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
536 pthread_mutex_unlock(&gLock);
542 gBufMgr->ref_count = 1;
544 TBM_INFO("create tizen bufmgr:%p ref_count:%d\n",
545 gBufMgr, gBufMgr->ref_count);
547 /* setup the bo_lock_type */
548 env = getenv("BUFMGR_LOCK_TYPE");
549 if (env && !strcmp(env, "always"))
550 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS;
551 else if (env && !strcmp(env, "none"))
552 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_NEVER;
553 else if (env && !strcmp(env, "once"))
554 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ONCE;
556 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS;
558 TBM_DBG("BUFMGR_LOCK_TYPE=%s\n", env ? env : "default:once");
560 /* intialize bo_list */
561 LIST_INITHEAD(&gBufMgr->bo_list);
563 /* intialize surf_list */
564 LIST_INITHEAD(&gBufMgr->surf_list);
566 /* intialize surf_queue_list */
567 LIST_INITHEAD(&gBufMgr->surf_queue_list);
569 /* intialize debug_key_list */
570 LIST_INITHEAD(&gBufMgr->debug_key_list);
572 #ifdef TBM_BUFMGR_INIT_TIME
574 gettimeofday(&end_tv, NULL);
575 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)));
578 pthread_mutex_unlock(&gLock);
584 tbm_bufmgr_init(int fd)
588 bufmgr = _tbm_bufmgr_init(fd, 0);
594 tbm_bufmgr_deinit(tbm_bufmgr bufmgr)
596 TBM_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
598 _tbm_bufmgr_mutex_lock();
599 pthread_mutex_lock(&gLock);
600 _tbm_set_last_result(TBM_ERROR_NONE);
603 TBM_ERR("gBufmgr already destroy: bufmgr:%p\n", bufmgr);
604 pthread_mutex_unlock(&gLock);
605 _tbm_bufmgr_mutex_unlock();
610 if (bufmgr->ref_count > 0) {
611 TBM_DBG("reduce a ref_count(%d) of tbm_bufmgr(%p)\n", bufmgr->ref_count, bufmgr);
612 pthread_mutex_unlock(&gLock);
613 _tbm_bufmgr_mutex_unlock();
617 /* destroy bo_list */
618 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
619 tbm_bo bo = NULL, tmp;
621 LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &bufmgr->bo_list, item_link) {
622 TBM_ERR("Un-freed bo(%p, ref:%d)\n", bo, bo->ref_cnt);
625 LIST_DELINIT(&bufmgr->bo_list);
628 /* destroy surf_list */
629 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
630 tbm_surface_h surf = NULL, tmp;
632 LIST_FOR_EACH_ENTRY_SAFE(surf, tmp, &bufmgr->surf_list, item_link) {
633 TBM_ERR("Un-freed surf(%p, ref:%d)\n", surf, surf->refcnt);
634 tbm_surface_destroy(surf);
636 LIST_DELINIT(&bufmgr->surf_list);
639 if (bufmgr->backend_module_data) {
640 /* deinit and backend destroys the backend func and data */
641 bufmgr->backend_module_data->deinit(bufmgr->bufmgr_data);
642 bufmgr->bo_func = NULL;
643 bufmgr->bufmgr_func = NULL;
644 bufmgr->bufmgr_data = NULL;
645 bufmgr->backend_module_data = NULL;
647 /* destroy bufmgr priv */
648 bufmgr->backend->bufmgr_deinit(bufmgr->backend->priv);
649 bufmgr->backend->priv = NULL;
650 tbm_backend_free(bufmgr->backend);
651 bufmgr->backend = NULL;
654 TBM_INFO("destroy tbm_bufmgr(%p)\n", bufmgr);
656 dlclose(bufmgr->module_data);
664 pthread_mutex_unlock(&gLock);
665 _tbm_bufmgr_mutex_unlock();
669 tbm_bufmgr_get_capability(tbm_bufmgr bufmgr)
671 unsigned int capabilities = TBM_BUFMGR_CAPABILITY_NONE;
673 _tbm_bufmgr_mutex_lock();
674 _tbm_set_last_result(TBM_ERROR_NONE);
676 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), TBM_BUFMGR_CAPABILITY_NONE);
677 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, TBM_BUFMGR_CAPABILITY_NONE);
679 capabilities = bufmgr->capabilities;
681 _tbm_bufmgr_mutex_unlock();
686 /* LCOV_EXCL_START */
688 tbm_bufmgr_debug_tbm_info_get(tbm_bufmgr bufmgr)
690 char app_name[255] = {0,}, title[512] = {0,};
691 tbm_surface_debug_data *debug_old_data = NULL;
699 pthread_mutex_lock(&gLock);
700 _tbm_set_last_result(TBM_ERROR_NONE);
702 if (!TBM_BUFMGR_IS_VALID(bufmgr) || (bufmgr != gBufMgr)) {
703 TBM_ERR("invalid bufmgr\n");
704 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
705 pthread_mutex_unlock(&gLock);
711 TBM_ERR("Fail to allocate the string.\n");
712 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
713 pthread_mutex_unlock(&gLock);
717 TBM_SNRPRINTF(str, len, c, "\n");
718 pid = syscall(SYS_getpid);
719 _tbm_util_get_appname_from_pid(pid, app_name);
720 _tbm_util_get_appname_brief(app_name);
721 TBM_SNRPRINTF(str, len, c, "===========================================TBM DEBUG: %s(%ld)===========================================\n",
724 snprintf(title, 255, "%s", "no surface refcnt width height bpp size n_b n_p flags format app_name ");
726 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
727 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
728 strncat(title, " ", MAX_SIZE_N(title));
729 strncat(title, debug_old_data->key, MAX_SIZE_N(title));
733 TBM_SNRPRINTF(str, len, c, "[tbm_surface information]\n");
734 TBM_SNRPRINTF(str, len, c, "%s\n", title);
736 /* show the tbm_surface information in surf_list */
737 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
738 tbm_surface_h surf = NULL;
741 LIST_FOR_EACH_ENTRY(surf, &bufmgr->surf_list, item_link) {
742 char data[512] = {0,};
743 unsigned int surf_pid = 0;
746 surf_pid = _tbm_surface_internal_get_debug_pid(surf);
748 /* if pid is null, set the self_pid */
749 surf_pid = syscall(SYS_getpid);;
752 memset(app_name, 0x0, 255 * sizeof(char));
753 if (geteuid() == 0) {
754 _tbm_util_get_appname_from_pid(surf_pid, app_name);
755 _tbm_util_get_appname_brief(app_name);
757 snprintf(app_name, sizeof(app_name), "%d", surf_pid);
760 snprintf(data, 255, "%-3d %-11p %-5d %-6u %-7u %-4u %-7u %-3d %-3d %-8d %-9s %-22s",
767 surf->info.size / 1024,
771 _tbm_surface_internal_format_to_str(surf->info.format) + 11,
774 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
775 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
778 strncat(data, " ", MAX_SIZE_N(title));
780 value = _tbm_surface_internal_get_debug_data(surf, debug_old_data->key);
782 strncat(data, value, MAX_SIZE_N(title));
784 strncat(data, "none", MAX_SIZE_N(title));
787 TBM_SNRPRINTF(str, len, c, "%s\n", data);
789 for (i = 0; i < surf->num_bos; i++) {
790 if (bufmgr->backend_module_data) {
791 size = bufmgr->bo_func->bo_get_size(surf->bos[i]->bo_data, &error);
792 if (error != TBM_ERROR_NONE)
793 TBM_WRN("fail to get the size of bo.");
795 size = bufmgr->backend->bo_size(surf->bos[i]);
796 TBM_SNRPRINTF(str, len, c, " bo:%-12p %-26d%-10d\n",
798 surf->bos[i]->ref_cnt,
803 TBM_SNRPRINTF(str, len, c, " no tbm_surfaces.\n");
804 TBM_SNRPRINTF(str, len, c, "\n");
806 TBM_SNRPRINTF(str, len, c, "[tbm_bo information]\n");
807 TBM_SNRPRINTF(str, len, c, "no bo refcnt size lock_cnt map_cnt flags surface name\n");
809 /* show the tbm_bo information in bo_list */
810 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
815 LIST_FOR_EACH_ENTRY(bo, &bufmgr->bo_list, item_link) {
816 if (bufmgr->backend_module_data) {
817 size = bufmgr->bo_func->bo_get_size(bo->bo_data, &error);
818 if (error != TBM_ERROR_NONE)
819 TBM_WRN("fail to get the size of bo.");
820 key = bufmgr->bo_func->bo_export_key(bo->bo_data, &error);
821 if (error != TBM_ERROR_NONE)
822 TBM_WRN("fail to get the tdm_key of bo.");
824 size = bufmgr->backend->bo_size(bo);
825 key = bufmgr->backend->bo_export(bo);
827 TBM_SNRPRINTF(str, len, c, "%-3d %-11p %-5d %-7d %-6d %-5u %-7d %-11p %-4d\n",
839 TBM_SNRPRINTF(str, len, c, "no tbm_bos.\n");
840 TBM_SNRPRINTF(str, len, c, "\n");
842 TBM_SNRPRINTF(str, len, c, "========================================================================================================\n");
844 pthread_mutex_unlock(&gLock);
850 tbm_bufmgr_debug_show(tbm_bufmgr bufmgr)
853 str = tbm_bufmgr_debug_tbm_info_get(bufmgr);
861 tbm_bufmgr_debug_trace(tbm_bufmgr bufmgr, int onoff)
863 _tbm_bufmgr_mutex_lock();
864 _tbm_set_last_result(TBM_ERROR_NONE);
866 TBM_BUFMGR_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
867 TBM_BUFMGR_RETURN_IF_FAIL(bufmgr == gBufMgr);
870 TBM_LOG_D("bufmgr=%p onoff=%d\n", bufmgr, onoff);
874 _tbm_bufmgr_mutex_unlock();
878 tbm_bufmgr_debug_set_trace_mask(tbm_bufmgr bufmgr, tbm_bufmgr_debug_trace_mask mask, int set)
880 _tbm_bufmgr_mutex_lock();
881 _tbm_set_last_result(TBM_ERROR_NONE);
883 TBM_BUFMGR_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
884 TBM_BUFMGR_RETURN_IF_FAIL(bufmgr == gBufMgr);
889 TBM_INFO("bufmgr=%p sets the trace_mask=%d\n", bufmgr, mask);
890 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_BO)
891 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_BO");
892 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL)
893 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL");
894 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE)
895 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE");
896 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE)
897 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE");
898 } else if (set == 0) {
901 TBM_INFO("bufmgr=%p unsets the trace_mask=%d\n", bufmgr, mask);
902 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_BO)
903 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_BO");
904 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL)
905 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL");
906 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE)
907 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE");
908 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE)
909 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE");
911 TBM_WRN("set value is wrong.(set=%d)", set);
914 _tbm_bufmgr_mutex_unlock();
918 tbm_bufmgr_debug_dump_set_scale(double scale)
920 pthread_mutex_lock(&gLock);
921 _tbm_set_last_result(TBM_ERROR_NONE);
922 scale_factor = scale;
923 pthread_mutex_unlock(&gLock);
927 tbm_bufmgr_debug_get_ref_count(void)
931 pthread_mutex_lock(&gLock);
933 _tbm_set_last_result(TBM_ERROR_NONE);
935 refcnt = (gBufMgr) ? gBufMgr->ref_count : 0;
937 pthread_mutex_unlock(&gLock);
943 tbm_bufmgr_debug_queue_dump(char *path, int count, int onoff)
945 pthread_mutex_lock(&gLock);
946 _tbm_set_last_result(TBM_ERROR_NONE);
949 TBM_DBG("count=%d onoff=%d\n", count, onoff);
951 tbm_surface_internal_dump_end();
956 TBM_ERR("path is null");
957 pthread_mutex_unlock(&gLock);
960 TBM_DBG("path=%s count=%d onoff=%d\n", path, count, onoff);
962 if (_tbm_util_get_max_surface_size(&w, &h) == 0) {
963 TBM_ERR("Fail to get tbm_surface size.\n");
964 pthread_mutex_unlock(&gLock);
968 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
974 pthread_mutex_unlock(&gLock);
980 tbm_bufmgr_debug_dump_all(char *path)
983 tbm_surface_h surface = NULL;
985 pthread_mutex_lock(&gLock);
986 _tbm_set_last_result(TBM_ERROR_NONE);
989 TBM_ERR("path is null.\n");
990 pthread_mutex_unlock(&gLock);
994 TBM_DBG("path=%s\n", path);
996 count = _tbm_util_get_max_surface_size(&w, &h);
998 TBM_ERR("No tbm_surface.\n");
999 pthread_mutex_unlock(&gLock);
1003 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
1006 LIST_FOR_EACH_ENTRY(surface, &gBufMgr->surf_list, item_link)
1007 tbm_surface_internal_dump_buffer(surface, "dump_all");
1009 tbm_surface_internal_dump_end();
1011 pthread_mutex_unlock(&gLock);
1016 /* internal function */
1018 _tbm_bufmgr_get_bufmgr(void)
1024 tbm_bufmgr_bind_native_display(tbm_bufmgr bufmgr, void *native_display)
1029 _tbm_bufmgr_mutex_lock();
1030 _tbm_set_last_result(TBM_ERROR_NONE);
1032 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1034 if (bufmgr->backend_module_data) {
1035 if (!bufmgr->bufmgr_func->bufmgr_bind_native_display) {
1036 TBM_WRN("skip: tbm_bufmgr(%p) native_display(%p)\n",
1037 bufmgr, native_display);
1038 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
1039 _tbm_bufmgr_mutex_unlock();
1043 error = bufmgr->bufmgr_func->bufmgr_bind_native_display(bufmgr->bufmgr_data, (tbm_native_display *)native_display);
1044 if (error != TBM_ERROR_NONE) {
1045 TBM_ERR("error: tbm_bufmgr(%p) native_display(%p) error(%d)\n",
1046 bufmgr, native_display, error);
1047 _tbm_set_last_result(error);
1048 _tbm_bufmgr_mutex_unlock();
1053 if (!bufmgr->backend->bufmgr_bind_native_display) {
1054 TBM_WRN("skip: tbm_bufmgr(%p) native_display(%p)\n",
1055 bufmgr, native_display);
1056 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
1057 _tbm_bufmgr_mutex_unlock();
1061 ret = bufmgr->backend->bufmgr_bind_native_display(bufmgr, native_display);
1063 TBM_ERR("error: tbm_bufmgr(%p) native_display(%p)\n",
1064 bufmgr, native_display);
1065 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1066 _tbm_bufmgr_mutex_unlock();
1071 TBM_INFO("tbm_bufmgr(%p) native_display(%p)\n", bufmgr, native_display);
1073 _tbm_bufmgr_mutex_unlock();
1079 tbm_bufmgr_server_init(void)
1083 bufmgr = _tbm_bufmgr_init(-1, 1);
1089 tbm_bufmgr_set_bo_lock_type(tbm_bufmgr bufmgr, tbm_bufmgr_bo_lock_type bo_lock_type)
1091 _tbm_bufmgr_mutex_lock();
1092 _tbm_set_last_result(TBM_ERROR_NONE);
1094 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1095 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, 0);
1097 pthread_mutex_lock(&gLock);
1098 gBufMgr->bo_lock_type = bo_lock_type;
1099 pthread_mutex_unlock(&gLock);
1101 TBM_INFO("The bo_lock_type of the bo is %d\n", bo_lock_type);
1103 _tbm_bufmgr_mutex_unlock();
1109 int tbm_bufmgr_get_fd_limit(void)
1113 if (getrlimit(RLIMIT_NOFILE, &lim))
1116 return (int)lim.rlim_cur;
1119 tbm_bufmgr tbm_bufmgr_get(void)
1123 /* LCOV_EXCL_STOP */