Move user data code to tbm_bufmgr
[platform/core/uifw/libtbm.git] / src / tbm_surface_internal.c
index 51771a7..a444dce 100644 (file)
@@ -38,829 +38,1008 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 static tbm_bufmgr g_surface_bufmgr = NULL;
 static pthread_mutex_t tbm_surface_lock;
 
-static bool
-_tbm_surface_mutex_init (void)
+char *_tbm_surface_internal_format_to_str(tbm_format format)
 {
-    static bool tbm_surface_mutex_init = false;
+       switch (format) {
+       case TBM_FORMAT_C8:
+               return "TBM_FORMAT_C8";
+       case TBM_FORMAT_RGB332:
+               return "TBM_FORMAT_RGB332";
+       case TBM_FORMAT_BGR233:
+               return "TBM_FORMAT_BGR233";
+       case TBM_FORMAT_XRGB4444:
+               return "TBM_FORMAT_XRGB4444";
+       case TBM_FORMAT_XBGR4444:
+               return "TBM_FORMAT_XBGR4444";
+       case TBM_FORMAT_RGBX4444:
+               return "TBM_FORMAT_RGBX4444";
+       case TBM_FORMAT_BGRX4444:
+               return "TBM_FORMAT_BGRX4444";
+       case TBM_FORMAT_ARGB4444:
+               return "TBM_FORMAT_ARGB4444";
+       case TBM_FORMAT_ABGR4444:
+               return "TBM_FORMAT_ABGR4444";
+       case TBM_FORMAT_RGBA4444:
+               return "TBM_FORMAT_RGBA4444";
+       case TBM_FORMAT_BGRA4444:
+               return "TBM_FORMAT_BGRA4444";
+       case TBM_FORMAT_XRGB1555:
+               return "TBM_FORMAT_XRGB1555";
+       case TBM_FORMAT_XBGR1555:
+               return "TBM_FORMAT_XBGR1555";
+       case TBM_FORMAT_RGBX5551:
+               return "TBM_FORMAT_RGBX5551";
+       case TBM_FORMAT_BGRX5551:
+               return "TBM_FORMAT_BGRX5551";
+       case TBM_FORMAT_ARGB1555:
+               return "TBM_FORMAT_ARGB1555";
+       case TBM_FORMAT_ABGR1555:
+               return "TBM_FORMAT_ABGR1555";
+       case TBM_FORMAT_RGBA5551:
+               return "TBM_FORMAT_RGBA5551";
+       case TBM_FORMAT_BGRA5551:
+               return "TBM_FORMAT_BGRA5551";
+       case TBM_FORMAT_RGB565:
+               return "TBM_FORMAT_RGB565";
+       case TBM_FORMAT_BGR565:
+               return "TBM_FORMAT_BGR565";
+       case TBM_FORMAT_RGB888:
+               return "TBM_FORMAT_RGB888";
+       case TBM_FORMAT_BGR888:
+               return "TBM_FORMAT_BGR888";
+       case TBM_FORMAT_XRGB8888:
+               return "TBM_FORMAT_XRGB8888";
+       case TBM_FORMAT_XBGR8888:
+               return "TBM_FORMAT_XBGR8888";
+       case TBM_FORMAT_RGBX8888:
+               return "TBM_FORMAT_RGBX8888";
+       case TBM_FORMAT_BGRX8888:
+               return "TBM_FORMAT_BGRX8888";
+       case TBM_FORMAT_ARGB8888:
+               return "TBM_FORMAT_ARGB8888";
+       case TBM_FORMAT_ABGR8888:
+               return "TBM_FORMAT_ABGR8888";
+       case TBM_FORMAT_RGBA8888:
+               return "TBM_FORMAT_RGBA8888";
+       case TBM_FORMAT_BGRA8888:
+               return "TBM_FORMAT_BGRA8888";
+       case TBM_FORMAT_XRGB2101010:
+               return "TBM_FORMAT_XRGB2101010";
+       case TBM_FORMAT_XBGR2101010:
+               return "TBM_FORMAT_XBGR2101010";
+       case TBM_FORMAT_RGBX1010102:
+               return "TBM_FORMAT_RGBX1010102";
+       case TBM_FORMAT_BGRX1010102:
+               return "TBM_FORMAT_BGRX1010102";
+       case TBM_FORMAT_ARGB2101010:
+               return "TBM_FORMAT_ARGB2101010";
+       case TBM_FORMAT_ABGR2101010:
+               return "TBM_FORMAT_ABGR2101010";
+       case TBM_FORMAT_RGBA1010102:
+               return "TBM_FORMAT_RGBA1010102";
+       case TBM_FORMAT_BGRA1010102:
+               return "TBM_FORMAT_BGRA1010102";
+       case TBM_FORMAT_YUYV:
+               return "TBM_FORMAT_YUYV";
+       case TBM_FORMAT_YVYU:
+               return "TBM_FORMAT_YVYU";
+       case TBM_FORMAT_UYVY:
+               return "TBM_FORMAT_UYVY";
+       case TBM_FORMAT_VYUY:
+               return "TBM_FORMAT_VYUY";
+       case TBM_FORMAT_AYUV:
+               return "TBM_FORMAT_AYUV";
+       case TBM_FORMAT_NV12:
+               return "TBM_FORMAT_NV12";
+       case TBM_FORMAT_NV21:
+               return "TBM_FORMAT_NV21";
+       case TBM_FORMAT_NV16:
+               return "TBM_FORMAT_NV16";
+       case TBM_FORMAT_NV61:
+               return "TBM_FORMAT_NV61";
+       case TBM_FORMAT_YUV410:
+               return "TBM_FORMAT_YUV410";
+       case TBM_FORMAT_YVU410:
+               return "TBM_FORMAT_YVU410";
+       case TBM_FORMAT_YUV411:
+               return "TBM_FORMAT_YUV411";
+       case TBM_FORMAT_YVU411:
+               return "TBM_FORMAT_YVU411";
+       case TBM_FORMAT_YUV420:
+               return "TBM_FORMAT_YUV420";
+       case TBM_FORMAT_YVU420:
+               return "TBM_FORMAT_YVU420";
+       case TBM_FORMAT_YUV422:
+               return "TBM_FORMAT_YUV422";
+       case TBM_FORMAT_YVU422:
+               return "TBM_FORMAT_YVU422";
+       case TBM_FORMAT_YUV444:
+               return "TBM_FORMAT_YUV444";
+       case TBM_FORMAT_YVU444:
+               return "TBM_FORMAT_YVU444";
+       case TBM_FORMAT_NV12MT:
+               return "TBM_FORMAT_NV12MT";
+       default:
+               return "unknwon";
+       }
+}
+
+static bool _tbm_surface_mutex_init(void)
+{
+       static bool tbm_surface_mutex_init = false;
 
-    if (tbm_surface_mutex_init)
-        return true;
+       if (tbm_surface_mutex_init)
+               return true;
 
-    if (pthread_mutex_init (&tbm_surface_lock, NULL))
-    {
-        TBM_LOG ("[libtbm] fail: tbm_surface mutex init\n");
-        return false;
-    }
+       if (pthread_mutex_init(&tbm_surface_lock, NULL)) {
+               TBM_LOG("[libtbm] fail: tbm_surface mutex init\n");
+               return false;
+       }
 
-    tbm_surface_mutex_init = true;
+       tbm_surface_mutex_init = true;
 
-    return true;
+       return true;
 }
 
