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_drm_helper.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 MAX_SIZE_N(dest) (sizeof(dest) - strlen(dest) - 1)
60 #define TBM_BUFMGR_RETURN_IF_FAIL(cond) {\
62 TBM_ERR("'%s' failed.\n", #cond);\
63 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
64 _tbm_bufmgr_mutex_unlock();\
69 #define TBM_BUFMGR_RETURN_VAL_IF_FAIL(cond, val) {\
71 TBM_ERR("'%s' failed.\n", #cond);\
72 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
73 _tbm_bufmgr_mutex_unlock();\
81 _tbm_bufmgr_check_bo_cnt(tbm_bufmgr bufmgr)
83 static int last_chk_bo_cnt = 0;
85 if ((bufmgr->bo_cnt >= 500) && ((bufmgr->bo_cnt % 20) == 0) &&
86 (bufmgr->bo_cnt > last_chk_bo_cnt)) {
87 TBM_DBG("============TBM BO CNT DEBUG: bo_cnt=%d\n", bufmgr->bo_cnt);
88 tbm_bufmgr_debug_show(bufmgr);
89 last_chk_bo_cnt = bufmgr->bo_cnt;
94 _tbm_bufmgr_initialize_bo(tbm_bufmgr bufmgr, tbm_bo bo, int flags)
98 bo->magic = TBM_BO_MAGIC;
101 LIST_INITHEAD(&bo->user_data_list);
104 LIST_ADD(&bo->item_link, &bufmgr->bo_list);
108 _tbm_bufmgr_mutex_lock(void)
110 pthread_mutex_lock(&tbm_bufmgr_lock);
114 _tbm_bufmgr_mutex_unlock(void)
116 pthread_mutex_unlock(&tbm_bufmgr_lock);
120 _tbm_util_get_max_surface_size(int *w, int *h)
122 tbm_surface_info_s info;
123 tbm_surface_h surface = NULL;
129 if (gBufMgr == NULL || LIST_IS_EMPTY(&gBufMgr->surf_list))
132 LIST_FOR_EACH_ENTRY(surface, &gBufMgr->surf_list, item_link) {
133 if (tbm_surface_get_info(surface, &info) == TBM_SURFACE_ERROR_NONE) {
137 if (*h < info.height)
146 _tbm_util_get_appname_brief(char *brief)
150 char temp[255] = {0,};
151 char *saveptr = NULL;
153 token = strtok_r(brief, delim, &saveptr);
155 while (token != NULL) {
156 memset(temp, 0x00, 255 * sizeof(char));
157 strncpy(temp, token, 254 * sizeof(char));
158 token = strtok_r(NULL, delim, &saveptr);
161 snprintf(brief, sizeof(temp), "%s", temp);
165 _tbm_util_get_appname_from_pid(long pid, char *str)
167 char fn_cmdline[255] = {0, }, cmdline[255];
171 if (pid <= 0) return;
173 snprintf(fn_cmdline, sizeof(fn_cmdline), "/proc/%ld/cmdline", pid);
175 fp = fopen(fn_cmdline, "r");
177 TBM_ERR("cannot file open %s\n", fn_cmdline);
181 if (!fgets(cmdline, 255, fp)) {
182 TBM_ERR("fail to get appname for pid(%ld)\n", pid);
189 len = strlen(cmdline);
191 memset(cmdline, 0x00, 255);
195 snprintf(str, sizeof(cmdline), "%s", cmdline);
199 _tbm_bufmgr_copy_module_data(tbm_bufmgr bufmgr, tbm_module *module, int reset)
202 bufmgr->module_data = module->module_data;
203 bufmgr->backend = module->backend;
205 bufmgr->backend_module_data = module->backend_module_data;
206 bufmgr->bufmgr_data = module->bufmgr_data;
207 bufmgr->bufmgr_func = module->bufmgr_func;
208 bufmgr->bo_func = module->bo_func;
210 bufmgr->use_hal_tbm = module->use_hal_tbm;
211 bufmgr->auth_wl_socket_created = module->auth_wl_socket_created;
212 bufmgr->auth_fd = module->auth_fd;
213 bufmgr->hal_backend = module->hal_backend;
214 bufmgr->hal_bufmgr = module->hal_bufmgr;
216 bufmgr->module_data = NULL;
217 bufmgr->backend = NULL;
219 bufmgr->backend_module_data = NULL;
220 bufmgr->bufmgr_data = NULL;
221 bufmgr->bufmgr_func = NULL;
222 bufmgr->bo_func = NULL;
224 bufmgr->use_hal_tbm = 0;
225 bufmgr->auth_wl_socket_created = 0;
226 bufmgr->auth_fd = -1;
227 bufmgr->hal_backend = NULL;
228 bufmgr->hal_bufmgr = NULL;
236 _tbm_bufmgr_init(int fd, int server)
238 tbm_error_e error = TBM_ERROR_NONE;
240 #ifdef TBM_BUFMGR_INIT_TIME
241 struct timeval start_tv, end_tv;
245 #ifdef TBM_BUFMGR_INIT_TIME
246 /* get the start tv */
247 gettimeofday(&start_tv, NULL);
252 /* LCOV_EXCL_START */
254 env = getenv("TBM_TRACE");
256 trace_mask = atoi(env);
257 TBM_DBG("TBM_TRACE=%s\n", env);
262 pthread_mutex_lock(&gLock);
264 _tbm_set_last_result(TBM_ERROR_NONE);
267 TBM_WRN("!!!!!WARNING:: The tbm_bufmgr_init DOSE NOT use argument fd ANYMORE.\n");
268 TBM_WRN("!!!!!WARNING:: IT WILL BE CHANGED like tbm_bufmgr_init(int fd) --> tbm_bufmgr_init(void).\n");
272 /* initialize buffer manager */
274 gBufMgr->ref_count++;
275 TBM_DBG("reuse tbm_bufmgr(%p) ref_count(%d) fd(%d)\n", gBufMgr, gBufMgr->ref_count, gBufMgr->fd);
276 pthread_mutex_unlock(&gLock);
280 TBM_DBG("bufmgr init\n");
282 /* allocate bufmgr */
283 gBufMgr = calloc(1, sizeof(struct _tbm_bufmgr));
285 TBM_ERR("error: fail to alloc bufmgr fd(%d)\n", fd);
286 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
287 pthread_mutex_unlock(&gLock);
293 /* set the display_server flag before loading the backend module */
295 TBM_INFO("The tbm_bufmgr(%p) is used by display server. Need to bind the native_display.\n", gBufMgr);
296 gBufMgr->display_server = 1;
299 /* load bufmgr priv from env */
300 gBufMgr->module = tbm_module_load(gBufMgr->fd);
301 if (!gBufMgr->module) {
302 TBM_ERR("error : Fail to load bufmgr backend\n");
303 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
306 pthread_mutex_unlock(&gLock);
311 // TODO: this is temporary. it will be removed after finishing refactoring the tbm_module.
312 _tbm_bufmgr_copy_module_data(gBufMgr, gBufMgr->module, 0);
314 /* check the essential capabilities of tbm_module */
315 gBufMgr->capabilities = tbm_module_bufmgr_get_capabilities(gBufMgr->module, &error);
316 if (gBufMgr->capabilities == TBM_BUFMGR_CAPABILITY_NONE) {
317 TBM_ERR("The capabilities of the backend module is TBM_BUFMGR_CAPABILITY_NONE.");
318 TBM_ERR("TBM_BUFMGR_CAPABILITY_SHARE_FD is the essential capability.");
319 tbm_module_unload(gBufMgr->module);
320 _tbm_set_last_result(error);
323 pthread_mutex_unlock(&gLock);
327 if (!(gBufMgr->capabilities & TBM_BUFMGR_CAPABILITY_SHARE_FD)) {
328 TBM_ERR("The capabilities of the backend module had no TBM_BUFMGR_CAPABILITY_SHARE_FD.");
329 TBM_ERR("The tbm backend has to get TBM_BUFMGR_CAPABILITY_SHARE_FD. ");
330 tbm_module_unload(gBufMgr->module);
331 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
334 pthread_mutex_unlock(&gLock);
340 gBufMgr->ref_count = 1;
342 TBM_INFO("create tizen bufmgr:%p ref_count:%d\n",
343 gBufMgr, gBufMgr->ref_count);
345 /* setup the bo_lock_type */
346 env = getenv("BUFMGR_LOCK_TYPE");
347 if (env && !strcmp(env, "always"))
348 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS;
349 else if (env && !strcmp(env, "none"))
350 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_NEVER;
351 else if (env && !strcmp(env, "once"))
352 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ONCE;
354 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS;
356 TBM_DBG("BUFMGR_LOCK_TYPE=%s\n", env ? env : "default:once");
358 /* intialize bo_list */
359 LIST_INITHEAD(&gBufMgr->bo_list);
361 /* intialize surf_list */
362 LIST_INITHEAD(&gBufMgr->surf_list);
364 /* intialize surf_queue_list */
365 LIST_INITHEAD(&gBufMgr->surf_queue_list);
367 /* intialize debug_key_list */
368 LIST_INITHEAD(&gBufMgr->debug_key_list);
370 #ifdef TBM_BUFMGR_INIT_TIME
372 gettimeofday(&end_tv, NULL);
373 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)));
376 pthread_mutex_unlock(&gLock);
382 tbm_bufmgr_init(int fd)
386 bufmgr = _tbm_bufmgr_init(fd, 0);
392 tbm_bufmgr_deinit(tbm_bufmgr bufmgr)
394 TBM_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
396 _tbm_bufmgr_mutex_lock();
397 pthread_mutex_lock(&gLock);
398 _tbm_set_last_result(TBM_ERROR_NONE);
401 TBM_ERR("gBufmgr already destroy: bufmgr:%p\n", bufmgr);
402 pthread_mutex_unlock(&gLock);
403 _tbm_bufmgr_mutex_unlock();
408 if (bufmgr->ref_count > 0) {
409 TBM_DBG("reduce a ref_count(%d) of tbm_bufmgr(%p)\n", bufmgr->ref_count, bufmgr);
410 pthread_mutex_unlock(&gLock);
411 _tbm_bufmgr_mutex_unlock();
415 /* destroy bo_list */
416 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
417 tbm_bo bo = NULL, tmp;
419 LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &bufmgr->bo_list, item_link) {
420 TBM_ERR("Un-freed bo(%p, ref:%d)\n", bo, bo->ref_cnt);
423 LIST_DELINIT(&bufmgr->bo_list);
426 /* destroy surf_list */
427 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
428 tbm_surface_h surf = NULL, tmp;
430 LIST_FOR_EACH_ENTRY_SAFE(surf, tmp, &bufmgr->surf_list, item_link) {
431 TBM_ERR("Un-freed surf(%p, ref:%d)\n", surf, surf->refcnt);
432 tbm_surface_destroy(surf);
434 LIST_DELINIT(&bufmgr->surf_list);
437 tbm_module_unload(bufmgr->module);
439 // TODO: this is temporary. it will be removed after finishing refactoring the tbm_module.
440 _tbm_bufmgr_copy_module_data(bufmgr, bufmgr->module, 1);
445 TBM_INFO("destroy tbm_bufmgr(%p)\n", bufmgr);
450 pthread_mutex_unlock(&gLock);
451 _tbm_bufmgr_mutex_unlock();
455 tbm_bufmgr_get_capability(tbm_bufmgr bufmgr)
457 unsigned int capabilities = TBM_BUFMGR_CAPABILITY_NONE;
459 _tbm_bufmgr_mutex_lock();
460 _tbm_set_last_result(TBM_ERROR_NONE);
462 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), TBM_BUFMGR_CAPABILITY_NONE);
463 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, TBM_BUFMGR_CAPABILITY_NONE);
465 capabilities = bufmgr->capabilities;
467 _tbm_bufmgr_mutex_unlock();
472 /* LCOV_EXCL_START */
474 tbm_bufmgr_debug_tbm_info_get(tbm_bufmgr bufmgr)
476 char app_name[255] = {0,}, title[512] = {0,};
477 tbm_surface_debug_data *debug_old_data = NULL;
485 pthread_mutex_lock(&gLock);
486 _tbm_set_last_result(TBM_ERROR_NONE);
488 if (!TBM_BUFMGR_IS_VALID(bufmgr) || (bufmgr != gBufMgr)) {
489 TBM_ERR("invalid bufmgr\n");
490 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
491 pthread_mutex_unlock(&gLock);
497 TBM_ERR("Fail to allocate the string.\n");
498 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
499 pthread_mutex_unlock(&gLock);
503 TBM_SNRPRINTF(str, len, c, "\n");
504 pid = syscall(SYS_getpid);
505 _tbm_util_get_appname_from_pid(pid, app_name);
506 _tbm_util_get_appname_brief(app_name);
507 TBM_SNRPRINTF(str, len, c, "===========================================TBM DEBUG: %s(%ld)===========================================\n",
510 snprintf(title, 255, "%s", "no surface refcnt width height bpp size n_b n_p flags format app_name ");
512 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
513 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
514 strncat(title, " ", MAX_SIZE_N(title));
515 strncat(title, debug_old_data->key, MAX_SIZE_N(title));
519 TBM_SNRPRINTF(str, len, c, "[tbm_surface information]\n");
520 TBM_SNRPRINTF(str, len, c, "%s\n", title);
522 /* show the tbm_surface information in surf_list */
523 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
524 tbm_surface_h surf = NULL;
527 LIST_FOR_EACH_ENTRY(surf, &bufmgr->surf_list, item_link) {
528 char data[512] = {0,};
529 unsigned int surf_pid = 0;
532 surf_pid = _tbm_surface_internal_get_debug_pid(surf);
534 /* if pid is null, set the self_pid */
535 surf_pid = syscall(SYS_getpid);;
538 memset(app_name, 0x0, 255 * sizeof(char));
539 if (geteuid() == 0) {
540 _tbm_util_get_appname_from_pid(surf_pid, app_name);
541 _tbm_util_get_appname_brief(app_name);
543 snprintf(app_name, sizeof(app_name), "%d", surf_pid);
546 snprintf(data, 255, "%-3d %-11p %-5d %-6u %-7u %-4u %-7u %-3d %-3d %-8d %-9s %-22s",
553 surf->info.size / 1024,
557 _tbm_surface_internal_format_to_str(surf->info.format) + 11,
560 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
561 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
564 strncat(data, " ", MAX_SIZE_N(title));
566 value = _tbm_surface_internal_get_debug_data(surf, debug_old_data->key);
568 strncat(data, value, MAX_SIZE_N(title));
570 strncat(data, "none", MAX_SIZE_N(title));
573 TBM_SNRPRINTF(str, len, c, "%s\n", data);
575 for (i = 0; i < surf->num_bos; i++) {
576 if (bufmgr->use_hal_tbm) {
577 size = hal_tbm_bo_get_size((hal_tbm_bo *)surf->bos[i]->bo_data, (hal_tbm_error *)&error);
578 if (error != TBM_ERROR_NONE)
579 TBM_WRN("fail to get the size of bo.");
580 } else if (bufmgr->backend_module_data) {
581 size = bufmgr->bo_func->bo_get_size(surf->bos[i]->bo_data, &error);
582 if (error != TBM_ERROR_NONE)
583 TBM_WRN("fail to get the size of bo.");
585 size = bufmgr->backend->bo_size(surf->bos[i]);
586 TBM_SNRPRINTF(str, len, c, " bo:%-12p %-26d%-10d\n",
588 surf->bos[i]->ref_cnt,
593 TBM_SNRPRINTF(str, len, c, " no tbm_surfaces.\n");
594 TBM_SNRPRINTF(str, len, c, "\n");
596 TBM_SNRPRINTF(str, len, c, "[tbm_bo information]\n");
597 TBM_SNRPRINTF(str, len, c, "no bo refcnt size lock_cnt map_cnt flags surface name\n");
599 /* show the tbm_bo information in bo_list */
600 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
605 LIST_FOR_EACH_ENTRY(bo, &bufmgr->bo_list, item_link) {
606 if (bo->bufmgr->use_hal_tbm) {
607 size = hal_tbm_bo_get_size((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
608 if (error != TBM_ERROR_NONE)
609 TBM_WRN("fail to get the size of bo.");
610 key = (tbm_key)hal_tbm_bo_export_key((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
611 } else if (bufmgr->backend_module_data) {
612 size = bufmgr->bo_func->bo_get_size(bo->bo_data, &error);
613 if (error != TBM_ERROR_NONE)
614 TBM_WRN("fail to get the size of bo.");
615 key = bufmgr->bo_func->bo_export_key(bo->bo_data, &error);
616 if (error != TBM_ERROR_NONE)
617 TBM_WRN("fail to get the tdm_key of bo.");
619 size = bufmgr->backend->bo_size(bo);
620 key = bufmgr->backend->bo_export(bo);
622 TBM_SNRPRINTF(str, len, c, "%-3d %-11p %-5d %-7d %-6d %-5u %-7d %-11p %-4d\n",
634 TBM_SNRPRINTF(str, len, c, "no tbm_bos.\n");
635 TBM_SNRPRINTF(str, len, c, "\n");
637 TBM_SNRPRINTF(str, len, c, "========================================================================================================\n");
639 pthread_mutex_unlock(&gLock);
645 tbm_bufmgr_debug_show(tbm_bufmgr bufmgr)
648 str = tbm_bufmgr_debug_tbm_info_get(bufmgr);
656 tbm_bufmgr_debug_trace(tbm_bufmgr bufmgr, int onoff)
658 _tbm_bufmgr_mutex_lock();
659 _tbm_set_last_result(TBM_ERROR_NONE);
661 TBM_BUFMGR_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
662 TBM_BUFMGR_RETURN_IF_FAIL(bufmgr == gBufMgr);
665 TBM_LOG_D("bufmgr=%p onoff=%d\n", bufmgr, onoff);
669 _tbm_bufmgr_mutex_unlock();
673 tbm_bufmgr_debug_set_trace_mask(tbm_bufmgr bufmgr, tbm_bufmgr_debug_trace_mask mask, int set)
675 _tbm_bufmgr_mutex_lock();
676 _tbm_set_last_result(TBM_ERROR_NONE);
678 TBM_BUFMGR_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
679 TBM_BUFMGR_RETURN_IF_FAIL(bufmgr == gBufMgr);
684 TBM_INFO("bufmgr=%p sets the trace_mask=%d\n", bufmgr, mask);
685 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_BO)
686 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_BO");
687 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL)
688 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL");
689 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE)
690 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE");
691 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE)
692 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE");
693 } else if (set == 0) {
696 TBM_INFO("bufmgr=%p unsets the trace_mask=%d\n", bufmgr, mask);
697 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_BO)
698 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_BO");
699 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL)
700 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL");
701 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE)
702 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE");
703 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE)
704 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE");
706 TBM_WRN("set value is wrong.(set=%d)", set);
709 _tbm_bufmgr_mutex_unlock();
713 tbm_bufmgr_debug_dump_set_scale(double scale)
715 pthread_mutex_lock(&gLock);
716 _tbm_set_last_result(TBM_ERROR_NONE);
717 scale_factor = scale;
718 pthread_mutex_unlock(&gLock);
722 tbm_bufmgr_debug_get_ref_count(void)
726 pthread_mutex_lock(&gLock);
728 _tbm_set_last_result(TBM_ERROR_NONE);
730 refcnt = (gBufMgr) ? gBufMgr->ref_count : 0;
732 pthread_mutex_unlock(&gLock);
738 tbm_bufmgr_debug_queue_dump(char *path, int count, int onoff)
740 pthread_mutex_lock(&gLock);
741 _tbm_set_last_result(TBM_ERROR_NONE);
744 TBM_DBG("count=%d onoff=%d\n", count, onoff);
746 tbm_surface_internal_dump_end();
751 TBM_ERR("path is null");
752 pthread_mutex_unlock(&gLock);
755 TBM_DBG("path=%s count=%d onoff=%d\n", path, count, onoff);
757 if (_tbm_util_get_max_surface_size(&w, &h) == 0) {
758 TBM_ERR("Fail to get tbm_surface size.\n");
759 pthread_mutex_unlock(&gLock);
763 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
769 pthread_mutex_unlock(&gLock);
775 tbm_bufmgr_debug_dump_all(char *path)
778 tbm_surface_h surface = NULL;
780 pthread_mutex_lock(&gLock);
781 _tbm_set_last_result(TBM_ERROR_NONE);
784 TBM_ERR("path is null.\n");
785 pthread_mutex_unlock(&gLock);
789 TBM_DBG("path=%s\n", path);
791 count = _tbm_util_get_max_surface_size(&w, &h);
793 TBM_ERR("No tbm_surface.\n");
794 pthread_mutex_unlock(&gLock);
798 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
801 LIST_FOR_EACH_ENTRY(surface, &gBufMgr->surf_list, item_link)
802 tbm_surface_internal_dump_buffer(surface, "dump_all");
804 tbm_surface_internal_dump_end();
806 pthread_mutex_unlock(&gLock);
811 /* internal function */
813 _tbm_bufmgr_get_bufmgr(void)
819 tbm_bufmgr_bind_native_display(tbm_bufmgr bufmgr, void *native_display)
823 _tbm_bufmgr_mutex_lock();
824 _tbm_set_last_result(TBM_ERROR_NONE);
826 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), 0);
828 error = tbm_module_bufmgr_bind_native_display(bufmgr->module, native_display);
829 if (error != TBM_ERROR_NONE) {
830 _tbm_set_last_result(error);
831 _tbm_bufmgr_mutex_unlock();
833 if (error == TBM_ERROR_NOT_SUPPORTED) {
834 TBM_WRN("Not supported, so skip: tbm_bufmgr(%p) native_display(%p)", bufmgr, native_display);
841 TBM_INFO("tbm_bufmgr(%p) native_display(%p)\n", bufmgr, native_display);
843 _tbm_bufmgr_mutex_unlock();
849 tbm_bufmgr_server_init(void)
853 bufmgr = _tbm_bufmgr_init(-1, 1);
859 tbm_bufmgr_set_bo_lock_type(tbm_bufmgr bufmgr, tbm_bufmgr_bo_lock_type bo_lock_type)
861 _tbm_bufmgr_mutex_lock();
862 _tbm_set_last_result(TBM_ERROR_NONE);
864 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
865 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, 0);
867 pthread_mutex_lock(&gLock);
868 gBufMgr->bo_lock_type = bo_lock_type;
869 pthread_mutex_unlock(&gLock);
871 TBM_INFO("The bo_lock_type of the bo is %d\n", bo_lock_type);
873 _tbm_bufmgr_mutex_unlock();
879 int tbm_bufmgr_get_fd_limit(void)
883 if (getrlimit(RLIMIT_NOFILE, &lim))
886 return (int)lim.rlim_cur;
889 tbm_bufmgr tbm_bufmgr_get(void)
896 tbm_bufmgr_internal_find_bo(tbm_bufmgr bufmgr, tbm_bo bo)
900 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), NULL);
901 TBM_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, NULL);
903 if (LIST_IS_EMPTY(&bufmgr->bo_list))
906 LIST_FOR_EACH_ENTRY(bo2, &bufmgr->bo_list, item_link) {
907 if (bo2->bo_data == bo->bo_data) {
916 tbm_bufmgr_internal_alloc_bo(tbm_bufmgr bufmgr, int size, int flags, tbm_error_e *error)
919 tbm_backend_bo_data *bo_data;
921 _tbm_bufmgr_check_bo_cnt(bufmgr);
923 bo = calloc(1, sizeof(struct _tbm_bo));
925 /* LCOV_EXCL_START */
926 TBM_ERR("memory allocationc failed.");
927 *error = TBM_ERROR_OUT_OF_MEMORY;
932 bo_data = tbm_module_bufmgr_bo_alloc(bufmgr->module, bo, size, flags, error);
934 /* LCOV_EXCL_START */
935 TBM_ERR("tbm_module_bufmgr_bo_alloc failed. size:%d flags:%s error:%d", size, _tbm_flag_to_str(flags), *error);
940 bo->bo_data = bo_data;
941 bo->priv = (void *)bo_data; // TODO: this will be DEPRECATED.
943 _tbm_bufmgr_initialize_bo(bufmgr, bo, flags);
949 /* LCOV_EXCL_START */
952 tbm_bufmgr_internal_alloc_bo_with_format(tbm_bufmgr bufmgr, int format, int bo_idx, int width,
953 int height, int bpp, tbm_bo_memory_type flags, tbm_error_e *error)
957 _tbm_bufmgr_mutex_lock();
958 _tbm_set_last_result(TBM_ERROR_NONE);
960 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
962 _tbm_bufmgr_check_bo_cnt(bufmgr);
964 bo = calloc(1, sizeof(struct _tbm_bo));
966 /* LCOV_EXCL_START */
967 TBM_ERR("memory allocationc failed.");
968 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
973 bo->bo_data = tbm_module_bufmgr_bo_alloc_with_format(bufmgr->module, format, bo_idx, width, height, bpp, flags, error);
975 /* LCOV_EXCL_START */
976 _tbm_set_last_result(*error);
981 _tbm_bufmgr_initialize_bo(bufmgr, bo, flags);
983 _tbm_bufmgr_mutex_unlock();
990 _tbm_bufmgr_mutex_unlock();
996 tbm_bufmgr_internal_alloc_bo_with_bo_data(tbm_bufmgr bufmgr, tbm_backend_bo_data *bo_data, int flags)
998 tbm_bo bo, bo2 = NULL;
1000 _tbm_bufmgr_mutex_lock();
1001 _tbm_set_last_result(TBM_ERROR_NONE);
1003 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
1004 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bo_data, NULL);
1006 _tbm_bufmgr_check_bo_cnt(bufmgr);
1008 bo = calloc(1, sizeof(struct _tbm_bo));
1010 /* LCOV_EXCL_START */
1011 TBM_ERR("memory allocationc failed.");
1012 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1013 _tbm_bufmgr_mutex_unlock();
1015 /* LCOV_EXCL_STOP */
1017 bo->bo_data = bo_data;
1018 bo->get_from_hal_surface = 1;
1020 // return an existed bo if the bo is already created with the same bo_data.
1021 bo2 = tbm_bufmgr_internal_find_bo(bufmgr, bo);
1025 _tbm_bufmgr_mutex_unlock();
1029 _tbm_bufmgr_initialize_bo(bufmgr, bo, flags);
1031 TBM_TRACE_BO("bo(%p) refcnt(%d), flag(%s)", bo, bo->ref_cnt, _tbm_flag_to_str(bo->flags));
1033 _tbm_bufmgr_mutex_unlock();
1039 tbm_bufmgr_internal_import_bo_with_key(tbm_bufmgr bufmgr, unsigned int key, tbm_error_e *error)
1044 _tbm_bufmgr_check_bo_cnt(bufmgr);
1046 bo = calloc(1, sizeof(struct _tbm_bo));
1048 /* LCOV_EXCL_START */
1049 TBM_ERR("memory allocationc failed.");
1050 *error = TBM_ERROR_OUT_OF_MEMORY;
1052 /* LCOV_EXCL_STOP */
1055 bo->bo_data = tbm_module_bufmgr_bo_import_key(bufmgr->module, bo, key, error);
1057 /* LCOV_EXCL_START */
1058 TBM_ERR("tbm_module_bufmgr_bo_import_key failed. tbm_key:%d", key);
1061 /* LCOV_EXCL_STOP */
1064 // return the existed bo2 if bo->bo_data and bo2->bo_data is the same
1065 bo2 = tbm_bufmgr_internal_find_bo(bufmgr, bo);
1067 TBM_TRACE_BO("find bo(%p) ref(%d) key(%d) flag(%s) in list",
1068 bo2, bo2->ref_cnt, key, _tbm_flag_to_str(bo2->flags));
1074 // TODO: refactoring tbm_module_bo
1075 if (bufmgr->use_hal_tbm) {
1076 flags = (tbm_bo_memory_type)hal_tbm_bo_get_memory_types((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)error);
1077 if (*error != TBM_ERROR_NONE) {
1078 TBM_ERR("fail to get the bo flags(memory_types)");
1079 flags = TBM_BO_DEFAULT;
1081 } else if (bufmgr->backend_module_data) {
1082 flags = bufmgr->bo_func->bo_get_memory_types(bo->bo_data, error);
1083 if (error != TBM_ERROR_NONE) {
1084 TBM_ERR("fail to get the bo flags(memory_types)");
1085 flags = TBM_BO_DEFAULT;
1088 if (bufmgr->backend->bo_get_flags)
1089 flags = bufmgr->backend->bo_get_flags(bo);
1091 flags = TBM_BO_DEFAULT;
1094 _tbm_bufmgr_initialize_bo(bufmgr, bo, flags);
1099 /* LCOV_EXCL_STOP */