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);
485 pthread_mutex_lock(&gLock);
487 _tbm_set_last_result(TBM_ERROR_NONE);
490 TBM_WRN("!!!!!WARNING:: The tbm_bufmgr_init DOSE NOT use argument fd ANYMORE.\n");
491 TBM_WRN("!!!!!WARNING:: IT WILL BE CHANGED like tbm_bufmgr_init(int fd) --> tbm_bufmgr_init(void).\n");
495 /* initialize buffer manager */
497 gBufMgr->ref_count++;
498 TBM_DBG("reuse tbm_bufmgr(%p) ref_count(%d) fd(%d)\n", gBufMgr, gBufMgr->ref_count, gBufMgr->fd);
499 pthread_mutex_unlock(&gLock);
503 TBM_DBG("bufmgr init\n");
505 /* allocate bufmgr */
506 gBufMgr = calloc(1, sizeof(struct _tbm_bufmgr));
508 TBM_ERR("error: fail to alloc bufmgr fd(%d)\n", fd);
509 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
510 pthread_mutex_unlock(&gLock);
516 /* set the display_server flag before loading the backend module */
518 TBM_INFO("The tbm_bufmgr(%p) is used by display server. Need to bind the native_display.\n", gBufMgr);
519 gBufMgr->display_server = 1;
522 /* load bufmgr priv from env */
523 TBM_STDOUT_INFO("loading backend module");
524 if (!_tbm_load_module(gBufMgr, gBufMgr->fd)) {
525 TBM_ERR("error : Fail to load bufmgr backend\n");
526 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
529 pthread_mutex_unlock(&gLock);
533 TBM_STDOUT_INFO("loading backend module done");
536 gBufMgr->ref_count = 1;
538 TBM_INFO("create tizen bufmgr:%p ref_count:%d\n",
539 gBufMgr, gBufMgr->ref_count);
541 /* setup the bo_lock_type */
542 env = getenv("BUFMGR_LOCK_TYPE");
543 if (env && !strcmp(env, "always"))
544 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS;
545 else if (env && !strcmp(env, "none"))
546 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_NEVER;
547 else if (env && !strcmp(env, "once"))
548 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ONCE;
550 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS;
552 TBM_DBG("BUFMGR_LOCK_TYPE=%s\n", env ? env : "default:once");
554 /* intialize bo_list */
555 LIST_INITHEAD(&gBufMgr->bo_list);
557 /* intialize surf_list */
558 LIST_INITHEAD(&gBufMgr->surf_list);
560 /* intialize surf_queue_list */
561 LIST_INITHEAD(&gBufMgr->surf_queue_list);
563 /* intialize debug_key_list */
564 LIST_INITHEAD(&gBufMgr->debug_key_list);
566 #ifdef TBM_BUFMGR_INIT_TIME
568 gettimeofday(&end_tv, NULL);
569 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)));
572 pthread_mutex_unlock(&gLock);
578 tbm_bufmgr_init(int fd)
582 bufmgr = _tbm_bufmgr_init(fd, 0);
588 tbm_bufmgr_deinit(tbm_bufmgr bufmgr)
590 TBM_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
592 _tbm_bufmgr_mutex_lock();
593 pthread_mutex_lock(&gLock);
594 _tbm_set_last_result(TBM_ERROR_NONE);
597 TBM_ERR("gBufmgr already destroy: bufmgr:%p\n", bufmgr);
598 pthread_mutex_unlock(&gLock);
599 _tbm_bufmgr_mutex_unlock();
604 if (bufmgr->ref_count > 0) {
605 TBM_DBG("reduce a ref_count(%d) of tbm_bufmgr(%p)\n", bufmgr->ref_count, bufmgr);
606 pthread_mutex_unlock(&gLock);
607 _tbm_bufmgr_mutex_unlock();
611 /* destroy bo_list */
612 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
613 tbm_bo bo = NULL, tmp;
615 LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &bufmgr->bo_list, item_link) {
616 TBM_ERR("Un-freed bo(%p, ref:%d)\n", bo, bo->ref_cnt);
619 LIST_DELINIT(&bufmgr->bo_list);
622 /* destroy surf_list */
623 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
624 tbm_surface_h surf = NULL, tmp;
626 LIST_FOR_EACH_ENTRY_SAFE(surf, tmp, &bufmgr->surf_list, item_link) {
627 TBM_ERR("Un-freed surf(%p, ref:%d)\n", surf, surf->refcnt);
628 tbm_surface_destroy(surf);
630 LIST_DELINIT(&bufmgr->surf_list);
633 if (bufmgr->backend_module_data) {
634 /* deinit and backend destroys the backend func and data */
635 bufmgr->backend_module_data->deinit(bufmgr->bufmgr_data);
636 bufmgr->bo_func = NULL;
637 bufmgr->bufmgr_func = NULL;
638 bufmgr->bufmgr_data = NULL;
639 bufmgr->backend_module_data = NULL;
641 /* destroy bufmgr priv */
642 bufmgr->backend->bufmgr_deinit(bufmgr->backend->priv);
643 bufmgr->backend->priv = NULL;
644 tbm_backend_free(bufmgr->backend);
645 bufmgr->backend = NULL;
648 TBM_INFO("destroy tbm_bufmgr(%p)\n", bufmgr);
650 dlclose(bufmgr->module_data);
658 pthread_mutex_unlock(&gLock);
659 _tbm_bufmgr_mutex_unlock();
663 tbm_bufmgr_get_capability(tbm_bufmgr bufmgr)
665 unsigned int capabilities = TBM_BUFMGR_CAPABILITY_NONE;
667 _tbm_bufmgr_mutex_lock();
668 _tbm_set_last_result(TBM_ERROR_NONE);
670 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), TBM_BUFMGR_CAPABILITY_NONE);
671 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, TBM_BUFMGR_CAPABILITY_NONE);
673 capabilities = bufmgr->capabilities;
675 _tbm_bufmgr_mutex_unlock();
680 /* LCOV_EXCL_START */
682 tbm_bufmgr_debug_tbm_info_get(tbm_bufmgr bufmgr)
684 char app_name[255] = {0,}, title[512] = {0,};
685 tbm_surface_debug_data *debug_old_data = NULL;
693 pthread_mutex_lock(&gLock);
694 _tbm_set_last_result(TBM_ERROR_NONE);
696 if (!TBM_BUFMGR_IS_VALID(bufmgr) || (bufmgr != gBufMgr)) {
697 TBM_ERR("invalid bufmgr\n");
698 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
699 pthread_mutex_unlock(&gLock);
705 TBM_ERR("Fail to allocate the string.\n");
706 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
707 pthread_mutex_unlock(&gLock);
711 TBM_SNRPRINTF(str, len, c, "\n");
712 pid = syscall(SYS_getpid);
713 _tbm_util_get_appname_from_pid(pid, app_name);
714 _tbm_util_get_appname_brief(app_name);
715 TBM_SNRPRINTF(str, len, c, "===========================================TBM DEBUG: %s(%ld)===========================================\n",
718 snprintf(title, 255, "%s", "no surface refcnt width height bpp size n_b n_p flags format app_name ");
720 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
721 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
722 strncat(title, " ", MAX_SIZE_N(title));
723 strncat(title, debug_old_data->key, MAX_SIZE_N(title));
727 TBM_SNRPRINTF(str, len, c, "[tbm_surface information]\n");
728 TBM_SNRPRINTF(str, len, c, "%s\n", title);
730 /* show the tbm_surface information in surf_list */
731 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
732 tbm_surface_h surf = NULL;
735 LIST_FOR_EACH_ENTRY(surf, &bufmgr->surf_list, item_link) {
736 char data[512] = {0,};
737 unsigned int surf_pid = 0;
740 surf_pid = _tbm_surface_internal_get_debug_pid(surf);
742 /* if pid is null, set the self_pid */
743 surf_pid = syscall(SYS_getpid);;
746 memset(app_name, 0x0, 255 * sizeof(char));
747 if (geteuid() == 0) {
748 _tbm_util_get_appname_from_pid(surf_pid, app_name);
749 _tbm_util_get_appname_brief(app_name);
751 snprintf(app_name, sizeof(app_name), "%d", surf_pid);
754 snprintf(data, 255, "%-3d %-11p %-5d %-6u %-7u %-4u %-7u %-3d %-3d %-8d %-9s %-22s",
761 surf->info.size / 1024,
765 _tbm_surface_internal_format_to_str(surf->info.format) + 11,
768 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
769 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
772 strncat(data, " ", MAX_SIZE_N(title));
774 value = _tbm_surface_internal_get_debug_data(surf, debug_old_data->key);
776 strncat(data, value, MAX_SIZE_N(title));
778 strncat(data, "none", MAX_SIZE_N(title));
781 TBM_SNRPRINTF(str, len, c, "%s\n", data);
783 for (i = 0; i < surf->num_bos; i++) {
784 if (bufmgr->backend_module_data) {
785 size = bufmgr->bo_func->bo_get_size(surf->bos[i]->bo_data, &error);
786 if (error != TBM_ERROR_NONE)
787 TBM_WRN("fail to get the size of bo.");
789 size = bufmgr->backend->bo_size(surf->bos[i]);
790 TBM_SNRPRINTF(str, len, c, " bo:%-12p %-26d%-10d\n",
792 surf->bos[i]->ref_cnt,
797 TBM_SNRPRINTF(str, len, c, " no tbm_surfaces.\n");
798 TBM_SNRPRINTF(str, len, c, "\n");
800 TBM_SNRPRINTF(str, len, c, "[tbm_bo information]\n");
801 TBM_SNRPRINTF(str, len, c, "no bo refcnt size lock_cnt map_cnt flags surface name\n");
803 /* show the tbm_bo information in bo_list */
804 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
809 LIST_FOR_EACH_ENTRY(bo, &bufmgr->bo_list, item_link) {
810 if (bufmgr->backend_module_data) {
811 size = bufmgr->bo_func->bo_get_size(bo->bo_data, &error);
812 if (error != TBM_ERROR_NONE)
813 TBM_WRN("fail to get the size of bo.");
814 key = bufmgr->bo_func->bo_export_key(bo->bo_data, &error);
815 if (error != TBM_ERROR_NONE)
816 TBM_WRN("fail to get the tdm_key of bo.");
818 size = bufmgr->backend->bo_size(bo);
819 key = bufmgr->backend->bo_export(bo);
821 TBM_SNRPRINTF(str, len, c, "%-3d %-11p %-5d %-7d %-6d %-5u %-7d %-11p %-4d\n",
833 TBM_SNRPRINTF(str, len, c, "no tbm_bos.\n");
834 TBM_SNRPRINTF(str, len, c, "\n");
836 TBM_SNRPRINTF(str, len, c, "========================================================================================================\n");
838 pthread_mutex_unlock(&gLock);
844 tbm_bufmgr_debug_show(tbm_bufmgr bufmgr)
847 str = tbm_bufmgr_debug_tbm_info_get(bufmgr);
855 tbm_bufmgr_debug_trace(tbm_bufmgr bufmgr, int onoff)
857 _tbm_bufmgr_mutex_lock();
858 _tbm_set_last_result(TBM_ERROR_NONE);
860 TBM_BUFMGR_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
861 TBM_BUFMGR_RETURN_IF_FAIL(bufmgr == gBufMgr);
864 TBM_LOG_D("bufmgr=%p onoff=%d\n", bufmgr, onoff);
868 _tbm_bufmgr_mutex_unlock();
872 tbm_bufmgr_debug_set_trace_mask(tbm_bufmgr bufmgr, tbm_bufmgr_debug_trace_mask mask, int set)
874 _tbm_bufmgr_mutex_lock();
875 _tbm_set_last_result(TBM_ERROR_NONE);
877 TBM_BUFMGR_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
878 TBM_BUFMGR_RETURN_IF_FAIL(bufmgr == gBufMgr);
883 TBM_INFO("bufmgr=%p sets the trace_mask=%d\n", bufmgr, mask);
884 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_BO)
885 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_BO");
886 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL)
887 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL");
888 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE)
889 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE");
890 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE)
891 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE");
892 } else if (set == 0) {
895 TBM_INFO("bufmgr=%p unsets the trace_mask=%d\n", bufmgr, mask);
896 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_BO)
897 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_BO");
898 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL)
899 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL");
900 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE)
901 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE");
902 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE)
903 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE");
905 TBM_WRN("set value is wrong.(set=%d)", set);
908 _tbm_bufmgr_mutex_unlock();
912 tbm_bufmgr_debug_dump_set_scale(double scale)
914 pthread_mutex_lock(&gLock);
915 _tbm_set_last_result(TBM_ERROR_NONE);
916 scale_factor = scale;
917 pthread_mutex_unlock(&gLock);
921 tbm_bufmgr_debug_get_ref_count(void)
925 pthread_mutex_lock(&gLock);
927 _tbm_set_last_result(TBM_ERROR_NONE);
929 refcnt = (gBufMgr) ? gBufMgr->ref_count : 0;
931 pthread_mutex_unlock(&gLock);
937 tbm_bufmgr_debug_queue_dump(char *path, int count, int onoff)
939 pthread_mutex_lock(&gLock);
940 _tbm_set_last_result(TBM_ERROR_NONE);
943 TBM_DBG("count=%d onoff=%d\n", count, onoff);
945 tbm_surface_internal_dump_end();
950 TBM_ERR("path is null");
951 pthread_mutex_unlock(&gLock);
954 TBM_DBG("path=%s count=%d onoff=%d\n", path, count, onoff);
956 if (_tbm_util_get_max_surface_size(&w, &h) == 0) {
957 TBM_ERR("Fail to get tbm_surface size.\n");
958 pthread_mutex_unlock(&gLock);
962 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
968 pthread_mutex_unlock(&gLock);
974 tbm_bufmgr_debug_dump_all(char *path)
977 tbm_surface_h surface = NULL;
979 pthread_mutex_lock(&gLock);
980 _tbm_set_last_result(TBM_ERROR_NONE);
983 TBM_ERR("path is null.\n");
984 pthread_mutex_unlock(&gLock);
988 TBM_DBG("path=%s\n", path);
990 count = _tbm_util_get_max_surface_size(&w, &h);
992 TBM_ERR("No tbm_surface.\n");
993 pthread_mutex_unlock(&gLock);
997 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
1000 LIST_FOR_EACH_ENTRY(surface, &gBufMgr->surf_list, item_link)
1001 tbm_surface_internal_dump_buffer(surface, "dump_all");
1003 tbm_surface_internal_dump_end();
1005 pthread_mutex_unlock(&gLock);
1010 /* internal function */
1012 _tbm_bufmgr_get_bufmgr(void)
1018 tbm_bufmgr_bind_native_display(tbm_bufmgr bufmgr, void *native_display)
1023 _tbm_bufmgr_mutex_lock();
1024 _tbm_set_last_result(TBM_ERROR_NONE);
1026 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1028 if (bufmgr->backend_module_data) {
1029 if (!bufmgr->bufmgr_func->bufmgr_bind_native_display) {
1030 TBM_WRN("skip: tbm_bufmgr(%p) native_display(%p)\n",
1031 bufmgr, native_display);
1032 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
1033 _tbm_bufmgr_mutex_unlock();
1037 error = bufmgr->bufmgr_func->bufmgr_bind_native_display(bufmgr->bufmgr_data, (tbm_native_display *)native_display);
1038 if (error != TBM_ERROR_NONE) {
1039 TBM_ERR("error: tbm_bufmgr(%p) native_display(%p) error(%d)\n",
1040 bufmgr, native_display, error);
1041 _tbm_set_last_result(error);
1042 _tbm_bufmgr_mutex_unlock();
1047 if (!bufmgr->backend->bufmgr_bind_native_display) {
1048 TBM_WRN("skip: tbm_bufmgr(%p) native_display(%p)\n",
1049 bufmgr, native_display);
1050 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
1051 _tbm_bufmgr_mutex_unlock();
1055 ret = bufmgr->backend->bufmgr_bind_native_display(bufmgr, native_display);
1057 TBM_ERR("error: tbm_bufmgr(%p) native_display(%p)\n",
1058 bufmgr, native_display);
1059 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1060 _tbm_bufmgr_mutex_unlock();
1065 TBM_INFO("tbm_bufmgr(%p) native_display(%p)\n", bufmgr, native_display);
1067 _tbm_bufmgr_mutex_unlock();
1073 tbm_bufmgr_server_init(void)
1077 bufmgr = _tbm_bufmgr_init(-1, 1);
1083 tbm_bufmgr_set_bo_lock_type(tbm_bufmgr bufmgr, tbm_bufmgr_bo_lock_type bo_lock_type)
1085 _tbm_bufmgr_mutex_lock();
1086 _tbm_set_last_result(TBM_ERROR_NONE);
1088 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1089 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, 0);
1091 pthread_mutex_lock(&gLock);
1092 gBufMgr->bo_lock_type = bo_lock_type;
1093 pthread_mutex_unlock(&gLock);
1095 TBM_INFO("The bo_lock_type of the bo is %d\n", bo_lock_type);
1097 _tbm_bufmgr_mutex_unlock();
1103 int tbm_bufmgr_get_fd_limit(void)
1107 if (getrlimit(RLIMIT_NOFILE, &lim))
1110 return (int)lim.rlim_cur;
1113 tbm_bufmgr tbm_bufmgr_get(void)
1117 /* LCOV_EXCL_STOP */