-void
-_tbm_surface_mutex_lock (void)
+void _tbm_surface_mutex_lock(void)
 {
-    if (!_tbm_surface_mutex_init ())
-        return;
+       if (!_tbm_surface_mutex_init())
+               return;
 
-    pthread_mutex_lock (&tbm_surface_lock);
+       pthread_mutex_lock(&tbm_surface_lock);
 }
 
-void
-_tbm_surface_mutex_unlock (void)
+void _tbm_surface_mutex_unlock(void)
 {
-    pthread_mutex_unlock (&tbm_surface_lock);
+       pthread_mutex_unlock(&tbm_surface_lock);
 }
 
-static void
-_init_surface_bufmgr()
+static void _init_surface_bufmgr()
 {
-    g_surface_bufmgr = tbm_bufmgr_init (-1);
+       g_surface_bufmgr = tbm_bufmgr_init(-1);
 }
 
-static void
-_deinit_surface_bufmgr()
+static void _deinit_surface_bufmgr()
 {
-    if (!g_surface_bufmgr)
-        return;
+       if (!g_surface_bufmgr)
+               return;
 
-    tbm_bufmgr_deinit (g_surface_bufmgr);
-    g_surface_bufmgr = NULL;
+       tbm_bufmgr_deinit(g_surface_bufmgr);
+       g_surface_bufmgr = NULL;
 }
 
-static int
-_tbm_surface_internal_query_size (tbm_surface_h surface)
+static int _tbm_surface_internal_query_size(tbm_surface_h surface)
 {
-    TBM_RETURN_VAL_IF_FAIL (surface, 0);
+       TBM_RETURN_VAL_IF_FAIL(surface, 0);
 
-    struct _tbm_surface *surf = (struct _tbm_surface *) surface;
-    struct _tbm_bufmgr *mgr = surf->bufmgr;
-    int size = 0;
+       struct _tbm_surface *surf = (struct _tbm_surface *)surface;
+       struct _tbm_bufmgr *mgr = surf->bufmgr;
+       int size = 0;
 
-    TBM_RETURN_VAL_IF_FAIL (mgr != NULL, 0);
-    TBM_RETURN_VAL_IF_FAIL (surf->info.width > 0, 0);
-    TBM_RETURN_VAL_IF_FAIL (surf->info.height > 0, 0);
-    TBM_RETURN_VAL_IF_FAIL (surf->info.format > 0, 0);
+       TBM_RETURN_VAL_IF_FAIL(mgr != NULL, 0);
+       TBM_RETURN_VAL_IF_FAIL(surf->info.width > 0, 0);
+       TBM_RETURN_VAL_IF_FAIL(surf->info.height > 0, 0);
+       TBM_RETURN_VAL_IF_FAIL(surf->info.format > 0, 0);
 
-    if (!mgr->backend->surface_get_size)
-        return 0;
+       if (!mgr->backend->surface_get_size)
+               return 0;
 
-    size = mgr->backend->surface_get_size (surf, surf->info.width, surf->info.height, surf->info.format);
+       size = mgr->backend->surface_get_size(surf, surf->info.width, surf->info.height, surf->info.format);
 
-    return size;
+       return size;
 }
 
-static int
-_tbm_surface_internal_query_plane_data (tbm_surface_h surface, int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch, int *bo_idx)
+static int _tbm_surface_internal_query_plane_data(tbm_surface_h surface, int plane_idx, uint32_t * size, uint32_t * offset, uint32_t * pitch, int *bo_idx)
 {
-    TBM_RETURN_VAL_IF_FAIL (surface, 0);
-    TBM_RETURN_VAL_IF_FAIL (plane_idx > -1, 0);
+       TBM_RETURN_VAL_IF_FAIL(surface, 0);
+       TBM_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
 
-    struct _tbm_surface *surf = (struct _tbm_surface *) surface;
-    struct _tbm_bufmgr *mgr = surf->bufmgr;
-    int ret = 0;
+       struct _tbm_surface *surf = (struct _tbm_surface *)surface;
+       struct _tbm_bufmgr *mgr = surf->bufmgr;
+       int ret = 0;
 
-    TBM_RETURN_VAL_IF_FAIL (mgr != NULL, 0);
-    TBM_RETURN_VAL_IF_FAIL (surf->info.width > 0, 0);
-    TBM_RETURN_VAL_IF_FAIL (surf->info.height > 0, 0);
-    TBM_RETURN_VAL_IF_FAIL (surf->info.format > 0, 0);
+       TBM_RETURN_VAL_IF_FAIL(mgr != NULL, 0);
+       TBM_RETURN_VAL_IF_FAIL(surf->info.width > 0, 0);
+       TBM_RETURN_VAL_IF_FAIL(surf->info.height > 0, 0);
+       TBM_RETURN_VAL_IF_FAIL(surf->info.format > 0, 0);
 
-    if (!mgr->backend->surface_get_plane_data)
-        return 0;
+       if (!mgr->backend->surface_get_plane_data)
+               return 0;
 
-    ret = mgr->backend->surface_get_plane_data (surf, surf->info.width, surf->info.height, surf->info.format, plane_idx, size, offset, pitch, bo_idx);
-    if (!ret)
-        return 0;
+       ret = mgr->backend->surface_get_plane_data(surf, surf->info.width, surf->info.height, surf->info.format, plane_idx, size, offset, pitch, bo_idx);
+       if (!ret)
+               return 0;
 
-    return 1;
+       return 1;
 }
 
-static int
-_tbm_surface_internal_query_num_bos (tbm_format format)
+static int _tbm_surface_internal_query_num_bos(tbm_format format)
 {
-    TBM_RETURN_VAL_IF_FAIL (format > 0, 0);
-    struct _tbm_bufmgr *mgr;
-    int ret = 0;
+       TBM_RETURN_VAL_IF_FAIL(format > 0, 0);
+       struct _tbm_bufmgr *mgr;
+       int ret = 0;
 
-    mgr = g_surface_bufmgr;
+       mgr = g_surface_bufmgr;
 
-    if (!mgr->backend->surface_get_num_bos)
-        return 0;
+       if (!mgr->backend->surface_get_num_bos)
+               return 0;
 
-    ret = mgr->backend->surface_get_num_bos (format);
-    if (!ret)
-        return 0;
+       ret = mgr->backend->surface_get_num_bos(format);
+       if (!ret)
+               return 0;
 
-    return ret;
+       return ret;
 }
 
