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);
484 /* LCOV_EXCL_START */
486 env = getenv("TBM_TRACE");
488 trace_mask = atoi(env);
489 TBM_DBG("TBM_TRACE=%s\n", env);
494 pthread_mutex_lock(&gLock);
496 _tbm_set_last_result(TBM_ERROR_NONE);
499 TBM_WRN("!!!!!WARNING:: The tbm_bufmgr_init DOSE NOT use argument fd ANYMORE.\n");
500 TBM_WRN("!!!!!WARNING:: IT WILL BE CHANGED like tbm_bufmgr_init(int fd) --> tbm_bufmgr_init(void).\n");
504 /* initialize buffer manager */
506 gBufMgr->ref_count++;
507 TBM_DBG("reuse tbm_bufmgr(%p) ref_count(%d) fd(%d)\n", gBufMgr, gBufMgr->ref_count, gBufMgr->fd);
508 pthread_mutex_unlock(&gLock);
512 TBM_DBG("bufmgr init\n");
514 /* allocate bufmgr */
515 gBufMgr = calloc(1, sizeof(struct _tbm_bufmgr));
517 TBM_ERR("error: fail to alloc bufmgr fd(%d)\n", fd);
518 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
519 pthread_mutex_unlock(&gLock);
525 /* set the display_server flag before loading the backend module */
527 TBM_INFO("The tbm_bufmgr(%p) is used by display server. Need to bind the native_display.\n", gBufMgr);
528 gBufMgr->display_server = 1;
531 /* load bufmgr priv from env */
532 TBM_STDOUT_INFO("loading backend module");
533 if (!_tbm_load_module(gBufMgr, gBufMgr->fd)) {
534 TBM_ERR("error : Fail to load bufmgr backend\n");
535 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
538 pthread_mutex_unlock(&gLock);
542 TBM_STDOUT_INFO("loading backend module done");
545 gBufMgr->ref_count = 1;
547 TBM_INFO("create tizen bufmgr:%p ref_count:%d\n",
548 gBufMgr, gBufMgr->ref_count);
550 /* setup the bo_lock_type */
551 env = getenv("BUFMGR_LOCK_TYPE");
552 if (env && !strcmp(env, "always"))
553 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS;
554 else if (env && !strcmp(env, "none"))
555 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_NEVER;
556 else if (env && !strcmp(env, "once"))
557 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ONCE;
559 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS;
561 TBM_DBG("BUFMGR_LOCK_TYPE=%s\n", env ? env : "default:once");
563 /* intialize bo_list */
564 LIST_INITHEAD(&gBufMgr->bo_list);
566 /* intialize surf_list */
567 LIST_INITHEAD(&gBufMgr->surf_list);
569 /* intialize surf_queue_list */
570 LIST_INITHEAD(&gBufMgr->surf_queue_list);
572 /* intialize debug_key_list */
573 LIST_INITHEAD(&gBufMgr->debug_key_list);
575 #ifdef TBM_BUFMGR_INIT_TIME
577 gettimeofday(&end_tv, NULL);
578 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)));
581 pthread_mutex_unlock(&gLock);
587 tbm_bufmgr_init(int fd)
591 bufmgr = _tbm_bufmgr_init(fd, 0);
597 tbm_bufmgr_deinit(tbm_bufmgr bufmgr)
599 TBM_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
601 _tbm_bufmgr_mutex_lock();
602 pthread_mutex_lock(&gLock);
603 _tbm_set_last_result(TBM_ERROR_NONE);
606 TBM_ERR("gBufmgr already destroy: bufmgr:%p\n", bufmgr);
607 pthread_mutex_unlock(&gLock);
608 _tbm_bufmgr_mutex_unlock();
613 if (bufmgr->ref_count > 0) {
614 TBM_DBG("reduce a ref_count(%d) of tbm_bufmgr(%p)\n", bufmgr->ref_count, bufmgr);
615 pthread_mutex_unlock(&gLock);
616 _tbm_bufmgr_mutex_unlock();
620 /* destroy bo_list */
621 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
622 tbm_bo bo = NULL, tmp;
624 LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &bufmgr->bo_list, item_link) {
625 TBM_ERR("Un-freed bo(%p, ref:%d)\n", bo, bo->ref_cnt);
628 LIST_DELINIT(&bufmgr->bo_list);
631 /* destroy surf_list */
632 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
633 tbm_surface_h surf = NULL, tmp;
635 LIST_FOR_EACH_ENTRY_SAFE(surf, tmp, &bufmgr->surf_list, item_link) {
636 TBM_ERR("Un-freed surf(%p, ref:%d)\n", surf, surf->refcnt);
637 tbm_surface_destroy(surf);
639 LIST_DELINIT(&bufmgr->surf_list);
642 if (bufmgr->backend_module_data) {
643 /* deinit and backend destroys the backend func and data */
644 bufmgr->backend_module_data->deinit(bufmgr->bufmgr_data);
645 bufmgr->bo_func = NULL;
646 bufmgr->bufmgr_func = NULL;
647 bufmgr->bufmgr_data = NULL;
648 bufmgr->backend_module_data = NULL;
650 /* destroy bufmgr priv */
651 bufmgr->backend->bufmgr_deinit(bufmgr->backend->priv);
652 bufmgr->backend->priv = NULL;
653 tbm_backend_free(bufmgr->backend);
654 bufmgr->backend = NULL;
657 TBM_INFO("destroy tbm_bufmgr(%p)\n", bufmgr);
659 dlclose(bufmgr->module_data);
667 pthread_mutex_unlock(&gLock);
668 _tbm_bufmgr_mutex_unlock();
672 tbm_bufmgr_get_capability(tbm_bufmgr bufmgr)
674 unsigned int capabilities = TBM_BUFMGR_CAPABILITY_NONE;
676 _tbm_bufmgr_mutex_lock();
677 _tbm_set_last_result(TBM_ERROR_NONE);
679 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), TBM_BUFMGR_CAPABILITY_NONE);
680 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, TBM_BUFMGR_CAPABILITY_NONE);
682 capabilities = bufmgr->capabilities;
684 _tbm_bufmgr_mutex_unlock();
689 /* LCOV_EXCL_START */
691 tbm_bufmgr_debug_tbm_info_get(tbm_bufmgr bufmgr)
693 char app_name[255] = {0,}, title[512] = {0,};
694 tbm_surface_debug_data *debug_old_data = NULL;
702 pthread_mutex_lock(&gLock);
703 _tbm_set_last_result(TBM_ERROR_NONE);
705 if (!TBM_BUFMGR_IS_VALID(bufmgr) || (bufmgr != gBufMgr)) {
706 TBM_ERR("invalid bufmgr\n");
707 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
708 pthread_mutex_unlock(&gLock);
714 TBM_ERR("Fail to allocate the string.\n");
715 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
716 pthread_mutex_unlock(&gLock);
720 TBM_SNRPRINTF(str, len, c, "\n");
721 pid = syscall(SYS_getpid);
722 _tbm_util_get_appname_from_pid(pid, app_name);
723 _tbm_util_get_appname_brief(app_name);
724 TBM_SNRPRINTF(str, len, c, "===========================================TBM DEBUG: %s(%ld)===========================================\n",
727 snprintf(title, 255, "%s", "no surface refcnt width height bpp size n_b n_p flags format app_name ");
729 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
730 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
731 strncat(title, " ", MAX_SIZE_N(title));
732 strncat(title, debug_old_data->key, MAX_SIZE_N(title));
736 TBM_SNRPRINTF(str, len, c, "[tbm_surface information]\n");
737 TBM_SNRPRINTF(str, len, c, "%s\n", title);
739 /* show the tbm_surface information in surf_list */
740 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
741 tbm_surface_h surf = NULL;
744 LIST_FOR_EACH_ENTRY(surf, &bufmgr->surf_list, item_link) {
745 char data[512] = {0,};
746 unsigned int surf_pid = 0;
749 surf_pid = _tbm_surface_internal_get_debug_pid(surf);
751 /* if pid is null, set the self_pid */
752 surf_pid = syscall(SYS_getpid);;
755 memset(app_name, 0x0, 255 * sizeof(char));
756 if (geteuid() == 0) {
757 _tbm_util_get_appname_from_pid(surf_pid, app_name);
758 _tbm_util_get_appname_brief(app_name);
760 snprintf(app_name, sizeof(app_name), "%d", surf_pid);
763 snprintf(data, 255, "%-3d %-11p %-5d %-6u %-7u %-4u %-7u %-3d %-3d %-8d %-9s %-22s",
770 surf->info.size / 1024,
774 _tbm_surface_internal_format_to_str(surf->info.format) + 11,
777 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
778 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
781 strncat(data, " ", MAX_SIZE_N(title));
783 value = _tbm_surface_internal_get_debug_data(surf, debug_old_data->key);
785 strncat(data, value, MAX_SIZE_N(title));
787 strncat(data, "none", MAX_SIZE_N(title));
790 TBM_SNRPRINTF(str, len, c, "%s\n", data);
792 for (i = 0; i < surf->num_bos; i++) {
793 if (bufmgr->backend_module_data) {
794 size = bufmgr->bo_func->bo_get_size(surf->bos[i]->bo_data, &error);
795 if (error != TBM_ERROR_NONE)
796 TBM_WRN("fail to get the size of bo.");
798 size = bufmgr->backend->bo_size(surf->bos[i]);
799 TBM_SNRPRINTF(str, len, c, " bo:%-12p %-26d%-10d\n",
801 surf->bos[i]->ref_cnt,
806 TBM_SNRPRINTF(str, len, c, " no tbm_surfaces.\n");
807 TBM_SNRPRINTF(str, len, c, "\n");
809 TBM_SNRPRINTF(str, len, c, "[tbm_bo information]\n");
810 TBM_SNRPRINTF(str, len, c, "no bo refcnt size lock_cnt map_cnt flags surface name\n");
812 /* show the tbm_bo information in bo_list */
813 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
818 LIST_FOR_EACH_ENTRY(bo, &bufmgr->bo_list, item_link) {
819 if (bufmgr->backend_module_data) {
820 size = bufmgr->bo_func->bo_get_size(bo->bo_data, &error);
821 if (error != TBM_ERROR_NONE)
822 TBM_WRN("fail to get the size of bo.");
823 key = bufmgr->bo_func->bo_export_key(bo->bo_data, &error);
824 if (error != TBM_ERROR_NONE)
825 TBM_WRN("fail to get the tdm_key of bo.");
827 size = bufmgr->backend->bo_size(bo);
828 key = bufmgr->backend->bo_export(bo);
830 TBM_SNRPRINTF(str, len, c, "%-3d %-11p %-5d %-7d %-6d %-5u %-7d %-11p %-4d\n",
842 TBM_SNRPRINTF(str, len, c, "no tbm_bos.\n");
843 TBM_SNRPRINTF(str, len, c, "\n");
845 TBM_SNRPRINTF(str, len, c, "========================================================================================================\n");
847 pthread_mutex_unlock(&gLock);
853 tbm_bufmgr_debug_show(tbm_bufmgr bufmgr)
856 str = tbm_bufmgr_debug_tbm_info_get(bufmgr);
864 tbm_bufmgr_debug_trace(tbm_bufmgr bufmgr, int onoff)
866 _tbm_bufmgr_mutex_lock();
867 _tbm_set_last_result(TBM_ERROR_NONE);
869 TBM_BUFMGR_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
870 TBM_BUFMGR_RETURN_IF_FAIL(bufmgr == gBufMgr);
873 TBM_LOG_D("bufmgr=%p onoff=%d\n", bufmgr, onoff);
877 _tbm_bufmgr_mutex_unlock();
881 tbm_bufmgr_debug_set_trace_mask(tbm_bufmgr bufmgr, tbm_bufmgr_debug_trace_mask mask, int set)
883 _tbm_bufmgr_mutex_lock();
884 _tbm_set_last_result(TBM_ERROR_NONE);
886 TBM_BUFMGR_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
887 TBM_BUFMGR_RETURN_IF_FAIL(bufmgr == gBufMgr);
892 TBM_INFO("bufmgr=%p sets the trace_mask=%d\n", bufmgr, mask);
893 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_BO)
894 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_BO");
895 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL)
896 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL");
897 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE)
898 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE");
899 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE)
900 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE");
901 } else if (set == 0) {
904 TBM_INFO("bufmgr=%p unsets the trace_mask=%d\n", bufmgr, mask);
905 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_BO)
906 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_BO");
907 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL)
908 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL");
909 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE)
910 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE");
911 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE)
912 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE");
914 TBM_WRN("set value is wrong.(set=%d)", set);
917 _tbm_bufmgr_mutex_unlock();
921 tbm_bufmgr_debug_dump_set_scale(double scale)
923 pthread_mutex_lock(&gLock);
924 _tbm_set_last_result(TBM_ERROR_NONE);
925 scale_factor = scale;
926 pthread_mutex_unlock(&gLock);
930 tbm_bufmgr_debug_get_ref_count(void)
934 pthread_mutex_lock(&gLock);
936 _tbm_set_last_result(TBM_ERROR_NONE);
938 refcnt = (gBufMgr) ? gBufMgr->ref_count : 0;
940 pthread_mutex_unlock(&gLock);
946 tbm_bufmgr_debug_queue_dump(char *path, int count, int onoff)
948 pthread_mutex_lock(&gLock);
949 _tbm_set_last_result(TBM_ERROR_NONE);
952 TBM_DBG("count=%d onoff=%d\n", count, onoff);
954 tbm_surface_internal_dump_end();
959 TBM_ERR("path is null");
960 pthread_mutex_unlock(&gLock);
963 TBM_DBG("path=%s count=%d onoff=%d\n", path, count, onoff);
965 if (_tbm_util_get_max_surface_size(&w, &h) == 0) {
966 TBM_ERR("Fail to get tbm_surface size.\n");
967 pthread_mutex_unlock(&gLock);
971 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
977 pthread_mutex_unlock(&gLock);
983 tbm_bufmgr_debug_dump_all(char *path)
986 tbm_surface_h surface = NULL;
988 pthread_mutex_lock(&gLock);
989 _tbm_set_last_result(TBM_ERROR_NONE);
992 TBM_ERR("path is null.\n");
993 pthread_mutex_unlock(&gLock);
997 TBM_DBG("path=%s\n", path);
999 count = _tbm_util_get_max_surface_size(&w, &h);
1001 TBM_ERR("No tbm_surface.\n");
1002 pthread_mutex_unlock(&gLock);
1006 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
1009 LIST_FOR_EACH_ENTRY(surface, &gBufMgr->surf_list, item_link)
1010 tbm_surface_internal_dump_buffer(surface, "dump_all");
1012 tbm_surface_internal_dump_end();
1014 pthread_mutex_unlock(&gLock);
1019 /* internal function */
1021 _tbm_bufmgr_get_bufmgr(void)
1027 tbm_bufmgr_bind_native_display(tbm_bufmgr bufmgr, void *native_display)
1032 _tbm_bufmgr_mutex_lock();
1033 _tbm_set_last_result(TBM_ERROR_NONE);
1035 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1037 if (bufmgr->backend_module_data) {
1038 if (!bufmgr->bufmgr_func->bufmgr_bind_native_display) {
1039 TBM_WRN("skip: tbm_bufmgr(%p) native_display(%p)\n",
1040 bufmgr, native_display);
1041 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
1042 _tbm_bufmgr_mutex_unlock();
1046 error = bufmgr->bufmgr_func->bufmgr_bind_native_display(bufmgr->bufmgr_data, (tbm_native_display *)native_display);
1047 if (error != TBM_ERROR_NONE) {
1048 TBM_ERR("error: tbm_bufmgr(%p) native_display(%p) error(%d)\n",
1049 bufmgr, native_display, error);
1050 _tbm_set_last_result(error);
1051 _tbm_bufmgr_mutex_unlock();
1056 if (!bufmgr->backend->bufmgr_bind_native_display) {
1057 TBM_WRN("skip: tbm_bufmgr(%p) native_display(%p)\n",
1058 bufmgr, native_display);
1059 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
1060 _tbm_bufmgr_mutex_unlock();
1064 ret = bufmgr->backend->bufmgr_bind_native_display(bufmgr, native_display);
1066 TBM_ERR("error: tbm_bufmgr(%p) native_display(%p)\n",
1067 bufmgr, native_display);
1068 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1069 _tbm_bufmgr_mutex_unlock();
1074 TBM_INFO("tbm_bufmgr(%p) native_display(%p)\n", bufmgr, native_display);
1076 _tbm_bufmgr_mutex_unlock();
1082 tbm_bufmgr_server_init(void)
1086 bufmgr = _tbm_bufmgr_init(-1, 1);
1092 tbm_bufmgr_set_bo_lock_type(tbm_bufmgr bufmgr, tbm_bufmgr_bo_lock_type bo_lock_type)
1094 _tbm_bufmgr_mutex_lock();
1095 _tbm_set_last_result(TBM_ERROR_NONE);
1097 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1098 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, 0);
1100 pthread_mutex_lock(&gLock);
1101 gBufMgr->bo_lock_type = bo_lock_type;
1102 pthread_mutex_unlock(&gLock);
1104 TBM_INFO("The bo_lock_type of the bo is %d\n", bo_lock_type);
1106 _tbm_bufmgr_mutex_unlock();
1112 int tbm_bufmgr_get_fd_limit(void)
1116 if (getrlimit(RLIMIT_NOFILE, &lim))
1119 return (int)lim.rlim_cur;
1122 tbm_bufmgr tbm_bufmgr_get(void)
1126 /* LCOV_EXCL_STOP */