1 /**************************************************************************
5 Copyright 2012 Samsung Electronics co., Ltd. All Rights Reserved.
7 Contact: SooChan Lim <sc1.lim@samsung.com>, Sangjin Lee <lsj119@samsung.com>
8 Boram Park <boram1288.park@samsung.com>, Changyeon Lee <cyeon.lee@samsung.com>
10 Permission is hereby granted, free of charge, to any person obtaining a
11 copy of this software and associated documentation files (the
12 "Software"), to deal in the Software without restriction, including
13 without limitation the rights to use, copy, modify, merge, publish,
14 distribute, sub license, and/or sell copies of the Software, and to
15 permit persons to whom the Software is furnished to do so, subject to
16 the following conditions:
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial portions
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
25 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 **************************************************************************/
34 #include "tbm_bufmgr.h"
35 #include "tbm_bufmgr_int.h"
36 #include "tbm_bufmgr_backend.h"
39 #include <sys/resource.h>
50 static pthread_mutex_t gLock = PTHREAD_MUTEX_INITIALIZER;
51 static pthread_mutex_t tbm_bufmgr_lock = PTHREAD_MUTEX_INITIALIZER;
52 static double scale_factor = 0;
53 static void _tbm_bufmgr_mutex_unlock(void);
55 //#define TBM_BUFMGR_INIT_TIME
57 #define PREFIX_LIB "libtbm_"
58 #define SUFFIX_LIB ".so"
59 #define DEFAULT_LIB PREFIX_LIB"default"SUFFIX_LIB
61 /* values to indicate unspecified fields in XF86ModReqInfo. */
62 #define MAJOR_UNSPEC 0xFF
63 #define MINOR_UNSPEC 0xFF
64 #define PATCH_UNSPEC 0xFFFF
65 #define ABI_VERS_UNSPEC 0xFFFFFFFF
67 #define MODULE_VERSION_NUMERIC(maj, min, patch) \
68 ((((maj) & 0xFF) << 24) | (((min) & 0xFF) << 16) | (patch & 0xFFFF))
69 #define GET_MODULE_MAJOR_VERSION(vers) (((vers) >> 24) & 0xFF)
70 #define GET_MODULE_MINOR_VERSION(vers) (((vers) >> 16) & 0xFF)
71 #define GET_MODULE_PATCHLEVEL(vers) ((vers) & 0xFFFF)
73 #define MAX_SIZE_N(dest) (sizeof(dest) - strlen(dest) - 1)
76 #define TBM_BUFMGR_RETURN_IF_FAIL(cond) {\
78 TBM_ERR("'%s' failed.\n", #cond);\
79 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
80 _tbm_bufmgr_mutex_unlock();\
85 #define TBM_BUFMGR_RETURN_VAL_IF_FAIL(cond, val) {\
87 TBM_ERR("'%s' failed.\n", #cond);\
88 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
89 _tbm_bufmgr_mutex_unlock();\
96 _tbm_bufmgr_mutex_init(void)
98 static bool tbm_bufmgr_mutex_init = false;
100 if (tbm_bufmgr_mutex_init)
103 if (pthread_mutex_init(&tbm_bufmgr_lock, NULL)) {
104 TBM_ERR("fail: Cannot pthread_mutex_init for tbm_bufmgr_lock.\n");
108 tbm_bufmgr_mutex_init = true;
114 _tbm_bufmgr_mutex_lock(void)
116 if (!_tbm_bufmgr_mutex_init()) {
117 TBM_ERR("fail: _tbm_bufmgr_mutex_init()\n");
121 pthread_mutex_lock(&tbm_bufmgr_lock);
125 _tbm_bufmgr_mutex_unlock(void)
127 pthread_mutex_unlock(&tbm_bufmgr_lock);
131 _tbm_util_get_max_surface_size(int *w, int *h)
133 tbm_surface_info_s info;
134 tbm_surface_h surface = NULL;
140 if (gBufMgr == NULL || LIST_IS_EMPTY(&gBufMgr->surf_list))
143 LIST_FOR_EACH_ENTRY(surface, &gBufMgr->surf_list, item_link) {
144 if (tbm_surface_get_info(surface, &info) == TBM_SURFACE_ERROR_NONE) {
148 if (*h < info.height)
157 _tbm_util_get_appname_brief(char *brief)
161 char temp[255] = {0,};
162 char *saveptr = NULL;
164 token = strtok_r(brief, delim, &saveptr);
166 while (token != NULL) {
167 memset(temp, 0x00, 255 * sizeof(char));
168 strncpy(temp, token, 254 * sizeof(char));
169 token = strtok_r(NULL, delim, &saveptr);
172 snprintf(brief, sizeof(temp), "%s", temp);
176 _tbm_util_get_appname_from_pid(long pid, char *str)
178 char fn_cmdline[255] = {0, }, cmdline[255];
182 snprintf(fn_cmdline, sizeof(fn_cmdline), "/proc/%ld/cmdline", pid);
184 fp = fopen(fn_cmdline, "r");
186 TBM_ERR("cannot file open %s\n", fn_cmdline);
190 if (!fgets(cmdline, 255, fp)) {
191 TBM_ERR("fail to get appname for pid(%ld)\n", pid);
198 len = strlen(cmdline);
200 memset(cmdline, 0x00, 255);
204 snprintf(str, sizeof(cmdline), "%s", cmdline);
208 _check_version(TBMModuleVersionInfo *data)
213 abimaj = GET_ABI_MAJOR(data->abiversion);
214 abimin = GET_ABI_MINOR(data->abiversion);
216 TBM_DBG("TBM module %s: vendor=\"%s\" ABI=%d,%d\n",
217 data->modname ? data->modname : "UNKNOWN!",
218 data->vendor ? data->vendor : "UNKNOWN!", abimaj, abimin);
220 vermaj = GET_ABI_MAJOR(TBM_ABI_VERSION);
221 vermin = GET_ABI_MINOR(TBM_ABI_VERSION);
223 TBM_DBG("TBM ABI version %d.%d\n",
226 if (abimaj != vermaj) {
227 TBM_ERR("TBM module ABI major ver(%d) doesn't match the TBM's ver(%d)\n",
230 } else if (abimin > vermin) {
231 TBM_ERR("TBM module ABI minor ver(%d) is newer than the TBM's ver(%d)\n",
240 _tbm_backend_check_bufmgr_func(tbm_backend_bufmgr_func *bufmgr_func)
242 TBM_RETURN_VAL_IF_FAIL(bufmgr_func, 0); /* mandatory symbol */
243 TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_get_capabilities, 0); /* mandatory symbol */
244 TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_bind_native_display, 0); /* mandatory symbol */
245 TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_get_supported_formats, 0); /* mandatory symbol */
246 TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_get_plane_data, 0); /* mandatory symbol */
247 TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_alloc_bo, 0); /* mandatory symbol */
248 if (!bufmgr_func->bufmgr_alloc_bo_with_format)
249 TBM_DBG("No bufmgr_func->bufmgr_alloc_bo_with_format.");
250 TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_import_fd, 0); /* mandatory symbol */
251 if (!bufmgr_func->bufmgr_import_key)
252 TBM_DBG("No bufmgr_func->bo_export_key.");
258 _tbm_backend_check_bufmgr_bo(tbm_backend_bo_func *bo_func)
260 TBM_RETURN_VAL_IF_FAIL(bo_func, 0); /* mandatory symbol */
261 TBM_RETURN_VAL_IF_FAIL(bo_func->bo_free, 0); /* mandatory symbol */
262 TBM_RETURN_VAL_IF_FAIL(bo_func->bo_get_size, 0); /* mandatory symbol */
263 TBM_RETURN_VAL_IF_FAIL(bo_func->bo_get_memory_types, 0); /* mandatory symbol */
264 TBM_RETURN_VAL_IF_FAIL(bo_func->bo_get_handle, 0); /* mandatory symbol */
265 TBM_RETURN_VAL_IF_FAIL(bo_func->bo_map, 0); /* mandatory symbol */
266 TBM_RETURN_VAL_IF_FAIL(bo_func->bo_unmap, 0); /* mandatory symbol */
267 if (!bo_func->bo_lock)
268 TBM_DBG("No bo_func->bo_lock.");
269 if (!bo_func->bo_unlock)
270 TBM_DBG("No bo_func->bo_unlock.");
271 TBM_RETURN_VAL_IF_FAIL(bo_func->bo_export_fd, 0); /* mandatory symbol */
272 if (!bo_func->bo_export_key)
273 TBM_INFO("No bo_func->bo_export_key.");
279 _tbm_backend_load_module(tbm_bufmgr bufmgr, const char *file)
281 char path[PATH_MAX] = {0, };
282 void *module_data = NULL;
283 tbm_backend_module *backend_module_data = NULL;
284 tbm_backend_bufmgr_data *bufmgr_data = NULL;
289 snprintf(path, sizeof(path), BUFMGR_MODULE_DIR "/%s", file);
291 module_data = dlopen(path, RTLD_LAZY);
293 TBM_ERR("failed to load module: %s(%s)\n", dlerror(), file);
297 backend_module_data = dlsym(module_data, "tbm_backend_module_data");
298 if (!backend_module_data) {
299 TBM_ERR("Error: module does not have data object.\n");
303 abimaj = GET_ABI_MAJOR(backend_module_data->abi_version);
304 abimin = GET_ABI_MINOR(backend_module_data->abi_version);
306 TBM_DBG("TBM module %s: vendor=\"%s\" ABI=%d,%d\n",
307 backend_module_data->name ? backend_module_data->name : "UNKNOWN!",
308 backend_module_data->vendor ? backend_module_data->vendor : "UNKNOWN!",
311 vermaj = GET_ABI_MAJOR(TBM_BACKEND_ABI_LATEST_VERSION);
312 vermin = GET_ABI_MINOR(TBM_BACKEND_ABI_LATEST_VERSION);
313 TBM_DBG("TBM ABI version %d.%d\n", vermaj, vermin);
315 if (abimaj > vermaj) {
316 TBM_ERR("TBM module ABI major ver(%d) is newer than the TBM's ver(%d)\n",
319 } else if (abimin > vermin) {
320 TBM_ERR("TBM module ABI minor ver(%d) is newer than the TBM's ver(%d)\n",
325 if (!backend_module_data->init) {
326 TBM_ERR("Error: module does not supply init symbol.\n");
330 if (!backend_module_data->deinit) {
331 TBM_ERR("Error: module does not supply deinit symbol.\n");
335 bufmgr_data = backend_module_data->init(bufmgr, &error);
337 TBM_ERR("Fail to init module(%s)\n", file);
341 /* check the mandatory symbols of the backend module */
342 if (!_tbm_backend_check_bufmgr_func(bufmgr->bufmgr_func)) {
343 TBM_ERR("Fail to check the bufmgr_func symboles.");
347 if (!_tbm_backend_check_bufmgr_bo(bufmgr->bo_func)) {
348 TBM_ERR("Fail to check the bufmgr_bo symboles.");
352 /* get the capability */
353 bufmgr->capabilities = bufmgr->bufmgr_func->bufmgr_get_capabilities(bufmgr_data, &error);
354 if (bufmgr->capabilities == TBM_BUFMGR_CAPABILITY_NONE) {
355 TBM_ERR("The capabilities of the backend module is TBM_BUFMGR_CAPABILITY_NONE.");
356 TBM_ERR("TBM_BUFMGR_CAPABILITY_SHARE_FD is the essential capability.");
360 if (!(bufmgr->capabilities & TBM_BUFMGR_CAPABILITY_SHARE_FD)) {
361 TBM_ERR("The capabilities of the backend module had no TBM_BUFMGR_CAPABILITY_SHARE_FD.");
362 TBM_ERR("The tbm backend has to get TBM_BUFMGR_CAPABILITY_SHARE_FD. ");
366 bufmgr->module_data = module_data;
367 bufmgr->backend_module_data = backend_module_data;
368 bufmgr->bufmgr_data = bufmgr_data;
370 TBM_DBG("Success to load module(%s)\n", file);
376 bufmgr->backend_module_data->deinit(bufmgr_data);
378 dlclose(module_data);
384 _tbm_bufmgr_load_module(tbm_bufmgr bufmgr, int fd, const char *file)
386 char path[PATH_MAX] = {0, };
387 TBMModuleVersionInfo *vers;
388 TBMModuleData *initdata;
392 snprintf(path, sizeof(path), BUFMGR_MODULE_DIR "/%s", file);
394 module_data = dlopen(path, RTLD_LAZY);
396 TBM_ERR("failed to load module: %s(%s)\n", dlerror(), file);
400 initdata = dlsym(module_data, "tbmModuleData");
402 TBM_ERR("Error: module does not have data object.\n");
406 vers = initdata->vers;
408 TBM_ERR("Error: module does not supply version information.\n");
412 init = initdata->init;
414 TBM_ERR("Error: module does not supply init symbol.\n");
418 if (!_check_version(vers)) {
419 TBM_ERR("Fail to check version.\n");
423 if (!init(bufmgr, fd)) {
424 TBM_ERR("Fail to init module(%s)\n", file);
428 if (!bufmgr->backend || !bufmgr->backend->priv) {
429 TBM_ERR("Error: module(%s) wrong operation. Check backend or backend's priv.\n", file);
433 bufmgr->module_data = module_data;
435 TBM_DBG("Success to load module(%s)\n", file);
440 dlclose(module_data);
445 _tbm_load_module(tbm_bufmgr bufmgr, int fd)
447 struct dirent **namelist;
450 /* try to load the new backend module */
451 ret = _tbm_backend_load_module(bufmgr, DEFAULT_LIB);
455 /* try to load the old(deprecated) backend mdoule */
456 ret = _tbm_bufmgr_load_module(bufmgr, fd, DEFAULT_LIB);
460 /* load bufmgr priv from configured path */
461 n = scandir(BUFMGR_MODULE_DIR, &namelist, 0, alphasort);
463 TBM_ERR("no files : %s\n", BUFMGR_MODULE_DIR);
468 if (!ret && strstr(namelist[n]->d_name, PREFIX_LIB)) {
469 const char *p = strstr(namelist[n]->d_name, SUFFIX_LIB);
471 if (p && !strcmp(p, SUFFIX_LIB)) {
472 ret = _tbm_backend_load_module(bufmgr, namelist[n]->d_name);
474 ret = _tbm_bufmgr_load_module(bufmgr, fd,
475 namelist[n]->d_name);
489 _tbm_bufmgr_init(int fd, int server)
491 #ifdef TBM_BUFMGR_INIT_TIME
492 struct timeval start_tv, end_tv;
496 #ifdef TBM_BUFMGR_INIT_TIME
497 /* get the start tv */
498 gettimeofday(&start_tv, NULL);
501 /* LCOV_EXCL_START */
503 env = getenv("TBM_DLOG");
506 TBM_DBG("TBM_DLOG=%s\n", env);
512 env = getenv("TBM_TRACE");
514 trace_mask = atoi(env);
515 TBM_DBG("TBM_TRACE=%s\n", env);
520 pthread_mutex_lock(&gLock);
522 _tbm_set_last_result(TBM_ERROR_NONE);
525 TBM_WRN("!!!!!WARNING:: The tbm_bufmgr_init DOSE NOT use argument fd ANYMORE.\n");
526 TBM_WRN("!!!!!WARNING:: IT WILL BE CHANGED like tbm_bufmgr_init(int fd) --> tbm_bufmgr_init(void).\n");
530 /* initialize buffer manager */
532 gBufMgr->ref_count++;
533 TBM_INFO("reuse tbm_bufmgr(%p) ref_count(%d) fd(%d)\n", gBufMgr, gBufMgr->ref_count, gBufMgr->fd);
534 pthread_mutex_unlock(&gLock);
538 TBM_DBG("bufmgr init\n");
540 /* allocate bufmgr */
541 gBufMgr = calloc(1, sizeof(struct _tbm_bufmgr));
543 TBM_ERR("error: fail to alloc bufmgr fd(%d)\n", fd);
544 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
545 pthread_mutex_unlock(&gLock);
551 /* set the display_server flag before loading the backend module */
553 TBM_INFO("The tbm_bufmgr(%p) is used by display server. Need to bind the native_display.\n", gBufMgr);
554 gBufMgr->display_server = 1;
557 /* load bufmgr priv from env */
558 if (!_tbm_load_module(gBufMgr, gBufMgr->fd)) {
559 TBM_ERR("error : Fail to load bufmgr backend\n");
560 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
563 pthread_mutex_unlock(&gLock);
569 gBufMgr->ref_count = 1;
571 TBM_INFO("create tizen bufmgr:%p ref_count:%d\n",
572 gBufMgr, gBufMgr->ref_count);
574 /* setup the bo_lock_type */
575 env = getenv("BUFMGR_LOCK_TYPE");
576 if (env && !strcmp(env, "always"))
577 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS;
578 else if (env && !strcmp(env, "none"))
579 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_NEVER;
580 else if (env && !strcmp(env, "once"))
581 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ONCE;
583 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS;
585 TBM_DBG("BUFMGR_LOCK_TYPE=%s\n", env ? env : "default:once");
587 /* intialize bo_list */
588 LIST_INITHEAD(&gBufMgr->bo_list);
590 /* intialize surf_list */
591 LIST_INITHEAD(&gBufMgr->surf_list);
593 /* intialize surf_queue_list */
594 LIST_INITHEAD(&gBufMgr->surf_queue_list);
596 /* intialize debug_key_list */
597 LIST_INITHEAD(&gBufMgr->debug_key_list);
599 #ifdef TBM_BUFMGR_INIT_TIME
601 gettimeofday(&end_tv, NULL);
602 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)));
605 pthread_mutex_unlock(&gLock);
611 tbm_bufmgr_init(int fd)
615 bufmgr = _tbm_bufmgr_init(fd, 0);
621 tbm_bufmgr_deinit(tbm_bufmgr bufmgr)
623 TBM_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
625 _tbm_bufmgr_mutex_lock();
626 pthread_mutex_lock(&gLock);
627 _tbm_set_last_result(TBM_ERROR_NONE);
630 TBM_ERR("gBufmgr already destroy: bufmgr:%p\n", bufmgr);
631 pthread_mutex_unlock(&gLock);
632 _tbm_bufmgr_mutex_unlock();
637 if (bufmgr->ref_count > 0) {
638 TBM_INFO("reduce a ref_count(%d) of tbm_bufmgr(%p)\n", bufmgr->ref_count, bufmgr);
639 pthread_mutex_unlock(&gLock);
640 _tbm_bufmgr_mutex_unlock();
644 /* destroy bo_list */
645 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
646 tbm_bo bo = NULL, tmp;
648 LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &bufmgr->bo_list, item_link) {
649 TBM_ERR("Un-freed bo(%p, ref:%d)\n", bo, bo->ref_cnt);
652 LIST_DELINIT(&bufmgr->bo_list);
655 /* destroy surf_list */
656 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
657 tbm_surface_h surf = NULL, tmp;
659 LIST_FOR_EACH_ENTRY_SAFE(surf, tmp, &bufmgr->surf_list, item_link) {
660 TBM_ERR("Un-freed surf(%p, ref:%d)\n", surf, surf->refcnt);
661 tbm_surface_destroy(surf);
663 LIST_DELINIT(&bufmgr->surf_list);
666 if (bufmgr->backend_module_data) {
667 /* deinit and backend destroys the backend func and data */
668 bufmgr->backend_module_data->deinit(bufmgr->bufmgr_data);
669 bufmgr->bo_func = NULL;
670 bufmgr->bufmgr_func = NULL;
671 bufmgr->bufmgr_data = NULL;
672 bufmgr->backend_module_data = NULL;
674 /* destroy bufmgr priv */
675 bufmgr->backend->bufmgr_deinit(bufmgr->backend->priv);
676 bufmgr->backend->priv = NULL;
677 tbm_backend_free(bufmgr->backend);
678 bufmgr->backend = NULL;
681 TBM_INFO("destroy tbm_bufmgr(%p)\n", bufmgr);
683 dlclose(bufmgr->module_data);
691 pthread_mutex_unlock(&gLock);
692 _tbm_bufmgr_mutex_unlock();
696 tbm_bufmgr_get_capability(tbm_bufmgr bufmgr)
698 unsigned int capabilities = TBM_BUFMGR_CAPABILITY_NONE;
700 _tbm_bufmgr_mutex_lock();
701 _tbm_set_last_result(TBM_ERROR_NONE);
703 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), TBM_BUFMGR_CAPABILITY_NONE);
704 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, TBM_BUFMGR_CAPABILITY_NONE);
706 capabilities = bufmgr->capabilities;
708 _tbm_bufmgr_mutex_unlock();
713 /* LCOV_EXCL_START */
715 tbm_bufmgr_debug_tbm_info_get(tbm_bufmgr bufmgr)
717 char app_name[255] = {0,}, title[512] = {0,};
718 tbm_surface_debug_data *debug_old_data = NULL;
725 pthread_mutex_lock(&gLock);
726 _tbm_set_last_result(TBM_ERROR_NONE);
728 if (!TBM_BUFMGR_IS_VALID(bufmgr) || (bufmgr != gBufMgr)) {
729 TBM_ERR("invalid bufmgr\n");
730 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
731 pthread_mutex_unlock(&gLock);
737 TBM_ERR("Fail to allocate the string.\n");
738 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
739 pthread_mutex_unlock(&gLock);
743 TBM_SNRPRINTF(str, len, c, "\n");
744 _tbm_util_get_appname_from_pid(getpid(), app_name);
745 _tbm_util_get_appname_brief(app_name);
746 TBM_SNRPRINTF(str, len, c, "============TBM DEBUG: %s(%d)===========================\n",
749 snprintf(title, 255, "%s", "no surface refcnt width height bpp size n_b n_p flags format app_name ");
751 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
752 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
753 strncat(title, " ", MAX_SIZE_N(title));
754 strncat(title, debug_old_data->key, MAX_SIZE_N(title));
758 TBM_SNRPRINTF(str, len, c, "[tbm_surface information]\n");
759 TBM_SNRPRINTF(str, len, c, "%s\n", title);
761 /* show the tbm_surface information in surf_list */
762 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
763 tbm_surface_h surf = NULL;
766 LIST_FOR_EACH_ENTRY(surf, &bufmgr->surf_list, item_link) {
767 char data[512] = {0,};
771 pid = _tbm_surface_internal_get_debug_pid(surf);
773 /* if pid is null, set the self_pid */
777 memset(app_name, 0x0, 255 * sizeof(char));
778 _tbm_util_get_appname_from_pid(pid, app_name);
779 _tbm_util_get_appname_brief(app_name);
781 snprintf(data, 255, "%-2d %-9p %-4d %-5u %-6u %-3u %-6u %-2d %-2d %-3d %-8s %-15s",
788 surf->info.size / 1024,
792 _tbm_surface_internal_format_to_str(surf->info.format) + 11,
795 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
796 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
799 strncat(data, " ", MAX_SIZE_N(title));
801 value = _tbm_surface_internal_get_debug_data(surf, debug_old_data->key);
803 strncat(data, value, MAX_SIZE_N(title));
805 strncat(data, "none", MAX_SIZE_N(title));
808 TBM_SNRPRINTF(str, len, c, "%s\n", data);
810 for (i = 0; i < surf->num_bos; i++) {
811 if (bufmgr->backend_module_data) {
812 size = bufmgr->bo_func->bo_get_size(surf->bos[i]->bo_data, &error);
813 if (error != TBM_ERROR_NONE)
814 TBM_WRN("fail to get the size of bo.");
816 size = bufmgr->backend->bo_size(surf->bos[i]);
817 TBM_SNRPRINTF(str, len, c, " bo:%-12p %-26d%-10d\n",
819 surf->bos[i]->ref_cnt,
824 TBM_SNRPRINTF(str, len, c, " no tbm_surfaces.\n");
825 TBM_SNRPRINTF(str, len, c, "\n");
827 TBM_SNRPRINTF(str, len, c, "[tbm_bo information]\n");
828 TBM_SNRPRINTF(str, len, c, "no bo refcnt size lock_cnt map_cnt flags surface name\n");
830 /* show the tbm_bo information in bo_list */
831 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
836 LIST_FOR_EACH_ENTRY(bo, &bufmgr->bo_list, item_link) {
837 if (bufmgr->backend_module_data) {
838 size = bufmgr->bo_func->bo_get_size(bo->bo_data, &error);
839 if (error != TBM_ERROR_NONE)
840 TBM_WRN("fail to get the size of bo.");
841 key = bufmgr->bo_func->bo_export_key(bo->bo_data, &error);
842 if (error != TBM_ERROR_NONE)
843 TBM_WRN("fail to get the tdm_key of bo.");
845 size = bufmgr->backend->bo_size(bo);
846 key = bufmgr->backend->bo_export(bo);
848 TBM_SNRPRINTF(str, len, c, "%-4d%-11p %-4d %-6d %-5d %-4u %-3d %-11p %-4d\n",
860 TBM_SNRPRINTF(str, len, c, "no tbm_bos.\n");
861 TBM_SNRPRINTF(str, len, c, "\n");
863 TBM_SNRPRINTF(str, len, c, "===============================================================\n");
865 pthread_mutex_unlock(&gLock);
871 tbm_bufmgr_debug_show(tbm_bufmgr bufmgr)
874 str = tbm_bufmgr_debug_tbm_info_get(bufmgr);
882 tbm_bufmgr_debug_trace(tbm_bufmgr bufmgr, int onoff)
884 _tbm_bufmgr_mutex_lock();
885 _tbm_set_last_result(TBM_ERROR_NONE);
887 TBM_BUFMGR_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
888 TBM_BUFMGR_RETURN_IF_FAIL(bufmgr == gBufMgr);
891 TBM_LOG_D("bufmgr=%p onoff=%d\n", bufmgr, onoff);
895 _tbm_bufmgr_mutex_unlock();
899 tbm_bufmgr_debug_set_trace_mask(tbm_bufmgr bufmgr, tbm_bufmgr_debug_trace_mask mask, int set)
901 _tbm_bufmgr_mutex_lock();
902 _tbm_set_last_result(TBM_ERROR_NONE);
904 TBM_BUFMGR_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
905 TBM_BUFMGR_RETURN_IF_FAIL(bufmgr == gBufMgr);
910 TBM_INFO("bufmgr=%p sets the trace_mask=%d\n", bufmgr, mask);
911 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_BO)
912 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_BO");
913 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL)
914 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL");
915 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE)
916 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE");
917 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE)
918 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE");
919 } else if (set == 0) {
922 TBM_INFO("bufmgr=%p unsets the trace_mask=%d\n", bufmgr, mask);
923 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_BO)
924 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_BO");
925 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL)
926 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL");
927 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE)
928 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE");
929 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE)
930 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE");
932 TBM_WRN("set value is wrong.(set=%d)", set);
935 _tbm_bufmgr_mutex_unlock();
939 tbm_bufmgr_debug_dump_set_scale(double scale)
941 pthread_mutex_lock(&gLock);
942 _tbm_set_last_result(TBM_ERROR_NONE);
943 scale_factor = scale;
944 pthread_mutex_unlock(&gLock);
948 tbm_bufmgr_debug_get_ref_count(void)
952 pthread_mutex_lock(&gLock);
954 _tbm_set_last_result(TBM_ERROR_NONE);
956 refcnt = (gBufMgr) ? gBufMgr->ref_count : 0;
958 pthread_mutex_unlock(&gLock);
964 tbm_bufmgr_debug_queue_dump(char *path, int count, int onoff)
966 pthread_mutex_lock(&gLock);
967 _tbm_set_last_result(TBM_ERROR_NONE);
970 TBM_DBG("count=%d onoff=%d\n", count, onoff);
972 tbm_surface_internal_dump_end();
977 TBM_ERR("path is null");
978 pthread_mutex_unlock(&gLock);
981 TBM_DBG("path=%s count=%d onoff=%d\n", path, count, onoff);
983 if (_tbm_util_get_max_surface_size(&w, &h) == 0) {
984 TBM_ERR("Fail to get tbm_surface size.\n");
985 pthread_mutex_unlock(&gLock);
989 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
995 pthread_mutex_unlock(&gLock);
1001 tbm_bufmgr_debug_dump_all(char *path)
1003 int w, h, count = 0;
1004 tbm_surface_h surface = NULL;
1006 pthread_mutex_lock(&gLock);
1007 _tbm_set_last_result(TBM_ERROR_NONE);
1009 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
1010 TBM_DBG("path=%s\n", path);
1012 count = _tbm_util_get_max_surface_size(&w, &h);
1014 TBM_ERR("No tbm_surface.\n");
1015 pthread_mutex_unlock(&gLock);
1019 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
1022 LIST_FOR_EACH_ENTRY(surface, &gBufMgr->surf_list, item_link)
1023 tbm_surface_internal_dump_buffer(surface, "dump_all");
1025 tbm_surface_internal_dump_end();
1027 pthread_mutex_unlock(&gLock);
1032 /* internal function */
1034 _tbm_bufmgr_get_bufmgr(void)
1040 tbm_bufmgr_bind_native_display(tbm_bufmgr bufmgr, void *native_display)
1045 _tbm_bufmgr_mutex_lock();
1046 _tbm_set_last_result(TBM_ERROR_NONE);
1048 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1050 if (bufmgr->backend_module_data) {
1051 if (!bufmgr->bufmgr_func->bufmgr_bind_native_display) {
1052 TBM_WRN("skip: tbm_bufmgr(%p) native_display(%p)\n",
1053 bufmgr, native_display);
1054 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
1055 _tbm_bufmgr_mutex_unlock();
1059 error = bufmgr->bufmgr_func->bufmgr_bind_native_display(bufmgr->bufmgr_data, (tbm_native_display *)native_display);
1060 if (error != TBM_ERROR_NONE) {
1061 TBM_ERR("error: tbm_bufmgr(%p) native_display(%p) error(%d)\n",
1062 bufmgr, native_display, error);
1063 _tbm_set_last_result(error);
1064 _tbm_bufmgr_mutex_unlock();
1069 if (!bufmgr->backend->bufmgr_bind_native_display) {
1070 TBM_WRN("skip: tbm_bufmgr(%p) native_display(%p)\n",
1071 bufmgr, native_display);
1072 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
1073 _tbm_bufmgr_mutex_unlock();
1077 ret = bufmgr->backend->bufmgr_bind_native_display(bufmgr, native_display);
1079 TBM_ERR("error: tbm_bufmgr(%p) native_display(%p)\n",
1080 bufmgr, native_display);
1081 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1082 _tbm_bufmgr_mutex_unlock();
1087 TBM_INFO("tbm_bufmgr(%p) native_display(%p)\n", bufmgr, native_display);
1089 _tbm_bufmgr_mutex_unlock();
1095 tbm_bufmgr_server_init(void)
1099 bufmgr = _tbm_bufmgr_init(-1, 1);
1105 tbm_bufmgr_set_bo_lock_type(tbm_bufmgr bufmgr, tbm_bufmgr_bo_lock_type bo_lock_type)
1107 _tbm_bufmgr_mutex_lock();
1108 _tbm_set_last_result(TBM_ERROR_NONE);
1110 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1111 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, 0);
1113 pthread_mutex_lock(&gLock);
1114 gBufMgr->bo_lock_type = bo_lock_type;
1115 pthread_mutex_unlock(&gLock);
1117 TBM_INFO("The bo_lock_type of the bo is %d\n", bo_lock_type);
1119 _tbm_bufmgr_mutex_unlock();
1125 int tbm_bufmgr_get_fd_limit(void)
1129 if (getrlimit(RLIMIT_NOFILE, &lim))
1132 return (int)lim.rlim_cur;
1135 tbm_bufmgr tbm_bufmgr_get(void)
1139 /* LCOV_EXCL_STOP */