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 _tbm_backend_load_hal_tbm(tbm_bufmgr bufmgr)
190 hal_tbm_backend *hal_backend = NULL;
191 hal_tbm_bufmgr_capability capability;
192 hal_tbm_bufmgr *hal_bufmgr;
193 hal_tbm_error ret = HAL_TBM_ERROR_NONE;
195 hal_backend = hal_tbm_get_backend(&ret);
196 if (hal_backend == NULL || ret != HAL_TBM_ERROR_NONE) {
197 TBM_ERR("get backend fail");
201 hal_bufmgr = hal_tbm_backend_get_bufmgr(hal_backend, &ret);
202 if (hal_bufmgr == NULL || ret != HAL_TBM_ERROR_NONE) {
203 TBM_ERR("get hal_bufmgr fail");
204 goto get_backend_fail;
207 capability = hal_tbm_bufmgr_get_capabilities(hal_bufmgr, &ret);
208 if (ret != HAL_TBM_ERROR_NONE) {
209 TBM_ERR("hal_tbm_bufmgr_get_capabilities fail.");
210 goto get_backend_fail;
213 if (capability == HAL_TBM_BUFMGR_CAPABILITY_NONE) {
214 TBM_ERR("The capabilities of the backend module is TBM_BUFMGR_CAPABILITY_NONE.");
215 TBM_ERR("TBM_BUFMGR_CAPABILITY_SHARE_FD is the essential capability.");
216 goto get_backend_fail;
218 if (!(capability & HAL_TBM_BUFMGR_CAPABILITY_SHARE_FD)) {
219 TBM_ERR("The capabilities of the backend module had no TBM_BUFMGR_CAPABILITY_SHARE_FD.");
220 TBM_ERR("The tbm backend has to get TBM_BUFMGR_CAPABILITY_SHARE_FD. ");
221 goto get_backend_fail;
223 bufmgr->capabilities = capability;
225 bufmgr->hal_backend = hal_backend;
226 bufmgr->hal_bufmgr = hal_bufmgr;
228 bufmgr->use_hal_tbm = 1;
230 TBM_INFO("use hal tbm");
235 hal_tbm_put_backend(hal_backend);
240 _check_version(TBMModuleVersionInfo *data)
242 int backend_module_major, backend_module_minor;
243 int tbm_backend_major, tbm_backend_minor;
245 backend_module_major = GET_ABI_MAJOR(data->abiversion);
246 backend_module_minor = GET_ABI_MINOR(data->abiversion);
248 TBM_DBG("TBM module %s: vendor=\"%s\" ABI=%d,%d\n",
249 data->modname ? data->modname : "UNKNOWN!",
250 data->vendor ? data->vendor : "UNKNOWN!", backend_module_major, backend_module_minor);
252 tbm_backend_major = GET_ABI_MAJOR(TBM_ABI_VERSION);
253 tbm_backend_minor = GET_ABI_MINOR(TBM_ABI_VERSION);
255 TBM_DBG("TBM ABI version %d.%d\n",
256 tbm_backend_major, tbm_backend_minor);
258 if (backend_module_major != tbm_backend_major) {
259 TBM_ERR("TBM module ABI major ver(%d) doesn't match the TBM's ver(%d)\n",
260 backend_module_major, tbm_backend_major);
262 } else if (backend_module_minor > tbm_backend_minor) {
263 TBM_ERR("TBM module ABI minor ver(%d) is newer than the TBM's ver(%d)\n",
264 backend_module_minor, tbm_backend_minor);
272 _tbm_backend_check_bufmgr_func(tbm_backend_bufmgr_func *bufmgr_func)
274 TBM_RETURN_VAL_IF_FAIL(bufmgr_func, 0); /* mandatory symbol */
275 TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_get_capabilities, 0); /* mandatory symbol */
276 TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_bind_native_display, 0); /* mandatory symbol */
277 TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_get_supported_formats, 0); /* mandatory symbol */
278 TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_get_plane_data, 0); /* mandatory symbol */
279 TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_alloc_bo, 0); /* mandatory symbol */
280 if (!bufmgr_func->bufmgr_alloc_bo_with_format)
281 TBM_DBG("No bufmgr_func->bufmgr_alloc_bo_with_format.");
282 TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_import_fd, 0); /* mandatory symbol */
283 if (!bufmgr_func->bufmgr_import_key)
284 TBM_DBG("No bufmgr_func->bo_export_key.");
290 _tbm_backend_check_bufmgr_bo(tbm_backend_bo_func *bo_func)
292 TBM_RETURN_VAL_IF_FAIL(bo_func, 0); /* mandatory symbol */
293 TBM_RETURN_VAL_IF_FAIL(bo_func->bo_free, 0); /* mandatory symbol */
294 TBM_RETURN_VAL_IF_FAIL(bo_func->bo_get_size, 0); /* mandatory symbol */
295 TBM_RETURN_VAL_IF_FAIL(bo_func->bo_get_memory_types, 0); /* mandatory symbol */
296 TBM_RETURN_VAL_IF_FAIL(bo_func->bo_get_handle, 0); /* mandatory symbol */
297 TBM_RETURN_VAL_IF_FAIL(bo_func->bo_map, 0); /* mandatory symbol */
298 TBM_RETURN_VAL_IF_FAIL(bo_func->bo_unmap, 0); /* mandatory symbol */
299 if (!bo_func->bo_lock)
300 TBM_DBG("No bo_func->bo_lock.");
301 if (!bo_func->bo_unlock)
302 TBM_DBG("No bo_func->bo_unlock.");
303 TBM_RETURN_VAL_IF_FAIL(bo_func->bo_export_fd, 0); /* mandatory symbol */
304 if (!bo_func->bo_export_key)
305 TBM_INFO("No bo_func->bo_export_key.");
311 _tbm_backend_load_module(tbm_bufmgr bufmgr, const char *file)
313 char path[PATH_MAX] = {0, };
314 void *module_data = NULL;
315 tbm_backend_module *backend_module_data = NULL;
316 tbm_backend_bufmgr_data *bufmgr_data = NULL;
317 int backend_module_major, backend_module_minor;
318 int tbm_backend_major, tbm_backend_minor;
321 snprintf(path, sizeof(path), BUFMGR_MODULE_DIR "/%s", file);
323 module_data = dlopen(path, RTLD_LAZY);
325 TBM_ERR("failed to load module: %s(%s)\n", dlerror(), file);
329 backend_module_data = dlsym(module_data, "tbm_backend_module_data");
330 if (!backend_module_data) {
331 TBM_ERR("Error: module does not have data object.\n");
335 tbm_backend_major = GET_ABI_MAJOR(TBM_BACKEND_ABI_LATEST_VERSION);
336 tbm_backend_minor = GET_ABI_MINOR(TBM_BACKEND_ABI_LATEST_VERSION);
337 TBM_INFO("TBM Backend ABI version %d.%d\n", tbm_backend_major, tbm_backend_minor);
339 backend_module_major = GET_ABI_MAJOR(backend_module_data->abi_version);
340 backend_module_minor = GET_ABI_MINOR(backend_module_data->abi_version);
342 TBM_INFO("TBM module %s: vendor=\"%s\" Backend ABI version=%d.%d\n",
343 backend_module_data->name ? backend_module_data->name : "UNKNOWN!",
344 backend_module_data->vendor ? backend_module_data->vendor : "UNKNOWN!",
345 backend_module_major, backend_module_minor);
347 if (backend_module_major > tbm_backend_major) {
348 TBM_ERR("TBM module ABI major ver(%d) is newer than the TBM's ver(%d)\n",
349 backend_module_major, tbm_backend_major);
351 } else if (backend_module_minor > tbm_backend_minor) {
352 TBM_ERR("TBM module ABI minor ver(%d) is newer than the TBM's ver(%d)\n",
353 backend_module_minor, tbm_backend_minor);
357 if (!backend_module_data->init) {
358 TBM_ERR("Error: module does not supply init symbol.\n");
362 if (!backend_module_data->deinit) {
363 TBM_ERR("Error: module does not supply deinit symbol.\n");
367 bufmgr_data = backend_module_data->init(bufmgr, &error);
369 TBM_ERR("Fail to init module(%s)\n", file);
373 /* check the mandatory symbols of the backend module */
374 if (!_tbm_backend_check_bufmgr_func(bufmgr->bufmgr_func)) {
375 TBM_ERR("Fail to check the bufmgr_func symboles.");
379 if (!_tbm_backend_check_bufmgr_bo(bufmgr->bo_func)) {
380 TBM_ERR("Fail to check the bufmgr_bo symboles.");
384 /* get the capability */
385 bufmgr->capabilities = bufmgr->bufmgr_func->bufmgr_get_capabilities(bufmgr_data, &error);
386 if (bufmgr->capabilities == TBM_BUFMGR_CAPABILITY_NONE) {
387 TBM_ERR("The capabilities of the backend module is TBM_BUFMGR_CAPABILITY_NONE.");
388 TBM_ERR("TBM_BUFMGR_CAPABILITY_SHARE_FD is the essential capability.");
392 if (!(bufmgr->capabilities & TBM_BUFMGR_CAPABILITY_SHARE_FD)) {
393 TBM_ERR("The capabilities of the backend module had no TBM_BUFMGR_CAPABILITY_SHARE_FD.");
394 TBM_ERR("The tbm backend has to get TBM_BUFMGR_CAPABILITY_SHARE_FD. ");
398 bufmgr->module_data = module_data;
399 bufmgr->backend_module_data = backend_module_data;
400 bufmgr->bufmgr_data = bufmgr_data;
402 TBM_INFO("Success to load module(%s)\n", file);
408 bufmgr->backend_module_data->deinit(bufmgr_data);
410 dlclose(module_data);
416 _tbm_bufmgr_load_module(tbm_bufmgr bufmgr, int fd, const char *file)
418 char path[PATH_MAX] = {0, };
419 TBMModuleVersionInfo *vers;
420 TBMModuleData *initdata;
424 snprintf(path, sizeof(path), BUFMGR_MODULE_DIR "/%s", file);
426 module_data = dlopen(path, RTLD_LAZY);
428 TBM_ERR("failed to load module: %s(%s)\n", dlerror(), file);
432 initdata = dlsym(module_data, "tbmModuleData");
434 TBM_ERR("Error: module does not have data object.\n");
438 vers = initdata->vers;
440 TBM_ERR("Error: module does not supply version information.\n");
444 init = initdata->init;
446 TBM_ERR("Error: module does not supply init symbol.\n");
450 if (!_check_version(vers)) {
451 TBM_ERR("Fail to check version.\n");
455 if (!init(bufmgr, fd)) {
456 TBM_ERR("Fail to init module(%s)\n", file);
460 if (!bufmgr->backend || !bufmgr->backend->priv) {
461 TBM_ERR("Error: module(%s) wrong operation. Check backend or backend's priv.\n", file);
465 bufmgr->module_data = module_data;
467 TBM_DBG("Success to load module(%s)\n", file);
472 dlclose(module_data);
477 _tbm_load_module(tbm_bufmgr bufmgr, int fd)
479 struct dirent **namelist;
482 /* try to load the hal-tbm backend module */
483 ret = _tbm_backend_load_hal_tbm(bufmgr);
487 /* try to load the new backend module */
488 ret = _tbm_backend_load_module(bufmgr, DEFAULT_LIB);
492 /* try to load the old(deprecated) backend mdoule */
493 ret = _tbm_bufmgr_load_module(bufmgr, fd, DEFAULT_LIB);
497 /* load bufmgr priv from configured path */
498 n = scandir(BUFMGR_MODULE_DIR, &namelist, 0, alphasort);
500 TBM_ERR("no files : %s\n", BUFMGR_MODULE_DIR);
505 if (!ret && strstr(namelist[n]->d_name, PREFIX_LIB)) {
506 const char *p = strstr(namelist[n]->d_name, SUFFIX_LIB);
508 if (p && !strcmp(p, SUFFIX_LIB)) {
509 ret = _tbm_backend_load_module(bufmgr, namelist[n]->d_name);
511 ret = _tbm_bufmgr_load_module(bufmgr, fd,
512 namelist[n]->d_name);
526 _tbm_bufmgr_init(int fd, int server)
528 #ifdef TBM_BUFMGR_INIT_TIME
529 struct timeval start_tv, end_tv;
533 #ifdef TBM_BUFMGR_INIT_TIME
534 /* get the start tv */
535 gettimeofday(&start_tv, NULL);
540 /* LCOV_EXCL_START */
542 env = getenv("TBM_TRACE");
544 trace_mask = atoi(env);
545 TBM_DBG("TBM_TRACE=%s\n", env);
550 pthread_mutex_lock(&gLock);
552 _tbm_set_last_result(TBM_ERROR_NONE);
555 TBM_WRN("!!!!!WARNING:: The tbm_bufmgr_init DOSE NOT use argument fd ANYMORE.\n");
556 TBM_WRN("!!!!!WARNING:: IT WILL BE CHANGED like tbm_bufmgr_init(int fd) --> tbm_bufmgr_init(void).\n");
560 /* initialize buffer manager */
562 gBufMgr->ref_count++;
563 TBM_DBG("reuse tbm_bufmgr(%p) ref_count(%d) fd(%d)\n", gBufMgr, gBufMgr->ref_count, gBufMgr->fd);
564 pthread_mutex_unlock(&gLock);
568 TBM_DBG("bufmgr init\n");
570 /* allocate bufmgr */
571 gBufMgr = calloc(1, sizeof(struct _tbm_bufmgr));
573 TBM_ERR("error: fail to alloc bufmgr fd(%d)\n", fd);
574 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
575 pthread_mutex_unlock(&gLock);
581 /* set the display_server flag before loading the backend module */
583 TBM_INFO("The tbm_bufmgr(%p) is used by display server. Need to bind the native_display.\n", gBufMgr);
584 gBufMgr->display_server = 1;
587 /* load bufmgr priv from env */
588 if (!_tbm_load_module(gBufMgr, gBufMgr->fd)) {
589 TBM_ERR("error : Fail to load bufmgr backend\n");
590 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
593 pthread_mutex_unlock(&gLock);
599 gBufMgr->ref_count = 1;
601 TBM_INFO("create tizen bufmgr:%p ref_count:%d\n",
602 gBufMgr, gBufMgr->ref_count);
604 /* setup the bo_lock_type */
605 env = getenv("BUFMGR_LOCK_TYPE");
606 if (env && !strcmp(env, "always"))
607 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS;
608 else if (env && !strcmp(env, "none"))
609 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_NEVER;
610 else if (env && !strcmp(env, "once"))
611 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ONCE;
613 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS;
615 TBM_DBG("BUFMGR_LOCK_TYPE=%s\n", env ? env : "default:once");
617 /* intialize bo_list */
618 LIST_INITHEAD(&gBufMgr->bo_list);
620 /* intialize surf_list */
621 LIST_INITHEAD(&gBufMgr->surf_list);
623 /* intialize surf_queue_list */
624 LIST_INITHEAD(&gBufMgr->surf_queue_list);
626 /* intialize debug_key_list */
627 LIST_INITHEAD(&gBufMgr->debug_key_list);
629 #ifdef TBM_BUFMGR_INIT_TIME
631 gettimeofday(&end_tv, NULL);
632 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)));
635 pthread_mutex_unlock(&gLock);
641 tbm_bufmgr_init(int fd)
645 bufmgr = _tbm_bufmgr_init(fd, 0);
651 tbm_bufmgr_deinit(tbm_bufmgr bufmgr)
653 TBM_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
655 _tbm_bufmgr_mutex_lock();
656 pthread_mutex_lock(&gLock);
657 _tbm_set_last_result(TBM_ERROR_NONE);
660 TBM_ERR("gBufmgr already destroy: bufmgr:%p\n", bufmgr);
661 pthread_mutex_unlock(&gLock);
662 _tbm_bufmgr_mutex_unlock();
667 if (bufmgr->ref_count > 0) {
668 TBM_DBG("reduce a ref_count(%d) of tbm_bufmgr(%p)\n", bufmgr->ref_count, bufmgr);
669 pthread_mutex_unlock(&gLock);
670 _tbm_bufmgr_mutex_unlock();
674 /* destroy bo_list */
675 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
676 tbm_bo bo = NULL, tmp;
678 LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &bufmgr->bo_list, item_link) {
679 TBM_ERR("Un-freed bo(%p, ref:%d)\n", bo, bo->ref_cnt);
682 LIST_DELINIT(&bufmgr->bo_list);
685 /* destroy surf_list */
686 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
687 tbm_surface_h surf = NULL, tmp;
689 LIST_FOR_EACH_ENTRY_SAFE(surf, tmp, &bufmgr->surf_list, item_link) {
690 TBM_ERR("Un-freed surf(%p, ref:%d)\n", surf, surf->refcnt);
691 tbm_surface_destroy(surf);
693 LIST_DELINIT(&bufmgr->surf_list);
696 if (bufmgr->use_hal_tbm) {
697 hal_tbm_put_backend(bufmgr->hal_backend);
698 bufmgr->hal_backend = NULL;
699 bufmgr->hal_bufmgr = NULL;
700 bufmgr->use_hal_tbm = 0;
702 if (bufmgr->backend_module_data) {
703 /* deinit and backend destroys the backend func and data */
704 bufmgr->backend_module_data->deinit(bufmgr->bufmgr_data);
705 bufmgr->bo_func = NULL;
706 bufmgr->bufmgr_func = NULL;
707 bufmgr->bufmgr_data = NULL;
708 bufmgr->backend_module_data = NULL;
710 /* destroy bufmgr priv */
711 bufmgr->backend->bufmgr_deinit(bufmgr->backend->priv);
712 bufmgr->backend->priv = NULL;
713 tbm_backend_free(bufmgr->backend);
714 bufmgr->backend = NULL;
717 dlclose(bufmgr->module_data);
722 TBM_INFO("destroy tbm_bufmgr(%p)\n", bufmgr);
727 pthread_mutex_unlock(&gLock);
728 _tbm_bufmgr_mutex_unlock();
732 tbm_bufmgr_get_capability(tbm_bufmgr bufmgr)
734 unsigned int capabilities = TBM_BUFMGR_CAPABILITY_NONE;
736 _tbm_bufmgr_mutex_lock();
737 _tbm_set_last_result(TBM_ERROR_NONE);
739 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), TBM_BUFMGR_CAPABILITY_NONE);
740 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, TBM_BUFMGR_CAPABILITY_NONE);
742 capabilities = bufmgr->capabilities;
744 _tbm_bufmgr_mutex_unlock();
749 /* LCOV_EXCL_START */
751 tbm_bufmgr_debug_tbm_info_get(tbm_bufmgr bufmgr)
753 char app_name[255] = {0,}, title[512] = {0,};
754 tbm_surface_debug_data *debug_old_data = NULL;
762 pthread_mutex_lock(&gLock);
763 _tbm_set_last_result(TBM_ERROR_NONE);
765 if (!TBM_BUFMGR_IS_VALID(bufmgr) || (bufmgr != gBufMgr)) {
766 TBM_ERR("invalid bufmgr\n");
767 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
768 pthread_mutex_unlock(&gLock);
774 TBM_ERR("Fail to allocate the string.\n");
775 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
776 pthread_mutex_unlock(&gLock);
780 TBM_SNRPRINTF(str, len, c, "\n");
781 pid = syscall(SYS_getpid);
782 _tbm_util_get_appname_from_pid(pid, app_name);
783 _tbm_util_get_appname_brief(app_name);
784 TBM_SNRPRINTF(str, len, c, "===========================================TBM DEBUG: %s(%ld)===========================================\n",
787 snprintf(title, 255, "%s", "no surface refcnt width height bpp size n_b n_p flags format app_name ");
789 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
790 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
791 strncat(title, " ", MAX_SIZE_N(title));
792 strncat(title, debug_old_data->key, MAX_SIZE_N(title));
796 TBM_SNRPRINTF(str, len, c, "[tbm_surface information]\n");
797 TBM_SNRPRINTF(str, len, c, "%s\n", title);
799 /* show the tbm_surface information in surf_list */
800 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
801 tbm_surface_h surf = NULL;
804 LIST_FOR_EACH_ENTRY(surf, &bufmgr->surf_list, item_link) {
805 char data[512] = {0,};
806 unsigned int surf_pid = 0;
809 surf_pid = _tbm_surface_internal_get_debug_pid(surf);
811 /* if pid is null, set the self_pid */
812 surf_pid = syscall(SYS_getpid);;
815 memset(app_name, 0x0, 255 * sizeof(char));
816 if (geteuid() == 0) {
817 _tbm_util_get_appname_from_pid(surf_pid, app_name);
818 _tbm_util_get_appname_brief(app_name);
820 snprintf(app_name, sizeof(app_name), "%d", surf_pid);
823 snprintf(data, 255, "%-3d %-11p %-5d %-6u %-7u %-4u %-7u %-3d %-3d %-8d %-9s %-22s",
830 surf->info.size / 1024,
834 _tbm_surface_internal_format_to_str(surf->info.format) + 11,
837 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
838 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
841 strncat(data, " ", MAX_SIZE_N(title));
843 value = _tbm_surface_internal_get_debug_data(surf, debug_old_data->key);
845 strncat(data, value, MAX_SIZE_N(title));
847 strncat(data, "none", MAX_SIZE_N(title));
850 TBM_SNRPRINTF(str, len, c, "%s\n", data);
852 for (i = 0; i < surf->num_bos; i++) {
853 if (bufmgr->use_hal_tbm) {
854 size = hal_tbm_bo_get_size((hal_tbm_bo *)surf->bos[i]->bo_data, (hal_tbm_error *)&error);
855 if (error != TBM_ERROR_NONE)
856 TBM_WRN("fail to get the size of bo.");
857 } else if (bufmgr->backend_module_data) {
858 size = bufmgr->bo_func->bo_get_size(surf->bos[i]->bo_data, &error);
859 if (error != TBM_ERROR_NONE)
860 TBM_WRN("fail to get the size of bo.");
862 size = bufmgr->backend->bo_size(surf->bos[i]);
863 TBM_SNRPRINTF(str, len, c, " bo:%-12p %-26d%-10d\n",
865 surf->bos[i]->ref_cnt,
870 TBM_SNRPRINTF(str, len, c, " no tbm_surfaces.\n");
871 TBM_SNRPRINTF(str, len, c, "\n");
873 TBM_SNRPRINTF(str, len, c, "[tbm_bo information]\n");
874 TBM_SNRPRINTF(str, len, c, "no bo refcnt size lock_cnt map_cnt flags surface name\n");
876 /* show the tbm_bo information in bo_list */
877 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
882 LIST_FOR_EACH_ENTRY(bo, &bufmgr->bo_list, item_link) {
883 if (bo->bufmgr->use_hal_tbm) {
884 size = hal_tbm_bo_get_size((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
885 if (error != TBM_ERROR_NONE)
886 TBM_WRN("fail to get the size of bo.");
887 key = (tbm_key)hal_tbm_bo_export_key((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
888 } else if (bufmgr->backend_module_data) {
889 size = bufmgr->bo_func->bo_get_size(bo->bo_data, &error);
890 if (error != TBM_ERROR_NONE)
891 TBM_WRN("fail to get the size of bo.");
892 key = bufmgr->bo_func->bo_export_key(bo->bo_data, &error);
893 if (error != TBM_ERROR_NONE)
894 TBM_WRN("fail to get the tdm_key of bo.");
896 size = bufmgr->backend->bo_size(bo);
897 key = bufmgr->backend->bo_export(bo);
899 TBM_SNRPRINTF(str, len, c, "%-3d %-11p %-5d %-7d %-6d %-5u %-7d %-11p %-4d\n",
911 TBM_SNRPRINTF(str, len, c, "no tbm_bos.\n");
912 TBM_SNRPRINTF(str, len, c, "\n");
914 TBM_SNRPRINTF(str, len, c, "========================================================================================================\n");
916 pthread_mutex_unlock(&gLock);
922 tbm_bufmgr_debug_show(tbm_bufmgr bufmgr)
925 str = tbm_bufmgr_debug_tbm_info_get(bufmgr);
933 tbm_bufmgr_debug_trace(tbm_bufmgr bufmgr, int onoff)
935 _tbm_bufmgr_mutex_lock();
936 _tbm_set_last_result(TBM_ERROR_NONE);
938 TBM_BUFMGR_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
939 TBM_BUFMGR_RETURN_IF_FAIL(bufmgr == gBufMgr);
942 TBM_LOG_D("bufmgr=%p onoff=%d\n", bufmgr, onoff);
946 _tbm_bufmgr_mutex_unlock();
950 tbm_bufmgr_debug_set_trace_mask(tbm_bufmgr bufmgr, tbm_bufmgr_debug_trace_mask mask, int set)
952 _tbm_bufmgr_mutex_lock();
953 _tbm_set_last_result(TBM_ERROR_NONE);
955 TBM_BUFMGR_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
956 TBM_BUFMGR_RETURN_IF_FAIL(bufmgr == gBufMgr);
961 TBM_INFO("bufmgr=%p sets the trace_mask=%d\n", bufmgr, mask);
962 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_BO)
963 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_BO");
964 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL)
965 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL");
966 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE)
967 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE");
968 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE)
969 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE");
970 } else if (set == 0) {
973 TBM_INFO("bufmgr=%p unsets the trace_mask=%d\n", bufmgr, mask);
974 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_BO)
975 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_BO");
976 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL)
977 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL");
978 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE)
979 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE");
980 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE)
981 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE");
983 TBM_WRN("set value is wrong.(set=%d)", set);
986 _tbm_bufmgr_mutex_unlock();
990 tbm_bufmgr_debug_dump_set_scale(double scale)
992 pthread_mutex_lock(&gLock);
993 _tbm_set_last_result(TBM_ERROR_NONE);
994 scale_factor = scale;
995 pthread_mutex_unlock(&gLock);
999 tbm_bufmgr_debug_get_ref_count(void)
1003 pthread_mutex_lock(&gLock);
1005 _tbm_set_last_result(TBM_ERROR_NONE);
1007 refcnt = (gBufMgr) ? gBufMgr->ref_count : 0;
1009 pthread_mutex_unlock(&gLock);
1015 tbm_bufmgr_debug_queue_dump(char *path, int count, int onoff)
1017 pthread_mutex_lock(&gLock);
1018 _tbm_set_last_result(TBM_ERROR_NONE);
1021 TBM_DBG("count=%d onoff=%d\n", count, onoff);
1023 tbm_surface_internal_dump_end();
1028 TBM_ERR("path is null");
1029 pthread_mutex_unlock(&gLock);
1032 TBM_DBG("path=%s count=%d onoff=%d\n", path, count, onoff);
1034 if (_tbm_util_get_max_surface_size(&w, &h) == 0) {
1035 TBM_ERR("Fail to get tbm_surface size.\n");
1036 pthread_mutex_unlock(&gLock);
1040 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
1046 pthread_mutex_unlock(&gLock);
1052 tbm_bufmgr_debug_dump_all(char *path)
1054 int w, h, count = 0;
1055 tbm_surface_h surface = NULL;
1057 pthread_mutex_lock(&gLock);
1058 _tbm_set_last_result(TBM_ERROR_NONE);
1061 TBM_ERR("path is null.\n");
1062 pthread_mutex_unlock(&gLock);
1066 TBM_DBG("path=%s\n", path);
1068 count = _tbm_util_get_max_surface_size(&w, &h);
1070 TBM_ERR("No tbm_surface.\n");
1071 pthread_mutex_unlock(&gLock);
1075 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
1078 LIST_FOR_EACH_ENTRY(surface, &gBufMgr->surf_list, item_link)
1079 tbm_surface_internal_dump_buffer(surface, "dump_all");
1081 tbm_surface_internal_dump_end();
1083 pthread_mutex_unlock(&gLock);
1088 /* internal function */
1090 _tbm_bufmgr_get_bufmgr(void)
1096 tbm_bufmgr_bind_native_display(tbm_bufmgr bufmgr, void *native_display)
1101 _tbm_bufmgr_mutex_lock();
1102 _tbm_set_last_result(TBM_ERROR_NONE);
1104 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1106 if (bufmgr->use_hal_tbm) {
1107 error = (tbm_error_e)hal_tbm_bufmgr_bind_native_display(bufmgr->hal_bufmgr, (hal_tbm_native_display *)native_display);
1108 if (error == TBM_ERROR_NOT_SUPPORTED) {
1109 TBM_WRN("skip: tbm_bufmgr(%p) native_display(%p)\n", bufmgr, native_display);
1110 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
1111 _tbm_bufmgr_mutex_unlock();
1113 } else if (error != TBM_ERROR_NONE) {
1114 TBM_ERR("error: tbm_bufmgr(%p) native_display(%p)\n", bufmgr, native_display);
1115 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1116 _tbm_bufmgr_mutex_unlock();
1119 } else if (bufmgr->backend_module_data) {
1120 if (!bufmgr->bufmgr_func->bufmgr_bind_native_display) {
1121 TBM_WRN("skip: tbm_bufmgr(%p) native_display(%p)\n",
1122 bufmgr, native_display);
1123 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
1124 _tbm_bufmgr_mutex_unlock();
1128 error = bufmgr->bufmgr_func->bufmgr_bind_native_display(bufmgr->bufmgr_data, (tbm_native_display *)native_display);
1129 if (error != TBM_ERROR_NONE) {
1130 TBM_ERR("error: tbm_bufmgr(%p) native_display(%p) error(%d)\n",
1131 bufmgr, native_display, error);
1132 _tbm_set_last_result(error);
1133 _tbm_bufmgr_mutex_unlock();
1138 if (!bufmgr->backend->bufmgr_bind_native_display) {
1139 TBM_WRN("skip: tbm_bufmgr(%p) native_display(%p)\n",
1140 bufmgr, native_display);
1141 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
1142 _tbm_bufmgr_mutex_unlock();
1146 ret = bufmgr->backend->bufmgr_bind_native_display(bufmgr, native_display);
1148 TBM_ERR("error: tbm_bufmgr(%p) native_display(%p)\n",
1149 bufmgr, native_display);
1150 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
1151 _tbm_bufmgr_mutex_unlock();
1156 TBM_INFO("tbm_bufmgr(%p) native_display(%p)\n", bufmgr, native_display);
1158 _tbm_bufmgr_mutex_unlock();
1164 tbm_bufmgr_server_init(void)
1168 bufmgr = _tbm_bufmgr_init(-1, 1);
1174 tbm_bufmgr_set_bo_lock_type(tbm_bufmgr bufmgr, tbm_bufmgr_bo_lock_type bo_lock_type)
1176 _tbm_bufmgr_mutex_lock();
1177 _tbm_set_last_result(TBM_ERROR_NONE);
1179 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
1180 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, 0);
1182 pthread_mutex_lock(&gLock);
1183 gBufMgr->bo_lock_type = bo_lock_type;
1184 pthread_mutex_unlock(&gLock);
1186 TBM_INFO("The bo_lock_type of the bo is %d\n", bo_lock_type);
1188 _tbm_bufmgr_mutex_unlock();
1194 int tbm_bufmgr_get_fd_limit(void)
1198 if (getrlimit(RLIMIT_NOFILE, &lim))
1201 return (int)lim.rlim_cur;
1204 tbm_bufmgr tbm_bufmgr_get(void)
1208 /* LCOV_EXCL_STOP */