bufmgr: add tbm_bufmgr_set_bo_lock_type api
[platform/core/uifw/libtbm.git] / src / tbm_bufmgr.c
index 1c7449d..4208000 100644 (file)
@@ -77,6 +77,8 @@ static void _tbm_bufmgr_mutex_unlock(void);
 #define GET_MODULE_MINOR_VERSION(vers)    (((vers) >> 16) & 0xFF)
 #define GET_MODULE_PATCHLEVEL(vers)    ((vers) & 0xFFFF)
 
+#define MAX_SIZE_N(dest)       (sizeof(dest) - strlen(dest) - 1)
+
 /* check condition */
 #define TBM_BUFMGR_RETURN_IF_FAIL(cond) {\
        if (!(cond)) {\
@@ -94,12 +96,6 @@ static void _tbm_bufmgr_mutex_unlock(void);
        } \
 }
 
-enum {
-       LOCK_TRY_ONCE,
-       LOCK_TRY_ALWAYS,
-       LOCK_TRY_NEVER
-};
-
 static void
 _tbm_set_last_result(tbm_error_e err)
 {
@@ -153,18 +149,22 @@ _tbm_flag_to_str(int f)
                int c = 0;
 
                if (f & TBM_BO_SCANOUT)
-                       c = snprintf(&str[c], 255, "SCANOUT");
+                       c += snprintf(&str[c], 255-c, "SCANOUT");
 
                if (f & TBM_BO_NONCACHABLE) {
-                       if (c)
-                               c = snprintf(&str[c], 255, ", ");
-                       c = snprintf(&str[c], 255, "NONCACHABLE,");
+                       if (c >= 0 && c < 255)
+                               c += snprintf(&str[c], 255-c, ", ");
+
+                       if (c >= 0 && c < 255)
+                               c += snprintf(&str[c], 255-c, "NONCACHABLE,");
                }
 
                if (f & TBM_BO_WC) {
-                       if (c)
-                               c = snprintf(&str[c], 255, ", ");
-                       c = snprintf(&str[c], 255, "WC");
+                       if (c >= 0 && c < 255)
+                               c += snprintf(&str[c], 255-c, ", ");
+
+                       if (c >= 0 && c < 255)
+                               c += snprintf(&str[c], 255-c, "WC");
                }
        }
 
@@ -344,7 +344,7 @@ _tbm_bo_lock(tbm_bo bo, int device, int opt)
        bufmgr = bo->bufmgr;
 
        /* do not try to lock the bo */
