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.");
604 if (bo->bufmgr->use_hal_tbm) {
605 key = (tbm_key)hal_tbm_bo_export_key((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)&error);
606 } else if (bufmgr->backend_module_data) {
607 key = bufmgr->bo_func->bo_export_key(bo->bo_data, &error);
608 if (error != TBM_ERROR_NONE)
609 TBM_WRN("fail to get the tdm_key of bo.");
611 key = bufmgr->backend->bo_export(bo);
613 TBM_SNRPRINTF(str, len, c, "%-3d %-11p %-5d %-7d %-6d %-5u %-7d %-11p %-4d\n",
625 TBM_SNRPRINTF(str, len, c, "no tbm_bos.\n");
626 TBM_SNRPRINTF(str, len, c, "\n");
628 TBM_SNRPRINTF(str, len, c, "========================================================================================================\n");
630 pthread_mutex_unlock(&gLock);
636 tbm_bufmgr_debug_show(tbm_bufmgr bufmgr)
639 str = tbm_bufmgr_debug_tbm_info_get(bufmgr);
647 tbm_bufmgr_debug_trace(tbm_bufmgr bufmgr, int onoff)
649 _tbm_bufmgr_mutex_lock();
650 _tbm_set_last_result(TBM_ERROR_NONE);
652 TBM_BUFMGR_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
653 TBM_BUFMGR_RETURN_IF_FAIL(bufmgr == gBufMgr);
656 TBM_LOG_D("bufmgr=%p onoff=%d\n", bufmgr, onoff);
660 _tbm_bufmgr_mutex_unlock();
664 tbm_bufmgr_debug_set_trace_mask(tbm_bufmgr bufmgr, tbm_bufmgr_debug_trace_mask mask, int set)
666 _tbm_bufmgr_mutex_lock();
667 _tbm_set_last_result(TBM_ERROR_NONE);
669 TBM_BUFMGR_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
670 TBM_BUFMGR_RETURN_IF_FAIL(bufmgr == gBufMgr);
675 TBM_INFO("bufmgr=%p sets the trace_mask=%d\n", bufmgr, mask);
676 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_BO)
677 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_BO");
678 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL)
679 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL");
680 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE)
681 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE");
682 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE)
683 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE");
684 } else if (set == 0) {
687 TBM_INFO("bufmgr=%p unsets the trace_mask=%d\n", bufmgr, mask);
688 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_BO)
689 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_BO");
690 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL)
691 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL");
692 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE)
693 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE");
694 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE)
695 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE");
697 TBM_WRN("set value is wrong.(set=%d)", set);
700 _tbm_bufmgr_mutex_unlock();
704 tbm_bufmgr_debug_dump_set_scale(double scale)
706 pthread_mutex_lock(&gLock);
707 _tbm_set_last_result(TBM_ERROR_NONE);
708 scale_factor = scale;
709 pthread_mutex_unlock(&gLock);
713 tbm_bufmgr_debug_get_ref_count(void)
717 pthread_mutex_lock(&gLock);
719 _tbm_set_last_result(TBM_ERROR_NONE);
721 refcnt = (gBufMgr) ? gBufMgr->ref_count : 0;
723 pthread_mutex_unlock(&gLock);
729 tbm_bufmgr_debug_queue_dump(char *path, int count, int onoff)
731 pthread_mutex_lock(&gLock);
732 _tbm_set_last_result(TBM_ERROR_NONE);
735 TBM_DBG("count=%d onoff=%d\n", count, onoff);
737 tbm_surface_internal_dump_end();
742 TBM_ERR("path is null");
743 pthread_mutex_unlock(&gLock);
746 TBM_DBG("path=%s count=%d onoff=%d\n", path, count, onoff);
748 if (_tbm_util_get_max_surface_size(&w, &h) == 0) {
749 TBM_ERR("Fail to get tbm_surface size.\n");
750 pthread_mutex_unlock(&gLock);
754 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
760 pthread_mutex_unlock(&gLock);
766 tbm_bufmgr_debug_dump_all(char *path)
769 tbm_surface_h surface = NULL;
771 pthread_mutex_lock(&gLock);
772 _tbm_set_last_result(TBM_ERROR_NONE);
775 TBM_ERR("path is null.\n");
776 pthread_mutex_unlock(&gLock);
780 TBM_DBG("path=%s\n", path);
782 count = _tbm_util_get_max_surface_size(&w, &h);
784 TBM_ERR("No tbm_surface.\n");
785 pthread_mutex_unlock(&gLock);
789 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
792 LIST_FOR_EACH_ENTRY(surface, &gBufMgr->surf_list, item_link)
793 tbm_surface_internal_dump_buffer(surface, "dump_all");
795 tbm_surface_internal_dump_end();
797 pthread_mutex_unlock(&gLock);
802 /* internal function */
804 _tbm_bufmgr_get_bufmgr(void)
810 tbm_bufmgr_bind_native_display(tbm_bufmgr bufmgr, void *native_display)
814 _tbm_bufmgr_mutex_lock();
815 _tbm_set_last_result(TBM_ERROR_NONE);
817 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), 0);
819 error = tbm_module_bufmgr_bind_native_display(bufmgr->module, native_display);
820 if (error != TBM_ERROR_NONE) {
821 _tbm_set_last_result(error);
822 _tbm_bufmgr_mutex_unlock();
824 if (error == TBM_ERROR_NOT_SUPPORTED) {
825 TBM_WRN("Not supported, so skip: tbm_bufmgr(%p) native_display(%p)", bufmgr, native_display);
832 TBM_INFO("tbm_bufmgr(%p) native_display(%p)\n", bufmgr, native_display);
834 _tbm_bufmgr_mutex_unlock();
840 tbm_bufmgr_server_init(void)
844 bufmgr = _tbm_bufmgr_init(-1, 1);
850 tbm_bufmgr_set_bo_lock_type(tbm_bufmgr bufmgr, tbm_bufmgr_bo_lock_type bo_lock_type)
852 _tbm_bufmgr_mutex_lock();
853 _tbm_set_last_result(TBM_ERROR_NONE);
855 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
856 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, 0);
858 pthread_mutex_lock(&gLock);
859 gBufMgr->bo_lock_type = bo_lock_type;
860 pthread_mutex_unlock(&gLock);
862 TBM_INFO("The bo_lock_type of the bo is %d\n", bo_lock_type);
864 _tbm_bufmgr_mutex_unlock();
870 int tbm_bufmgr_get_fd_limit(void)
874 if (getrlimit(RLIMIT_NOFILE, &lim))
877 return (int)lim.rlim_cur;
880 tbm_bufmgr tbm_bufmgr_get(void)
887 tbm_bufmgr_internal_find_bo(tbm_bufmgr bufmgr, tbm_bo bo)
891 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), NULL);
892 TBM_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, NULL);
894 if (LIST_IS_EMPTY(&bufmgr->bo_list))
897 LIST_FOR_EACH_ENTRY(bo2, &bufmgr->bo_list, item_link) {
898 if (bo2->bo_data == bo->bo_data) {
907 tbm_bufmgr_internal_alloc_bo(tbm_bufmgr bufmgr, int size, int flags, tbm_error_e *error)
910 tbm_backend_bo_data *bo_data;
912 _tbm_bufmgr_check_bo_cnt(bufmgr);
914 bo = calloc(1, sizeof(struct _tbm_bo));
916 /* LCOV_EXCL_START */
917 TBM_ERR("memory allocationc failed.");
918 *error = TBM_ERROR_OUT_OF_MEMORY;
923 bo_data = tbm_module_bufmgr_bo_alloc(bufmgr->module, bo, size, flags, error);
925 /* LCOV_EXCL_START */
926 TBM_ERR("tbm_module_bufmgr_bo_alloc failed. size:%d flags:%s error:%d", size, _tbm_flag_to_str(flags), *error);
931 bo->bo_data = bo_data;
932 bo->priv = (void *)bo_data; // TODO: this will be DEPRECATED.
934 _tbm_bufmgr_initialize_bo(bufmgr, bo, flags);
940 /* LCOV_EXCL_START */
943 tbm_bufmgr_internal_alloc_bo_with_format(tbm_bufmgr bufmgr, int format, int bo_idx, int width,
944 int height, int bpp, tbm_bo_memory_type flags, tbm_error_e *error)
948 _tbm_bufmgr_mutex_lock();
949 _tbm_set_last_result(TBM_ERROR_NONE);
951 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
953 _tbm_bufmgr_check_bo_cnt(bufmgr);
955 bo = calloc(1, sizeof(struct _tbm_bo));
957 /* LCOV_EXCL_START */
958 TBM_ERR("memory allocationc failed.");
959 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
964 bo->bo_data = tbm_module_bufmgr_bo_alloc_with_format(bufmgr->module, format, bo_idx, width, height, bpp, flags, error);
966 /* LCOV_EXCL_START */
967 _tbm_set_last_result(*error);
972 _tbm_bufmgr_initialize_bo(bufmgr, bo, flags);
974 _tbm_bufmgr_mutex_unlock();
981 _tbm_bufmgr_mutex_unlock();
987 tbm_bufmgr_internal_alloc_bo_with_bo_data(tbm_bufmgr bufmgr, tbm_backend_bo_data *bo_data, int flags)
989 tbm_bo bo, bo2 = NULL;
991 _tbm_bufmgr_mutex_lock();
992 _tbm_set_last_result(TBM_ERROR_NONE);
994 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
995 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bo_data, NULL);
997 _tbm_bufmgr_check_bo_cnt(bufmgr);
999 bo = calloc(1, sizeof(struct _tbm_bo));
1001 /* LCOV_EXCL_START */
1002 TBM_ERR("memory allocationc failed.");
1003 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
1004 _tbm_bufmgr_mutex_unlock();
1006 /* LCOV_EXCL_STOP */
1008 bo->bo_data = bo_data;
1009 bo->get_from_hal_surface = 1;
1011 // return an existed bo if the bo is already created with the same bo_data.
1012 bo2 = tbm_bufmgr_internal_find_bo(bufmgr, bo);
1016 _tbm_bufmgr_mutex_unlock();
1020 _tbm_bufmgr_initialize_bo(bufmgr, bo, flags);
1022 TBM_TRACE_BO("bo(%p) refcnt(%d), flag(%s)", bo, bo->ref_cnt, _tbm_flag_to_str(bo->flags));
1024 _tbm_bufmgr_mutex_unlock();
1030 tbm_bufmgr_internal_import_bo_with_key(tbm_bufmgr bufmgr, unsigned int key, tbm_error_e *error)
1035 _tbm_bufmgr_check_bo_cnt(bufmgr);
1037 bo = calloc(1, sizeof(struct _tbm_bo));
1039 /* LCOV_EXCL_START */
1040 TBM_ERR("memory allocationc failed.");
1041 *error = TBM_ERROR_OUT_OF_MEMORY;
1043 /* LCOV_EXCL_STOP */
1046 bo->bo_data = tbm_module_bufmgr_bo_import_key(bufmgr->module, bo, key, error);
1048 /* LCOV_EXCL_START */
1049 TBM_ERR("tbm_module_bufmgr_bo_import_key failed. tbm_key:%d", key);
1052 /* LCOV_EXCL_STOP */
1055 // return the existed bo2 if bo->bo_data and bo2->bo_data is the same
1056 bo2 = tbm_bufmgr_internal_find_bo(bufmgr, bo);
1058 TBM_TRACE_BO("find bo(%p) ref(%d) key(%d) flag(%s) in list",
1059 bo2, bo2->ref_cnt, key, _tbm_flag_to_str(bo2->flags));
1065 // TODO: refactoring tbm_module_bo
1066 if (bufmgr->use_hal_tbm) {
1067 flags = (tbm_bo_memory_type)hal_tbm_bo_get_memory_types((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)error);
1068 if (*error != TBM_ERROR_NONE) {
1069 TBM_ERR("fail to get the bo flags(memory_types)");
1070 flags = TBM_BO_DEFAULT;
1072 } else if (bufmgr->backend_module_data) {
1073 flags = bufmgr->bo_func->bo_get_memory_types(bo->bo_data, error);
1074 if (error != TBM_ERROR_NONE) {
1075 TBM_ERR("fail to get the bo flags(memory_types)");
1076 flags = TBM_BO_DEFAULT;
1079 if (bufmgr->backend->bo_get_flags)
1080 flags = bufmgr->backend->bo_get_flags(bo);
1082 flags = TBM_BO_DEFAULT;
1085 _tbm_bufmgr_initialize_bo(bufmgr, bo, flags);
1091 tbm_bufmgr_internal_import_bo_with_fd(tbm_bufmgr bufmgr, tbm_fd fd, tbm_error_e *error)
1096 _tbm_bufmgr_check_bo_cnt(bufmgr);
1098 bo = calloc(1, sizeof(struct _tbm_bo));
1100 /* LCOV_EXCL_START */
1101 TBM_ERR("memory allocationc failed.");
1102 *error = TBM_ERROR_OUT_OF_MEMORY;
1104 /* LCOV_EXCL_STOP */
1107 bo->bo_data = tbm_module_bufmgr_bo_import_fd(bufmgr->module, bo, fd, error);
1109 /* LCOV_EXCL_START */
1110 TBM_ERR("tbm_module_bufmgr_bo_import_fd failed. tbm_fd:%d", fd);
1113 /* LCOV_EXCL_STOP */
1116 // return the existed bo2 if bo->bo_data and bo2->bo_data is the same
1117 bo2 = tbm_bufmgr_internal_find_bo(bufmgr, bo);
1119 TBM_TRACE_BO("find bo(%p) ref(%d) fd(%d) flag(%s) in list",
1120 bo2, bo2->ref_cnt, fd, _tbm_flag_to_str(bo2->flags));
1126 // TODO: refactoring tbm_module_bo
1127 if (bufmgr->use_hal_tbm) {
1128 flags = (tbm_bo_memory_type)hal_tbm_bo_get_memory_types((hal_tbm_bo *)bo->bo_data, (hal_tbm_error *)error);
1129 if (error != TBM_ERROR_NONE) {
1130 TBM_ERR("fail to get the bo flags(memory_types)");
1131 flags = TBM_BO_DEFAULT;
1133 } else if (bufmgr->backend_module_data) {
1134 flags = bufmgr->bo_func->bo_get_memory_types(bo->bo_data, error);
1135 if (error != TBM_ERROR_NONE) {
1136 TBM_ERR("fail to get the bo flags(memory_types)");
1137 flags = TBM_BO_DEFAULT;
1140 if (bufmgr->backend->bo_get_flags)
1141 flags = bufmgr->backend->bo_get_flags(bo);
1143 flags = TBM_BO_DEFAULT;
1146 _tbm_bufmgr_initialize_bo(bufmgr, bo, flags);
1151 /* LCOV_EXCL_STOP */