-static void
-_tbm_surface_internal_destroy (tbm_surface_h surface)
+static void _tbm_surface_internal_destroy(tbm_surface_h surface)
 {
-    int i;
+       int i;
        tbm_bufmgr bufmgr = surface->bufmgr;
+       tbm_user_data *old_data = NULL, *tmp = NULL;
 
-    for (i = 0; i < surface->num_bos; i++)
-    {
-        tbm_bo_unref (surface->bos[i]);
-        surface->bos[i] = NULL;
-    }
-
-    LIST_DEL (&surface->item_link);
-
-    free (surface);
-    surface = NULL;
-
-    if(LIST_IS_EMPTY (&bufmgr->surf_list))
-    {
-        LIST_DELINIT (&bufmgr->surf_list);
-        _deinit_surface_bufmgr ();
-    }
-
-}
-
-
-int
-tbm_surface_internal_query_supported_formats (uint32_t **formats, uint32_t *num)
-{
-    struct _tbm_bufmgr *mgr;
-    int ret = 0;
-
-    _tbm_surface_mutex_lock();
-
-    if (!g_surface_bufmgr)
-    {
-        _init_surface_bufmgr();
-        LIST_INITHEAD (&g_surface_bufmgr->surf_list);
-    }
-
-    mgr = g_surface_bufmgr;
-
-    if (!mgr->backend->surface_supported_format)
-    {
-        _tbm_surface_mutex_unlock();
-        return 0;
-    }
-
-    ret = mgr->backend->surface_supported_format (formats, num);
-
-    _tbm_surface_mutex_unlock();
-
-    return ret;
-}
-
-
-int tbm_surface_internal_get_num_planes (tbm_format format)
-{
-    int num_planes = 0;
-
-    switch (format)
-    {
-        case TBM_FORMAT_C8:
-        case TBM_FORMAT_RGB332:
-        case TBM_FORMAT_BGR233:
-        case TBM_FORMAT_XRGB4444:
-        case TBM_FORMAT_XBGR4444:
-        case TBM_FORMAT_RGBX4444:
-        case TBM_FORMAT_BGRX4444:
-        case TBM_FORMAT_ARGB4444:
-        case TBM_FORMAT_ABGR4444:
-        case TBM_FORMAT_RGBA4444:
-        case TBM_FORMAT_BGRA4444:
-        case TBM_FORMAT_XRGB1555:
-        case TBM_FORMAT_XBGR1555:
-        case TBM_FORMAT_RGBX5551:
-        case TBM_FORMAT_BGRX5551:
-        case TBM_FORMAT_ARGB1555:
-        case TBM_FORMAT_ABGR1555:
-        case TBM_FORMAT_RGBA5551:
-        case TBM_FORMAT_BGRA5551:
-        case TBM_FORMAT_RGB565:
-        case TBM_FORMAT_BGR565:
-        case TBM_FORMAT_RGB888:
-        case TBM_FORMAT_BGR888:
-        case TBM_FORMAT_XRGB8888:
-        case TBM_FORMAT_XBGR8888:
-        case TBM_FORMAT_RGBX8888:
-        case TBM_FORMAT_BGRX8888:
-        case TBM_FORMAT_ARGB8888:
-        case TBM_FORMAT_ABGR8888:
-        case TBM_FORMAT_RGBA8888:
-        case TBM_FORMAT_BGRA8888:
-        case TBM_FORMAT_XRGB2101010:
-        case TBM_FORMAT_XBGR2101010:
-        case TBM_FORMAT_RGBX1010102:
-        case TBM_FORMAT_BGRX1010102:
-        case TBM_FORMAT_ARGB2101010:
-        case TBM_FORMAT_ABGR2101010:
-        case TBM_FORMAT_RGBA1010102:
-        case TBM_FORMAT_BGRA1010102:
-        case TBM_FORMAT_YUYV:
-        case TBM_FORMAT_YVYU:
-        case TBM_FORMAT_UYVY:
-        case TBM_FORMAT_VYUY:
-        case TBM_FORMAT_AYUV:
-            num_planes = 1;
-            break;
-        case TBM_FORMAT_NV12:
-        case TBM_FORMAT_NV21:
-        case TBM_FORMAT_NV16:
-        case TBM_FORMAT_NV61:
-            num_planes = 2;
-            break;
-        case TBM_FORMAT_YUV410:
-        case TBM_FORMAT_YVU410:
-        case TBM_FORMAT_YUV411:
-        case TBM_FORMAT_YVU411:
-        case TBM_FORMAT_YUV420:
-        case TBM_FORMAT_YVU420:
-        case TBM_FORMAT_YUV422:
-        case TBM_FORMAT_YVU422:
-        case TBM_FORMAT_YUV444:
-        case TBM_FORMAT_YVU444:
-            num_planes = 3;
-            break;
-
-        default :
-            break;
-    }
-
-    return num_planes;
-}
-
-int tbm_surface_internal_get_bpp (tbm_format format)
-{
-    int bpp = 0;
-
-    switch (format)
-    {
-        case TBM_FORMAT_C8:
-        case TBM_FORMAT_RGB332:
-        case TBM_FORMAT_BGR233:
-            bpp = 8;
-            break;
-        case TBM_FORMAT_XRGB4444:
-        case TBM_FORMAT_XBGR4444:
-        case TBM_FORMAT_RGBX4444:
-        case TBM_FORMAT_BGRX4444:
-        case TBM_FORMAT_ARGB4444:
-        case TBM_FORMAT_ABGR4444:
-        case TBM_FORMAT_RGBA4444:
-        case TBM_FORMAT_BGRA4444:
-        case TBM_FORMAT_XRGB1555:
-        case TBM_FORMAT_XBGR1555:
-        case TBM_FORMAT_RGBX5551:
-        case TBM_FORMAT_BGRX5551:
-        case TBM_FORMAT_ARGB1555:
-        case TBM_FORMAT_ABGR1555:
-        case TBM_FORMAT_RGBA5551:
-        case TBM_FORMAT_BGRA5551:
-        case TBM_FORMAT_RGB565:
-        case TBM_FORMAT_BGR565:
-            bpp = 16;
-            break;
-        case TBM_FORMAT_RGB888:
-        case TBM_FORMAT_BGR888:
-            bpp = 24;
-            break;
-        case TBM_FORMAT_XRGB8888:
-        case TBM_FORMAT_XBGR8888:
-        case TBM_FORMAT_RGBX8888:
-        case TBM_FORMAT_BGRX8888:
-        case TBM_FORMAT_ARGB8888:
-        case TBM_FORMAT_ABGR8888:
-        case TBM_FORMAT_RGBA8888:
-        case TBM_FORMAT_BGRA8888:
-        case TBM_FORMAT_XRGB2101010:
-        case TBM_FORMAT_XBGR2101010:
-        case TBM_FORMAT_RGBX1010102:
-        case TBM_FORMAT_BGRX1010102:
-        case TBM_FORMAT_ARGB2101010:
-        case TBM_FORMAT_ABGR2101010:
-        case TBM_FORMAT_RGBA1010102:
-        case TBM_FORMAT_BGRA1010102:
-        case TBM_FORMAT_YUYV:
-        case TBM_FORMAT_YVYU:
-        case TBM_FORMAT_UYVY:
-        case TBM_FORMAT_VYUY:
-        case TBM_FORMAT_AYUV:
-            bpp = 32;
-            break;
-        case TBM_FORMAT_NV12:
-        case TBM_FORMAT_NV21:
-            bpp = 12;
-            break;
-        case TBM_FORMAT_NV16:
-        case TBM_FORMAT_NV61:
-            bpp = 16;
-            break;
-        case TBM_FORMAT_YUV410:
-        case TBM_FORMAT_YVU410:
-            bpp = 9;
-            break;
-        case TBM_FORMAT_YUV411:
-        case TBM_FORMAT_YVU411:
-        case TBM_FORMAT_YUV420:
-        case TBM_FORMAT_YVU420:
-            bpp = 12;
-            break;
-        case TBM_FORMAT_YUV422:
-        case TBM_FORMAT_YVU422:
-            bpp = 16;
-            break;
-        case TBM_FORMAT_YUV444:
-        case TBM_FORMAT_YVU444:
-            bpp = 24;
-            break;
-        default :
-            break;
-    }
-
-    return bpp;
-}
-
-tbm_surface_h
-tbm_surface_internal_create_with_flags (int width, int height, int format, int flags)
-{
-    TBM_RETURN_VAL_IF_FAIL (width > 0, NULL);
-    TBM_RETURN_VAL_IF_FAIL (height > 0, NULL);
-
-    struct _tbm_bufmgr *mgr;
-    struct _tbm_surface *surf = NULL;
-    uint32_t size = 0;
-    uint32_t offset = 0;
-    uint32_t stride = 0;
-    uint32_t bo_size = 0;
-    int bo_idx;
-    int i, j;
-
-    _tbm_surface_mutex_lock();
-
-    if (!g_surface_bufmgr)
-    {
-        _init_surface_bufmgr();
-        LIST_INITHEAD (&g_surface_bufmgr->surf_list);
-    }
-
-    mgr = g_surface_bufmgr;
-    if (!TBM_BUFMGR_IS_VALID(mgr))
-    {
-        _tbm_surface_mutex_unlock();
-        return NULL;
-    }
-    surf = calloc (1, sizeof(struct _tbm_surface));
-    if (!surf)
-    {
-        _tbm_surface_mutex_unlock();
-        return NULL;
-    }
-
-    surf->bufmgr = mgr;
-    surf->info.width = width;
-    surf->info.height = height;
-    surf->info.format = format;
-    surf->info.bpp = tbm_surface_internal_get_bpp (format);
-    surf->info.size = _tbm_surface_internal_query_size (surf);
-    surf->info.num_planes = tbm_surface_internal_get_num_planes(format);
-    surf->num_bos = _tbm_surface_internal_query_num_bos(format);
-    surf->refcnt = 1;
-
-    /* get size, stride and offset bo_idx*/
-    for (i = 0; i < surf->info.num_planes; i++)
-    {
-        _tbm_surface_internal_query_plane_data (surf, i, &size, &offset, &stride, &bo_idx);
-        surf->info.planes[i].size = size;
-        surf->info.planes[i].offset = offset;
-        surf->info.planes[i].stride = stride;
-        surf->planes_bo_idx[i] = bo_idx;
-    }
-
-    surf->flags = flags;
-
-    for (i = 0; i < surf->num_bos; i++)
-    {
-        bo_size = 0;
-        for (j = 0; j < surf->info.num_planes; j++)
-        {
-            if (surf->planes_bo_idx[j] == i)
-                bo_size += surf->info.planes[j].size;
-        }
-        surf->bos[i] = tbm_bo_alloc (mgr, bo_size, flags);
-        if (!surf->bos[i]) {
-            for (j = 0; j < i; j++)
-                tbm_bo_unref (surf->bos[j]);
-
-            free (surf);
-            surf = NULL;
-
-            if(LIST_IS_EMPTY (&mgr->surf_list))
-            {
-                LIST_DELINIT (&mgr->surf_list);
-                _deinit_surface_bufmgr ();
-            }
-
-            _tbm_surface_mutex_unlock();
-            return NULL;
-        }
-    }
-
-    LIST_ADD (&surf->item_link, &mgr->surf_list);
-
-    _tbm_surface_mutex_unlock();
-
-    return surf;
-}
-
-tbm_surface_h
-tbm_surface_internal_create_with_bos (tbm_surface_info_s *info, tbm_bo *bos, int num)
-{
-    TBM_RETURN_VAL_IF_FAIL (bos, NULL);
-    TBM_RETURN_VAL_IF_FAIL (info, NULL);
-    TBM_RETURN_VAL_IF_FAIL (num == 1 || info->num_planes == num, NULL);
-
-    struct _tbm_bufmgr *mgr;
-    struct _tbm_surface *surf = NULL;
-    int i;
-
-    _tbm_surface_mutex_lock();
-
-    if (!g_surface_bufmgr)
-    {
-        _init_surface_bufmgr();
-        LIST_INITHEAD (&g_surface_bufmgr->surf_list);
-    }
-
-    mgr = g_surface_bufmgr;
-    if (!TBM_BUFMGR_IS_VALID(mgr))
-    {
-        _tbm_surface_mutex_unlock();
-        return NULL;
-    }
-
-    surf = calloc (1, sizeof(struct _tbm_surface));
-    if (!surf)
-    {
-        _tbm_surface_mutex_unlock();
-        return NULL;
-    }
-
-    surf->bufmgr = mgr;
-    surf->info.width = info->width;
-    surf->info.height = info->height;
-    surf->info.format = info->format;
-    surf->info.bpp = info->bpp;
-    surf->info.num_planes = info->num_planes;
-    surf->refcnt = 1;
-
-    /* get size, stride and offset */
-    for (i = 0; i < info->num_planes; i++)
-    {
-        surf->info.planes[i].offset = info->planes[i].offset;
-        surf->info.planes[i].stride = info->planes[i].stride;
+       for (i = 0; i < surface->num_bos; i++) {
+               surface->bos[i]->surface = NULL;
 
-        if (info->planes[i].size > 0)
-            surf->info.planes[i].size = info->planes[i].size;
-        else
-            surf->info.planes[i].size += surf->info.planes[i].stride * info->height;
+               tbm_bo_unref(surface->bos[i]);
+               surface->bos[i] = NULL;
+       }
 
-        if (num == 1)
-            surf->planes_bo_idx[i] = 0;
-        else
-            surf->planes_bo_idx[i] = i;
-    }
+       /* destory the user_data_list */
+       if (!LIST_IS_EMPTY(&surface->user_data_list)) {
+               LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &surface->user_data_list, item_link) {
+                       TBM_LOG("[tbm_surface:%d] free user_data \n",
+                               getpid());
+                       user_data_delete(old_data);
+               }
+       }
 
