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();\
78 #define TBM_BUFMGR_RETURN_VAL_SET_ERR_IF_FAIL(cond, val, error, error_type) {\
80 TBM_ERR("'%s' failed.\n", #cond);\
82 _tbm_bufmgr_mutex_unlock();\
90 _tbm_bufmgr_check_bo_cnt(tbm_bufmgr bufmgr)
92 static int last_chk_bo_cnt = 0;
94 if ((bufmgr->bo_cnt >= 500) && ((bufmgr->bo_cnt % 20) == 0) &&
95 (bufmgr->bo_cnt > last_chk_bo_cnt)) {
96 TBM_DBG("============TBM BO CNT DEBUG: bo_cnt=%d\n", bufmgr->bo_cnt);
97 tbm_bufmgr_debug_show(bufmgr);
98 last_chk_bo_cnt = bufmgr->bo_cnt;
103 _tbm_bufmgr_initialize_bo(tbm_bufmgr bufmgr, tbm_bo bo, int flags)
107 bo->magic = TBM_BO_MAGIC;
110 LIST_INITHEAD(&bo->user_data_list);
113 LIST_ADD(&bo->item_link, &bufmgr->bo_list);
117 _tbm_bufmgr_mutex_lock(void)
119 pthread_mutex_lock(&tbm_bufmgr_lock);
123 _tbm_bufmgr_mutex_unlock(void)
125 pthread_mutex_unlock(&tbm_bufmgr_lock);
129 _tbm_util_get_max_surface_size(int *w, int *h)
131 tbm_surface_info_s info;
132 tbm_surface_h surface = NULL;
138 if (gBufMgr == NULL || LIST_IS_EMPTY(&gBufMgr->surf_list))
141 LIST_FOR_EACH_ENTRY(surface, &gBufMgr->surf_list, item_link) {
142 if (tbm_surface_get_info(surface, &info) == TBM_SURFACE_ERROR_NONE) {
146 if (*h < info.height)
155 _tbm_util_get_appname_brief(char *brief)
159 char temp[255] = {0,};
160 char *saveptr = NULL;
162 token = strtok_r(brief, delim, &saveptr);
164 while (token != NULL) {
165 memset(temp, 0x00, 255 * sizeof(char));
166 strncpy(temp, token, 254 * sizeof(char));
167 token = strtok_r(NULL, delim, &saveptr);
170 snprintf(brief, sizeof(temp), "%s", temp);
174 _tbm_util_get_appname_from_pid(long pid, char *str)
176 char fn_cmdline[255] = {0, }, cmdline[255];
180 if (pid <= 0) return;
182 snprintf(fn_cmdline, sizeof(fn_cmdline), "/proc/%ld/cmdline", pid);
184 fp = fopen(fn_cmdline, "r");
186 TBM_ERR("cannot file open %s\n", fn_cmdline);
190 if (!fgets(cmdline, 255, fp)) {
191 TBM_ERR("fail to get appname for pid(%ld)\n", pid);
198 len = strlen(cmdline);
200 memset(cmdline, 0x00, 255);
204 snprintf(str, sizeof(cmdline), "%s", cmdline);
210 _tbm_bufmgr_init(int fd, int server)
212 tbm_error_e error = TBM_ERROR_NONE;
214 #ifdef TBM_BUFMGR_INIT_TIME
215 struct timeval start_tv, end_tv;
219 #ifdef TBM_BUFMGR_INIT_TIME
220 /* get the start tv */
221 gettimeofday(&start_tv, NULL);
226 /* LCOV_EXCL_START */
228 env = getenv("TBM_TRACE");
230 trace_mask = atoi(env);
231 TBM_DBG("TBM_TRACE=%s\n", env);
236 pthread_mutex_lock(&gLock);
238 _tbm_set_last_result(TBM_ERROR_NONE);
241 TBM_WRN("!!!!!WARNING:: The tbm_bufmgr_init DOSE NOT use argument fd ANYMORE.\n");
242 TBM_WRN("!!!!!WARNING:: IT WILL BE CHANGED like tbm_bufmgr_init(int fd) --> tbm_bufmgr_init(void).\n");
246 /* initialize buffer manager */
248 gBufMgr->ref_count++;
249 TBM_DBG("reuse tbm_bufmgr(%p) ref_count(%d) fd(%d)\n", gBufMgr, gBufMgr->ref_count, gBufMgr->fd);
250 pthread_mutex_unlock(&gLock);
254 TBM_DBG("bufmgr init\n");
256 /* allocate bufmgr */
257 gBufMgr = calloc(1, sizeof(struct _tbm_bufmgr));
259 TBM_ERR("error: fail to alloc bufmgr fd(%d)\n", fd);
260 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
261 pthread_mutex_unlock(&gLock);
267 /* set the display_server flag before loading the backend module */
269 TBM_INFO("The tbm_bufmgr(%p) is used by display server. Need to bind the native_display.\n", gBufMgr);
270 gBufMgr->display_server = 1;
273 /* load bufmgr priv from env */
274 gBufMgr->module = tbm_module_load(gBufMgr->fd);
275 if (!gBufMgr->module) {
276 TBM_ERR("error : Fail to load bufmgr backend\n");
277 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
280 pthread_mutex_unlock(&gLock);
285 /* check the essential capabilities of tbm_module */
286 gBufMgr->capabilities = tbm_module_get_capabilities(gBufMgr->module, &error);
287 if (gBufMgr->capabilities == TBM_BUFMGR_CAPABILITY_NONE) {
288 TBM_ERR("The capabilities of the backend module is TBM_BUFMGR_CAPABILITY_NONE.");
289 TBM_ERR("TBM_BUFMGR_CAPABILITY_SHARE_FD is the essential capability.");
290 tbm_module_unload(gBufMgr->module);
291 _tbm_set_last_result(error);
294 pthread_mutex_unlock(&gLock);
298 if (!(gBufMgr->capabilities & TBM_BUFMGR_CAPABILITY_SHARE_FD)) {
299 TBM_ERR("The capabilities of the backend module had no TBM_BUFMGR_CAPABILITY_SHARE_FD.");
300 TBM_ERR("The tbm backend has to get TBM_BUFMGR_CAPABILITY_SHARE_FD. ");
301 tbm_module_unload(gBufMgr->module);
302 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
305 pthread_mutex_unlock(&gLock);
311 gBufMgr->ref_count = 1;
313 TBM_INFO("create tizen bufmgr:%p ref_count:%d\n",
314 gBufMgr, gBufMgr->ref_count);
316 /* setup the bo_lock_type */
317 env = getenv("BUFMGR_LOCK_TYPE");
318 if (env && !strcmp(env, "always"))
319 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS;
320 else if (env && !strcmp(env, "none"))
321 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_NEVER;
322 else if (env && !strcmp(env, "once"))
323 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ONCE;
325 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS;
327 TBM_DBG("BUFMGR_LOCK_TYPE=%s\n", env ? env : "default:once");
329 /* intialize bo_list */
330 LIST_INITHEAD(&gBufMgr->bo_list);
332 /* intialize surf_list */
333 LIST_INITHEAD(&gBufMgr->surf_list);
335 /* intialize surf_queue_list */
336 LIST_INITHEAD(&gBufMgr->surf_queue_list);
338 /* intialize debug_key_list */
339 LIST_INITHEAD(&gBufMgr->debug_key_list);
341 #ifdef TBM_BUFMGR_INIT_TIME
343 gettimeofday(&end_tv, NULL);
344 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)));
347 pthread_mutex_unlock(&gLock);
353 tbm_bufmgr_init(int fd)
357 bufmgr = _tbm_bufmgr_init(fd, 0);
363 tbm_bufmgr_deinit(tbm_bufmgr bufmgr)
365 TBM_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
367 _tbm_bufmgr_mutex_lock();
368 pthread_mutex_lock(&gLock);
369 _tbm_set_last_result(TBM_ERROR_NONE);
372 TBM_ERR("gBufmgr already destroy: bufmgr:%p\n", bufmgr);
373 pthread_mutex_unlock(&gLock);
374 _tbm_bufmgr_mutex_unlock();
379 if (bufmgr->ref_count > 0) {
380 TBM_DBG("reduce a ref_count(%d) of tbm_bufmgr(%p)\n", bufmgr->ref_count, bufmgr);
381 pthread_mutex_unlock(&gLock);
382 _tbm_bufmgr_mutex_unlock();
386 /* destroy bo_list */
387 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
388 tbm_bo bo = NULL, tmp;
390 LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &bufmgr->bo_list, item_link) {
391 TBM_ERR("Un-freed bo(%p, ref:%d)\n", bo, bo->ref_cnt);
394 LIST_DELINIT(&bufmgr->bo_list);
397 /* destroy surf_list */
398 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
399 tbm_surface_h surf = NULL, tmp;
401 LIST_FOR_EACH_ENTRY_SAFE(surf, tmp, &bufmgr->surf_list, item_link) {
402 TBM_ERR("Un-freed surf(%p, ref:%d)\n", surf, surf->refcnt);
403 tbm_surface_destroy(surf);
405 LIST_DELINIT(&bufmgr->surf_list);
408 tbm_module_unload(bufmgr->module);
413 TBM_INFO("destroy tbm_bufmgr(%p)\n", bufmgr);
418 pthread_mutex_unlock(&gLock);
419 _tbm_bufmgr_mutex_unlock();
423 tbm_bufmgr_get_capability(tbm_bufmgr bufmgr)
425 unsigned int capabilities = TBM_BUFMGR_CAPABILITY_NONE;
427 _tbm_bufmgr_mutex_lock();
428 _tbm_set_last_result(TBM_ERROR_NONE);
430 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), TBM_BUFMGR_CAPABILITY_NONE);
431 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, TBM_BUFMGR_CAPABILITY_NONE);
433 capabilities = bufmgr->capabilities;
435 _tbm_bufmgr_mutex_unlock();
440 /* LCOV_EXCL_START */
442 tbm_bufmgr_debug_tbm_info_get(tbm_bufmgr bufmgr)
444 char app_name[255] = {0,}, title[512] = {0,};
445 tbm_surface_debug_data *debug_old_data = NULL;
453 pthread_mutex_lock(&gLock);
454 _tbm_set_last_result(TBM_ERROR_NONE);
456 if (!TBM_BUFMGR_IS_VALID(bufmgr) || (bufmgr != gBufMgr)) {
457 TBM_ERR("invalid bufmgr\n");
458 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
459 pthread_mutex_unlock(&gLock);
465 TBM_ERR("Fail to allocate the string.\n");
466 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
467 pthread_mutex_unlock(&gLock);
471 TBM_SNRPRINTF(str, len, c, "\n");
472 pid = syscall(SYS_getpid);
473 _tbm_util_get_appname_from_pid(pid, app_name);
474 _tbm_util_get_appname_brief(app_name);
475 TBM_SNRPRINTF(str, len, c, "===========================================TBM DEBUG: %s(%ld)===========================================\n",
478 snprintf(title, 255, "%s", "no surface refcnt width height bpp size n_b n_p flags format app_name ");
480 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
481 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
482 strncat(title, " ", MAX_SIZE_N(title));
483 strncat(title, debug_old_data->key, MAX_SIZE_N(title));
487 TBM_SNRPRINTF(str, len, c, "[tbm_surface information]\n");
488 TBM_SNRPRINTF(str, len, c, "%s\n", title);
490 /* show the tbm_surface information in surf_list */
491 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
492 tbm_surface_h surf = NULL;
495 LIST_FOR_EACH_ENTRY(surf, &bufmgr->surf_list, item_link) {
496 char data[512] = {0,};
497 unsigned int surf_pid = 0;
500 surf_pid = _tbm_surface_internal_get_debug_pid(surf);
502 /* if pid is null, set the self_pid */
503 surf_pid = syscall(SYS_getpid);;
506 memset(app_name, 0x0, 255 * sizeof(char));
507 if (geteuid() == 0) {
508 _tbm_util_get_appname_from_pid(surf_pid, app_name);
509 _tbm_util_get_appname_brief(app_name);
511 snprintf(app_name, sizeof(app_name), "%d", surf_pid);
514 snprintf(data, 255, "%-3d %-11p %-5d %-6u %-7u %-4u %-7u %-3d %-3d %-8d %-9s %-22s",
521 surf->info.size / 1024,
525 _tbm_surface_internal_format_to_str(surf->info.format) + 11,
528 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
529 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
532 strncat(data, " ", MAX_SIZE_N(title));
534 value = _tbm_surface_internal_get_debug_data(surf, debug_old_data->key);
536 strncat(data, value, MAX_SIZE_N(title));
538 strncat(data, "none", MAX_SIZE_N(title));
541 TBM_SNRPRINTF(str, len, c, "%s\n", data);
543 for (i = 0; i < surf->num_bos; i++) {
544 size = tbm_bo_data_get_size(surf->bos[i]->bo_data, &error);
545 if (error != TBM_ERROR_NONE)
546 TBM_WRN("fail to get the size of bo.");
547 TBM_SNRPRINTF(str, len, c, " bo:%-12p %-26d%-10d\n",
549 surf->bos[i]->ref_cnt,
554 TBM_SNRPRINTF(str, len, c, " no tbm_surfaces.\n");
555 TBM_SNRPRINTF(str, len, c, "\n");
557 TBM_SNRPRINTF(str, len, c, "[tbm_bo information]\n");
558 TBM_SNRPRINTF(str, len, c, "no bo refcnt size lock_cnt map_cnt flags surface name\n");
560 /* show the tbm_bo information in bo_list */
561 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
566 LIST_FOR_EACH_ENTRY(bo, &bufmgr->bo_list, item_link) {
567 size = tbm_bo_data_get_size(bo->bo_data, &error);
568 if (error != TBM_ERROR_NONE)
569 TBM_WRN("fail to get the size of bo.");
570 key = tbm_bo_data_export_key(bo->bo_data, &error);
571 if (error != TBM_ERROR_NONE)
572 TBM_WRN("fail to get the tdm_key of bo.");
573 TBM_SNRPRINTF(str, len, c, "%-3d %-11p %-5d %-7d %-6d %-5u %-7d %-11p %-4d\n",
585 TBM_SNRPRINTF(str, len, c, "no tbm_bos.\n");
586 TBM_SNRPRINTF(str, len, c, "\n");
588 TBM_SNRPRINTF(str, len, c, "========================================================================================================\n");
590 pthread_mutex_unlock(&gLock);
596 tbm_bufmgr_debug_show(tbm_bufmgr bufmgr)
599 str = tbm_bufmgr_debug_tbm_info_get(bufmgr);
607 tbm_bufmgr_debug_trace(tbm_bufmgr bufmgr, int onoff)
609 _tbm_bufmgr_mutex_lock();
610 _tbm_set_last_result(TBM_ERROR_NONE);
612 TBM_BUFMGR_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
613 TBM_BUFMGR_RETURN_IF_FAIL(bufmgr == gBufMgr);
616 TBM_LOG_D("bufmgr=%p onoff=%d\n", bufmgr, onoff);
620 _tbm_bufmgr_mutex_unlock();
624 tbm_bufmgr_debug_set_trace_mask(tbm_bufmgr bufmgr, tbm_bufmgr_debug_trace_mask mask, int set)
626 _tbm_bufmgr_mutex_lock();
627 _tbm_set_last_result(TBM_ERROR_NONE);
629 TBM_BUFMGR_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
630 TBM_BUFMGR_RETURN_IF_FAIL(bufmgr == gBufMgr);
635 TBM_INFO("bufmgr=%p sets the trace_mask=%d\n", bufmgr, mask);
636 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_BO)
637 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_BO");
638 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL)
639 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL");
640 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE)
641 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE");
642 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE)
643 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE");
644 } else if (set == 0) {
647 TBM_INFO("bufmgr=%p unsets the trace_mask=%d\n", bufmgr, mask);
648 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_BO)
649 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_BO");
650 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL)
651 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL");
652 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE)
653 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE");
654 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE)
655 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE");
657 TBM_WRN("set value is wrong.(set=%d)", set);
660 _tbm_bufmgr_mutex_unlock();
664 tbm_bufmgr_debug_dump_set_scale(double scale)
666 pthread_mutex_lock(&gLock);
667 _tbm_set_last_result(TBM_ERROR_NONE);
668 scale_factor = scale;
669 pthread_mutex_unlock(&gLock);
673 tbm_bufmgr_debug_get_ref_count(void)
677 pthread_mutex_lock(&gLock);
679 _tbm_set_last_result(TBM_ERROR_NONE);
681 refcnt = (gBufMgr) ? gBufMgr->ref_count : 0;
683 pthread_mutex_unlock(&gLock);
689 tbm_bufmgr_debug_queue_dump(char *path, int count, int onoff)
691 pthread_mutex_lock(&gLock);
692 _tbm_set_last_result(TBM_ERROR_NONE);
695 TBM_DBG("count=%d onoff=%d\n", count, onoff);
697 tbm_surface_internal_dump_end();
702 TBM_ERR("path is null");
703 pthread_mutex_unlock(&gLock);
706 TBM_DBG("path=%s count=%d onoff=%d\n", path, count, onoff);
708 if (_tbm_util_get_max_surface_size(&w, &h) == 0) {
709 TBM_ERR("Fail to get tbm_surface size.\n");
710 pthread_mutex_unlock(&gLock);
714 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
720 pthread_mutex_unlock(&gLock);
726 tbm_bufmgr_debug_dump_all(char *path)
729 tbm_surface_h surface = NULL;
731 pthread_mutex_lock(&gLock);
732 _tbm_set_last_result(TBM_ERROR_NONE);
735 TBM_ERR("path is null.\n");
736 pthread_mutex_unlock(&gLock);
740 TBM_DBG("path=%s\n", path);
742 count = _tbm_util_get_max_surface_size(&w, &h);
744 TBM_ERR("No tbm_surface.\n");
745 pthread_mutex_unlock(&gLock);
749 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
752 LIST_FOR_EACH_ENTRY(surface, &gBufMgr->surf_list, item_link)
753 tbm_surface_internal_dump_buffer(surface, "dump_all");
755 tbm_surface_internal_dump_end();
757 pthread_mutex_unlock(&gLock);
762 /* internal function */
764 _tbm_bufmgr_get_bufmgr(void)
770 tbm_bufmgr_bind_native_display(tbm_bufmgr bufmgr, void *native_display)
774 _tbm_bufmgr_mutex_lock();
775 _tbm_set_last_result(TBM_ERROR_NONE);
777 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), 0);
779 error = tbm_module_bind_native_display(bufmgr->module, native_display);
780 if (error != TBM_ERROR_NONE) {
781 _tbm_set_last_result(error);
782 _tbm_bufmgr_mutex_unlock();
784 if (error == TBM_ERROR_NOT_SUPPORTED) {
785 TBM_WRN("Not supported, so skip: tbm_bufmgr(%p) native_display(%p)", bufmgr, native_display);
792 TBM_INFO("tbm_bufmgr(%p) native_display(%p)\n", bufmgr, native_display);
794 _tbm_bufmgr_mutex_unlock();
800 tbm_bufmgr_server_init(void)
804 bufmgr = _tbm_bufmgr_init(-1, 1);
810 tbm_bufmgr_set_bo_lock_type(tbm_bufmgr bufmgr, tbm_bufmgr_bo_lock_type bo_lock_type)
812 _tbm_bufmgr_mutex_lock();
813 _tbm_set_last_result(TBM_ERROR_NONE);
815 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
816 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, 0);
818 pthread_mutex_lock(&gLock);
819 gBufMgr->bo_lock_type = bo_lock_type;
820 pthread_mutex_unlock(&gLock);
822 TBM_INFO("The bo_lock_type of the bo is %d\n", bo_lock_type);
824 _tbm_bufmgr_mutex_unlock();
830 int tbm_bufmgr_get_fd_limit(void)
834 if (getrlimit(RLIMIT_NOFILE, &lim))
837 return (int)lim.rlim_cur;
840 tbm_bufmgr tbm_bufmgr_get(void)
847 tbm_bufmgr_internal_find_bo(tbm_bufmgr bufmgr, tbm_bo bo)
851 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), NULL);
852 TBM_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, NULL);
854 if (LIST_IS_EMPTY(&bufmgr->bo_list))
857 LIST_FOR_EACH_ENTRY(bo2, &bufmgr->bo_list, item_link) {
858 if (tbm_module_compare_bo_data(bufmgr->module, bo2->bo_data, bo->bo_data))
866 tbm_bufmgr_internal_alloc_bo(tbm_bufmgr bufmgr, int size, int flags)
868 tbm_error_e error = TBM_ERROR_NONE;
871 _tbm_bufmgr_mutex_lock();
873 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
874 TBM_BUFMGR_RETURN_VAL_IF_FAIL(size > 0, NULL);
876 _tbm_bufmgr_check_bo_cnt(bufmgr);
878 bo = calloc(1, sizeof(struct _tbm_bo));
880 /* LCOV_EXCL_START */
881 TBM_ERR("memory allocationc failed.");
882 error = TBM_ERROR_OUT_OF_MEMORY;
887 bo->bo_data = tbm_module_alloc_bo_data(bufmgr->module, bo, size, flags, &error);
889 /* LCOV_EXCL_START */
890 TBM_ERR("tbm_module_alloc_bo_data failed. size:%d flags:%s error:%d", size, _tbm_flag_to_str(flags), error);
892 _tbm_set_last_result(error);
893 _tbm_bufmgr_mutex_unlock();
898 _tbm_bufmgr_initialize_bo(bufmgr, bo, flags);
900 TBM_TRACE_BO("bo(%p) size(%d) refcnt(%d), flag(%s)", bo, size, bo->ref_cnt, _tbm_flag_to_str(bo->flags));
902 _tbm_set_last_result(TBM_ERROR_NONE);
903 _tbm_bufmgr_mutex_unlock();
907 /* LCOV_EXCL_START */
909 _tbm_set_last_result(error);
910 _tbm_bufmgr_mutex_unlock();
917 /* LCOV_EXCL_START */
920 tbm_bufmgr_internal_alloc_bo_with_format(tbm_bufmgr bufmgr, int format, int bo_idx, int width,
921 int height, int bpp, tbm_bo_memory_type flags, tbm_error_e *error)
925 _tbm_bufmgr_mutex_lock();
927 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
929 _tbm_bufmgr_check_bo_cnt(bufmgr);
931 bo = calloc(1, sizeof(struct _tbm_bo));
933 /* LCOV_EXCL_START */
934 TBM_ERR("memory allocationc failed.");
935 *error = TBM_ERROR_OUT_OF_MEMORY;
936 _tbm_bufmgr_mutex_unlock();
941 bo->bo_data = tbm_module_alloc_bo_data_with_format(bufmgr->module, format, bo_idx, width, height, bpp, flags, error);
943 /* LCOV_EXCL_START */
945 _tbm_bufmgr_mutex_unlock();
950 _tbm_bufmgr_initialize_bo(bufmgr, bo, flags);
952 _tbm_bufmgr_mutex_unlock();
955 /* LCOV_EXCL_START */
957 _tbm_bufmgr_mutex_unlock();
964 tbm_bufmgr_internal_alloc_bo_with_bo_data(tbm_bufmgr bufmgr, tbm_bo_data *bo_data, int flags, tbm_error_e *error)
966 tbm_bo bo, bo2 = NULL;
968 _tbm_bufmgr_mutex_lock();
970 *error = TBM_ERROR_NONE;
972 TBM_BUFMGR_RETURN_VAL_SET_ERR_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL, *error, TBM_ERROR_INVALID_PARAMETER);
973 TBM_BUFMGR_RETURN_VAL_SET_ERR_IF_FAIL(bo_data, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
975 _tbm_bufmgr_check_bo_cnt(bufmgr);
977 bo = calloc(1, sizeof(struct _tbm_bo));
979 /* LCOV_EXCL_START */
980 TBM_ERR("memory allocationc failed.");
981 *error = TBM_ERROR_OUT_OF_MEMORY;
982 _tbm_bufmgr_mutex_unlock();
986 bo->bo_data = bo_data;
987 bo->get_from_surface_data = 1;
989 // return an existed bo if the bo is already created with the same bo_data.
990 bo2 = tbm_bufmgr_internal_find_bo(bufmgr, bo);
994 _tbm_bufmgr_mutex_unlock();
998 _tbm_bufmgr_initialize_bo(bufmgr, bo, flags);
1000 TBM_TRACE_BO("bo(%p) refcnt(%d), flag(%s)", bo, bo->ref_cnt, _tbm_flag_to_str(bo->flags));
1002 _tbm_bufmgr_mutex_unlock();
1008 tbm_bufmgr_internal_import_bo_with_key(tbm_bufmgr bufmgr, unsigned int key)
1010 tbm_error_e error = TBM_ERROR_NONE;
1014 _tbm_bufmgr_mutex_lock();
1016 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
1018 _tbm_bufmgr_check_bo_cnt(bufmgr);
1020 bo = calloc(1, sizeof(struct _tbm_bo));
1022 /* LCOV_EXCL_START */
1023 TBM_ERR("memory allocationc failed.");
1025 /* LCOV_EXCL_STOP */
1028 bo->bo_data = tbm_module_import_bo_data_with_key(bufmgr->module, bo, key, &error);
1030 /* LCOV_EXCL_START */
1031 TBM_ERR("tbm_module_import_bo_data_with_key failed. tbm_key:%d", key);
1034 /* LCOV_EXCL_STOP */
1037 // return the existed bo2 if bo->bo_data and bo2->bo_data is the same
1038 bo2 = tbm_bufmgr_internal_find_bo(bufmgr, bo);
1040 TBM_TRACE_BO("find bo(%p) ref(%d) key(%d) flag(%s) in list",
1041 bo2, bo2->ref_cnt, key, _tbm_flag_to_str(bo2->flags));
1044 _tbm_set_last_result(TBM_ERROR_NONE);
1045 _tbm_bufmgr_mutex_unlock();
1049 flags = tbm_bo_data_get_memory_types(bo->bo_data, &error);
1050 if (error != TBM_ERROR_NONE) {
1051 TBM_WRN("tbm_bo_data_get_memory_types filed. use the default flags:TBM_BO_DEFAULT.");
1052 flags = TBM_BO_DEFAULT;
1053 error = TBM_ERROR_NONE;
1056 _tbm_bufmgr_initialize_bo(bufmgr, bo, flags);
1058 TBM_TRACE_BO("import new bo(%p) ref(%d) key(%d) flag(%s) in list",
1059 bo, bo->ref_cnt, key, _tbm_flag_to_str(bo->flags));
1061 _tbm_set_last_result(TBM_ERROR_NONE);
1062 _tbm_bufmgr_mutex_unlock();
1067 _tbm_set_last_result(error);
1068 _tbm_bufmgr_mutex_unlock();
1074 tbm_bufmgr_internal_import_bo_with_fd(tbm_bufmgr bufmgr, tbm_fd fd)
1076 tbm_error_e error = TBM_ERROR_NONE;
1080 _tbm_bufmgr_mutex_lock();
1082 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
1084 _tbm_bufmgr_check_bo_cnt(bufmgr);
1086 bo = calloc(1, sizeof(struct _tbm_bo));
1088 /* LCOV_EXCL_START */
1089 TBM_ERR("memory allocationc failed.");
1091 /* LCOV_EXCL_STOP */
1094 bo->bo_data = tbm_module_import_bo_data_with_fd(bufmgr->module, bo, fd, &error);
1096 /* LCOV_EXCL_START */
1097 TBM_ERR("tbm_module_import_bo_data_with_fd failed. tbm_fd:%d", fd);
1100 /* LCOV_EXCL_STOP */
1103 // return the existed bo2 if bo->bo_data and bo2->bo_data is the same
1104 bo2 = tbm_bufmgr_internal_find_bo(bufmgr, bo);
1106 TBM_TRACE_BO("find bo(%p) ref(%d) fd(%d) flag(%s) in list",
1107 bo2, bo2->ref_cnt, fd, _tbm_flag_to_str(bo2->flags));
1110 _tbm_set_last_result(TBM_ERROR_NONE);
1111 _tbm_bufmgr_mutex_unlock();
1115 flags = tbm_bo_data_get_memory_types(bo->bo_data, &error);
1116 if (error != TBM_ERROR_NONE) {
1117 TBM_WRN("tbm_bo_data_get_memory_types filed. use the default flags:TBM_BO_DEFAULT.");
1118 flags = TBM_BO_DEFAULT;
1119 error = TBM_ERROR_NONE;
1122 TBM_TRACE_BO("import bo(%p) ref(%d) fd(%d) flag(%s)",
1123 bo, bo->ref_cnt, fd, _tbm_flag_to_str(bo->flags));
1125 _tbm_bufmgr_initialize_bo(bufmgr, bo, flags);
1127 _tbm_set_last_result(TBM_ERROR_NONE);
1128 _tbm_bufmgr_mutex_unlock();
1133 _tbm_set_last_result(error);
1134 _tbm_bufmgr_mutex_unlock();
1139 /* LCOV_EXCL_STOP */