-       if (bufmgr->lock_type == LOCK_TRY_NEVER)
+       if (bufmgr->bo_lock_type == TBM_BUFMGR_BO_LOCK_TYPE_NEVER)
                return 1;
 
        if (bo->lock_cnt < 0) {
@@ -355,8 +355,8 @@ _tbm_bo_lock(tbm_bo bo, int device, int opt)
 
        old = bo->lock_cnt;
 
-       switch (bufmgr->lock_type) {
-       case LOCK_TRY_ONCE:
+       switch (bufmgr->bo_lock_type) {
+       case TBM_BUFMGR_BO_LOCK_TYPE_ONCE:
                if (bo->lock_cnt == 0) {
                        _tbm_bufmgr_mutex_unlock();
                        ret = _bo_lock(bo, device, opt);
@@ -366,7 +366,7 @@ _tbm_bo_lock(tbm_bo bo, int device, int opt)
                } else
                        ret = 1;
                break;
-       case LOCK_TRY_ALWAYS:
+       case TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS:
                _tbm_bufmgr_mutex_unlock();
                ret = _bo_lock(bo, device, opt);
                _tbm_bufmgr_mutex_lock();
@@ -374,8 +374,8 @@ _tbm_bo_lock(tbm_bo bo, int device, int opt)
                        bo->lock_cnt++;
                break;
        default:
-               TBM_LOG_E("error bo:%p lock_type[%d] is wrong.\n",
-                               bo, bufmgr->lock_type);
+               TBM_LOG_E("error bo:%p bo_lock_type[%d] is wrong.\n",
+                               bo, bufmgr->bo_lock_type);
                ret = 0;
                break;
        }
@@ -397,28 +397,28 @@ _tbm_bo_unlock(tbm_bo bo)
        bufmgr = bo->bufmgr;
 
        /* do not try to unlock the bo */
-       if (bufmgr->lock_type == LOCK_TRY_NEVER)
+       if (bufmgr->bo_lock_type == TBM_BUFMGR_BO_LOCK_TYPE_NEVER)
                return;
 
        old = bo->lock_cnt;
 
-       switch (bufmgr->lock_type) {
-       case LOCK_TRY_ONCE:
+       switch (bufmgr->bo_lock_type) {
+       case TBM_BUFMGR_BO_LOCK_TYPE_ONCE:
                if (bo->lock_cnt > 0) {
                        bo->lock_cnt--;
                        if (bo->lock_cnt == 0)
                                _bo_unlock(bo);
                }
                break;
-       case LOCK_TRY_ALWAYS:
+       case TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS:
                if (bo->lock_cnt > 0) {
                        bo->lock_cnt--;
                        _bo_unlock(bo);
                }
                break;
        default:
-               TBM_LOG_E("error bo:%p lock_type[%d] is wrong.\n",
-                               bo, bufmgr->lock_type);
+               TBM_LOG_E("error bo:%p bo_lock_type[%d] is wrong.\n",
+                               bo, bufmgr->bo_lock_type);
                break;
        }
 
@@ -614,8 +614,8 @@ _tbm_load_module(tbm_bufmgr bufmgr, int fd)
 }
 /* LCOV_EXCL_STOP */
 
-tbm_bufmgr
-tbm_bufmgr_init(int fd)
+static tbm_bufmgr
+_tbm_bufmgr_init(int fd, int server)
 {
 #ifdef TBM_BUFMGR_INIT_TIME
        struct timeval start_tv, end_tv;
@@ -684,6 +684,12 @@ tbm_bufmgr_init(int fd)
 
        gBufMgr->fd = fd;
 
+       /* set the display_server flag before loading the backend module */
+       if (server) {
+               TBM_LOG_I("The tbm_bufmgr(%p) is used by display server. Need to bind the native_display.\n", gBufMgr);
+               gBufMgr->display_server = 1;
+       }
+
        /* load bufmgr priv from env */
        if (!_tbm_load_module(gBufMgr, gBufMgr->fd)) {
                _tbm_set_last_result(TBM_BO_ERROR_LOAD_MODULE_FAILED);
@@ -705,16 +711,16 @@ tbm_bufmgr_init(int fd)
        TBM_DBG("create tizen bufmgr:%p ref_count:%d\n",
            gBufMgr, gBufMgr->ref_count);
 
-       /* setup the lock_type */
+       /* setup the bo_lock_type */
        env = getenv("BUFMGR_LOCK_TYPE");
        if (env && !strcmp(env, "always"))
-               gBufMgr->lock_type = LOCK_TRY_ALWAYS;
+               gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS;
        else if (env && !strcmp(env, "none"))
-               gBufMgr->lock_type = LOCK_TRY_NEVER;
+               gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_NEVER;
        else if (env && !strcmp(env, "once"))
-               gBufMgr->lock_type = LOCK_TRY_ONCE;
+               gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ONCE;
        else
-               gBufMgr->lock_type = LOCK_TRY_ALWAYS;
+               gBufMgr->bo_lock_type = TBM_BUFMGR_BO_LOCK_TYPE_ALWAYS;
 
        TBM_DBG("BUFMGR_LOCK_TYPE=%s\n", env ? env : "default:once");
 
@@ -743,6 +749,16 @@ tbm_bufmgr_init(int fd)
        return gBufMgr;
 }
 
+tbm_bufmgr
+tbm_bufmgr_init(int fd)
+{
+       tbm_bufmgr bufmgr;
+
+       bufmgr = _tbm_bufmgr_init(fd, 0);
+
+       return bufmgr;
+}
+
 void
 tbm_bufmgr_deinit(tbm_bufmgr bufmgr)
 {
@@ -774,6 +790,7 @@ tbm_bufmgr_deinit(tbm_bufmgr bufmgr)
                        TBM_LOG_E("Un-freed bo(%p, ref:%d)\n", bo, bo->ref_cnt);
                        _tbm_bo_free(bo);
                }
+               LIST_DELINIT(&bufmgr->bo_list);
        }
 
        /* destroy surf_list */
@@ -784,6 +801,7 @@ tbm_bufmgr_deinit(tbm_bufmgr bufmgr)
                        TBM_LOG_E("Un-freed surf(%p, ref:%d)\n", surf, surf->refcnt);
                        tbm_surface_destroy(surf);
                }
+               LIST_DELINIT(&bufmgr->surf_list);
        }
 
        /* destroy bufmgr priv */