-    if (info->size > 0)
-    {
-        surf->info.size = info->size;
-    }
-    else
-    {
-        surf->info.size = 0;
-        for (i = 0; i < info->num_planes; i++)
-        {
-            surf->info.size += surf->info.planes[i].size;
-        }
-    }
+       LIST_DEL(&surface->item_link);
 
-    surf->flags = TBM_BO_DEFAULT;
+       free(surface);
+       surface = NULL;
 
-    /* create only one bo */
-    surf->num_bos = num;
-    for (i = 0; i < num; i++)
-    {
-        if (bos[i] == NULL)
-            goto bail1;
+       if (LIST_IS_EMPTY(&bufmgr->surf_list)) {
+               LIST_DELINIT(&bufmgr->surf_list);
+               _deinit_surface_bufmgr();
+       }
+}
 
-        surf->bos[i] = tbm_bo_ref(bos[i]);
-    }
+int tbm_surface_internal_query_supported_formats(uint32_t ** formats, uint32_t * num)
+{
+       struct _tbm_bufmgr *mgr;
+       int ret = 0;
 
-    LIST_ADD (&surf->item_link, &mgr->surf_list);
+       _tbm_surface_mutex_lock();
 
-    _tbm_surface_mutex_unlock();
+       if (!g_surface_bufmgr) {
+               _init_surface_bufmgr();
+               LIST_INITHEAD(&g_surface_bufmgr->surf_list);
+       }
 
-    return surf;
-bail1:
-    for (i = 0; i < num; i++)
-    {
-        if (surf->bos[i])
-        {
-            tbm_bo_unref (surf->bos[i]);
-            surf->bos[i] = NULL;
-        }
-    }
+       mgr = g_surface_bufmgr;
 
-    free (surf);
-    surf = NULL;
+       if (!mgr->backend->surface_supported_format) {
+               _tbm_surface_mutex_unlock();
+               return 0;
+       }
 
-    if(LIST_IS_EMPTY (&g_surface_bufmgr->surf_list))
-    {
-        LIST_DELINIT (&g_surface_bufmgr->surf_list);
-        _deinit_surface_bufmgr ();
-    }
+       ret = mgr->backend->surface_supported_format(formats, num);
 
-    _tbm_surface_mutex_unlock();
+       _tbm_surface_mutex_unlock();
 
-    return NULL;
+       return ret;
 }
 
