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);
54 static char *_tbm_bufmgr_debug_tbm_info_get(tbm_bufmgr bufmgr, tbm_error_e *error);
56 //#define TBM_BUFMGR_INIT_TIME
58 #define MAX_SIZE_N(dest) (sizeof(dest) - strlen(dest) - 1)
61 #define TBM_BUFMGR_RETURN_IF_FAIL(cond) {\
63 TBM_ERR("'%s' failed.\n", #cond);\
64 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
65 _tbm_bufmgr_mutex_unlock();\
70 #define TBM_BUFMGR_RETURN_VAL_IF_FAIL(cond, val) {\
72 TBM_ERR("'%s' failed.\n", #cond);\
73 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
74 _tbm_bufmgr_mutex_unlock();\
79 #define TBM_BUFMGR_RETURN_VAL_SET_ERR_IF_FAIL(cond, val, error, error_type) {\
81 TBM_ERR("'%s' failed.\n", #cond);\
83 _tbm_bufmgr_mutex_unlock();\
91 _tbm_bufmgr_check_bo_cnt(tbm_bufmgr bufmgr)
93 static int last_chk_bo_cnt = 0;
95 tbm_error_e error = TBM_ERROR_NONE;
97 if ((bufmgr->bo_cnt >= 500) && ((bufmgr->bo_cnt % 20) == 0) &&
98 (bufmgr->bo_cnt > last_chk_bo_cnt)) {
99 TBM_DBG("============TBM BO CNT DEBUG: bo_cnt=%d\n", bufmgr->bo_cnt);
100 str = _tbm_bufmgr_debug_tbm_info_get(bufmgr, &error);
106 last_chk_bo_cnt = bufmgr->bo_cnt;
111 _tbm_bufmgr_initialize_bo(tbm_bufmgr bufmgr, tbm_bo bo, int flags)
115 bo->magic = TBM_BO_MAGIC;
118 LIST_INITHEAD(&bo->user_data_list);
121 LIST_ADD(&bo->item_link, &bufmgr->bo_list);
125 _tbm_bufmgr_mutex_lock(void)
127 pthread_mutex_lock(&tbm_bufmgr_lock);
131 _tbm_bufmgr_mutex_unlock(void)
133 pthread_mutex_unlock(&tbm_bufmgr_lock);
137 _tbm_util_get_max_surface_size(int *w, int *h)
139 tbm_surface_info_s info;
140 tbm_surface_h surface = NULL;
146 if (gBufMgr == NULL || LIST_IS_EMPTY(&gBufMgr->surf_list))
149 LIST_FOR_EACH_ENTRY(surface, &gBufMgr->surf_list, item_link) {
150 if (tbm_surface_get_info(surface, &info) == TBM_SURFACE_ERROR_NONE) {
154 if (*h < info.height)
163 _tbm_util_get_appname_brief(char *brief)
167 char temp[255] = {0,};
168 char *saveptr = NULL;
170 token = strtok_r(brief, delim, &saveptr);
172 while (token != NULL) {
173 memset(temp, 0x00, 255 * sizeof(char));
174 strncpy(temp, token, 254 * sizeof(char));
175 token = strtok_r(NULL, delim, &saveptr);
178 snprintf(brief, sizeof(temp), "%s", temp);
182 _tbm_util_get_appname_from_pid(long pid, char *str)
184 char fn_cmdline[255] = {0, }, cmdline[255];
188 if (pid <= 0) return;
190 snprintf(fn_cmdline, sizeof(fn_cmdline), "/proc/%ld/cmdline", pid);
192 fp = fopen(fn_cmdline, "r");
194 TBM_ERR("cannot file open %s\n", fn_cmdline);
198 if (!fgets(cmdline, 255, fp)) {
199 TBM_ERR("fail to get appname for pid(%ld)\n", pid);
206 len = strlen(cmdline);
208 memset(cmdline, 0x00, 255);
212 snprintf(str, sizeof(cmdline), "%s", cmdline);
218 _tbm_bufmgr_init(int fd, int server)
220 tbm_error_e error = TBM_ERROR_NONE;
222 #ifdef TBM_BUFMGR_INIT_TIME
223 struct timeval start_tv, end_tv;
227 #ifdef TBM_BUFMGR_INIT_TIME
228 /* get the start tv */
229 gettimeofday(&start_tv, NULL);
234 /* LCOV_EXCL_START */
236 env = getenv("TBM_TRACE");
238 trace_mask = atoi(env);
239 TBM_DBG("TBM_TRACE=%s\n", env);
244 pthread_mutex_lock(&gLock);
246 _tbm_set_last_result(TBM_ERROR_NONE);
249 TBM_WRN("!!!!!WARNING:: The tbm_bufmgr_init DOSE NOT use argument fd ANYMORE.\n");
250 TBM_WRN("!!!!!WARNING:: IT WILL BE CHANGED like tbm_bufmgr_init(int fd) --> tbm_bufmgr_init(void).\n");
254 /* initialize buffer manager */
256 gBufMgr->ref_count++;
257 TBM_DBG("reuse tbm_bufmgr(%p) ref_count(%d) fd(%d)\n", gBufMgr, gBufMgr->ref_count, gBufMgr->fd);
258 pthread_mutex_unlock(&gLock);
262 TBM_DBG("bufmgr init\n");
264 /* allocate bufmgr */
265 gBufMgr = calloc(1, sizeof(struct _tbm_bufmgr));
267 TBM_ERR("error: fail to alloc bufmgr fd(%d)\n", fd);
268 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
269 pthread_mutex_unlock(&gLock);
275 /* set the display_server flag before loading the backend module */
277 TBM_INFO("The tbm_bufmgr(%p) is used by display server. Need to bind the native_display.\n", gBufMgr);
278 gBufMgr->display_server = 1;
281 /* load bufmgr priv from env */
282 gBufMgr->module = tbm_module_load(gBufMgr->fd);
283 if (!gBufMgr->module) {
284 TBM_ERR("error : Fail to load bufmgr backend\n");
285 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
288 pthread_mutex_unlock(&gLock);
293 /* check the essential capabilities of tbm_module */
294 gBufMgr->capabilities = tbm_module_get_capabilities(gBufMgr->module, &error);
295 if (gBufMgr->capabilities == TBM_BUFMGR_CAPABILITY_NONE) {
296 TBM_ERR("The capabilities of the backend module is TBM_BUFMGR_CAPABILITY_NONE.");
297 TBM_ERR("TBM_BUFMGR_CAPABILITY_SHARE_FD is the essential capability.");
298 tbm_module_unload(gBufMgr->module);
299 _tbm_set_last_result(error);
302 pthread_mutex_unlock(&gLock);
306 if (!(gBufMgr->capabilities & TBM_BUFMGR_CAPABILITY_SHARE_FD)) {
307 TBM_ERR("The capabilities of the backend module had no TBM_BUFMGR_CAPABILITY_SHARE_FD.");
308 TBM_ERR("The tbm backend has to get TBM_BUFMGR_CAPABILITY_SHARE_FD. ");
309 tbm_module_unload(gBufMgr->module);
310 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
313 pthread_mutex_unlock(&gLock);
319 gBufMgr->ref_count = 1;
321 TBM_INFO("create tizen bufmgr:%p ref_count:%d\n",
322 gBufMgr, gBufMgr->ref_count);
324 /* setup the bo_lock_type */
325 env = getenv("BUFMGR_LOCK_TYPE");
326 if (env && !strcmp(env, "always"))
327 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS;
328 else if (env && !strcmp(env, "none"))
329 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_NEVER;
330 else if (env && !strcmp(env, "once"))
331 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ONCE;
333 gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS;
335 TBM_DBG("BUFMGR_LOCK_TYPE=%s\n", env ? env : "default:once");
337 /* intialize bo_list */
338 LIST_INITHEAD(&gBufMgr->bo_list);
340 /* intialize surf_list */
341 LIST_INITHEAD(&gBufMgr->surf_list);
343 /* intialize surf_queue_list */
344 LIST_INITHEAD(&gBufMgr->surf_queue_list);
346 /* intialize debug_key_list */
347 LIST_INITHEAD(&gBufMgr->debug_key_list);
349 #ifdef TBM_BUFMGR_INIT_TIME
351 gettimeofday(&end_tv, NULL);
352 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)));
355 pthread_mutex_unlock(&gLock);
361 tbm_bufmgr_init(int fd)
365 bufmgr = _tbm_bufmgr_init(fd, 0);
371 tbm_bufmgr_deinit(tbm_bufmgr bufmgr)
373 TBM_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
375 pthread_mutex_lock(&gLock);
376 _tbm_bufmgr_mutex_lock();
377 _tbm_set_last_result(TBM_ERROR_NONE);
380 TBM_ERR("gBufmgr already destroy: bufmgr:%p\n", bufmgr);
381 _tbm_bufmgr_mutex_unlock();
382 pthread_mutex_unlock(&gLock);
387 if (bufmgr->ref_count > 0) {
388 TBM_DBG("reduce a ref_count(%d) of tbm_bufmgr(%p)\n", bufmgr->ref_count, bufmgr);
389 _tbm_bufmgr_mutex_unlock();
390 pthread_mutex_unlock(&gLock);
394 /* destroy bo_list */
395 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
396 tbm_bo bo = NULL, tmp;
398 LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &bufmgr->bo_list, item_link) {
399 TBM_ERR("Un-freed bo(%p, ref:%d)\n", bo, bo->ref_cnt);
402 LIST_DELINIT(&bufmgr->bo_list);
405 /* destroy surf_list */
406 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
407 tbm_surface_h surf = NULL, tmp;
409 LIST_FOR_EACH_ENTRY_SAFE(surf, tmp, &bufmgr->surf_list, item_link) {
410 TBM_ERR("Un-freed surf(%p, ref:%d)\n", surf, surf->refcnt);
411 tbm_surface_destroy(surf);
413 LIST_DELINIT(&bufmgr->surf_list);
416 tbm_module_unload(bufmgr->module);
421 TBM_INFO("destroy tbm_bufmgr(%p)\n", bufmgr);
426 _tbm_bufmgr_mutex_unlock();
427 pthread_mutex_unlock(&gLock);
431 tbm_bufmgr_get_capability(tbm_bufmgr bufmgr)
433 unsigned int capabilities = TBM_BUFMGR_CAPABILITY_NONE;
435 _tbm_bufmgr_mutex_lock();
436 _tbm_set_last_result(TBM_ERROR_NONE);
438 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), TBM_BUFMGR_CAPABILITY_NONE);
439 TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, TBM_BUFMGR_CAPABILITY_NONE);
441 capabilities = bufmgr->capabilities;
443 _tbm_bufmgr_mutex_unlock();
448 /* LCOV_EXCL_START */
450 _tbm_bufmgr_debug_tbm_info_get(tbm_bufmgr bufmgr, tbm_error_e *error)
452 char app_name[255] = {0,}, title[512] = {0,};
453 tbm_surface_debug_data *debug_old_data = NULL;
460 if (!TBM_BUFMGR_IS_VALID(bufmgr) || (bufmgr != gBufMgr)) {
461 TBM_ERR("invalid bufmgr\n");
462 *error = TBM_ERROR_INVALID_PARAMETER;
468 TBM_ERR("Fail to allocate the string.\n");
469 *error = TBM_ERROR_OUT_OF_MEMORY;
473 TBM_SNRPRINTF(str, len, c, "\n");
474 pid = syscall(SYS_getpid);
475 _tbm_util_get_appname_from_pid(pid, app_name);
476 _tbm_util_get_appname_brief(app_name);
477 TBM_SNRPRINTF(str, len, c, "===========================================TBM DEBUG: %s(%ld)===========================================\n",
480 snprintf(title, 255, "%s", "no surface refcnt width height bpp size n_b n_p flags format app_name ");
482 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
483 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
484 strncat(title, " ", MAX_SIZE_N(title));
485 strncat(title, debug_old_data->key, MAX_SIZE_N(title));
489 TBM_SNRPRINTF(str, len, c, "[tbm_surface information]\n");
490 TBM_SNRPRINTF(str, len, c, "%s\n", title);
492 /* show the tbm_surface information in surf_list */
493 if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
494 tbm_surface_h surf = NULL;
497 LIST_FOR_EACH_ENTRY(surf, &bufmgr->surf_list, item_link) {
498 char data[512] = {0,};
499 unsigned int surf_pid = 0;
502 surf_pid = _tbm_surface_internal_get_debug_pid(surf);
504 /* if pid is null, set the self_pid */
505 surf_pid = syscall(SYS_getpid);;
508 memset(app_name, 0x0, 255 * sizeof(char));
509 if (geteuid() == 0) {
510 _tbm_util_get_appname_from_pid(surf_pid, app_name);
511 _tbm_util_get_appname_brief(app_name);
513 snprintf(app_name, sizeof(app_name), "%d", surf_pid);
516 snprintf(data, 255, "%-3d %-11p %-5d %-6u %-7u %-4u %-7u %-3d %-3d %-8d %-9s %-22s",
523 surf->info.size / 1024,
527 _tbm_surface_internal_format_to_str(surf->info.format) + 11,
530 if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
531 LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
534 strncat(data, " ", MAX_SIZE_N(title));
536 value = _tbm_surface_internal_get_debug_data(surf, debug_old_data->key);
538 strncat(data, value, MAX_SIZE_N(title));
540 strncat(data, "none", MAX_SIZE_N(title));
543 TBM_SNRPRINTF(str, len, c, "%s\n", data);
545 for (i = 0; i < surf->num_bos; i++) {
546 size = tbm_bo_data_get_size(surf->bos[i]->bo_data, error);
547 if (error != TBM_ERROR_NONE)
548 TBM_WRN("fail to get the size of bo.");
549 TBM_SNRPRINTF(str, len, c, " bo:%-12p %-26d%-10d\n",
551 surf->bos[i]->ref_cnt,
556 TBM_SNRPRINTF(str, len, c, " no tbm_surfaces.\n");
557 TBM_SNRPRINTF(str, len, c, "\n");
559 TBM_SNRPRINTF(str, len, c, "[tbm_bo information]\n");
560 TBM_SNRPRINTF(str, len, c, "no bo refcnt size lock_cnt map_cnt flags surface name\n");
562 /* show the tbm_bo information in bo_list */
563 if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
568 LIST_FOR_EACH_ENTRY(bo, &bufmgr->bo_list, item_link) {
569 size = tbm_bo_data_get_size(bo->bo_data, error);
570 if (error != TBM_ERROR_NONE)
571 TBM_WRN("fail to get the size of bo.");
572 key = tbm_bo_data_export_key(bo->bo_data, error);
573 if (error != TBM_ERROR_NONE)
574 TBM_WRN("fail to get the tdm_key of bo.");
575 TBM_SNRPRINTF(str, len, c, "%-3d %-11p %-5d %-7d %-6d %-5u %-7d %-11p %-4d\n",
587 TBM_SNRPRINTF(str, len, c, "no tbm_bos.\n");
588 TBM_SNRPRINTF(str, len, c, "\n");
590 TBM_SNRPRINTF(str, len, c, "========================================================================================================\n");
596 tbm_bufmgr_debug_tbm_info_get(tbm_bufmgr bufmgr)
599 tbm_error_e error = TBM_ERROR_NONE;
601 pthread_mutex_lock(&gLock);
602 _tbm_set_last_result(TBM_ERROR_NONE);
604 str = _tbm_bufmgr_debug_tbm_info_get(bufmgr, &error);
606 TBM_ERR("tbm_bufmgr_internal_debug_tbm_info_get failed.");
607 _tbm_set_last_result(error);
608 pthread_mutex_unlock(&gLock);
612 _tbm_set_last_result(error);
613 pthread_mutex_unlock(&gLock);
619 tbm_bufmgr_debug_show(tbm_bufmgr bufmgr)
622 str = tbm_bufmgr_debug_tbm_info_get(bufmgr);
630 tbm_bufmgr_debug_trace(tbm_bufmgr bufmgr, int onoff)
632 _tbm_bufmgr_mutex_lock();
633 _tbm_set_last_result(TBM_ERROR_NONE);
635 TBM_BUFMGR_RETURN_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr));
636 TBM_BUFMGR_RETURN_IF_FAIL(bufmgr == gBufMgr);
639 TBM_LOG_D("bufmgr=%p onoff=%d\n", bufmgr, onoff);
643 _tbm_bufmgr_mutex_unlock();
647 tbm_bufmgr_debug_set_trace_mask(tbm_bufmgr bufmgr, tbm_bufmgr_debug_trace_mask mask, int set)
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);
658 TBM_INFO("bufmgr=%p sets the trace_mask=%d\n", bufmgr, mask);
659 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_BO)
660 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_BO");
661 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL)
662 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL");
663 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE)
664 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE");
665 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE)
666 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE");
667 } else if (set == 0) {
670 TBM_INFO("bufmgr=%p unsets the trace_mask=%d\n", bufmgr, mask);
671 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_BO)
672 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_BO");
673 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL)
674 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_INTERNAL");
675 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE)
676 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE");
677 if (trace_mask&TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE)
678 TBM_INFO(" TBM_BUFGMR_DEBUG_TRACE_SURFACE_QUEUE");
680 TBM_WRN("set value is wrong.(set=%d)", set);
683 _tbm_bufmgr_mutex_unlock();
687 tbm_bufmgr_debug_dump_set_scale(double scale)
689 pthread_mutex_lock(&gLock);
690 _tbm_set_last_result(TBM_ERROR_NONE);
691 scale_factor = scale;
692 pthread_mutex_unlock(&gLock);
696 tbm_bufmgr_debug_get_ref_count(void)
700 pthread_mutex_lock(&gLock);
702 _tbm_set_last_result(TBM_ERROR_NONE);
704 refcnt = (gBufMgr) ? gBufMgr->ref_count : 0;
706 pthread_mutex_unlock(&gLock);
712 tbm_bufmgr_debug_queue_dump(char *path, int count, int onoff)
714 pthread_mutex_lock(&gLock);
715 _tbm_set_last_result(TBM_ERROR_NONE);
718 TBM_DBG("count=%d onoff=%d\n", count, onoff);
720 tbm_surface_internal_dump_end();
725 TBM_ERR("path is null");
726 pthread_mutex_unlock(&gLock);
729 TBM_DBG("path=%s count=%d onoff=%d\n", path, count, onoff);
731 if (_tbm_util_get_max_surface_size(&w, &h) == 0) {
732 TBM_ERR("Fail to get tbm_surface size.\n");
733 pthread_mutex_unlock(&gLock);
737 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
743 pthread_mutex_unlock(&gLock);
749 tbm_bufmgr_debug_dump_all(char *path)
752 tbm_surface_h surface = NULL;
754 pthread_mutex_lock(&gLock);
755 _tbm_set_last_result(TBM_ERROR_NONE);
758 TBM_ERR("path is null.\n");
759 pthread_mutex_unlock(&gLock);
763 TBM_DBG("path=%s\n", path);
765 count = _tbm_util_get_max_surface_size(&w, &h);
767 TBM_ERR("No tbm_surface.\n");
768 pthread_mutex_unlock(&gLock);
772 tbm_surface_internal_dump_with_scale_start(path, w, h, count, scale_factor);
775 LIST_FOR_EACH_ENTRY(surface, &gBufMgr->surf_list, item_link)
776 tbm_surface_internal_dump_buffer(surface, "dump_all");
778 tbm_surface_internal_dump_end();
780 pthread_mutex_unlock(&gLock);
785 /* internal function */
787 _tbm_bufmgr_get_bufmgr(void)
793 tbm_bufmgr_bind_native_display(tbm_bufmgr bufmgr, void *native_display)
797 _tbm_bufmgr_mutex_lock();
798 _tbm_set_last_result(TBM_ERROR_NONE);
800 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), 0);
802 error = tbm_module_bind_native_display(bufmgr->module, native_display);
803 if (error != TBM_ERROR_NONE) {
804 _tbm_set_last_result(error);
805 _tbm_bufmgr_mutex_unlock();
807 if (error == TBM_ERROR_NOT_SUPPORTED) {
808 TBM_WRN("Not supported, so skip: tbm_bufmgr(%p) native_display(%p)", bufmgr, native_display);
815 TBM_INFO("tbm_bufmgr(%p) native_display(%p)\n", bufmgr, native_display);
817 _tbm_bufmgr_mutex_unlock();
823 tbm_bufmgr_server_init(void)
827 bufmgr = _tbm_bufmgr_init(-1, 1);
833 tbm_bufmgr_set_bo_lock_type(tbm_bufmgr bufmgr, tbm_bufmgr_bo_lock_type bo_lock_type)
835 pthread_mutex_lock(&gLock);
836 _tbm_bufmgr_mutex_lock();
838 _tbm_set_last_result(TBM_ERROR_NONE);
840 TBM_GOTO_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), failed);
841 TBM_GOTO_VAL_IF_FAIL(bufmgr == gBufMgr, failed);
843 gBufMgr->bo_lock_type = bo_lock_type;
845 TBM_INFO("The bo_lock_type of the bo is %d\n", bo_lock_type);
847 _tbm_bufmgr_mutex_unlock();
848 pthread_mutex_unlock(&gLock);
853 _tbm_bufmgr_mutex_unlock();
854 pthread_mutex_unlock(&gLock);
860 int tbm_bufmgr_get_fd_limit(void)
864 if (getrlimit(RLIMIT_NOFILE, &lim))
867 return (int)lim.rlim_cur;
870 tbm_bufmgr tbm_bufmgr_get(void)
877 tbm_bufmgr_internal_find_bo(tbm_bufmgr bufmgr, tbm_bo bo)
881 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), NULL);
882 TBM_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, NULL);
884 if (LIST_IS_EMPTY(&bufmgr->bo_list))
887 LIST_FOR_EACH_ENTRY(bo2, &bufmgr->bo_list, item_link) {
888 if (tbm_module_compare_bo_data(bufmgr->module, bo2->bo_data, bo->bo_data))
896 tbm_bufmgr_internal_alloc_bo(tbm_bufmgr bufmgr, int size, int flags)
898 tbm_error_e error = TBM_ERROR_NONE;
901 _tbm_bufmgr_mutex_lock();
903 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
904 TBM_BUFMGR_RETURN_VAL_IF_FAIL(size > 0, NULL);
906 _tbm_bufmgr_check_bo_cnt(bufmgr);
908 bo = calloc(1, sizeof(struct _tbm_bo));
910 /* LCOV_EXCL_START */
911 TBM_ERR("memory allocationc failed.");
912 error = TBM_ERROR_OUT_OF_MEMORY;
917 bo->bo_data = tbm_module_alloc_bo_data(bufmgr->module, bo, size, flags, &error);
919 /* LCOV_EXCL_START */
920 TBM_ERR("tbm_module_alloc_bo_data failed. size:%d flags:%s error:%d", size, _tbm_flag_to_str(flags), error);
922 _tbm_set_last_result(error);
923 _tbm_bufmgr_mutex_unlock();
928 _tbm_bufmgr_initialize_bo(bufmgr, bo, flags);
930 TBM_TRACE_BO("bo(%p) size(%d) refcnt(%d), flag(%s)", bo, size, bo->ref_cnt, _tbm_flag_to_str(bo->flags));
932 _tbm_set_last_result(TBM_ERROR_NONE);
933 _tbm_bufmgr_mutex_unlock();
937 /* LCOV_EXCL_START */
939 _tbm_set_last_result(error);
940 _tbm_bufmgr_mutex_unlock();
947 /* LCOV_EXCL_START */
950 tbm_bufmgr_internal_alloc_bo_with_format(tbm_bufmgr bufmgr, int format, int bo_idx, int width,
951 int height, int bpp, tbm_bo_memory_type flags, tbm_error_e *error)
955 _tbm_bufmgr_mutex_lock();
957 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
959 _tbm_bufmgr_check_bo_cnt(bufmgr);
961 bo = calloc(1, sizeof(struct _tbm_bo));
963 /* LCOV_EXCL_START */
964 TBM_ERR("memory allocationc failed.");
965 *error = TBM_ERROR_OUT_OF_MEMORY;
970 bo->bo_data = tbm_module_alloc_bo_data_with_format(bufmgr->module, format, bo_idx, width, height, bpp, flags, error);
972 /* LCOV_EXCL_START */
978 _tbm_bufmgr_initialize_bo(bufmgr, bo, flags);
980 _tbm_bufmgr_mutex_unlock();
984 /* LCOV_EXCL_START */
986 _tbm_bufmgr_mutex_unlock();
993 tbm_bufmgr_internal_alloc_bo_with_bo_data(tbm_bufmgr bufmgr, tbm_bo_data *bo_data, int flags, tbm_error_e *error)
995 tbm_bo bo, bo2 = NULL;
997 _tbm_bufmgr_mutex_lock();
999 *error = TBM_ERROR_NONE;
1001 TBM_BUFMGR_RETURN_VAL_SET_ERR_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL, *error, TBM_ERROR_INVALID_PARAMETER);
1002 TBM_BUFMGR_RETURN_VAL_SET_ERR_IF_FAIL(bo_data, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
1004 _tbm_bufmgr_check_bo_cnt(bufmgr);
1006 bo = calloc(1, sizeof(struct _tbm_bo));
1008 /* LCOV_EXCL_START */
1009 TBM_ERR("memory allocationc failed.");
1010 *error = TBM_ERROR_OUT_OF_MEMORY;
1011 _tbm_bufmgr_mutex_unlock();
1013 /* LCOV_EXCL_STOP */
1015 bo->bo_data = bo_data;
1016 bo->get_from_surface_data = 1;
1018 // return an existed bo if the bo is already created with the same bo_data.
1019 bo2 = tbm_bufmgr_internal_find_bo(bufmgr, bo);
1023 _tbm_bufmgr_mutex_unlock();
1027 _tbm_bufmgr_initialize_bo(bufmgr, bo, flags);
1029 TBM_TRACE_BO("bo(%p) refcnt(%d), flag(%s)", bo, bo->ref_cnt, _tbm_flag_to_str(bo->flags));
1031 _tbm_bufmgr_mutex_unlock();
1037 tbm_bufmgr_internal_import_bo_with_key(tbm_bufmgr bufmgr, unsigned int key)
1039 tbm_error_e error = TBM_ERROR_NONE;
1043 _tbm_bufmgr_mutex_lock();
1045 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
1047 _tbm_bufmgr_check_bo_cnt(bufmgr);
1049 bo = calloc(1, sizeof(struct _tbm_bo));
1051 /* LCOV_EXCL_START */
1052 TBM_ERR("memory allocationc failed.");
1054 /* LCOV_EXCL_STOP */
1057 bo->bo_data = tbm_module_import_bo_data_with_key(bufmgr->module, bo, key, &error);
1059 /* LCOV_EXCL_START */
1060 TBM_ERR("tbm_module_import_bo_data_with_key failed. tbm_key:%d", key);
1063 /* LCOV_EXCL_STOP */
1066 // return the existed bo2 if bo->bo_data and bo2->bo_data is the same
1067 bo2 = tbm_bufmgr_internal_find_bo(bufmgr, bo);
1069 TBM_TRACE_BO("find bo(%p) ref(%d) key(%d) flag(%s) in list",
1070 bo2, bo2->ref_cnt, key, _tbm_flag_to_str(bo2->flags));
1073 _tbm_set_last_result(TBM_ERROR_NONE);
1074 _tbm_bufmgr_mutex_unlock();
1078 flags = tbm_bo_data_get_memory_types(bo->bo_data, &error);
1079 if (error != TBM_ERROR_NONE) {
1080 TBM_WRN("tbm_bo_data_get_memory_types filed. use the default flags:TBM_BO_DEFAULT.");
1081 flags = TBM_BO_DEFAULT;
1082 error = TBM_ERROR_NONE;
1085 _tbm_bufmgr_initialize_bo(bufmgr, bo, flags);
1087 TBM_TRACE_BO("import new bo(%p) ref(%d) key(%d) flag(%s) in list",
1088 bo, bo->ref_cnt, key, _tbm_flag_to_str(bo->flags));
1090 _tbm_set_last_result(TBM_ERROR_NONE);
1091 _tbm_bufmgr_mutex_unlock();
1096 _tbm_set_last_result(error);
1097 _tbm_bufmgr_mutex_unlock();
1103 tbm_bufmgr_internal_import_bo_with_fd(tbm_bufmgr bufmgr, tbm_fd fd)
1105 tbm_error_e error = TBM_ERROR_NONE;
1109 _tbm_bufmgr_mutex_lock();
1111 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
1113 _tbm_bufmgr_check_bo_cnt(bufmgr);
1115 bo = calloc(1, sizeof(struct _tbm_bo));
1117 /* LCOV_EXCL_START */
1118 TBM_ERR("memory allocationc failed.");
1120 /* LCOV_EXCL_STOP */
1123 bo->bo_data = tbm_module_import_bo_data_with_fd(bufmgr->module, bo, fd, &error);
1125 /* LCOV_EXCL_START */
1126 TBM_ERR("tbm_module_import_bo_data_with_fd failed. tbm_fd:%d", fd);
1129 /* LCOV_EXCL_STOP */
1132 // return the existed bo2 if bo->bo_data and bo2->bo_data is the same
1133 bo2 = tbm_bufmgr_internal_find_bo(bufmgr, bo);
1135 TBM_TRACE_BO("find bo(%p) ref(%d) fd(%d) flag(%s) in list",
1136 bo2, bo2->ref_cnt, fd, _tbm_flag_to_str(bo2->flags));
1139 _tbm_set_last_result(TBM_ERROR_NONE);
1140 _tbm_bufmgr_mutex_unlock();
1144 flags = tbm_bo_data_get_memory_types(bo->bo_data, &error);
1145 if (error != TBM_ERROR_NONE) {
1146 TBM_WRN("tbm_bo_data_get_memory_types filed. use the default flags:TBM_BO_DEFAULT.");
1147 flags = TBM_BO_DEFAULT;
1148 error = TBM_ERROR_NONE;
1151 TBM_TRACE_BO("import bo(%p) ref(%d) fd(%d) flag(%s)",
1152 bo, bo->ref_cnt, fd, _tbm_flag_to_str(bo->flags));
1154 _tbm_bufmgr_initialize_bo(bufmgr, bo, flags);
1156 _tbm_set_last_result(TBM_ERROR_NONE);
1157 _tbm_bufmgr_mutex_unlock();
1162 _tbm_set_last_result(error);
1163 _tbm_bufmgr_mutex_unlock();
1168 /* LCOV_EXCL_STOP */