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)
201 bufmgr->module_data = module->module_data;
202 bufmgr->backend = module->backend;
204 bufmgr->backend_module_data = module->backend_module_data;
205 bufmgr->bufmgr_data = module->bufmgr_data;
206 bufmgr->bufmgr_func = module->bufmgr_func;
207 bufmgr->bo_func = module->bo_func;
209 bufmgr->use_hal_tbm = module->use_hal_tbm;
210 bufmgr->auth_wl_socket_created = module->auth_wl_socket_created;
211 bufmgr->auth_fd = module->auth_fd;
212 bufmgr->hal_backend = module->hal_backend;
213 bufmgr->hal_bufmgr = module->hal_bufmgr;
217 _tbm_bufmgr_reset_modlue_data(tbm_bufmgr bufmgr)
219 bufmgr->module_data = NULL;
220 bufmgr->backend = NULL;
222 bufmgr->backend_module_data = NULL;
223 bufmgr->bufmgr_data = NULL;
224 bufmgr->bufmgr_func = NULL;
225 bufmgr->bo_func = NULL;
227 bufmgr->use_hal_tbm = 0;
228 bufmgr->auth_wl_socket_created = 0;
229 bufmgr->auth_fd = -1;
230 bufmgr->hal_backend = NULL;
231 bufmgr->hal_bufmgr = NULL;
237 _tbm_bufmgr_init(int fd, int server)
239 tbm_error_e error = TBM_ERROR_NONE;
241 #ifdef TBM_BUFMGR_INIT_TIME
242 struct timeval start_tv, end_tv;
246 #ifdef TBM_BUFMGR_INIT_TIME
247 /* get the start tv */
248 gettimeofday(&start_tv, NULL);
253 /* LCOV_EXCL_START */
255 env = getenv("TBM_TRACE");
257 trace_mask = atoi(env);
258 TBM_DBG("TBM_TRACE=%s\n", env);
263 pthread_mutex_lock(&gLock);
265 _tbm_set_last_result(TBM_ERROR_NONE);
268 TBM_WRN("!!!!!WARNING:: The tbm_bufmgr_init DOSE NOT use argument fd ANYMORE.\n");
269 TBM_WRN("!!!!!WARNING:: IT WILL BE CHANGED like tbm_bufmgr_init(int fd) --> tbm_bufmgr_init(void).\n");
273 /* initialize buffer manager */
275 gBufMgr->ref_count++;
276 TBM_DBG("reuse tbm_bufmgr(%p) ref_count(%d) fd(%d)\n", gBufMgr, gBufMgr->ref_count, gBufMgr->fd);
277 pthread_mutex_unlock(&gLock);
281 TBM_DBG("bufmgr init\n");
283 /* allocate bufmgr */
284 gBufMgr = calloc(1, sizeof(struct _tbm_bufmgr));
286 TBM_ERR("error: fail to alloc bufmgr fd(%d)\n", fd);
287 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
288 pthread_mutex_unlock(&gLock);
294 /* set the display_server flag before loading the backend module */
296 TBM_INFO("The tbm_bufmgr(%p) is used by display server. Need to bind the native_display.\n", gBufMgr);
297 gBufMgr->display_server = 1;
300 /* load bufmgr priv from env */
301 gBufMgr->module = tbm_module_load(gBufMgr->fd);
302 if (!gBufMgr->module) {
303 TBM_ERR("error : Fail to load bufmgr backend\n");
304 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
307 pthread_mutex_unlock(&gLock);
312 // TODO: this is temporary. it will be removed after finishing refactoring the tbm_module.
313 _tbm_bufmgr_copy_module_data(gBufMgr, gBufMgr->module);
315 /* check the essential capabilities of tbm_module */
316 gBufMgr->capabilities = tbm_module_bufmgr_get_capabilities(gBufMgr->module, &error);
317 if (gBufMgr->capabilities == TBM_BUFMGR_CAPABILITY_NONE) {
318 TBM_ERR("The capabilities of the backend module is TBM_BUFMGR_CAPABILITY_NONE.");
319 TBM_ERR("TBM_BUFMGR_CAPABILITY_SHARE_FD is the essential capability.");
320 tbm_module_unload(gBufMgr->module);
321 _tbm_set_last_result(error);
324 pthread_mutex_unlock(&gLock);
328 if (!(gBufMgr->capabilities & TBM_BUFMGR_CAPABILITY_SHARE_FD)) {
329 TBM_ERR("The capabilities of the backend module had no TBM_BUFMGR_CAPABILITY_SHARE_FD.");
330 TBM_ERR("The tbm backend has to get TBM_BUFMGR_CAPABILITY_SHARE_FD. ");
331 tbm_module_unload(gBufMgr->module);
332 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
335 pthread_mutex_unlock(&gLock);
341 gBufMgr->ref_count = 1;
343 TBM_INFO("create tizen bufmgr:%p ref_count:%d\n",
344 gBufMgr, gBufMgr->ref_count);
346 /* setup the bo_lock_type */
347 env = getenv("BUFMGR_LOCK_TYPE");
348 if (env && !strcmp(env, "always"))
349 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS;
350 else if (env && !strcmp(env, "none"))
351 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_NEVER;
352 else if (env && !strcmp(env, "once"))
353 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ONCE;
355 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS;
357 TBM_DBG("BUFMGR_LOCK_TYPE=%s\n", env ? env : "default:once");
359 /* intialize bo_list */
360 LIST_INITHEAD(&gBufMgr->bo_list);
362 /* intialize surf_list */
363 LIST_INITHEAD(&gBufMgr->surf_list);
365 /* intialize surf_queue_list */
366 LIST_INITHEAD(&gBufMgr->surf_queue_list);
368 /* intialize debug_key_list */
369 LIST_INITHEAD(&gBufMgr->debug_key_list);
371 #ifdef TBM_BUFMGR_INIT_TIME
373 gettimeofday(&end_tv, NULL);
374 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)));
377 pthread_mutex_unlock(&gLock);
383 tbm_bufmgr_init(int fd)
387 bufmgr = _tbm_bufmgr_init(fd, 0);
393 tbm_bufmgr_deinit(tbm_bufmgr bufmgr)
395 TBM_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
397 _tbm_bufmgr_mutex_lock();
398 pthread_mutex_lock(&gLock);
399 _tbm_set_last_result(TBM_ERROR_NONE);
402 TBM_ERR("gBufmgr already destroy: bufmgr:%p\n", bufmgr);
403 pthread_mutex_unlock(&gLock);
404 _tbm_bufmgr_mutex_unlock();
409 if (bufmgr->ref_count > 0) {
410 TBM_DBG("reduce a ref_count(%d) of tbm_bufmgr(%p)\n", bufmgr->ref_count, bufmgr);
411 pthread_mutex_unlock(&gLock);
412 _tbm_bufmgr_mutex_unlock();
416 /* destroy bo_list */
417 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
418 tbm_bo bo = NULL, tmp;
420 LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &bufmgr->bo_list, item_link) {
421 TBM_ERR("Un-freed bo(%p, ref:%d)\n", bo, bo->ref_cnt);
424 LIST_DELINIT(&bufmgr->bo_list);
427 /* destroy surf_list */
428 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
429 tbm_surface_h surf = NULL, tmp;
431 LIST_FOR_EACH_ENTRY_SAFE(surf, tmp, &bufmgr->surf_list, item_link) {
432 TBM_ERR("Un-freed surf(%p, ref:%d)\n", surf, surf->refcnt);
433 tbm_surface_destroy(surf);
435 LIST_DELINIT(&bufmgr->surf_list);
438 tbm_module_unload(bufmgr->module);
440 // TODO: this is temporary. it will be removed after finishing refactoring the tbm_module.
441 _tbm_bufmgr_reset_modlue_data(bufmgr);
446 TBM_INFO("destroy tbm_bufmgr(%p)\n", bufmgr);
451 pthread_mutex_unlock(&gLock);
452 _tbm_bufmgr_mutex_unlock();
456 tbm_bufmgr_get_capability(tbm_bufmgr bufmgr)
458 unsigned int capabilities = TBM_BUFMGR_CAPABILITY_NONE;
460 _tbm_bufmgr_mutex_lock();
461 _tbm_set_last_result(TBM_ERROR_NONE);
463 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), TBM_BUFMGR_CAPABILITY_NONE);
464 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, TBM_BUFMGR_CAPABILITY_NONE);
466 capabilities = bufmgr->capabilities;
468 _tbm_bufmgr_mutex_unlock();
473 /* LCOV_EXCL_START */
475 tbm_bufmgr_debug_tbm_info_get(tbm_bufmgr bufmgr)
477 char app_name[255] = {0,}, title[512] = {0,};
478 tbm_surface_debug_data *debug_old_data = NULL;
486 pthread_mutex_lock(&gLock);
487 _tbm_set_last_result(TBM_ERROR_NONE);
489 if (!TBM_BUFMGR_IS_VALID(bufmgr) || (bufmgr != gBufMgr)) {
490 TBM_ERR("invalid bufmgr\n");
491 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
492 pthread_mutex_unlock(&gLock);
498 TBM_ERR("Fail to allocate the string.\n");
499 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
500 pthread_mutex_unlock(&gLock);
504 TBM_SNRPRINTF(str, len, c, "\n");
505 pid = syscall(SYS_getpid);
506 _tbm_util_get_appname_from_pid(pid, app_name);
507 _tbm_util_get_appname_brief(app_name);
508 TBM_SNRPRINTF(str, len, c, "===========================================TBM DEBUG: %s(%ld)===========================================\n",
511 snprintf(title, 255, "%s", "no surface refcnt width height bpp size n_b n_p flags format app_name ");
513 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
514 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
515 strncat(title, " ", MAX_SIZE_N(title));
516 strncat(title, debug_old_data->key, MAX_SIZE_N(title));
520 TBM_SNRPRINTF(str, len, c, "[tbm_surface information]\n");
521 TBM_SNRPRINTF(str, len, c, "%s\n", title);
523 /* show the tbm_surface information in surf_list */
524 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
525 tbm_surface_h surf = NULL;
528 LIST_FOR_EACH_ENTRY(surf, &bufmgr->surf_list, item_link) {
529 char data[512] = {0,};
530 unsigned int surf_pid = 0;
533 surf_pid = _tbm_surface_internal_get_debug_pid(surf);
535 /* if pid is null, set the self_pid */
536 surf_pid = syscall(SYS_getpid);;
539 memset(app_name, 0x0, 255 * sizeof(char));
540 if (geteuid() == 0) {
541 _tbm_util_get_appname_from_pid(surf_pid, app_name);
542 _tbm_util_get_appname_brief(app_name);
544 snprintf(app_name, sizeof(app_name), "%d", surf_pid);
547 snprintf(data, 255, "%-3d %-11p %-5d %-6u %-7u %-4u %-7u %-3d %-3d %-8d %-9s %-22s",
554 surf->info.size / 1024,
558 _tbm_surface_internal_format_to_str(surf->info.format) + 11,
561 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
562 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
565 strncat(data, " ", MAX_SIZE_N(title));
567 value = _tbm_surface_internal_get_debug_data(surf, debug_old_data->key);
569 strncat(data, value, MAX_SIZE_N(title));
571 strncat(data, "none", MAX_SIZE_N(title));
574 TBM_SNRPRINTF(str, len, c, "%s\n", data);
576 for (i = 0; i < surf->num_bos; i++) {
577 size = tbm_module_bo_get_size(bufmgr->module, surf->bos[i], surf->bos[i]->bo_data, &error);
578 if (error != TBM_ERROR_NONE)
579 TBM_WRN("fail to get the size of bo.");
580 TBM_SNRPRINTF(str, len, c, " bo:%-12p %-26d%-10d\n",
582 surf->bos[i]->ref_cnt,
587 TBM_SNRPRINTF(str, len, c, " no tbm_surfaces.\n");
588 TBM_SNRPRINTF(str, len, c, "\n");
590 TBM_SNRPRINTF(str, len, c, "[tbm_bo information]\n");
591 TBM_SNRPRINTF(str, len, c, "no bo refcnt size lock_cnt map_cnt flags surface name\n");
593 /* show the tbm_bo information in bo_list */
594 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
599 LIST_FOR_EACH_ENTRY(bo, &bufmgr->bo_list, item_link) {
600 size = tbm_module_bo_get_size(bufmgr->module, bo, bo->bo_data, &error);
601 if (error != TBM_ERROR_NONE)
602 TBM_WRN("fail to get the size of bo.");
603 key = tbm_module_bo_export_key(bufmgr->module, bo, bo->bo_data, &error);
604 if (error != TBM_ERROR_NONE)
605 TBM_WRN("fail to get the tdm_key of bo.");
606 TBM_SNRPRINTF(str, len, c, "%-3d %-11p %-5d %-7d %-6d %-5u %-7d %-11p %-4d\n",
618 TBM_SNRPRINTF(str, len, c, "no tbm_bos.\n");
619 TBM_SNRPRINTF(str, len, c, "\n");
621 TBM_SNRPRINTF(str, len, c, "========================================================================================================\n");
623 pthread_mutex_unlock(&gLock);
629 tbm_bufmgr_debug_show(tbm_bufmgr bufmgr)
632 str = tbm_bufmgr_debug_tbm_info_get(bufmgr);
640 tbm_bufmgr_debug_trace(tbm_bufmgr bufmgr, int onoff)
642 _tbm_bufmgr_mutex_lock();
643 _tbm_set_last_result(TBM_ERROR_NONE);
645 TBM_BUFMGR_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
646 TBM_BUFMGR_RETURN_IF_FAIL(bufmgr == gBufMgr);
649 TBM_LOG_D("bufmgr=%p onoff=%d\n", bufmgr, onoff);
653 _tbm_bufmgr_mutex_unlock();
657 tbm_bufmgr_debug_set_trace_mask(tbm_bufmgr bufmgr, tbm_bufmgr_debug_trace_mask mask, int set)
659 _tbm_bufmgr_mutex_lock();
660 _tbm_set_last_result(TBM_ERROR_NONE);
662 TBM_BUFMGR_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
663 TBM_BUFMGR_RETURN_IF_FAIL(bufmgr == gBufMgr);
668 TBM_INFO("bufmgr=%p sets the trace_mask=%d\n", bufmgr, mask);
669 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_BO)
670 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_BO");
671 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL)
672 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL");
673 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE)
674 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE");
675 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE)
676 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE");
677 } else if (set == 0) {
680 TBM_INFO("bufmgr=%p unsets the trace_mask=%d\n", bufmgr, mask);
681 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_BO)
682 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_BO");
683 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL)
684 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL");
685 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE)
686 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE");
687 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE)
688 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE");
690 TBM_WRN("set value is wrong.(set=%d)", set);
693 _tbm_bufmgr_mutex_unlock();
697 tbm_bufmgr_debug_dump_set_scale(double scale)
699 pthread_mutex_lock(&gLock);
700 _tbm_set_last_result(TBM_ERROR_NONE);
701 scale_factor = scale;
702 pthread_mutex_unlock(&gLock);
706 tbm_bufmgr_debug_get_ref_count(void)
710 pthread_mutex_lock(&gLock);
712 _tbm_set_last_result(TBM_ERROR_NONE);
714 refcnt = (gBufMgr) ? gBufMgr->ref_count : 0;
716 pthread_mutex_unlock(&gLock);
722 tbm_bufmgr_debug_queue_dump(char *path, int count, int onoff)
724 pthread_mutex_lock(&gLock);
725 _tbm_set_last_result(TBM_ERROR_NONE);
728 TBM_DBG("count=%d onoff=%d\n", count, onoff);
730 tbm_surface_internal_dump_end();
735 TBM_ERR("path is null");
736 pthread_mutex_unlock(&gLock);
739 TBM_DBG("path=%s count=%d onoff=%d\n", path, count, onoff);
741 if (_tbm_util_get_max_surface_size(&w, &h) == 0) {
742 TBM_ERR("Fail to get tbm_surface size.\n");
743 pthread_mutex_unlock(&gLock);
747 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
753 pthread_mutex_unlock(&gLock);
759 tbm_bufmgr_debug_dump_all(char *path)
762 tbm_surface_h surface = NULL;
764 pthread_mutex_lock(&gLock);
765 _tbm_set_last_result(TBM_ERROR_NONE);
768 TBM_ERR("path is null.\n");
769 pthread_mutex_unlock(&gLock);
773 TBM_DBG("path=%s\n", path);
775 count = _tbm_util_get_max_surface_size(&w, &h);
777 TBM_ERR("No tbm_surface.\n");
778 pthread_mutex_unlock(&gLock);
782 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
785 LIST_FOR_EACH_ENTRY(surface, &gBufMgr->surf_list, item_link)
786 tbm_surface_internal_dump_buffer(surface, "dump_all");
788 tbm_surface_internal_dump_end();
790 pthread_mutex_unlock(&gLock);
795 /* internal function */
797 _tbm_bufmgr_get_bufmgr(void)
803 tbm_bufmgr_bind_native_display(tbm_bufmgr bufmgr, void *native_display)
807 _tbm_bufmgr_mutex_lock();
808 _tbm_set_last_result(TBM_ERROR_NONE);
810 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), 0);
812 error = tbm_module_bufmgr_bind_native_display(bufmgr->module, native_display);
813 if (error != TBM_ERROR_NONE) {
814 _tbm_set_last_result(error);
815 _tbm_bufmgr_mutex_unlock();
817 if (error == TBM_ERROR_NOT_SUPPORTED) {
818 TBM_WRN("Not supported, so skip: tbm_bufmgr(%p) native_display(%p)", bufmgr, native_display);
825 TBM_INFO("tbm_bufmgr(%p) native_display(%p)\n", bufmgr, native_display);
827 _tbm_bufmgr_mutex_unlock();
833 tbm_bufmgr_server_init(void)
837 bufmgr = _tbm_bufmgr_init(-1, 1);
843 tbm_bufmgr_set_bo_lock_type(tbm_bufmgr bufmgr, tbm_bufmgr_bo_lock_type bo_lock_type)
845 _tbm_bufmgr_mutex_lock();
846 _tbm_set_last_result(TBM_ERROR_NONE);
848 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
849 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, 0);
851 pthread_mutex_lock(&gLock);
852 gBufMgr->bo_lock_type = bo_lock_type;
853 pthread_mutex_unlock(&gLock);
855 TBM_INFO("The bo_lock_type of the bo is %d\n", bo_lock_type);
857 _tbm_bufmgr_mutex_unlock();
863 int tbm_bufmgr_get_fd_limit(void)
867 if (getrlimit(RLIMIT_NOFILE, &lim))
870 return (int)lim.rlim_cur;
873 tbm_bufmgr tbm_bufmgr_get(void)
880 tbm_bufmgr_internal_find_bo(tbm_bufmgr bufmgr, tbm_bo bo)
884 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), NULL);
885 TBM_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, NULL);
887 if (LIST_IS_EMPTY(&bufmgr->bo_list))
890 LIST_FOR_EACH_ENTRY(bo2, &bufmgr->bo_list, item_link) {
891 if (bo2->bo_data == bo->bo_data) {
900 tbm_bufmgr_internal_alloc_bo(tbm_bufmgr bufmgr, int size, int flags, tbm_error_e *error)
903 tbm_backend_bo_data *bo_data;
905 _tbm_bufmgr_check_bo_cnt(bufmgr);
907 bo = calloc(1, sizeof(struct _tbm_bo));
909 /* LCOV_EXCL_START */
910 TBM_ERR("memory allocationc failed.");
911 *error = TBM_ERROR_OUT_OF_MEMORY;
916 bo_data = tbm_module_bufmgr_alloc_bo(bufmgr->module, bo, size, flags, error);
918 /* LCOV_EXCL_START */
919 TBM_ERR("tbm_module_bufmgr_alloc_bo failed. size:%d flags:%s error:%d", size, _tbm_flag_to_str(flags), *error);
924 bo->bo_data = bo_data;
925 bo->priv = (void *)bo_data; // TODO: this will be DEPRECATED.
927 _tbm_bufmgr_initialize_bo(bufmgr, bo, flags);
933 /* LCOV_EXCL_START */
936 tbm_bufmgr_internal_alloc_bo_with_format(tbm_bufmgr bufmgr, int format, int bo_idx, int width,
937 int height, int bpp, tbm_bo_memory_type flags, tbm_error_e *error)
941 _tbm_bufmgr_mutex_lock();
942 _tbm_set_last_result(TBM_ERROR_NONE);
944 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
946 _tbm_bufmgr_check_bo_cnt(bufmgr);
948 bo = calloc(1, sizeof(struct _tbm_bo));
950 /* LCOV_EXCL_START */
951 TBM_ERR("memory allocationc failed.");
952 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
957 bo->bo_data = tbm_module_bufmgr_alloc_bo_with_format(bufmgr->module, format, bo_idx, width, height, bpp, flags, error);
959 /* LCOV_EXCL_START */
960 _tbm_set_last_result(*error);
965 _tbm_bufmgr_initialize_bo(bufmgr, bo, flags);
967 _tbm_bufmgr_mutex_unlock();
974 _tbm_bufmgr_mutex_unlock();
980 tbm_bufmgr_internal_alloc_bo_with_bo_data(tbm_bufmgr bufmgr, tbm_backend_bo_data *bo_data, int flags)
982 tbm_bo bo, bo2 = NULL;
984 _tbm_bufmgr_mutex_lock();
985 _tbm_set_last_result(TBM_ERROR_NONE);
987 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
988 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bo_data, NULL);
990 _tbm_bufmgr_check_bo_cnt(bufmgr);
992 bo = calloc(1, sizeof(struct _tbm_bo));
994 /* LCOV_EXCL_START */
995 TBM_ERR("memory allocationc failed.");
996 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
997 _tbm_bufmgr_mutex_unlock();
1001 bo->bo_data = bo_data;
1002 bo->get_from_hal_surface = 1;
1004 // return an existed bo if the bo is already created with the same bo_data.
1005 bo2 = tbm_bufmgr_internal_find_bo(bufmgr, bo);
1009 _tbm_bufmgr_mutex_unlock();
1013 _tbm_bufmgr_initialize_bo(bufmgr, bo, flags);
1015 TBM_TRACE_BO("bo(%p) refcnt(%d), flag(%s)", bo, bo->ref_cnt, _tbm_flag_to_str(bo->flags));
1017 _tbm_bufmgr_mutex_unlock();
1023 tbm_bufmgr_internal_import_bo_with_key(tbm_bufmgr bufmgr, unsigned int key, tbm_error_e *error)
1028 _tbm_bufmgr_check_bo_cnt(bufmgr);
1030 bo = calloc(1, sizeof(struct _tbm_bo));
1032 /* LCOV_EXCL_START */
1033 TBM_ERR("memory allocationc failed.");
1034 *error = TBM_ERROR_OUT_OF_MEMORY;
1036 /* LCOV_EXCL_STOP */
1039 bo->bo_data = tbm_module_bufmgr_import_bo_with_key(bufmgr->module, bo, key, error);
1041 /* LCOV_EXCL_START */
1042 TBM_ERR("tbm_module_bufmgr_import_bo_with_key failed. tbm_key:%d", key);
1045 /* LCOV_EXCL_STOP */
1048 // return the existed bo2 if bo->bo_data and bo2->bo_data is the same
1049 bo2 = tbm_bufmgr_internal_find_bo(bufmgr, bo);
1051 TBM_TRACE_BO("find bo(%p) ref(%d) key(%d) flag(%s) in list",
1052 bo2, bo2->ref_cnt, key, _tbm_flag_to_str(bo2->flags));
1058 flags = tbm_module_bo_get_memory_types(bufmgr->module, bo, bo->bo_data, error);
1059 if (*error != TBM_ERROR_NONE) {
1060 TBM_ERR("fail to get the bo flags(memory_types)");
1061 flags = TBM_BO_DEFAULT;
1064 _tbm_bufmgr_initialize_bo(bufmgr, bo, flags);
1070 tbm_bufmgr_internal_import_bo_with_fd(tbm_bufmgr bufmgr, tbm_fd fd, tbm_error_e *error)
1075 _tbm_bufmgr_check_bo_cnt(bufmgr);
1077 bo = calloc(1, sizeof(struct _tbm_bo));
1079 /* LCOV_EXCL_START */
1080 TBM_ERR("memory allocationc failed.");
1081 *error = TBM_ERROR_OUT_OF_MEMORY;
1083 /* LCOV_EXCL_STOP */
1086 bo->bo_data = tbm_module_bufmgr_import_bo_with_fd(bufmgr->module, bo, fd, error);
1088 /* LCOV_EXCL_START */
1089 TBM_ERR("tbm_module_bufmgr_import_bo_with_fd failed. tbm_fd:%d", fd);
1092 /* LCOV_EXCL_STOP */
1095 // return the existed bo2 if bo->bo_data and bo2->bo_data is the same
1096 bo2 = tbm_bufmgr_internal_find_bo(bufmgr, bo);
1098 TBM_TRACE_BO("find bo(%p) ref(%d) fd(%d) flag(%s) in list",
1099 bo2, bo2->ref_cnt, fd, _tbm_flag_to_str(bo2->flags));
1105 flags = tbm_module_bo_get_memory_types(bufmgr->module, bo, bo->bo_data, error);
1106 if (*error != TBM_ERROR_NONE) {
1107 TBM_ERR("fail to get the bo flags(memory_types)");
1108 flags = TBM_BO_DEFAULT;
1111 _tbm_bufmgr_initialize_bo(bufmgr, bo, flags);
1116 /* LCOV_EXCL_STOP */