+int tbm_surface_internal_get_num_planes(tbm_format format)
+{
+       int num_planes = 0;
+
+       switch (format) {
+       case TBM_FORMAT_C8:
+       case TBM_FORMAT_RGB332:
+       case TBM_FORMAT_BGR233:
+       case TBM_FORMAT_XRGB4444:
+       case TBM_FORMAT_XBGR4444:
+       case TBM_FORMAT_RGBX4444:
+       case TBM_FORMAT_BGRX4444:
+       case TBM_FORMAT_ARGB4444:
+       case TBM_FORMAT_ABGR4444:
+       case TBM_FORMAT_RGBA4444:
+       case TBM_FORMAT_BGRA4444:
+       case TBM_FORMAT_XRGB1555:
+       case TBM_FORMAT_XBGR1555:
+       case TBM_FORMAT_RGBX5551:
+       case TBM_FORMAT_BGRX5551:
+       case TBM_FORMAT_ARGB1555:
+       case TBM_FORMAT_ABGR1555:
+       case TBM_FORMAT_RGBA5551:
+       case TBM_FORMAT_BGRA5551:
+       case TBM_FORMAT_RGB565:
+       case TBM_FORMAT_BGR565:
+       case TBM_FORMAT_RGB888:
+       case TBM_FORMAT_BGR888:
+       case TBM_FORMAT_XRGB8888:
+       case TBM_FORMAT_XBGR8888:
+       case TBM_FORMAT_RGBX8888:
+       case TBM_FORMAT_BGRX8888:
+       case TBM_FORMAT_ARGB8888:
+       case TBM_FORMAT_ABGR8888:
+       case TBM_FORMAT_RGBA8888:
+       case TBM_FORMAT_BGRA8888:
+       case TBM_FORMAT_XRGB2101010:
+       case TBM_FORMAT_XBGR2101010:
+       case TBM_FORMAT_RGBX1010102:
+       case TBM_FORMAT_BGRX1010102:
+       case TBM_FORMAT_ARGB2101010:
+       case TBM_FORMAT_ABGR2101010:
+       case TBM_FORMAT_RGBA1010102:
+       case TBM_FORMAT_BGRA1010102:
+       case TBM_FORMAT_YUYV:
+       case TBM_FORMAT_YVYU:
+       case TBM_FORMAT_UYVY:
+       case TBM_FORMAT_VYUY:
+       case TBM_FORMAT_AYUV:
+               num_planes = 1;
+               break;
+       case TBM_FORMAT_NV12:
+       case TBM_FORMAT_NV21:
+       case TBM_FORMAT_NV16:
+       case TBM_FORMAT_NV61:
+               num_planes = 2;
+               break;
+       case TBM_FORMAT_YUV410:
+       case TBM_FORMAT_YVU410:
+       case TBM_FORMAT_YUV411:
+       case TBM_FORMAT_YVU411:
+       case TBM_FORMAT_YUV420:
+       case TBM_FORMAT_YVU420:
+       case TBM_FORMAT_YUV422:
+       case TBM_FORMAT_YVU422:
+       case TBM_FORMAT_YUV444:
+       case TBM_FORMAT_YVU444:
+               num_planes = 3;
+               break;
+
+       default:
+               break;
+       }
+
+       return num_planes;
+}
 
-void
-tbm_surface_internal_destroy (tbm_surface_h surface)
+int tbm_surface_internal_get_bpp(tbm_format format)
 {
-    if (!surface)
-        return;
+       int bpp = 0;
+
+       switch (format) {
+       case TBM_FORMAT_C8:
+       case TBM_FORMAT_RGB332:
+       case TBM_FORMAT_BGR233:
+               bpp = 8;
+               break;
+       case TBM_FORMAT_XRGB4444:
+       case TBM_FORMAT_XBGR4444:
+       case TBM_FORMAT_RGBX4444:
+       case TBM_FORMAT_BGRX4444:
+       case TBM_FORMAT_ARGB4444:
+       case TBM_FORMAT_ABGR4444:
+       case TBM_FORMAT_RGBA4444:
+       case TBM_FORMAT_BGRA4444:
+       case TBM_FORMAT_XRGB1555:
+       case TBM_FORMAT_XBGR1555:
+       case TBM_FORMAT_RGBX5551:
+       case TBM_FORMAT_BGRX5551:
+       case TBM_FORMAT_ARGB1555:
+       case TBM_FORMAT_ABGR1555:
+       case TBM_FORMAT_RGBA5551:
+       case TBM_FORMAT_BGRA5551:
+       case TBM_FORMAT_RGB565:
+       case TBM_FORMAT_BGR565:
+               bpp = 16;
+               break;
+       case TBM_FORMAT_RGB888:
+       case TBM_FORMAT_BGR888:
+               bpp = 24;
+               break;
+       case TBM_FORMAT_XRGB8888:
+       case TBM_FORMAT_XBGR8888:
+       case TBM_FORMAT_RGBX8888:
+       case TBM_FORMAT_BGRX8888:
+       case TBM_FORMAT_ARGB8888:
+       case TBM_FORMAT_ABGR8888:
+       case TBM_FORMAT_RGBA8888:
+       case TBM_FORMAT_BGRA8888:
+       case TBM_FORMAT_XRGB2101010:
+       case TBM_FORMAT_XBGR2101010:
+       case TBM_FORMAT_RGBX1010102:
+       case TBM_FORMAT_BGRX1010102:
+       case TBM_FORMAT_ARGB2101010:
+       case TBM_FORMAT_ABGR2101010:
+       case TBM_FORMAT_RGBA1010102:
+       case TBM_FORMAT_BGRA1010102:
+       case TBM_FORMAT_YUYV:
+       case TBM_FORMAT_YVYU:
+       case TBM_FORMAT_UYVY:
+       case TBM_FORMAT_VYUY:
+       case TBM_FORMAT_AYUV:
+               bpp = 32;
+               break;
+       case TBM_FORMAT_NV12:
+       case TBM_FORMAT_NV21:
+               bpp = 12;
+               break;
+       case TBM_FORMAT_NV16:
+       case TBM_FORMAT_NV61:
+               bpp = 16;
+               break;
+       case TBM_FORMAT_YUV410:
+       case TBM_FORMAT_YVU410:
+               bpp = 9;
+               break;
+       case TBM_FORMAT_YUV411:
+       case TBM_FORMAT_YVU411:
+       case TBM_FORMAT_YUV420:
+       case TBM_FORMAT_YVU420:
+               bpp = 12;
+               break;
+       case TBM_FORMAT_YUV422:
+       case TBM_FORMAT_YVU422:
+               bpp = 16;
+               break;
+       case TBM_FORMAT_YUV444:
+       case TBM_FORMAT_YVU444:
+               bpp = 24;
+               break;
+       default:
+               break;
+       }
+
+       return bpp;
+}
 