@@ -846,8 +864,6 @@ tbm_bo_ref(tbm_bo bo)
 void
 tbm_bo_unref(tbm_bo bo)
 {
-       tbm_bufmgr bufmgr = gBufMgr;
-
        _tbm_bufmgr_mutex_lock();
 
        TBM_BUFMGR_RETURN_IF_FAIL(gBufMgr);
@@ -1231,6 +1247,7 @@ tbm_bo_unmap(tbm_bo bo)
 
        TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
        TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
+       TBM_BUFMGR_RETURN_VAL_IF_FAIL(bo->map_cnt > 0, 0);
 
        ret = bufmgr->backend->bo_unmap(bo);
        if (!ret) {
@@ -1296,7 +1313,7 @@ tbm_bo_locked(tbm_bo bo)
        TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
        TBM_BUFMGR_RETURN_VAL_IF_FAIL(_tbm_bo_is_valid(bo), 0);
 
-       if (bufmgr->lock_type == LOCK_TRY_NEVER) {
+       if (bufmgr->bo_lock_type == TBM_BUFMGR_BO_LOCK_TYPE_NEVER) {
                TBM_LOG_E("bo(%p) lock_cnt(%d)\n", bo, bo->lock_cnt);
                _tbm_bufmgr_mutex_unlock();
                return 0;
@@ -1493,37 +1510,47 @@ tbm_get_last_error(void)
        return tbm_last_error;
 }
 
-void
-tbm_bufmgr_debug_tbm_info_get(tbm_bufmgr bufmgr, char *str, int *len)
+char *
+tbm_bufmgr_debug_tbm_info_get(tbm_bufmgr bufmgr)
 {
        char app_name[255] = {0,}, title[512] = {0,};
        tbm_surface_debug_data *debug_old_data = NULL;
+       char *str;
+       int len = 1024*4;
+       int c = 0;
 
        pthread_mutex_lock(&gLock);
 
        if (!TBM_BUFMGR_IS_VALID(bufmgr) || (bufmgr != gBufMgr)) {
                TBM_LOG_E("invalid bufmgr\n");
                pthread_mutex_unlock(&gLock);
-               return;
+               return NULL;
+       }
+
+       str = malloc(len);
+       if (!str) {
+               TBM_LOG_E("Fail to allocate the string.\n");
+               pthread_mutex_unlock(&gLock);
+               return NULL;
        }
 
-       TBM_SNPRINTF(str, len, "\n");
+       TBM_SNRPRINTF(str, len, c, "\n");
        _tbm_util_get_appname_from_pid(getpid(), app_name);
        _tbm_util_get_appname_brief(app_name);
-       TBM_SNPRINTF(str, len, "============TBM DEBUG: %s(%d)===========================\n",
+       TBM_SNRPRINTF(str, len, c, "============TBM DEBUG: %s(%d)===========================\n",
                  app_name, getpid());
 
        snprintf(title, 255, "%s", "no  surface     refcnt  width  height  bpp  size    n_b  n_p  flags  format    app_name       ");
 
        if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
                LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
-                       strncat(title, "  ", 3);
-                       strncat(title, debug_old_data->key, strlen(debug_old_data->key) + 1);
+                       strncat(title, "  ", MAX_SIZE_N(title));
+                       strncat(title, debug_old_data->key, MAX_SIZE_N(title));
                }
        }
 
-       TBM_SNPRINTF(str, len, "[tbm_surface information]\n");
-       TBM_SNPRINTF(str, len, "%s\n", title);
+       TBM_SNRPRINTF(str, len, c, "[tbm_surface information]\n");
+       TBM_SNRPRINTF(str, len, c, "%s\n", title);
 
        /* show the tbm_surface information in surf_list */
        if (!LIST_IS_EMPTY(&bufmgr->surf_list)) {
@@ -1563,30 +1590,30 @@ tbm_bufmgr_debug_tbm_info_get(tbm_bufmgr bufmgr, char *str, int *len)
                                LIST_FOR_EACH_ENTRY(debug_old_data, &bufmgr->debug_key_list, item_link) {
                                        char *value;
 
-                                       strncat(data, "  ", 3);
+                                       strncat(data, "  ", MAX_SIZE_N(title));
 
                                        value = _tbm_surface_internal_get_debug_data(surf, debug_old_data->key);
                                        if (value)
-                                               strncat(data, value, strlen(value) + 1);
+                                               strncat(data, value, MAX_SIZE_N(title));
                                        else
-                                               strncat(data, "none", 5);
+                                               strncat(data, "none", MAX_SIZE_N(title));
                                }
                        }
-                       TBM_SNPRINTF(str, len, "%s\n", data);
+                       TBM_SNRPRINTF(str, len, c, "%s\n", data);
 
                        for (i = 0; i < surf->num_bos; i++) {
-                               TBM_SNPRINTF(str, len, " bo:%-12p  %-26d%-10d\n",
+                               TBM_SNRPRINTF(str, len, c, " bo:%-12p  %-26d%-10d\n",
                                          surf->bos[i],
                                          surf->bos[i]->ref_cnt,
                                          bufmgr->backend->bo_size(surf->bos[i]) / 1024);
                        }
                }
        } else
-               TBM_SNPRINTF(str, len, " no tbm_surfaces.\n");
-       TBM_SNPRINTF(str, len, "\n");
+               TBM_SNRPRINTF(str, len, c, " no tbm_surfaces.\n");
+       TBM_SNRPRINTF(str, len, c, "\n");
 
-       TBM_SNPRINTF(str, len, "[tbm_bo information]\n");
-       TBM_SNPRINTF(str, len, "no  bo          refcnt  size    lock_cnt  map_cnt  flags  surface\n");
+       TBM_SNRPRINTF(str, len, c, "[tbm_bo information]\n");
+       TBM_SNRPRINTF(str, len, c, "no  bo          refcnt  size    lock_cnt  map_cnt  flags  surface     name\n");
 
        /* show the tbm_bo information in bo_list */
        if (!LIST_IS_EMPTY(&bufmgr->bo_list)) {
@@ -1594,7 +1621,7 @@ tbm_bufmgr_debug_tbm_info_get(tbm_bufmgr bufmgr, char *str, int *len)
                tbm_bo bo = NULL;
 
                LIST_FOR_EACH_ENTRY(bo, &bufmgr->bo_list, item_link) {
-                       TBM_SNPRINTF(str, len, "%-4d%-11p   %-4d  %-6d     %-5d     %-4u    %-3d  %-11p\n",
+                       TBM_SNRPRINTF(str, len, c, "%-4d%-11p   %-4d  %-6d     %-5d     %-4u    %-3d  %-11p  %-4d\n",
                                  ++bo_cnt,
                                  bo,
                                  bo->ref_cnt,
@@ -1602,24 +1629,29 @@ tbm_bufmgr_debug_tbm_info_get(tbm_bufmgr bufmgr, char *str, int *len)
                                  bo->lock_cnt,
                                  bo->map_cnt,
                                  bo->flags,
-                                 bo->surface);
+                                 bo->surface,
+                                 bufmgr->backend->bo_export(bo));
                }
        } else
-               TBM_SNPRINTF(str, len, "no tbm_bos.\n");
-       TBM_SNPRINTF(str, len, "\n");
+               TBM_SNRPRINTF(str, len, c, "no tbm_bos.\n");
+       TBM_SNRPRINTF(str, len, c, "\n");
 
-       TBM_SNPRINTF(str, len, "===============================================================\n");
+       TBM_SNRPRINTF(str, len, c, "===============================================================\n");
 
        pthread_mutex_unlock(&gLock);
+
+       return str;
 }
 
 void
 tbm_bufmgr_debug_show(tbm_bufmgr bufmgr)
 {
-       char str[1024*4];
-       int len = sizeof(str);
-       tbm_bufmgr_debug_tbm_info_get(bufmgr, str, &len);
-       TBM_DEBUG("     %s", str);
+       char * str;
+       str = tbm_bufmgr_debug_tbm_info_get(bufmgr);
+       if (str) {
+               TBM_DEBUG("     %s", str);
+               free(str);
+       }
 }
 
 void
@@ -1647,6 +1679,12 @@ tbm_bufmgr_debug_dump_set_scale(double scale)
 }
 
 int
