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_bufmgr_mutex_unlock();\
84 #define TBM_BUFMGR_RETURN_VAL_IF_FAIL(cond, val) {\
86 TBM_ERR("'%s' failed.\n", #cond);\
87 _tbm_bufmgr_mutex_unlock();\
94 _tbm_bufmgr_mutex_init(void)
96 static bool tbm_bufmgr_mutex_init = false;
98 if (tbm_bufmgr_mutex_init)
101 if (pthread_mutex_init(&tbm_bufmgr_lock, NULL)) {
102 TBM_ERR("fail: Cannot pthread_mutex_init for tbm_bufmgr_lock.\n");
106 tbm_bufmgr_mutex_init = true;
112 _tbm_bufmgr_mutex_lock(void)
114 if (!_tbm_bufmgr_mutex_init()) {
115 TBM_ERR("fail: _tbm_bufmgr_mutex_init()\n");
119 pthread_mutex_lock(&tbm_bufmgr_lock);
123 _tbm_bufmgr_mutex_unlock(void)
125 pthread_mutex_unlock(&tbm_bufmgr_lock);
129 _tbm_util_get_max_surface_size(int *w, int *h)
131 tbm_surface_info_s info;
132 tbm_surface_h surface = NULL;
138 if (gBufMgr == NULL || LIST_IS_EMPTY(&gBufMgr->surf_list))
141 LIST_FOR_EACH_ENTRY(surface, &gBufMgr->surf_list, item_link) {
142 if (tbm_surface_get_info(surface, &info) == TBM_SURFACE_ERROR_NONE) {
146 if (*h < info.height)
155 _tbm_util_get_appname_brief(char *brief)
159 char temp[255] = {0,};
160 char *saveptr = NULL;
162 token = strtok_r(brief, delim, &saveptr);
164 while (token != NULL) {
165 memset(temp, 0x00, 255 * sizeof(char));
166 strncpy(temp, token, 254 * sizeof(char));
167 token = strtok_r(NULL, delim, &saveptr);
170 snprintf(brief, sizeof(temp), "%s", temp);
174 _tbm_util_get_appname_from_pid(long pid, char *str)
176 char fn_cmdline[255] = {0, }, cmdline[255];
180 snprintf(fn_cmdline, sizeof(fn_cmdline), "/proc/%ld/cmdline", pid);
182 fp = fopen(fn_cmdline, "r");
184 TBM_ERR("cannot file open %s\n", fn_cmdline);
188 if (!fgets(cmdline, 255, fp)) {
189 TBM_ERR("fail to get appname for pid(%ld)\n", pid);
196 len = strlen(cmdline);
198 memset(cmdline, 0x00, 255);
202 snprintf(str, sizeof(cmdline), "%s", cmdline);
206 _check_version(TBMModuleVersionInfo *data)
211 abimaj = GET_ABI_MAJOR(data->abiversion);
212 abimin = GET_ABI_MINOR(data->abiversion);
214 TBM_DBG("TBM module %s: vendor=\"%s\" ABI=%d,%d\n",
215 data->modname ? data->modname : "UNKNOWN!",
216 data->vendor ? data->vendor : "UNKNOWN!", abimaj, abimin);
218 vermaj = GET_ABI_MAJOR(TBM_ABI_VERSION);
219 vermin = GET_ABI_MINOR(TBM_ABI_VERSION);
221 TBM_DBG("TBM ABI version %d.%d\n",
224 if (abimaj != vermaj) {
225 TBM_ERR("TBM module ABI major ver(%d) doesn't match the TBM's ver(%d)\n",
228 } else if (abimin > vermin) {
229 TBM_ERR("TBM module ABI minor ver(%d) is newer than the TBM's ver(%d)\n",
238 _tbm_backend_check_bufmgr_func(tbm_backend_bufmgr_func *bufmgr_func)
240 TBM_RETURN_VAL_IF_FAIL(bufmgr_func, 0); /* mandatory symbol */
241 TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_get_capabilities, 0); /* mandatory symbol */
242 TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_bind_native_display, 0); /* mandatory symbol */
243 TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_get_supported_formats, 0); /* mandatory symbol */
244 TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_get_plane_data, 0); /* mandatory symbol */
245 TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_alloc_bo, 0); /* mandatory symbol */
246 if (!bufmgr_func->bufmgr_alloc_bo_with_format)
247 TBM_DBG("No bufmgr_func->bufmgr_alloc_bo_with_format.");
248 TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_import_fd, 0); /* mandatory symbol */
249 if (!bufmgr_func->bufmgr_import_key)
250 TBM_DBG("No bufmgr_func->bo_export_key.");
256 _tbm_backend_check_bufmgr_bo(tbm_backend_bo_func *bo_func)
258 TBM_RETURN_VAL_IF_FAIL(bo_func, 0); /* mandatory symbol */
259 TBM_RETURN_VAL_IF_FAIL(bo_func->bo_free, 0); /* mandatory symbol */
260 TBM_RETURN_VAL_IF_FAIL(bo_func->bo_get_size, 0); /* mandatory symbol */
261 TBM_RETURN_VAL_IF_FAIL(bo_func->bo_get_memory_types, 0); /* mandatory symbol */
262 TBM_RETURN_VAL_IF_FAIL(bo_func->bo_get_handle, 0); /* mandatory symbol */
263 TBM_RETURN_VAL_IF_FAIL(bo_func->bo_map, 0); /* mandatory symbol */
264 TBM_RETURN_VAL_IF_FAIL(bo_func->bo_unmap, 0); /* mandatory symbol */
265 if (!bo_func->bo_lock)
266 TBM_DBG("No bo_func->bo_lock.");
267 if (!bo_func->bo_unlock)
268 TBM_DBG("No bo_func->bo_unlock.");
269 TBM_RETURN_VAL_IF_FAIL(bo_func->bo_export_fd, 0); /* mandatory symbol */
270 if (!bo_func->bo_export_key)
271 TBM_INFO("No bo_func->bo_export_key.");
277 _tbm_backend_load_module(tbm_bufmgr bufmgr, const char *file)
279 char path[PATH_MAX] = {0, };
280 void *module_data = NULL;
281 tbm_backend_module *backend_module_data = NULL;
282 tbm_backend_bufmgr_data *bufmgr_data = NULL;
287 snprintf(path, sizeof(path), BUFMGR_MODULE_DIR "/%s", file);
289 module_data = dlopen(path, RTLD_LAZY);
291 TBM_ERR("failed to load module: %s(%s)\n", dlerror(), file);
295 backend_module_data = dlsym(module_data, "tbm_backend_module_data");
296 if (!backend_module_data) {
297 TBM_ERR("Error: module does not have data object.\n");
301 abimaj = GET_ABI_MAJOR(backend_module_data->abi_version);
302 abimin = GET_ABI_MINOR(backend_module_data->abi_version);
304 TBM_DBG("TBM module %s: vendor=\"%s\" ABI=%d,%d\n",
305 backend_module_data->name ? backend_module_data->name : "UNKNOWN!",
306 backend_module_data->vendor ? backend_module_data->vendor : "UNKNOWN!",
309 vermaj = GET_ABI_MAJOR(TBM_BACKEND_ABI_LATEST_VERSION);
310 vermin = GET_ABI_MINOR(TBM_BACKEND_ABI_LATEST_VERSION);
311 TBM_DBG("TBM ABI version %d.%d\n", vermaj, vermin);
313 if (abimaj > vermaj) {
314 TBM_ERR("TBM module ABI major ver(%d) is newer than the TBM's ver(%d)\n",
317 } else if (abimin > vermin) {
318 TBM_ERR("TBM module ABI minor ver(%d) is newer than the TBM's ver(%d)\n",
323 if (!backend_module_data->init) {
324 TBM_ERR("Error: module does not supply init symbol.\n");
328 if (!backend_module_data->deinit) {
329 TBM_ERR("Error: module does not supply deinit symbol.\n");
333 bufmgr_data = backend_module_data->init(bufmgr, &error);
335 TBM_ERR("Fail to init module(%s)\n", file);
339 /* check the mandatory symbols of the backend module */
340 if (!_tbm_backend_check_bufmgr_func(bufmgr->bufmgr_func)) {
341 TBM_ERR("Fail to check the bufmgr_func symboles.");
345 if (!_tbm_backend_check_bufmgr_bo(bufmgr->bo_func)) {
346 TBM_ERR("Fail to check the bufmgr_bo symboles.");
350 /* get the capability */
351 bufmgr->capabilities = bufmgr->bufmgr_func->bufmgr_get_capabilities(bufmgr_data, &error);
352 if (bufmgr->capabilities == TBM_BUFMGR_CAPABILITY_NONE) {
353 TBM_ERR("The capabilities of the backend module is TBM_BUFMGR_CAPABILITY_NONE.");
354 TBM_ERR("TBM_BUFMGR_CAPABILITY_SHARE_FD is the essential capability.");
358 if (!(bufmgr->capabilities & TBM_BUFMGR_CAPABILITY_SHARE_FD)) {
359 TBM_ERR("The capabilities of the backend module had no TBM_BUFMGR_CAPABILITY_SHARE_FD.");
360 TBM_ERR("The tbm backend has to get TBM_BUFMGR_CAPABILITY_SHARE_FD. ");
364 bufmgr->module_data = module_data;
365 bufmgr->backend_module_data = backend_module_data;
366 bufmgr->bufmgr_data = bufmgr_data;
368 TBM_DBG("Success to load module(%s)\n", file);
374 bufmgr->backend_module_data->deinit(bufmgr_data);
376 dlclose(module_data);
382 _tbm_bufmgr_load_module(tbm_bufmgr bufmgr, int fd, const char *file)
384 char path[PATH_MAX] = {0, };
385 TBMModuleVersionInfo *vers;
386 TBMModuleData *initdata;
390 snprintf(path, sizeof(path), BUFMGR_MODULE_DIR "/%s", file);
392 module_data = dlopen(path, RTLD_LAZY);
394 TBM_ERR("failed to load module: %s(%s)\n", dlerror(), file);
398 initdata = dlsym(module_data, "tbmModuleData");
400 TBM_ERR("Error: module does not have data object.\n");
404 vers = initdata->vers;
406 TBM_ERR("Error: module does not supply version information.\n");
410 init = initdata->init;
412 TBM_ERR("Error: module does not supply init symbol.\n");
416 if (!_check_version(vers)) {
417 TBM_ERR("Fail to check version.\n");
421 if (!init(bufmgr, fd)) {
422 TBM_ERR("Fail to init module(%s)\n", file);
426 if (!bufmgr->backend || !bufmgr->backend->priv) {
427 TBM_ERR("Error: module(%s) wrong operation. Check backend or backend's priv.\n", file);
431 bufmgr->module_data = module_data;
433 TBM_DBG("Success to load module(%s)\n", file);
438 dlclose(module_data);
443 _tbm_load_module(tbm_bufmgr bufmgr, int fd)
445 struct dirent **namelist;
448 /* try to load the new backend module */
449 ret = _tbm_backend_load_module(bufmgr, DEFAULT_LIB);
453 /* try to load the old(deprecated) backend mdoule */
454 ret = _tbm_bufmgr_load_module(bufmgr, fd, DEFAULT_LIB);
458 /* load bufmgr priv from configured path */
459 n = scandir(BUFMGR_MODULE_DIR, &namelist, 0, alphasort);
461 TBM_ERR("no files : %s\n", BUFMGR_MODULE_DIR);
466 if (!ret && strstr(namelist[n]->d_name, PREFIX_LIB)) {
467 const char *p = strstr(namelist[n]->d_name, SUFFIX_LIB);
469 if (p && !strcmp(p, SUFFIX_LIB)) {
470 ret = _tbm_backend_load_module(bufmgr, namelist[n]->d_name);
472 ret = _tbm_bufmgr_load_module(bufmgr, fd,
473 namelist[n]->d_name);
487 _tbm_bufmgr_init(int fd, int server)
489 #ifdef TBM_BUFMGR_INIT_TIME
490 struct timeval start_tv, end_tv;
494 #ifdef TBM_BUFMGR_INIT_TIME
495 /* get the start tv */
496 gettimeofday(&start_tv, NULL);
499 /* LCOV_EXCL_START */
501 env = getenv("TBM_DLOG");
504 TBM_DBG("TBM_DLOG=%s\n", env);
510 env = getenv("TBM_TRACE");
512 trace_mask = atoi(env);
513 TBM_DBG("TBM_TRACE=%s\n", env);
518 pthread_mutex_lock(&gLock);
521 TBM_WRN("!!!!!WARNING:: The tbm_bufmgr_init DOSE NOT use argument fd ANYMORE.\n");
522 TBM_WRN("!!!!!WARNING:: IT WILL BE CHANGED like tbm_bufmgr_init(int fd) --> tbm_bufmgr_init(void).\n");
526 /* initialize buffer manager */
528 gBufMgr->ref_count++;
529 TBM_INFO("reuse tbm_bufmgr(%p) ref_count(%d) fd(%d)\n", gBufMgr, gBufMgr->ref_count, gBufMgr->fd);
530 pthread_mutex_unlock(&gLock);
534 TBM_DBG("bufmgr init\n");
536 /* allocate bufmgr */
537 gBufMgr = calloc(1, sizeof(struct _tbm_bufmgr));
539 TBM_ERR("error: fail to alloc bufmgr fd(%d)\n", fd);
540 pthread_mutex_unlock(&gLock);
546 /* set the display_server flag before loading the backend module */
548 TBM_INFO("The tbm_bufmgr(%p) is used by display server. Need to bind the native_display.\n", gBufMgr);
549 gBufMgr->display_server = 1;
552 /* load bufmgr priv from env */
553 if (!_tbm_load_module(gBufMgr, gBufMgr->fd)) {
554 TBM_ERR("error : Fail to load bufmgr backend\n");
557 pthread_mutex_unlock(&gLock);
563 gBufMgr->ref_count = 1;
565 TBM_INFO("create tizen bufmgr:%p ref_count:%d\n",
566 gBufMgr, gBufMgr->ref_count);
568 /* setup the bo_lock_type */
569 env = getenv("BUFMGR_LOCK_TYPE");
570 if (env && !strcmp(env, "always"))
571 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS;
572 else if (env && !strcmp(env, "none"))
573 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_NEVER;
574 else if (env && !strcmp(env, "once"))
575 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ONCE;
577 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS;
579 TBM_DBG("BUFMGR_LOCK_TYPE=%s\n", env ? env : "default:once");
581 /* intialize bo_list */
582 LIST_INITHEAD(&gBufMgr->bo_list);
584 /* intialize surf_list */
585 LIST_INITHEAD(&gBufMgr->surf_list);
587 /* intialize surf_queue_list */
588 LIST_INITHEAD(&gBufMgr->surf_queue_list);
590 /* intialize debug_key_list */
591 LIST_INITHEAD(&gBufMgr->debug_key_list);
593 #ifdef TBM_BUFMGR_INIT_TIME
595 gettimeofday(&end_tv, NULL);
596 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)));
599 pthread_mutex_unlock(&gLock);
605 tbm_bufmgr_init(int fd)
609 bufmgr = _tbm_bufmgr_init(fd, 0);
615 tbm_bufmgr_deinit(tbm_bufmgr bufmgr)
617 TBM_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
619 _tbm_bufmgr_mutex_lock();
620 pthread_mutex_lock(&gLock);
623 TBM_ERR("gBufmgr already destroy: bufmgr:%p\n", bufmgr);
624 pthread_mutex_unlock(&gLock);
625 _tbm_bufmgr_mutex_unlock();
630 if (bufmgr->ref_count > 0) {
631 TBM_INFO("reduce a ref_count(%d) of tbm_bufmgr(%p)\n", bufmgr->ref_count, bufmgr);
632 pthread_mutex_unlock(&gLock);
633 _tbm_bufmgr_mutex_unlock();
637 /* destroy bo_list */
638 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
639 tbm_bo bo = NULL, tmp;
641 LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &bufmgr->bo_list, item_link) {
642 TBM_ERR("Un-freed bo(%p, ref:%d)\n", bo, bo->ref_cnt);
645 LIST_DELINIT(&bufmgr->bo_list);
648 /* destroy surf_list */
649 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
650 tbm_surface_h surf = NULL, tmp;
652 LIST_FOR_EACH_ENTRY_SAFE(surf, tmp, &bufmgr->surf_list, item_link) {
653 TBM_ERR("Un-freed surf(%p, ref:%d)\n", surf, surf->refcnt);
654 tbm_surface_destroy(surf);
656 LIST_DELINIT(&bufmgr->surf_list);
659 if (bufmgr->backend_module_data) {
660 /* deinit and backend destroys the backend func and data */
661 bufmgr->backend_module_data->deinit(bufmgr->bufmgr_data);
662 bufmgr->bo_func = NULL;
663 bufmgr->bufmgr_func = NULL;
664 bufmgr->bufmgr_data = NULL;
665 bufmgr->backend_module_data = NULL;
667 /* destroy bufmgr priv */
668 bufmgr->backend->bufmgr_deinit(bufmgr->backend->priv);
669 bufmgr->backend->priv = NULL;
670 tbm_backend_free(bufmgr->backend);
671 bufmgr->backend = NULL;
674 TBM_INFO("destroy tbm_bufmgr(%p)\n", bufmgr);
676 dlclose(bufmgr->module_data);
684 pthread_mutex_unlock(&gLock);
685 _tbm_bufmgr_mutex_unlock();
689 tbm_bufmgr_get_capability(tbm_bufmgr bufmgr)
691 unsigned int capabilities = TBM_BUFMGR_CAPABILITY_NONE;
693 _tbm_bufmgr_mutex_lock();
695 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), TBM_BUFMGR_CAPABILITY_NONE);
696 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, TBM_BUFMGR_CAPABILITY_NONE);
698 capabilities = bufmgr->capabilities;
700 _tbm_bufmgr_mutex_unlock();
705 /* LCOV_EXCL_START */
707 tbm_bufmgr_debug_tbm_info_get(tbm_bufmgr bufmgr)
709 char app_name[255] = {0,}, title[512] = {0,};
710 tbm_surface_debug_data *debug_old_data = NULL;
717 pthread_mutex_lock(&gLock);
719 if (!TBM_BUFMGR_IS_VALID(bufmgr) || (bufmgr != gBufMgr)) {
720 TBM_ERR("invalid bufmgr\n");
721 pthread_mutex_unlock(&gLock);
727 TBM_ERR("Fail to allocate the string.\n");
728 pthread_mutex_unlock(&gLock);
732 TBM_SNRPRINTF(str, len, c, "\n");
733 _tbm_util_get_appname_from_pid(getpid(), app_name);
734 _tbm_util_get_appname_brief(app_name);
735 TBM_SNRPRINTF(str, len, c, "============TBM DEBUG: %s(%d)===========================\n",
738 snprintf(title, 255, "%s", "no surface refcnt width height bpp size n_b n_p flags format app_name ");
740 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
741 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
742 strncat(title, " ", MAX_SIZE_N(title));
743 strncat(title, debug_old_data->key, MAX_SIZE_N(title));
747 TBM_SNRPRINTF(str, len, c, "[tbm_surface information]\n");
748 TBM_SNRPRINTF(str, len, c, "%s\n", title);
750 /* show the tbm_surface information in surf_list */
751 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
752 tbm_surface_h surf = NULL;
755 LIST_FOR_EACH_ENTRY(surf, &bufmgr->surf_list, item_link) {
756 char data[512] = {0,};
760 pid = _tbm_surface_internal_get_debug_pid(surf);
762 /* if pid is null, set the self_pid */
766 memset(app_name, 0x0, 255 * sizeof(char));
767 _tbm_util_get_appname_from_pid(pid, app_name);
768 _tbm_util_get_appname_brief(app_name);
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();
875 TBM_BUFMGR_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
876 TBM_BUFMGR_RETURN_IF_FAIL(bufmgr == gBufMgr);
879 TBM_LOG_D("bufmgr=%p onoff=%d\n", bufmgr, onoff);
883 _tbm_bufmgr_mutex_unlock();
887 tbm_bufmgr_debug_set_trace_mask(tbm_bufmgr bufmgr, tbm_bufmgr_debug_trace_mask mask, int set)
889 _tbm_bufmgr_mutex_lock();
891 TBM_BUFMGR_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
892 TBM_BUFMGR_RETURN_IF_FAIL(bufmgr == gBufMgr);
897 TBM_INFO("bufmgr=%p sets the trace_mask=%d\n", bufmgr, mask);
898 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_BO)
899 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_BO");
900 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL)
901 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL");
902 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE)
903 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE");
904 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE)
905 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE");
906 } else if (set == 0) {
909 TBM_INFO("bufmgr=%p unsets the trace_mask=%d\n", bufmgr, mask);
910 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_BO)
911 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_BO");
912 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL)
913 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL");
914 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE)
915 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE");
916 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE)
917 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE");
919 TBM_WRN("set value is wrong.(set=%d)", set);
922 _tbm_bufmgr_mutex_unlock();
926 tbm_bufmgr_debug_dump_set_scale(double scale)
928 pthread_mutex_lock(&gLock);
929 scale_factor = scale;
930 pthread_mutex_unlock(&gLock);
934 tbm_bufmgr_debug_get_ref_count(void)
936 return (gBufMgr) ? gBufMgr->ref_count : 0;
940 tbm_bufmgr_debug_queue_dump(char *path, int count, int onoff)
942 pthread_mutex_lock(&gLock);
945 TBM_DBG("count=%d onoff=%d\n", count, onoff);
947 tbm_surface_internal_dump_end();
952 TBM_ERR("path is null");
953 pthread_mutex_unlock(&gLock);
956 TBM_DBG("path=%s count=%d onoff=%d\n", path, count, onoff);
958 if (_tbm_util_get_max_surface_size(&w, &h) == 0) {
959 TBM_ERR("Fail to get tbm_surface size.\n");
960 pthread_mutex_unlock(&gLock);
964 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
970 pthread_mutex_unlock(&gLock);
975 tbm_bufmgr_debug_dump_all(char *path)
978 tbm_surface_h surface = NULL;
980 TBM_RETURN_VAL_IF_FAIL(path != NULL, 0);
981 TBM_DBG("path=%s\n", path);
983 pthread_mutex_lock(&gLock);
985 count = _tbm_util_get_max_surface_size(&w, &h);
987 TBM_ERR("No tbm_surface.\n");
988 pthread_mutex_unlock(&gLock);
992 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
995 LIST_FOR_EACH_ENTRY(surface, &gBufMgr->surf_list, item_link)
996 tbm_surface_internal_dump_buffer(surface, "dump_all");
998 tbm_surface_internal_dump_end();
1000 pthread_mutex_unlock(&gLock);
1005 /* internal function */
1007 _tbm_bufmgr_get_bufmgr(void)
1013 tbm_bufmgr_bind_native_display(tbm_bufmgr bufmgr, void *native_display)
1018 _tbm_bufmgr_mutex_lock();
1020 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1022 if (bufmgr->backend_module_data) {
1023 if (!bufmgr->bufmgr_func->bufmgr_bind_native_display) {
1024 TBM_WRN("skip: tbm_bufmgr(%p) native_display(%p)\n",
1025 bufmgr, native_display);
1026 _tbm_bufmgr_mutex_unlock();
1030 error = bufmgr->bufmgr_func->bufmgr_bind_native_display(bufmgr->bufmgr_data, (tbm_native_display *)native_display);
1031 if (error != TBM_ERROR_NONE) {
1032 TBM_ERR("error: tbm_bufmgr(%p) native_display(%p) error(%d)\n",
1033 bufmgr, native_display, error);
1034 _tbm_bufmgr_mutex_unlock();
1039 if (!bufmgr->backend->bufmgr_bind_native_display) {
1040 TBM_WRN("skip: tbm_bufmgr(%p) native_display(%p)\n",
1041 bufmgr, native_display);
1042 _tbm_bufmgr_mutex_unlock();
1046 ret = bufmgr->backend->bufmgr_bind_native_display(bufmgr, native_display);
1048 TBM_ERR("error: tbm_bufmgr(%p) native_display(%p)\n",
1049 bufmgr, native_display);
1050 _tbm_bufmgr_mutex_unlock();
1055 TBM_INFO("tbm_bufmgr(%p) native_display(%p)\n", bufmgr, native_display);
1057 _tbm_bufmgr_mutex_unlock();
1063 tbm_bufmgr_server_init(void)
1067 bufmgr = _tbm_bufmgr_init(-1, 1);
1073 tbm_bufmgr_set_bo_lock_type(tbm_bufmgr bufmgr, tbm_bufmgr_bo_lock_type bo_lock_type)
1075 _tbm_bufmgr_mutex_lock();
1077 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1078 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, 0);
1080 gBufMgr->bo_lock_type = bo_lock_type;
1082 TBM_INFO("The bo_lock_type of the bo is %d\n", bo_lock_type);
1084 _tbm_bufmgr_mutex_unlock();
1090 int tbm_bufmgr_get_fd_limit(void)
1094 if (getrlimit(RLIMIT_NOFILE, &lim))
1097 return (int)lim.rlim_cur;
1100 tbm_bufmgr tbm_bufmgr_get(void)
1104 /* LCOV_EXCL_STOP */