-    _tbm_surface_mutex_lock();
+tbm_surface_h tbm_surface_internal_create_with_flags(int width, int height, int format, int flags)
+{
+       TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
+       TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
+
+       struct _tbm_bufmgr *mgr;
+       struct _tbm_surface *surf = NULL;
+       uint32_t size = 0;
+       uint32_t offset = 0;
+       uint32_t stride = 0;
+       uint32_t bo_size = 0;
+       int bo_idx;
+       int i, j;
+
+       _tbm_surface_mutex_lock();
+
+       if (!g_surface_bufmgr) {
+               _init_surface_bufmgr();
+               LIST_INITHEAD(&g_surface_bufmgr->surf_list);
+       }
+
+       mgr = g_surface_bufmgr;
+       if (!TBM_BUFMGR_IS_VALID(mgr)) {
+               _tbm_surface_mutex_unlock();
+               return NULL;
+       }
+       surf = calloc(1, sizeof(struct _tbm_surface));
+       if (!surf) {
+               _tbm_surface_mutex_unlock();
+               return NULL;
+       }
+
+       surf->bufmgr = mgr;
+       surf->info.width = width;
+       surf->info.height = height;
+       surf->info.format = format;
+       surf->info.bpp = tbm_surface_internal_get_bpp(format);
+       surf->info.size = _tbm_surface_internal_query_size(surf);
+       surf->info.num_planes = tbm_surface_internal_get_num_planes(format);
+       surf->num_bos = _tbm_surface_internal_query_num_bos(format);
+       surf->refcnt = 1;
+
+       /* get size, stride and offset bo_idx */
+       for (i = 0; i < surf->info.num_planes; i++) {
+               _tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx);
+               surf->info.planes[i].size = size;
+               surf->info.planes[i].offset = offset;
+               surf->info.planes[i].stride = stride;
+               surf->planes_bo_idx[i] = bo_idx;
+       }
+
+       surf->flags = flags;
+
+       for (i = 0; i < surf->num_bos; i++) {
+               bo_size = 0;
+               for (j = 0; j < surf->info.num_planes; j++) {
+                       if (surf->planes_bo_idx[j] == i)
+                               bo_size += surf->info.planes[j].size;
+               }
+               surf->bos[i] = tbm_bo_alloc(mgr, bo_size, flags);
+               if (!surf->bos[i]) {
+                       for (j = 0; j < i; j++) {
+                               if (surf->bos[j])
+                                       tbm_bo_unref(surf->bos[j]);
+                       }
+
+                       free(surf);
+                       surf = NULL;
+
+                       if (LIST_IS_EMPTY(&mgr->surf_list)) {
+                               LIST_DELINIT(&mgr->surf_list);
+                               _deinit_surface_bufmgr();
+                       }
+
+                       _tbm_surface_mutex_unlock();
+                       return NULL;
+               }
+               _tbm_bo_set_surface(surf->bos[i], surf);
+
+       }
+
+       LIST_ADD(&surf->item_link, &mgr->surf_list);
+
+       _tbm_surface_mutex_unlock();
+
+       return surf;
+}
 
-    surface->refcnt--;
+tbm_surface_h tbm_surface_internal_create_with_bos(tbm_surface_info_s * info, tbm_bo * bos, int num)
+{
+       TBM_RETURN_VAL_IF_FAIL(bos, NULL);
+       TBM_RETURN_VAL_IF_FAIL(info, NULL);
+       TBM_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
+
+       struct _tbm_bufmgr *mgr;
+       struct _tbm_surface *surf = NULL;
+       int i;
+
+       _tbm_surface_mutex_lock();
+
+       if (!g_surface_bufmgr) {
+               _init_surface_bufmgr();
+               LIST_INITHEAD(&g_surface_bufmgr->surf_list);
+       }
+
+       mgr = g_surface_bufmgr;
+       if (!TBM_BUFMGR_IS_VALID(mgr)) {
+               _tbm_surface_mutex_unlock();
+               return NULL;
+       }
+
+       surf = calloc(1, sizeof(struct _tbm_surface));
+       if (!surf) {
+               _tbm_surface_mutex_unlock();
+               return NULL;
+       }
+
+       surf->bufmgr = mgr;
+       surf->info.width = info->width;
+       surf->info.height = info->height;
+       surf->info.format = info->format;
+       surf->info.bpp = info->bpp;
+       surf->info.num_planes = info->num_planes;
+       surf->refcnt = 1;
+
+       /* get size, stride and offset */
+       for (i = 0; i < info->num_planes; i++) {
+               surf->info.planes[i].offset = info->planes[i].offset;
+               surf->info.planes[i].stride = info->planes[i].stride;
+
+               if (info->planes[i].size > 0)
+                       surf->info.planes[i].size = info->planes[i].size;
+               else
+                       surf->info.planes[i].size += surf->info.planes[i].stride * info->height;
+
+               if (num == 1)
+                       surf->planes_bo_idx[i] = 0;
+               else
+                       surf->planes_bo_idx[i] = i;
+       }
+
+       if (info->size > 0) {
+               surf->info.size = info->size;
+       } else {
+               surf->info.size = 0;
+               for (i = 0; i < info->num_planes; i++)
+                       surf->info.size += surf->info.planes[i].size;
+       }
+
+       surf->flags = TBM_BO_DEFAULT;
+
+       /* create only one bo */
+       surf->num_bos = num;
+       for (i = 0; i < num; i++) {
+               if (bos[i] == NULL)
+                       goto bail1;
+
+               surf->bos[i] = tbm_bo_ref(bos[i]);
+               _tbm_bo_set_surface(bos[i], surf);
+       }
+
+       LIST_ADD(&surf->item_link, &mgr->surf_list);
+
+       _tbm_surface_mutex_unlock();
+
+       return surf;
+ bail1:
+       for (i = 0; i < num; i++) {
+               if (surf->bos[i]) {
+                       tbm_bo_unref(surf->bos[i]);
+                       surf->bos[i] = NULL;
+               }
+       }
+
+       free(surf);
+       surf = NULL;
+
+       if (LIST_IS_EMPTY(&g_surface_bufmgr->surf_list)) {
+               LIST_DELINIT(&g_surface_bufmgr->surf_list);
+               _deinit_surface_bufmgr();
+       }
+
+       _tbm_surface_mutex_unlock();
+
+       return NULL;
+}
 
-    if (surface->refcnt > 0) {
-        _tbm_surface_mutex_unlock();
-        return;
-    }
+void tbm_surface_internal_destroy(tbm_surface_h surface)
+{
+       if (!surface)
+               return;
 
-    if (surface->refcnt == 0)
-        _tbm_surface_internal_destroy(surface);
+       _tbm_surface_mutex_lock();
 
-    _tbm_surface_mutex_unlock();
+       surface->refcnt--;
+
+       if (surface->refcnt > 0) {
+               _tbm_surface_mutex_unlock();
+               return;
+       }
+
+       if (surface->refcnt == 0)
+               _tbm_surface_internal_destroy(surface);
+
+       _tbm_surface_mutex_unlock();
 }
 
+void tbm_surface_internal_ref(tbm_surface_h surface)
+{
+       TBM_RETURN_IF_FAIL(surface);
+
+       _tbm_surface_mutex_lock();
+
+       surface->refcnt++;
 
-void
-tbm_surface_internal_ref (tbm_surface_h surface)
+       _tbm_surface_mutex_unlock();
+}
+
+void tbm_surface_internal_unref(tbm_surface_h surface)
 {
-    TBM_RETURN_IF_FAIL (surface);
+       TBM_RETURN_IF_FAIL(surface);
+
+       _tbm_surface_mutex_lock();
 
-    _tbm_surface_mutex_lock();
+       surface->refcnt--;
 
-    surface->refcnt++;
+       if (surface->refcnt > 0) {
+               _tbm_surface_mutex_unlock();
+               return;
+       }
 
-    _tbm_surface_mutex_unlock();
+       if (surface->refcnt == 0)
+               _tbm_surface_internal_destroy(surface);
+
+       _tbm_surface_mutex_unlock();
 }
 
