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);
201 _tbm_bufmgr_init(int fd, int server)
203 tbm_error_e error = TBM_ERROR_NONE;
205 #ifdef TBM_BUFMGR_INIT_TIME
206 struct timeval start_tv, end_tv;
210 #ifdef TBM_BUFMGR_INIT_TIME
211 /* get the start tv */
212 gettimeofday(&start_tv, NULL);
217 /* LCOV_EXCL_START */
219 env = getenv("TBM_TRACE");
221 trace_mask = atoi(env);
222 TBM_DBG("TBM_TRACE=%s\n", env);
227 pthread_mutex_lock(&gLock);
229 _tbm_set_last_result(TBM_ERROR_NONE);
232 TBM_WRN("!!!!!WARNING:: The tbm_bufmgr_init DOSE NOT use argument fd ANYMORE.\n");
233 TBM_WRN("!!!!!WARNING:: IT WILL BE CHANGED like tbm_bufmgr_init(int fd) --> tbm_bufmgr_init(void).\n");
237 /* initialize buffer manager */
239 gBufMgr->ref_count++;
240 TBM_DBG("reuse tbm_bufmgr(%p) ref_count(%d) fd(%d)\n", gBufMgr, gBufMgr->ref_count, gBufMgr->fd);
241 pthread_mutex_unlock(&gLock);
245 TBM_DBG("bufmgr init\n");
247 /* allocate bufmgr */
248 gBufMgr = calloc(1, sizeof(struct _tbm_bufmgr));
250 TBM_ERR("error: fail to alloc bufmgr fd(%d)\n", fd);
251 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
252 pthread_mutex_unlock(&gLock);
258 /* set the display_server flag before loading the backend module */
260 TBM_INFO("The tbm_bufmgr(%p) is used by display server. Need to bind the native_display.\n", gBufMgr);
261 gBufMgr->display_server = 1;
264 /* load bufmgr priv from env */
265 gBufMgr->module = tbm_module_load(gBufMgr->fd);
266 if (!gBufMgr->module) {
267 TBM_ERR("error : Fail to load bufmgr backend\n");
268 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
271 pthread_mutex_unlock(&gLock);
276 /* check the essential capabilities of tbm_module */
277 gBufMgr->capabilities = tbm_module_get_capabilities(gBufMgr->module, &error);
278 if (gBufMgr->capabilities == TBM_BUFMGR_CAPABILITY_NONE) {
279 TBM_ERR("The capabilities of the backend module is TBM_BUFMGR_CAPABILITY_NONE.");
280 TBM_ERR("TBM_BUFMGR_CAPABILITY_SHARE_FD is the essential capability.");
281 tbm_module_unload(gBufMgr->module);
282 _tbm_set_last_result(error);
285 pthread_mutex_unlock(&gLock);
289 if (!(gBufMgr->capabilities & TBM_BUFMGR_CAPABILITY_SHARE_FD)) {
290 TBM_ERR("The capabilities of the backend module had no TBM_BUFMGR_CAPABILITY_SHARE_FD.");
291 TBM_ERR("The tbm backend has to get TBM_BUFMGR_CAPABILITY_SHARE_FD. ");
292 tbm_module_unload(gBufMgr->module);
293 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
296 pthread_mutex_unlock(&gLock);
302 gBufMgr->ref_count = 1;
304 TBM_INFO("create tizen bufmgr:%p ref_count:%d\n",
305 gBufMgr, gBufMgr->ref_count);
307 /* setup the bo_lock_type */
308 env = getenv("BUFMGR_LOCK_TYPE");
309 if (env && !strcmp(env, "always"))
310 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS;
311 else if (env && !strcmp(env, "none"))
312 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_NEVER;
313 else if (env && !strcmp(env, "once"))
314 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ONCE;
316 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS;
318 TBM_DBG("BUFMGR_LOCK_TYPE=%s\n", env ? env : "default:once");
320 /* intialize bo_list */
321 LIST_INITHEAD(&gBufMgr->bo_list);
323 /* intialize surf_list */
324 LIST_INITHEAD(&gBufMgr->surf_list);
326 /* intialize surf_queue_list */
327 LIST_INITHEAD(&gBufMgr->surf_queue_list);
329 /* intialize debug_key_list */
330 LIST_INITHEAD(&gBufMgr->debug_key_list);
332 #ifdef TBM_BUFMGR_INIT_TIME
334 gettimeofday(&end_tv, NULL);
335 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)));
338 pthread_mutex_unlock(&gLock);
344 tbm_bufmgr_init(int fd)
348 bufmgr = _tbm_bufmgr_init(fd, 0);
354 tbm_bufmgr_deinit(tbm_bufmgr bufmgr)
356 TBM_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
358 _tbm_bufmgr_mutex_lock();
359 pthread_mutex_lock(&gLock);
360 _tbm_set_last_result(TBM_ERROR_NONE);
363 TBM_ERR("gBufmgr already destroy: bufmgr:%p\n", bufmgr);
364 pthread_mutex_unlock(&gLock);
365 _tbm_bufmgr_mutex_unlock();
370 if (bufmgr->ref_count > 0) {
371 TBM_DBG("reduce a ref_count(%d) of tbm_bufmgr(%p)\n", bufmgr->ref_count, bufmgr);
372 pthread_mutex_unlock(&gLock);
373 _tbm_bufmgr_mutex_unlock();
377 /* destroy bo_list */
378 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
379 tbm_bo bo = NULL, tmp;
381 LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &bufmgr->bo_list, item_link) {
382 TBM_ERR("Un-freed bo(%p, ref:%d)\n", bo, bo->ref_cnt);
385 LIST_DELINIT(&bufmgr->bo_list);
388 /* destroy surf_list */
389 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
390 tbm_surface_h surf = NULL, tmp;
392 LIST_FOR_EACH_ENTRY_SAFE(surf, tmp, &bufmgr->surf_list, item_link) {
393 TBM_ERR("Un-freed surf(%p, ref:%d)\n", surf, surf->refcnt);
394 tbm_surface_destroy(surf);
396 LIST_DELINIT(&bufmgr->surf_list);
399 tbm_module_unload(bufmgr->module);
404 TBM_INFO("destroy tbm_bufmgr(%p)\n", bufmgr);
409 pthread_mutex_unlock(&gLock);
410 _tbm_bufmgr_mutex_unlock();
414 tbm_bufmgr_get_capability(tbm_bufmgr bufmgr)
416 unsigned int capabilities = TBM_BUFMGR_CAPABILITY_NONE;
418 _tbm_bufmgr_mutex_lock();
419 _tbm_set_last_result(TBM_ERROR_NONE);
421 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), TBM_BUFMGR_CAPABILITY_NONE);
422 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, TBM_BUFMGR_CAPABILITY_NONE);
424 capabilities = bufmgr->capabilities;
426 _tbm_bufmgr_mutex_unlock();
431 /* LCOV_EXCL_START */
433 tbm_bufmgr_debug_tbm_info_get(tbm_bufmgr bufmgr)
435 char app_name[255] = {0,}, title[512] = {0,};
436 tbm_surface_debug_data *debug_old_data = NULL;
444 pthread_mutex_lock(&gLock);
445 _tbm_set_last_result(TBM_ERROR_NONE);
447 if (!TBM_BUFMGR_IS_VALID(bufmgr) || (bufmgr != gBufMgr)) {
448 TBM_ERR("invalid bufmgr\n");
449 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
450 pthread_mutex_unlock(&gLock);
456 TBM_ERR("Fail to allocate the string.\n");
457 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
458 pthread_mutex_unlock(&gLock);
462 TBM_SNRPRINTF(str, len, c, "\n");
463 pid = syscall(SYS_getpid);
464 _tbm_util_get_appname_from_pid(pid, app_name);
465 _tbm_util_get_appname_brief(app_name);
466 TBM_SNRPRINTF(str, len, c, "===========================================TBM DEBUG: %s(%ld)===========================================\n",
469 snprintf(title, 255, "%s", "no surface refcnt width height bpp size n_b n_p flags format app_name ");
471 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
472 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
473 strncat(title, " ", MAX_SIZE_N(title));
474 strncat(title, debug_old_data->key, MAX_SIZE_N(title));
478 TBM_SNRPRINTF(str, len, c, "[tbm_surface information]\n");
479 TBM_SNRPRINTF(str, len, c, "%s\n", title);
481 /* show the tbm_surface information in surf_list */
482 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
483 tbm_surface_h surf = NULL;
486 LIST_FOR_EACH_ENTRY(surf, &bufmgr->surf_list, item_link) {
487 char data[512] = {0,};
488 unsigned int surf_pid = 0;
491 surf_pid = _tbm_surface_internal_get_debug_pid(surf);
493 /* if pid is null, set the self_pid */
494 surf_pid = syscall(SYS_getpid);;
497 memset(app_name, 0x0, 255 * sizeof(char));
498 if (geteuid() == 0) {
499 _tbm_util_get_appname_from_pid(surf_pid, app_name);
500 _tbm_util_get_appname_brief(app_name);
502 snprintf(app_name, sizeof(app_name), "%d", surf_pid);
505 snprintf(data, 255, "%-3d %-11p %-5d %-6u %-7u %-4u %-7u %-3d %-3d %-8d %-9s %-22s",
512 surf->info.size / 1024,
516 _tbm_surface_internal_format_to_str(surf->info.format) + 11,
519 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
520 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
523 strncat(data, " ", MAX_SIZE_N(title));
525 value = _tbm_surface_internal_get_debug_data(surf, debug_old_data->key);
527 strncat(data, value, MAX_SIZE_N(title));
529 strncat(data, "none", MAX_SIZE_N(title));
532 TBM_SNRPRINTF(str, len, c, "%s\n", data);
534 for (i = 0; i < surf->num_bos; i++) {
535 size = tbm_bo_data_get_size(surf->bos[i]->bo_data, &error);
536 if (error != TBM_ERROR_NONE)
537 TBM_WRN("fail to get the size of bo.");
538 TBM_SNRPRINTF(str, len, c, " bo:%-12p %-26d%-10d\n",
540 surf->bos[i]->ref_cnt,
545 TBM_SNRPRINTF(str, len, c, " no tbm_surfaces.\n");
546 TBM_SNRPRINTF(str, len, c, "\n");
548 TBM_SNRPRINTF(str, len, c, "[tbm_bo information]\n");
549 TBM_SNRPRINTF(str, len, c, "no bo refcnt size lock_cnt map_cnt flags surface name\n");
551 /* show the tbm_bo information in bo_list */
552 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
557 LIST_FOR_EACH_ENTRY(bo, &bufmgr->bo_list, item_link) {
558 size = tbm_bo_data_get_size(bo->bo_data, &error);
559 if (error != TBM_ERROR_NONE)
560 TBM_WRN("fail to get the size of bo.");
561 key = tbm_bo_data_export_key(bo->bo_data, &error);
562 if (error != TBM_ERROR_NONE)
563 TBM_WRN("fail to get the tdm_key of bo.");
564 TBM_SNRPRINTF(str, len, c, "%-3d %-11p %-5d %-7d %-6d %-5u %-7d %-11p %-4d\n",
576 TBM_SNRPRINTF(str, len, c, "no tbm_bos.\n");
577 TBM_SNRPRINTF(str, len, c, "\n");
579 TBM_SNRPRINTF(str, len, c, "========================================================================================================\n");
581 pthread_mutex_unlock(&gLock);
587 tbm_bufmgr_debug_show(tbm_bufmgr bufmgr)
590 str = tbm_bufmgr_debug_tbm_info_get(bufmgr);
598 tbm_bufmgr_debug_trace(tbm_bufmgr bufmgr, int onoff)
600 _tbm_bufmgr_mutex_lock();
601 _tbm_set_last_result(TBM_ERROR_NONE);
603 TBM_BUFMGR_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
604 TBM_BUFMGR_RETURN_IF_FAIL(bufmgr == gBufMgr);
607 TBM_LOG_D("bufmgr=%p onoff=%d\n", bufmgr, onoff);
611 _tbm_bufmgr_mutex_unlock();
615 tbm_bufmgr_debug_set_trace_mask(tbm_bufmgr bufmgr, tbm_bufmgr_debug_trace_mask mask, int set)
617 _tbm_bufmgr_mutex_lock();
618 _tbm_set_last_result(TBM_ERROR_NONE);
620 TBM_BUFMGR_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
621 TBM_BUFMGR_RETURN_IF_FAIL(bufmgr == gBufMgr);
626 TBM_INFO("bufmgr=%p sets the trace_mask=%d\n", bufmgr, mask);
627 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_BO)
628 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_BO");
629 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL)
630 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL");
631 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE)
632 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE");
633 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE)
634 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE");
635 } else if (set == 0) {
638 TBM_INFO("bufmgr=%p unsets the trace_mask=%d\n", bufmgr, mask);
639 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_BO)
640 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_BO");
641 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL)
642 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL");
643 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE)
644 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE");
645 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE)
646 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE");
648 TBM_WRN("set value is wrong.(set=%d)", set);
651 _tbm_bufmgr_mutex_unlock();
655 tbm_bufmgr_debug_dump_set_scale(double scale)
657 pthread_mutex_lock(&gLock);
658 _tbm_set_last_result(TBM_ERROR_NONE);
659 scale_factor = scale;
660 pthread_mutex_unlock(&gLock);
664 tbm_bufmgr_debug_get_ref_count(void)
668 pthread_mutex_lock(&gLock);
670 _tbm_set_last_result(TBM_ERROR_NONE);
672 refcnt = (gBufMgr) ? gBufMgr->ref_count : 0;
674 pthread_mutex_unlock(&gLock);
680 tbm_bufmgr_debug_queue_dump(char *path, int count, int onoff)
682 pthread_mutex_lock(&gLock);
683 _tbm_set_last_result(TBM_ERROR_NONE);
686 TBM_DBG("count=%d onoff=%d\n", count, onoff);
688 tbm_surface_internal_dump_end();
693 TBM_ERR("path is null");
694 pthread_mutex_unlock(&gLock);
697 TBM_DBG("path=%s count=%d onoff=%d\n", path, count, onoff);
699 if (_tbm_util_get_max_surface_size(&w, &h) == 0) {
700 TBM_ERR("Fail to get tbm_surface size.\n");
701 pthread_mutex_unlock(&gLock);
705 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
711 pthread_mutex_unlock(&gLock);
717 tbm_bufmgr_debug_dump_all(char *path)
720 tbm_surface_h surface = NULL;
722 pthread_mutex_lock(&gLock);
723 _tbm_set_last_result(TBM_ERROR_NONE);
726 TBM_ERR("path is null.\n");
727 pthread_mutex_unlock(&gLock);
731 TBM_DBG("path=%s\n", path);
733 count = _tbm_util_get_max_surface_size(&w, &h);
735 TBM_ERR("No tbm_surface.\n");
736 pthread_mutex_unlock(&gLock);
740 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
743 LIST_FOR_EACH_ENTRY(surface, &gBufMgr->surf_list, item_link)
744 tbm_surface_internal_dump_buffer(surface, "dump_all");
746 tbm_surface_internal_dump_end();
748 pthread_mutex_unlock(&gLock);
753 /* internal function */
755 _tbm_bufmgr_get_bufmgr(void)
761 tbm_bufmgr_bind_native_display(tbm_bufmgr bufmgr, void *native_display)
765 _tbm_bufmgr_mutex_lock();
766 _tbm_set_last_result(TBM_ERROR_NONE);
768 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), 0);
770 error = tbm_module_bind_native_display(bufmgr->module, native_display);
771 if (error != TBM_ERROR_NONE) {
772 _tbm_set_last_result(error);
773 _tbm_bufmgr_mutex_unlock();
775 if (error == TBM_ERROR_NOT_SUPPORTED) {
776 TBM_WRN("Not supported, so skip: tbm_bufmgr(%p) native_display(%p)", bufmgr, native_display);
783 TBM_INFO("tbm_bufmgr(%p) native_display(%p)\n", bufmgr, native_display);
785 _tbm_bufmgr_mutex_unlock();
791 tbm_bufmgr_server_init(void)
795 bufmgr = _tbm_bufmgr_init(-1, 1);
801 tbm_bufmgr_set_bo_lock_type(tbm_bufmgr bufmgr, tbm_bufmgr_bo_lock_type bo_lock_type)
803 _tbm_bufmgr_mutex_lock();
804 _tbm_set_last_result(TBM_ERROR_NONE);
806 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
807 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, 0);
809 pthread_mutex_lock(&gLock);
810 gBufMgr->bo_lock_type = bo_lock_type;
811 pthread_mutex_unlock(&gLock);
813 TBM_INFO("The bo_lock_type of the bo is %d\n", bo_lock_type);
815 _tbm_bufmgr_mutex_unlock();
821 int tbm_bufmgr_get_fd_limit(void)
825 if (getrlimit(RLIMIT_NOFILE, &lim))
828 return (int)lim.rlim_cur;
831 tbm_bufmgr tbm_bufmgr_get(void)
838 tbm_bufmgr_internal_find_bo(tbm_bufmgr bufmgr, tbm_bo bo)
842 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), NULL);
843 TBM_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, NULL);
845 if (LIST_IS_EMPTY(&bufmgr->bo_list))
848 LIST_FOR_EACH_ENTRY(bo2, &bufmgr->bo_list, item_link) {
849 if (tbm_module_compare_bo_data(bufmgr->module, bo2->bo_data, bo->bo_data))
857 tbm_bufmgr_internal_alloc_bo(tbm_bufmgr bufmgr, int size, int flags, tbm_error_e *error)
860 tbm_bo_data *bo_data;
862 _tbm_bufmgr_check_bo_cnt(bufmgr);
864 bo = calloc(1, sizeof(struct _tbm_bo));
866 /* LCOV_EXCL_START */
867 TBM_ERR("memory allocationc failed.");
868 *error = TBM_ERROR_OUT_OF_MEMORY;
873 bo_data = tbm_module_alloc_bo_data(bufmgr->module, bo, size, flags, error);
875 /* LCOV_EXCL_START */
876 TBM_ERR("tbm_module_alloc_bo_data failed. size:%d flags:%s error:%d", size, _tbm_flag_to_str(flags), *error);
881 bo->bo_data = bo_data;
883 _tbm_bufmgr_initialize_bo(bufmgr, bo, flags);
889 /* LCOV_EXCL_START */
892 tbm_bufmgr_internal_alloc_bo_with_format(tbm_bufmgr bufmgr, int format, int bo_idx, int width,
893 int height, int bpp, tbm_bo_memory_type flags, tbm_error_e *error)
897 _tbm_bufmgr_mutex_lock();
898 _tbm_set_last_result(TBM_ERROR_NONE);
900 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
902 _tbm_bufmgr_check_bo_cnt(bufmgr);
904 bo = calloc(1, sizeof(struct _tbm_bo));
906 /* LCOV_EXCL_START */
907 TBM_ERR("memory allocationc failed.");
908 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
913 bo->bo_data = tbm_module_alloc_bo_data_with_format(bufmgr->module, format, bo_idx, width, height, bpp, flags, error);
915 /* LCOV_EXCL_START */
916 _tbm_set_last_result(*error);
921 _tbm_bufmgr_initialize_bo(bufmgr, bo, flags);
923 _tbm_bufmgr_mutex_unlock();
930 _tbm_bufmgr_mutex_unlock();
936 tbm_bufmgr_internal_alloc_bo_with_bo_data(tbm_bufmgr bufmgr, tbm_bo_data *bo_data, int flags)
938 tbm_bo bo, bo2 = NULL;
940 _tbm_bufmgr_mutex_lock();
941 _tbm_set_last_result(TBM_ERROR_NONE);
943 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
944 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bo_data, 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);
953 _tbm_bufmgr_mutex_unlock();
957 bo->bo_data = bo_data;
958 bo->get_from_surface_data = 1;
960 // return an existed bo if the bo is already created with the same bo_data.
961 bo2 = tbm_bufmgr_internal_find_bo(bufmgr, bo);
965 _tbm_bufmgr_mutex_unlock();
969 _tbm_bufmgr_initialize_bo(bufmgr, bo, flags);
971 TBM_TRACE_BO("bo(%p) refcnt(%d), flag(%s)", bo, bo->ref_cnt, _tbm_flag_to_str(bo->flags));
973 _tbm_bufmgr_mutex_unlock();
979 tbm_bufmgr_internal_import_bo_with_key(tbm_bufmgr bufmgr, unsigned int key, tbm_error_e *error)
984 _tbm_bufmgr_check_bo_cnt(bufmgr);
986 bo = calloc(1, sizeof(struct _tbm_bo));
988 /* LCOV_EXCL_START */
989 TBM_ERR("memory allocationc failed.");
990 *error = TBM_ERROR_OUT_OF_MEMORY;
995 bo->bo_data = tbm_module_import_bo_data_with_key(bufmgr->module, bo, key, error);
997 /* LCOV_EXCL_START */
998 TBM_ERR("tbm_module_import_bo_data_with_key failed. tbm_key:%d", key);
1001 /* LCOV_EXCL_STOP */
1004 // return the existed bo2 if bo->bo_data and bo2->bo_data is the same
1005 bo2 = tbm_bufmgr_internal_find_bo(bufmgr, bo);
1007 TBM_TRACE_BO("find bo(%p) ref(%d) key(%d) flag(%s) in list",
1008 bo2, bo2->ref_cnt, key, _tbm_flag_to_str(bo2->flags));
1014 flags = tbm_bo_data_get_memory_types(bo->bo_data, error);
1015 if (*error != TBM_ERROR_NONE) {
1016 TBM_ERR("fail to get the bo flags(memory_types)");
1017 flags = TBM_BO_DEFAULT;
1020 _tbm_bufmgr_initialize_bo(bufmgr, bo, flags);
1026 tbm_bufmgr_internal_import_bo_with_fd(tbm_bufmgr bufmgr, tbm_fd fd, tbm_error_e *error)
1031 _tbm_bufmgr_check_bo_cnt(bufmgr);
1033 bo = calloc(1, sizeof(struct _tbm_bo));
1035 /* LCOV_EXCL_START */
1036 TBM_ERR("memory allocationc failed.");
1037 *error = TBM_ERROR_OUT_OF_MEMORY;
1039 /* LCOV_EXCL_STOP */
1042 bo->bo_data = tbm_module_import_bo_data_with_fd(bufmgr->module, bo, fd, error);
1044 /* LCOV_EXCL_START */
1045 TBM_ERR("tbm_module_import_bo_data_with_fd failed. tbm_fd:%d", fd);
1048 /* LCOV_EXCL_STOP */
1051 // return the existed bo2 if bo->bo_data and bo2->bo_data is the same
1052 bo2 = tbm_bufmgr_internal_find_bo(bufmgr, bo);
1054 TBM_TRACE_BO("find bo(%p) ref(%d) fd(%d) flag(%s) in list",
1055 bo2, bo2->ref_cnt, fd, _tbm_flag_to_str(bo2->flags));
1061 flags = tbm_bo_data_get_memory_types(bo->bo_data, error);
1062 if (*error != TBM_ERROR_NONE) {
1063 TBM_ERR("fail to get the bo flags(memory_types)");
1064 flags = TBM_BO_DEFAULT;
1067 _tbm_bufmgr_initialize_bo(bufmgr, bo, flags);
1072 /* LCOV_EXCL_STOP */