+tbm_bufmgr_debug_get_ref_count(void)
+{
+       return (gBufMgr) ? gBufMgr->ref_count : 0;
+}
+
+int
 tbm_bufmgr_debug_queue_dump(char *path, int count, int onoff)
 {
        pthread_mutex_lock(&gLock);
@@ -1735,7 +1773,7 @@ _tbm_bo_set_surface(tbm_bo bo, tbm_surface_h surface)
 }
 
 int
-tbm_bufmgr_bind_native_display(tbm_bufmgr bufmgr, void *NativeDisplay)
+tbm_bufmgr_bind_native_display(tbm_bufmgr bufmgr, void *native_display)
 {
        int ret;
 
@@ -1744,27 +1782,51 @@ tbm_bufmgr_bind_native_display(tbm_bufmgr bufmgr, void *NativeDisplay)
        TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
 
        if (!bufmgr->backend->bufmgr_bind_native_display) {
-               TBM_TRACE("skip: tbm_bufmgr(%p) NativeDisplay(%p)\n",
-                               bufmgr, NativeDisplay);
+               TBM_TRACE("skip: tbm_bufmgr(%p) native_display(%p)\n",
+                               bufmgr, native_display);
                _tbm_bufmgr_mutex_unlock();
                return 1;
        }
 
-       ret = bufmgr->backend->bufmgr_bind_native_display(bufmgr, NativeDisplay);
+       ret = bufmgr->backend->bufmgr_bind_native_display(bufmgr, native_display);
        if (!ret) {
-               TBM_LOG_E("error: tbm_bufmgr(%p) NativeDisplay(%p)\n",
-                               bufmgr, NativeDisplay);
+               TBM_LOG_E("error: tbm_bufmgr(%p) native_display(%p)\n",
+                               bufmgr, native_display);
                _tbm_bufmgr_mutex_unlock();
                return 0;
        }
 
-       TBM_TRACE("tbm_bufmgr(%p) NativeDisplay(%p)\n", bufmgr, NativeDisplay);
+       TBM_TRACE("tbm_bufmgr(%p) native_display(%p)\n", bufmgr, native_display);
 
        _tbm_bufmgr_mutex_unlock();
 
        return 1;
 }
 
+tbm_bufmgr
+tbm_bufmgr_server_init(void)
+{
+       tbm_bufmgr bufmgr;
+
+       bufmgr = _tbm_bufmgr_init(-1, 1);
+
+       return bufmgr;
+}
+
+int
+tbm_bufmgr_set_bo_lock_type(tbm_bufmgr bufmgr, tbm_bufmgr_bo_lock_type bo_lock_type)
+{
+       TBM_BUFMGR_RETURN_VAL_IF_FAIL(TBM_BUFMGR_IS_VALID(gBufMgr), 0);
+       TBM_BUFMGR_RETURN_VAL_IF_FAIL(bufmgr == gBufMgr, 0);
+
+       gBufMgr->bo_lock_type = bo_lock_type;
+
+       TBM_LOG_I("The bo_lock_type of the bo is %d\n", bo_lock_type);
+
+       return 1;
+}
+
+
 int tbm_bufmgr_get_fd_limit(void)
 {
        struct rlimit lim;