-void
-tbm_surface_internal_unref (tbm_surface_h surface)
+int tbm_surface_internal_get_num_bos(tbm_surface_h surface)
 {
-    TBM_RETURN_IF_FAIL (surface);
+       TBM_RETURN_VAL_IF_FAIL(surface, 0);
 
-    _tbm_surface_mutex_lock();
+       struct _tbm_surface *surf;
+       int num;
 
-    surface->refcnt--;
+       _tbm_surface_mutex_lock();
 
-    if (surface->refcnt > 0) {
-        _tbm_surface_mutex_unlock();
-        return;
-    }
+       surf = (struct _tbm_surface *)surface;
+       num = surf->num_bos;
 
-    if (surface->refcnt == 0)
-        _tbm_surface_internal_destroy(surface);
+       _tbm_surface_mutex_unlock();
 
-    _tbm_surface_mutex_unlock();
+       return num;
 }
 
-int
-tbm_surface_internal_get_num_bos (tbm_surface_h surface)
+tbm_bo tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
 {
-    TBM_RETURN_VAL_IF_FAIL (surface, 0);
+       TBM_RETURN_VAL_IF_FAIL(surface, NULL);
+       TBM_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
 
-    struct _tbm_surface *surf;
-    int num;
+       struct _tbm_surface *surf;
+       tbm_bo bo;
 
-    _tbm_surface_mutex_lock();
+       _tbm_surface_mutex_lock();
 
-    surf = (struct _tbm_surface *) surface;
-    num = surf->num_bos;
+       surf = (struct _tbm_surface *)surface;
+       bo = surf->bos[bo_idx];
 
-    _tbm_surface_mutex_unlock();
+       _tbm_surface_mutex_unlock();
 
-    return num;
+       return bo;
 }
 
-tbm_bo
-tbm_surface_internal_get_bo (tbm_surface_h surface, int bo_idx)
+int tbm_surface_internal_get_size(tbm_surface_h surface)
 {
-    TBM_RETURN_VAL_IF_FAIL (surface, NULL);
-    TBM_RETURN_VAL_IF_FAIL (bo_idx > -1, NULL);
+       TBM_RETURN_VAL_IF_FAIL(surface, 0);
 
-    struct _tbm_surface *surf;
-    tbm_bo bo;
+       struct _tbm_surface *surf;
+       unsigned int size;
 
-    _tbm_surface_mutex_lock();
+       _tbm_surface_mutex_lock();
 
-    surf = (struct _tbm_surface *) surface;
-    bo = surf->bos[bo_idx];
+       surf = (struct _tbm_surface *)surface;
+       size = surf->info.size;
 
-    _tbm_surface_mutex_unlock();
+       _tbm_surface_mutex_unlock();
 
-    return bo;
+       return size;
 }
 
-int
-tbm_surface_internal_get_size (tbm_surface_h surface)
+int tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx, uint32_t * size, uint32_t * offset, uint32_t * pitch)
 {
-    TBM_RETURN_VAL_IF_FAIL (surface, 0);
+       TBM_RETURN_VAL_IF_FAIL(surface, 0);
+       TBM_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
+
+       struct _tbm_surface *surf;
+
+       _tbm_surface_mutex_lock();
 
-    struct _tbm_surface *surf;
-    unsigned int size;
+       surf = (struct _tbm_surface *)surface;
 
-    _tbm_surface_mutex_lock();
+       if (plane_idx >= surf->info.num_planes) {
+               _tbm_surface_mutex_unlock();
+               return 0;
+       }
 
-    surf = (struct _tbm_surface *) surface;
-    size = surf->info.size;
+       if (size)
+               *size = surf->info.planes[plane_idx].size;
 
-    _tbm_surface_mutex_unlock();
+       if (offset)
+               *offset = surf->info.planes[plane_idx].offset;
 
-    return size;
+       if (pitch)
+               *pitch = surf->info.planes[plane_idx].stride;
+
+       _tbm_surface_mutex_unlock();
+
+       return 1;
+}
+
+int tbm_surface_internal_get_info(tbm_surface_h surface, int opt, tbm_surface_info_s * info, int map)
+{
+       struct _tbm_surface *surf;
+       tbm_bo_handle bo_handles[4];
+       int i, j;
+
+       _tbm_surface_mutex_lock();
+
+       memset(bo_handles, 0, sizeof(tbm_bo_handle) * 4);
+
+       surf = (struct _tbm_surface *)surface;
+
+       info->width = surf->info.width;
+       info->height = surf->info.height;
+       info->format = surf->info.format;
+       info->bpp = surf->info.bpp;
+       info->size = surf->info.size;
+       info->num_planes = surf->info.num_planes;
+
+       if (map == 1) {
+               for (i = 0; i < surf->num_bos; i++) {
+                       bo_handles[i] = tbm_bo_map(surf->bos[i], TBM_DEVICE_CPU, opt);
+                       if (bo_handles[i].ptr == NULL) {
+                               for (j = 0; j < i; j++)
+                                       tbm_bo_unmap(surf->bos[j]);
+
+                               _tbm_surface_mutex_unlock();
+                               return 0;
+                       }
+               }
+       } else {
+               for (i = 0; i < surf->num_bos; i++) {
+                       bo_handles[i] = tbm_bo_get_handle(surf->bos[i], TBM_DEVICE_CPU);
+                       if (bo_handles[i].ptr == NULL) {
+                               _tbm_surface_mutex_unlock();
+                               return 0;
+                       }
+               }
+       }
+
+       for (i = 0; i < surf->info.num_planes; i++) {
+               info->planes[i].size = surf->info.planes[i].size;
+               info->planes[i].offset = surf->info.planes[i].offset;
+               info->planes[i].stride = surf->info.planes[i].stride;
+               info->planes[i].ptr = bo_handles[surf->planes_bo_idx[i]].ptr + surf->info.planes[i].offset;
+       }
+
+       _tbm_surface_mutex_unlock();
+
+       return 1;
 }
 
-int
-tbm_surface_internal_get_plane_data (tbm_surface_h surface, int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch)
+void tbm_surface_internal_unmap(tbm_surface_h surface)
 {
-    TBM_RETURN_VAL_IF_FAIL (surface, 0);
-    TBM_RETURN_VAL_IF_FAIL (plane_idx > -1, 0);
+       struct _tbm_surface *surf;
+       int i;
+
+       _tbm_surface_mutex_lock();
 
-    struct _tbm_surface *surf;
+       surf = (struct _tbm_surface *)surface;
 
-    _tbm_surface_mutex_lock();
+       for (i = 0; i < surf->num_bos; i++)
+               tbm_bo_unmap(surf->bos[i]);
 
-    surf = (struct _tbm_surface *) surface;
+       _tbm_surface_mutex_unlock();
+}
+
+unsigned int tbm_surface_internal_get_width(tbm_surface_h surface)
+{
+       struct _tbm_surface *surf;
+       unsigned int width;
 
-    if (plane_idx >= surf->info.num_planes)
-    {
-        _tbm_surface_mutex_unlock();
-        return 0;
-    }
+       _tbm_surface_mutex_lock();
 
-    *size = surf->info.planes[plane_idx].size;
-    *offset = surf->info.planes[plane_idx].offset;
-    *pitch = surf->info.planes[plane_idx].stride;
+       surf = (struct _tbm_surface *)surface;
+       width = surf->info.width;
 
-    _tbm_surface_mutex_unlock();
+       _tbm_surface_mutex_unlock();
 
-    return 1;
+       return width;
 }
 
