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_set_last_result(TBM_ERROR_INVALID_PARAMETER);
854 _tbm_bufmgr_mutex_unlock();
855 pthread_mutex_unlock(&gLock);
861 int tbm_bufmgr_get_fd_limit(void)
865 if (getrlimit(RLIMIT_NOFILE, &lim))
868 return (int)lim.rlim_cur;
871 tbm_bufmgr tbm_bufmgr_get(void)
878 tbm_bufmgr_internal_find_bo(tbm_bufmgr bufmgr, tbm_bo bo)
882 TBM_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), NULL);
883 TBM_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, NULL);
885 if (LIST_IS_EMPTY(&bufmgr->bo_list))
888 LIST_FOR_EACH_ENTRY(bo2, &bufmgr->bo_list, item_link) {
889 if (tbm_module_compare_bo_data(bufmgr->module, bo2->bo_data, bo->bo_data))
897 tbm_bufmgr_internal_alloc_bo(tbm_bufmgr bufmgr, int size, int flags)
899 tbm_error_e error = TBM_ERROR_NONE;
902 _tbm_bufmgr_mutex_lock();
904 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
905 TBM_BUFMGR_RETURN_VAL_IF_FAIL(size > 0, NULL);
907 _tbm_bufmgr_check_bo_cnt(bufmgr);
909 bo = calloc(1, sizeof(struct _tbm_bo));
911 /* LCOV_EXCL_START */
912 TBM_ERR("memory allocationc failed.");
913 error = TBM_ERROR_OUT_OF_MEMORY;
918 bo->bo_data = tbm_module_alloc_bo_data(bufmgr->module, bo, size, flags, &error);
920 /* LCOV_EXCL_START */
921 TBM_ERR("tbm_module_alloc_bo_data failed. size:%d flags:%s error:%d", size, _tbm_flag_to_str(flags), error);
923 _tbm_set_last_result(error);
924 _tbm_bufmgr_mutex_unlock();
929 _tbm_bufmgr_initialize_bo(bufmgr, bo, flags);
931 TBM_TRACE_BO("bo(%p) size(%d) refcnt(%d), flag(%s)", bo, size, bo->ref_cnt, _tbm_flag_to_str(bo->flags));
933 _tbm_set_last_result(TBM_ERROR_NONE);
934 _tbm_bufmgr_mutex_unlock();
938 /* LCOV_EXCL_START */
940 _tbm_set_last_result(error);
941 _tbm_bufmgr_mutex_unlock();
948 /* LCOV_EXCL_START */
951 tbm_bufmgr_internal_alloc_bo_with_format(tbm_bufmgr bufmgr, int format, int bo_idx, int width,
952 int height, int bpp, tbm_bo_memory_type flags, tbm_error_e *error)
956 _tbm_bufmgr_mutex_lock();
958 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
960 _tbm_bufmgr_check_bo_cnt(bufmgr);
962 bo = calloc(1, sizeof(struct _tbm_bo));
964 /* LCOV_EXCL_START */
965 TBM_ERR("memory allocationc failed.");
966 *error = TBM_ERROR_OUT_OF_MEMORY;
971 bo->bo_data = tbm_module_alloc_bo_data_with_format(bufmgr->module, format, bo_idx, width, height, bpp, flags, error);
973 /* LCOV_EXCL_START */
979 _tbm_bufmgr_initialize_bo(bufmgr, bo, flags);
981 _tbm_bufmgr_mutex_unlock();
985 /* LCOV_EXCL_START */
987 _tbm_bufmgr_mutex_unlock();
994 tbm_bufmgr_internal_alloc_bo_with_bo_data(tbm_bufmgr bufmgr, tbm_bo_data *bo_data, int flags, tbm_error_e *error)
996 tbm_bo bo, bo2 = NULL;
998 _tbm_bufmgr_mutex_lock();
1000 *error = TBM_ERROR_NONE;
1002 TBM_BUFMGR_RETURN_VAL_SET_ERR_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL, *error, TBM_ERROR_INVALID_PARAMETER);
1003 TBM_BUFMGR_RETURN_VAL_SET_ERR_IF_FAIL(bo_data, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
1005 _tbm_bufmgr_check_bo_cnt(bufmgr);
1007 bo = calloc(1, sizeof(struct _tbm_bo));
1009 /* LCOV_EXCL_START */
1010 TBM_ERR("memory allocationc failed.");
1011 *error = TBM_ERROR_OUT_OF_MEMORY;
1012 _tbm_bufmgr_mutex_unlock();
1014 /* LCOV_EXCL_STOP */
1016 bo->bo_data = bo_data;
1017 bo->get_from_surface_data = 1;
1019 // return an existed bo if the bo is already created with the same bo_data.
1020 bo2 = tbm_bufmgr_internal_find_bo(bufmgr, bo);
1024 _tbm_bufmgr_mutex_unlock();
1028 _tbm_bufmgr_initialize_bo(bufmgr, bo, flags);
1030 TBM_TRACE_BO("bo(%p) refcnt(%d), flag(%s)", bo, bo->ref_cnt, _tbm_flag_to_str(bo->flags));
1032 _tbm_bufmgr_mutex_unlock();
1038 tbm_bufmgr_internal_import_bo_with_key(tbm_bufmgr bufmgr, unsigned int key)
1040 tbm_error_e error = TBM_ERROR_NONE;
1044 _tbm_bufmgr_mutex_lock();
1046 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
1048 _tbm_bufmgr_check_bo_cnt(bufmgr);
1050 bo = calloc(1, sizeof(struct _tbm_bo));
1052 /* LCOV_EXCL_START */
1053 TBM_ERR("memory allocationc failed.");
1055 /* LCOV_EXCL_STOP */
1058 bo->bo_data = tbm_module_import_bo_data_with_key(bufmgr->module, bo, key, &error);
1060 /* LCOV_EXCL_START */
1061 TBM_ERR("tbm_module_import_bo_data_with_key failed. tbm_key:%d", key);
1064 /* LCOV_EXCL_STOP */
1067 // return the existed bo2 if bo->bo_data and bo2->bo_data is the same
1068 bo2 = tbm_bufmgr_internal_find_bo(bufmgr, bo);
1070 TBM_TRACE_BO("find bo(%p) ref(%d) key(%d) flag(%s) in list",
1071 bo2, bo2->ref_cnt, key, _tbm_flag_to_str(bo2->flags));
1074 _tbm_set_last_result(TBM_ERROR_NONE);
1075 _tbm_bufmgr_mutex_unlock();
1079 flags = tbm_bo_data_get_memory_types(bo->bo_data, &error);
1080 if (error != TBM_ERROR_NONE) {
1081 TBM_WRN("tbm_bo_data_get_memory_types filed. use the default flags:TBM_BO_DEFAULT.");
1082 flags = TBM_BO_DEFAULT;
1083 error = TBM_ERROR_NONE;
1086 _tbm_bufmgr_initialize_bo(bufmgr, bo, flags);
1088 TBM_TRACE_BO("import new bo(%p) ref(%d) key(%d) flag(%s) in list",
1089 bo, bo->ref_cnt, key, _tbm_flag_to_str(bo->flags));
1091 _tbm_set_last_result(TBM_ERROR_NONE);
1092 _tbm_bufmgr_mutex_unlock();
1097 _tbm_set_last_result(error);
1098 _tbm_bufmgr_mutex_unlock();
1104 tbm_bufmgr_internal_import_bo_with_fd(tbm_bufmgr bufmgr, tbm_fd fd)
1106 tbm_error_e error = TBM_ERROR_NONE;
1110 _tbm_bufmgr_mutex_lock();
1112 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), NULL);
1114 _tbm_bufmgr_check_bo_cnt(bufmgr);
1116 bo = calloc(1, sizeof(struct _tbm_bo));
1118 /* LCOV_EXCL_START */
1119 TBM_ERR("memory allocationc failed.");
1121 /* LCOV_EXCL_STOP */
1124 bo->bo_data = tbm_module_import_bo_data_with_fd(bufmgr->module, bo, fd, &error);
1126 /* LCOV_EXCL_START */
1127 TBM_ERR("tbm_module_import_bo_data_with_fd failed. tbm_fd:%d", fd);
1130 /* LCOV_EXCL_STOP */
1133 // return the existed bo2 if bo->bo_data and bo2->bo_data is the same
1134 bo2 = tbm_bufmgr_internal_find_bo(bufmgr, bo);
1136 TBM_TRACE_BO("find bo(%p) ref(%d) fd(%d) flag(%s) in list",
1137 bo2, bo2->ref_cnt, fd, _tbm_flag_to_str(bo2->flags));
1140 _tbm_set_last_result(TBM_ERROR_NONE);
1141 _tbm_bufmgr_mutex_unlock();
1145 flags = tbm_bo_data_get_memory_types(bo->bo_data, &error);
1146 if (error != TBM_ERROR_NONE) {
1147 TBM_WRN("tbm_bo_data_get_memory_types filed. use the default flags:TBM_BO_DEFAULT.");
1148 flags = TBM_BO_DEFAULT;
1149 error = TBM_ERROR_NONE;
1152 TBM_TRACE_BO("import bo(%p) ref(%d) fd(%d) flag(%s)",
1153 bo, bo->ref_cnt, fd, _tbm_flag_to_str(bo->flags));
1155 _tbm_bufmgr_initialize_bo(bufmgr, bo, flags);
1157 _tbm_set_last_result(TBM_ERROR_NONE);
1158 _tbm_bufmgr_mutex_unlock();
1163 _tbm_set_last_result(error);
1164 _tbm_bufmgr_mutex_unlock();
1170 tbm_bufmgr_internal_support_capabilites(tbm_bufmgr bufmgr, int capabilities)
1172 TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(bufmgr), 0);
1173 TBM_BUFMGR_RETURN_VAL_IF_FAIL(capabilities > 0, 0);
1175 _tbm_bufmgr_mutex_lock();
1177 // check if the bufmgr does not support capabilities at the same time.
1178 if (!(bufmgr->capabilities & capabilities)) {
1179 _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
1180 _tbm_bufmgr_mutex_unlock();
1184 _tbm_set_last_result(TBM_ERROR_NONE);
1185 _tbm_bufmgr_mutex_unlock();
1190 /* LCOV_EXCL_STOP */