-int
-tbm_surface_internal_get_info (tbm_surface_h surface, int opt, tbm_surface_info_s *info, int map)
+unsigned int tbm_surface_internal_get_height(tbm_surface_h surface)
 {
-    struct _tbm_surface *surf;
-    tbm_bo_handle bo_handles[4];
-    int i, j;
+       struct _tbm_surface *surf;
+       unsigned int height;
 
-    _tbm_surface_mutex_lock();
+       _tbm_surface_mutex_lock();
 
-    memset (bo_handles, 0, sizeof(tbm_bo_handle) * 4);
+       surf = (struct _tbm_surface *)surface;
+       height = surf->info.height;
 
-    surf = (struct _tbm_surface *)surface;
+       _tbm_surface_mutex_unlock();
 
-    info->width = surf->info.width;
-    info->height = surf->info.height;
-    info->format = surf->info.format;
-    info->bpp = surf->info.bpp;
-    info->size = surf->info.size;
-    info->num_planes = surf->info.num_planes;
+       return height;
 
-    if (map == 1)
-    {
-        for (i = 0; i < surf->num_bos; i++)
-        {
-            bo_handles[i] = tbm_bo_map (surf->bos[i], TBM_DEVICE_CPU, opt);
-            if (bo_handles[i].ptr == NULL)
-            {
-                for (j = 0; j < i; j++)
-                    tbm_bo_unmap (surf->bos[j]);
+}
+
+tbm_format tbm_surface_internal_get_format(tbm_surface_h surface)
+{
+       struct _tbm_surface *surf;
+       tbm_format format;
 
-                _tbm_surface_mutex_unlock();
-                return 0;
-            }
-        }
-    }
-    else
-    {
-        for (i = 0; i < surf->num_bos; i++)
-        {
-            bo_handles[i] = tbm_bo_get_handle (surf->bos[i], TBM_DEVICE_CPU);
-            if (bo_handles[i].ptr == NULL)
-            {
-                _tbm_surface_mutex_unlock();
-                return 0;
-            }
-        }
-    }
+       _tbm_surface_mutex_lock();
 
-    for (i = 0; i < surf->info.num_planes; i++)
-    {
-        info->planes[i].size = surf->info.planes[i].size;
-        info->planes[i].offset = surf->info.planes[i].offset;
-        info->planes[i].stride = surf->info.planes[i].stride;
-        info->planes[i].ptr = bo_handles[surf->planes_bo_idx[i]].ptr + surf->info.planes[i].offset;
-    }
+       surf = (struct _tbm_surface *)surface;
+       format = surf->info.format;
 
-    _tbm_surface_mutex_unlock();
+       _tbm_surface_mutex_unlock();
 
-    return 1;
+       return format;
 }
 
-void
-tbm_surface_internal_unmap (tbm_surface_h surface)
+int tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
 {
-    struct _tbm_surface *surf;
-    int i;
+       TBM_RETURN_VAL_IF_FAIL(surface, 0);
+       TBM_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
+       struct _tbm_surface *surf;
+       int bo_idx;
 
-    _tbm_surface_mutex_lock();
+       _tbm_surface_mutex_lock();
 
-    surf = (struct _tbm_surface *)surface;
+       surf = (struct _tbm_surface *)surface;
+       bo_idx = surf->planes_bo_idx[plane_idx];
 
-    for (i = 0; i < surf->num_bos; i++)
-        tbm_bo_unmap (surf->bos[i]);
+       _tbm_surface_mutex_unlock();
 
-    _tbm_surface_mutex_unlock();
+       return bo_idx;
 }
 
-unsigned int
-tbm_surface_internal_get_width (tbm_surface_h surface)
+unsigned int _tbm_surface_internal_get_debug_pid(tbm_surface_h surface)
 {
-    struct _tbm_surface *surf;
-    unsigned int width;
+       TBM_RETURN_VAL_IF_FAIL(surface, 0);
 
-    _tbm_surface_mutex_lock();
+       return surface->debug_pid;
+}
+
+void tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
+{
+       TBM_RETURN_IF_FAIL(surface);
+
+       surface->debug_pid = pid;
+}
+
+int tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key, tbm_data_free data_free_func)
+{
+       TBM_RETURN_VAL_IF_FAIL(surface, 0);
+
+       tbm_user_data *data;
+
+       /* check if the data according to the key exist if so, return false. */
+       data = user_data_lookup(&surface->user_data_list, key);
+       if (data) {
+               TBM_LOG("[libtbm:%d] "
+                       "waring: %s:%d user data already exist. key:%ld\n",
+                       getpid(), __FUNCTION__, __LINE__, key);
+               return 0;
+       }
 
-    surf = (struct _tbm_surface *)surface;
-    width = surf->info.width;
+       data = user_data_create(key, data_free_func);
+       if (!data)
+               return 0;
 
-    _tbm_surface_mutex_unlock();
+       LIST_ADD(&data->item_link, &surface->user_data_list);
 
-    return width;
+       return 1;
 }
 
-unsigned int
-tbm_surface_internal_get_height (tbm_surface_h surface)
+int tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key, void *data)
 {
-    struct _tbm_surface *surf;
-    unsigned int height;
+       TBM_RETURN_VAL_IF_FAIL(surface, 0);
 
-    _tbm_surface_mutex_lock();
+       tbm_user_data *old_data;
 
-    surf = (struct _tbm_surface *)surface;
-    height = surf->info.height;
+       if (LIST_IS_EMPTY(&surface->user_data_list))
+               return 0;
 
-    _tbm_surface_mutex_unlock();
+       old_data = user_data_lookup(&surface->user_data_list, key);
+       if (!old_data)
+               return 0;
 
-    return height;
+       if (old_data->data && old_data->free_func)
+               old_data->free_func(old_data->data);
 
+       old_data->data = data;
+
+       return 1;
 }
 
-tbm_format
-tbm_surface_internal_get_format (tbm_surface_h surface)
+int tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key, void **data)
 {
-    struct _tbm_surface *surf;
-    tbm_format format;
+       TBM_RETURN_VAL_IF_FAIL(surface, 0);
+
+       tbm_user_data *old_data;
 
-    _tbm_surface_mutex_lock();
+       if (!data || LIST_IS_EMPTY(&surface->user_data_list))
+               return 0;
 
-    surf = (struct _tbm_surface *)surface;
-    format = surf->info.format;
+       old_data = user_data_lookup(&surface->user_data_list, key);
+       if (!old_data) {
+               *data = NULL;
+               return 0;
+       }
 
-    _tbm_surface_mutex_unlock();
+       *data = old_data->data;
 
-    return format;
+       return 1;
 }
 
-int
-tbm_surface_internal_get_plane_bo_idx (tbm_surface_h surface, int plane_idx)
+int tbm_surface_internal_delete_user_data(tbm_surface_h surface, unsigned long key)
 {
-    TBM_RETURN_VAL_IF_FAIL (surface, 0);
-    TBM_RETURN_VAL_IF_FAIL (plane_idx > -1, 0);
-    struct _tbm_surface *surf;
-    int bo_idx;
+       TBM_RETURN_VAL_IF_FAIL(surface, 0);
+
+       tbm_user_data *old_data = (void *)0;
 
-    _tbm_surface_mutex_lock();
+       if (LIST_IS_EMPTY(&surface->user_data_list))
+               return 0;
 
-    surf = (struct _tbm_surface *)surface;
-    bo_idx = surf->planes_bo_idx[plane_idx];
+       old_data = user_data_lookup(&surface->user_data_list, key);
+       if (!old_data)
+               return 0;
 
-    _tbm_surface_mutex_unlock();
+       user_data_delete(old_data);
 
-    return bo_idx;
+       return 1;
 }