fix warning stringop-truncation
[platform/core/uifw/libtbm.git] / src / tbm_surface_internal.c
index ade66ef..50ae206 100644 (file)
@@ -42,7 +42,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include <pixman.h>
 
 static tbm_bufmgr g_surface_bufmgr;
-static pthread_mutex_t tbm_surface_lock;
+static pthread_mutex_t tbm_surface_lock = PTHREAD_MUTEX_INITIALIZER;
 void _tbm_surface_mutex_unlock(void);
 
 #define C(b, m)              (((b) >> (m)) & 0xFF)
@@ -55,6 +55,7 @@ void _tbm_surface_mutex_unlock(void);
 #define TBM_SURFACE_RETURN_IF_FAIL(cond) {\
        if (!(cond)) {\
                TBM_ERR("'%s' failed.\n", #cond);\
+               _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
                _tbm_surface_mutex_unlock();\
                return;\
        } \
@@ -63,6 +64,7 @@ void _tbm_surface_mutex_unlock(void);
 #define TBM_SURFACE_RETURN_VAL_IF_FAIL(cond, val) {\
        if (!(cond)) {\
                TBM_ERR("'%s' failed.\n", #cond);\
+               _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
                _tbm_surface_mutex_unlock();\
                return val;\
        } \
@@ -218,32 +220,9 @@ _tbm_surface_internal_format_to_str(tbm_format format)
        }
 }
 
-static bool
-_tbm_surface_mutex_init(void)
-{
-       static bool tbm_surface_mutex_init = false;
-
-       if (tbm_surface_mutex_init)
-               return true;
-
-       if (pthread_mutex_init(&tbm_surface_lock, NULL)) {
-               TBM_ERR("fail: pthread_mutex_init for tbm_surface_lock.\n");
-               return false;
-       }
-
-       tbm_surface_mutex_init = true;
-
-       return true;
-}
-
 void
 _tbm_surface_mutex_lock(void)
 {
-       if (!_tbm_surface_mutex_init()) {
-               TBM_ERR("fail: _tbm_surface_mutex_init.\n");
-               return;
-       }
-
        pthread_mutex_lock(&tbm_surface_lock);
 }
 
@@ -280,13 +259,13 @@ _tbm_surface_internal_is_valid(tbm_surface_h surface)
 
        if (!LIST_IS_EMPTY(&g_surface_bufmgr->surf_list)) {
                LIST_FOR_EACH_ENTRY(old_data, &g_surface_bufmgr->surf_list, item_link) {
-                       if (old_data == surface) {
-                               TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)\n", surface);
+                       if (old_data == surface)
                                return 1;
-                       }
                }
        }
 
+       _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
+
        TBM_ERR("error: No valid tbm_surface(%p)\n", surface);
 
        return 0;
@@ -310,27 +289,33 @@ _tbm_surface_internal_query_plane_data(tbm_surface_h surface,
        TBM_RETURN_VAL_IF_FAIL(surf->info.format > 0, 0);
 
        if (bufmgr->backend_module_data) {
-               if (!bufmgr->bufmgr_func->bufmgr_get_plane_data)
+               if (!bufmgr->bufmgr_func->bufmgr_get_plane_data) {
+                       _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
                        return 0;
+               }
 
                error = bufmgr->bufmgr_func->bufmgr_get_plane_data(bufmgr->bufmgr_data, surf->info.format, plane_idx,
                                                surf->info.width, surf->info.height, size, offset, pitch, bo_idx);
                if (error != TBM_ERROR_NONE) {
                        /* LCOV_EXCL_START */
                        TBM_ERR("Fail to surface_get_plane_data. surface(%p) error(%d)\n", surface, error);
+                       _tbm_set_last_result(error);
                        return 0;
                        /* LCOV_EXCL_STOP */
                }
                ret = 1;
        } else {
-               if (!bufmgr->backend->surface_get_plane_data)
+               if (!bufmgr->backend->surface_get_plane_data) {
+                       _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
                        return 0;
+               }
 
                ret = bufmgr->backend->surface_get_plane_data(surf->info.width,
                                surf->info.height, surf->info.format, plane_idx, size, offset, pitch, bo_idx);
                if (!ret) {
                        /* LCOV_EXCL_START */
                        TBM_ERR("Fail to surface_get_plane_data. surface(%p)\n", surface);
+                       _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
                        return 0;
                        /* LCOV_EXCL_STOP */
                }
@@ -372,7 +357,7 @@ _tbm_surface_internal_destroy(tbm_surface_h surface)
        free(surface);
        surface = NULL;
 
-       if (LIST_IS_EMPTY(&bufmgr->surf_list)) {
+       if (bufmgr && LIST_IS_EMPTY(&bufmgr->surf_list)) {
                LIST_DELINIT(&bufmgr->surf_list);
 
                if (!LIST_IS_EMPTY(&bufmgr->debug_key_list)) {
@@ -484,15 +469,111 @@ _tbm_surface_internal_get_num_planes(tbm_format format)
        return num_planes;
 }
 
+static 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_NV12MT:
+       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:
+               _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
+               break;
+       }
+
+       return bpp;
+}
+
 int
 tbm_surface_internal_is_valid(tbm_surface_h surface)
 {
        int ret = 0;
 
        _tbm_surface_mutex_lock();
+       _tbm_set_last_result(TBM_ERROR_NONE);
 
        /* Return silently if surface is null. */
        if (!surface) {
+               _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
                _tbm_surface_mutex_unlock();
                return 0;
        }
@@ -508,15 +589,16 @@ int
 tbm_surface_internal_query_supported_formats(uint32_t **formats,
                uint32_t *num)
 {
-       TBM_RETURN_VAL_IF_FAIL(formats, 0);
-       TBM_RETURN_VAL_IF_FAIL(num, 0);
-
        struct _tbm_bufmgr *bufmgr;
        int ret = 0;
        bool bufmgr_initialized = false;
        tbm_error_e error;
 
        _tbm_surface_mutex_lock();
+       _tbm_set_last_result(TBM_ERROR_NONE);
+
+       TBM_SURFACE_RETURN_VAL_IF_FAIL(formats, 0);
+       TBM_SURFACE_RETURN_VAL_IF_FAIL(num, 0);
 
        if (!g_surface_bufmgr) {
                _init_surface_bufmgr();
@@ -527,8 +609,10 @@ tbm_surface_internal_query_supported_formats(uint32_t **formats,
        bufmgr = g_surface_bufmgr;
 
        if (bufmgr->backend_module_data) {
-               if (!bufmgr->bufmgr_func->bufmgr_get_supported_formats)
+               if (!bufmgr->bufmgr_func->bufmgr_get_supported_formats) {
+                       _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
                        goto fail;
+               }
 
                error = bufmgr->bufmgr_func->bufmgr_get_supported_formats(bufmgr->bufmgr_data, formats, num);
                if (error != TBM_ERROR_NONE) {
@@ -539,13 +623,16 @@ tbm_surface_internal_query_supported_formats(uint32_t **formats,
                }
                ret = 1;
        } else {
-               if (!bufmgr->backend->surface_supported_format)
+               if (!bufmgr->backend->surface_supported_format) {
+                       _tbm_set_last_result(TBM_ERROR_NOT_SUPPORTED);
                        goto fail;
+               }
 
                ret = bufmgr->backend->surface_supported_format(formats, num);
                if (!ret)  {
                        /* LCOV_EXCL_START */
                        TBM_ERR("Fail to surface_supported_format.\n");
+                       _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
                        goto fail;
                        /* LCOV_EXCL_START */
                }
@@ -601,93 +688,20 @@ tbm_surface_internal_get_num_planes(tbm_format format)
 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_NV12MT:
-       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;
+       _tbm_surface_mutex_lock();
+       _tbm_set_last_result(TBM_ERROR_NONE);
+
+       bpp = _tbm_surface_internal_get_bpp(format);
+       if (!bpp) {
+               TBM_ERR("error: tbm_error(%s)\n", tbm_error_str(tbm_get_last_error()));
+               _tbm_surface_mutex_unlock();
+               return 0;
        }
 
+       _tbm_surface_mutex_unlock();
+
        TBM_TRACE_SURFACE_INTERNAL("tbm_format(%s) bpp(%d)\n", _tbm_surface_internal_format_to_str(format), bpp);
 
        return bpp;
@@ -697,9 +711,6 @@ 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 *bufmgr;
        struct _tbm_surface *surf = NULL;
        uint32_t size = 0;
@@ -715,6 +726,10 @@ tbm_surface_internal_create_with_flags(int width, int height,
        tbm_error_e error;
 
        _tbm_surface_mutex_lock();
+       _tbm_set_last_result(TBM_ERROR_NONE);
+
+       TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, NULL);
+       TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, NULL);
 
        if (!g_surface_bufmgr) {
                _init_surface_bufmgr();
@@ -732,6 +747,7 @@ tbm_surface_internal_create_with_flags(int width, int height,
        if (!surf) {
                /* LCOV_EXCL_START */
                TBM_ERR("fail to alloc surf\n");
+               _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
                goto alloc_surf_fail;
                /* LCOV_EXCL_STOP */
        }
@@ -740,7 +756,11 @@ tbm_surface_internal_create_with_flags(int width, int height,
        surf->info.width = width;
        surf->info.height = height;
        surf->info.format = format;
-       surf->info.bpp = tbm_surface_internal_get_bpp(format);
+       surf->info.bpp = _tbm_surface_internal_get_bpp(format);
+       if (!surf->info.bpp) {
+               TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
+               goto bpp_fail;
+       }
        surf->info.num_planes = _tbm_surface_internal_get_num_planes(format);
        if (!surf->info.num_planes) {
                TBM_ERR("fail to get num_planes. error(%s)\n", tbm_error_str(tbm_get_last_error()));
@@ -786,19 +806,21 @@ tbm_surface_internal_create_with_flags(int width, int height,
                                bo = calloc(1, sizeof(struct _tbm_bo));
                                if (!bo) {
                                        TBM_ERR("fail to alloc bo struct\n");
+                                       _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
                                        goto alloc_bo_fail;
                                }
 
                                bo->bufmgr = surf->bufmgr;
 
-                               pthread_mutex_lock(&surf->bufmgr->lock);
+                               _tbm_bufmgr_mutex_lock();
 
                                bo_data = bufmgr->bufmgr_func->bufmgr_alloc_bo_with_format(bufmgr->bufmgr_data, format, i,
                                                                                                                                width, height, flags, &error);
                                if (!bo_data) {
                                        TBM_ERR("fail to alloc bo priv. error(%d)\n", error);
+                                       _tbm_set_last_result(error);
                                        free(bo);
-                                       pthread_mutex_unlock(&surf->bufmgr->lock);
+                                       _tbm_bufmgr_mutex_unlock();
                                        goto alloc_bo_fail;
                                }
                                bo->bo_data = bo_data;
@@ -809,10 +831,42 @@ tbm_surface_internal_create_with_flags(int width, int height,
 
                                LIST_ADD(&bo->item_link, &surf->bufmgr->bo_list);
 
-                               pthread_mutex_unlock(&surf->bufmgr->lock);
+                               _tbm_bufmgr_mutex_unlock();
 
                                surf->bos[i] = bo;
                                /* LCOV_EXCL_STOP */
+                       } else if (bufmgr->bufmgr_func->bufmgr_alloc_bo_with_tiled_format && (flags & TBM_BO_TILED)) {
+                               bo = calloc(1, sizeof(struct _tbm_bo));
+                               if (!bo) {
+                                       TBM_ERR("fail to alloc bo struct\n");
+                                       _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
+                                       goto alloc_bo_fail;
+                               }
+
+                               bo->bufmgr = surf->bufmgr;
+
+                               _tbm_bufmgr_mutex_lock();
+
+                               bo_data = bufmgr->bufmgr_func->bufmgr_alloc_bo_with_tiled_format(bufmgr->bufmgr_data, width, height, surf->info.bpp/8, format, flags, i, &error);
+                               if (!bo_data) {
+                                       TBM_ERR("fail to alloc bo priv. error(%d)\n", error);
+                                       _tbm_set_last_result(error);
+                                       free(bo);
+                                       _tbm_bufmgr_mutex_unlock();
+                                       goto alloc_bo_fail;
+                               }
+                               bo->bo_data = bo_data;
+
+                               bo->ref_cnt = 1;
+                               bo->flags = flags;
+                               LIST_INITHEAD(&bo->user_data_list);
+
+                               LIST_ADD(&bo->item_link, &surf->bufmgr->bo_list);
+
+                               _tbm_bufmgr_mutex_unlock();
+
+                               surf->bos[i] = bo;
+
                        } else {
                                surf->bos[i] = tbm_bo_alloc(bufmgr, bo_size, flags);
                                if (!surf->bos[i]) {
@@ -826,18 +880,20 @@ tbm_surface_internal_create_with_flags(int width, int height,
                                bo = calloc(1, sizeof(struct _tbm_bo));
                                if (!bo) {
                                        TBM_ERR("fail to alloc bo struct\n");
+                                       _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
                                        goto alloc_bo_fail;
                                }
 
                                bo->bufmgr = surf->bufmgr;
 
-                               pthread_mutex_lock(&surf->bufmgr->lock);
+                               _tbm_bufmgr_mutex_lock();
 
                                bo_priv = bufmgr->backend->surface_bo_alloc(bo, width, height, format, flags, i);
                                if (!bo_priv) {
                                        TBM_ERR("fail to alloc bo priv\n");
+                                       _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
                                        free(bo);
-                                       pthread_mutex_unlock(&surf->bufmgr->lock);
+                                       _tbm_bufmgr_mutex_unlock();
                                        goto alloc_bo_fail;
                                }
                                bo->priv = bo_priv;
@@ -848,7 +904,7 @@ tbm_surface_internal_create_with_flags(int width, int height,
 
                                LIST_ADD(&bo->item_link, &surf->bufmgr->bo_list);
 
-                               pthread_mutex_unlock(&surf->bufmgr->lock);
+                               _tbm_bufmgr_mutex_unlock();
 
                                surf->bos[i] = bo;
                                /* LCOV_EXCL_STOP */
@@ -883,6 +939,7 @@ alloc_bo_fail:
                        tbm_bo_unref(surf->bos[j]);
        }
 query_plane_data_fail:
+bpp_fail:
 num_planes_fail:
        free(surf);
 alloc_surf_fail:
@@ -905,18 +962,19 @@ 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(info->num_planes > 0, NULL);
-       TBM_RETURN_VAL_IF_FAIL(num > 0, NULL);
-       TBM_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
-
        struct _tbm_bufmgr *bufmgr;
        struct _tbm_surface *surf = NULL;
        int i;
        bool bufmgr_initialized = false;
 
        _tbm_surface_mutex_lock();
+       _tbm_set_last_result(TBM_ERROR_NONE);
+
+       TBM_SURFACE_RETURN_VAL_IF_FAIL(bos, NULL);
+       TBM_SURFACE_RETURN_VAL_IF_FAIL(info, NULL);
+       TBM_SURFACE_RETURN_VAL_IF_FAIL(info->num_planes > 0, NULL);
+       TBM_SURFACE_RETURN_VAL_IF_FAIL(num > 0, NULL);
+       TBM_SURFACE_RETURN_VAL_IF_FAIL(num == 1 || info->num_planes == num, NULL);
 
        if (!g_surface_bufmgr) {
                _init_surface_bufmgr();
@@ -927,6 +985,7 @@ tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
        bufmgr = g_surface_bufmgr;
        if (!TBM_BUFMGR_IS_VALID(bufmgr)) {
                TBM_ERR("fail to validate the Bufmgr.\n");
+               _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
                goto check_valid_fail;
        }
 
@@ -934,6 +993,7 @@ tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
        if (!surf) {
                /* LCOV_EXCL_START */
                TBM_ERR("fail to allocate struct _tbm_surface.\n");
+               _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
                goto alloc_surf_fail;
                /* LCOV_EXCL_STOP */
        }
@@ -944,8 +1004,13 @@ tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
        surf->info.format = info->format;
        if (info->bpp > 0)
                surf->info.bpp = info->bpp;
-       else
-               surf->info.bpp = tbm_surface_internal_get_bpp(info->format);
+       else {
+               surf->info.bpp = _tbm_surface_internal_get_bpp(info->format);
+               if (!surf->info.bpp) {
+                       TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
+                       goto bpp_fail;
+               }
+       }
        surf->info.num_planes = info->num_planes;
        surf->refcnt = 1;
 
@@ -960,7 +1025,10 @@ tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
                        uint32_t size = 0, offset = 0, stride = 0;
                        int32_t bo_idx = 0;
 
-                       _tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx);
+                       if (!_tbm_surface_internal_query_plane_data(surf, i, &size, &offset, &stride, &bo_idx)) {
+                               TBM_ERR("fail to get plane_data. error(%s)\n", tbm_error_str(tbm_get_last_error()));
+                               goto plane_data_fail;
+                       }
                        surf->info.planes[i].size = size;
                }
 
@@ -985,6 +1053,7 @@ tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
        for (i = 0; i < num; i++) {
                if (bos[i] == NULL) {
                        TBM_ERR("bos[%d] is null.\n", i);
+                       _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
                        goto check_bo_fail;
                }
 
@@ -1006,6 +1075,8 @@ tbm_surface_internal_create_with_bos(tbm_surface_info_s *info,
 
 /* LCOV_EXCL_START */
 check_bo_fail:
+plane_data_fail:
+bpp_fail:
        for (i = 0; i < num; i++) {
                if (surf->bos[i])
                        tbm_bo_unref(surf->bos[i]);
@@ -1031,6 +1102,7 @@ void
 tbm_surface_internal_destroy(tbm_surface_h surface)
 {
        _tbm_surface_mutex_lock();
+       _tbm_set_last_result(TBM_ERROR_NONE);
 
        TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
 
@@ -1054,6 +1126,7 @@ void
 tbm_surface_internal_ref(tbm_surface_h surface)
 {
        _tbm_surface_mutex_lock();
+       _tbm_set_last_result(TBM_ERROR_NONE);
 
        TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
 
@@ -1068,6 +1141,7 @@ void
 tbm_surface_internal_unref(tbm_surface_h surface)
 {
        _tbm_surface_mutex_lock();
+       _tbm_set_last_result(TBM_ERROR_NONE);
 
        TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
 
@@ -1094,12 +1168,16 @@ tbm_surface_internal_get_num_bos(tbm_surface_h surface)
        int num;
 
        _tbm_surface_mutex_lock();
+       _tbm_set_last_result(TBM_ERROR_NONE);
 
        TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
 
        surf = (struct _tbm_surface *)surface;
        num = surf->num_bos;
 
+       if (!num)
+               _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
+
        TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) num_bos(%d)\n", surface, num);
 
        _tbm_surface_mutex_unlock();
@@ -1114,6 +1192,7 @@ tbm_surface_internal_get_bo(tbm_surface_h surface, int bo_idx)
        tbm_bo bo;
 
        _tbm_surface_mutex_lock();
+       _tbm_set_last_result(TBM_ERROR_NONE);
 
        TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL);
        TBM_SURFACE_RETURN_VAL_IF_FAIL(bo_idx > -1, NULL);
@@ -1135,6 +1214,7 @@ tbm_surface_internal_get_size(tbm_surface_h surface)
        unsigned int size;
 
        _tbm_surface_mutex_lock();
+       _tbm_set_last_result(TBM_ERROR_NONE);
 
        TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
 
@@ -1155,6 +1235,7 @@ tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
        struct _tbm_surface *surf;
 
        _tbm_surface_mutex_lock();
+       _tbm_set_last_result(TBM_ERROR_NONE);
 
        TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
        TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
@@ -1163,6 +1244,7 @@ tbm_surface_internal_get_plane_data(tbm_surface_h surface, int plane_idx,
 
        if (plane_idx >= surf->info.num_planes) {
                TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) plane_idx(%d)\n", surface, plane_idx);
+               _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
                _tbm_surface_mutex_unlock();
                return 0;
        }
@@ -1197,6 +1279,7 @@ tbm_surface_internal_get_info(tbm_surface_h surface, int opt,
        int i, j;
 
        _tbm_surface_mutex_lock();
+       _tbm_set_last_result(TBM_ERROR_NONE);
 
        TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
 
@@ -1267,6 +1350,7 @@ tbm_surface_internal_unmap(tbm_surface_h surface)
        int i;
 
        _tbm_surface_mutex_lock();
+       _tbm_set_last_result(TBM_ERROR_NONE);
 
        TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
 
@@ -1287,6 +1371,7 @@ tbm_surface_internal_get_width(tbm_surface_h surface)
        unsigned int width;
 
        _tbm_surface_mutex_lock();
+       _tbm_set_last_result(TBM_ERROR_NONE);
 
        TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
 
@@ -1307,6 +1392,7 @@ tbm_surface_internal_get_height(tbm_surface_h surface)
        unsigned int height;
 
        _tbm_surface_mutex_lock();
+       _tbm_set_last_result(TBM_ERROR_NONE);
 
        TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
 
@@ -1328,6 +1414,7 @@ tbm_surface_internal_get_format(tbm_surface_h surface)
        tbm_format format;
 
        _tbm_surface_mutex_lock();
+       _tbm_set_last_result(TBM_ERROR_NONE);
 
        TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
 
@@ -1348,6 +1435,7 @@ tbm_surface_internal_get_plane_bo_idx(tbm_surface_h surface, int plane_idx)
        int bo_idx;
 
        _tbm_surface_mutex_lock();
+       _tbm_set_last_result(TBM_ERROR_NONE);
 
        TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
        TBM_SURFACE_RETURN_VAL_IF_FAIL(plane_idx > -1, 0);
@@ -1369,6 +1457,7 @@ tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
        tbm_user_data *data;
 
        _tbm_surface_mutex_lock();
+       _tbm_set_last_result(TBM_ERROR_NONE);
 
        TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
 
@@ -1376,6 +1465,7 @@ tbm_surface_internal_add_user_data(tbm_surface_h surface, unsigned long key,
        data = user_data_lookup(&surface->user_data_list, key);
        if (data) {
                TBM_TRACE_SURFACE_INTERNAL("warning: user data already exist tbm_surface(%p) key(%lu)\n", surface, key);
+               _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
                _tbm_surface_mutex_unlock();
                return 0;
        }
@@ -1403,12 +1493,14 @@ tbm_surface_internal_set_user_data(tbm_surface_h surface, unsigned long key,
        tbm_user_data *old_data;
 
        _tbm_surface_mutex_lock();
+       _tbm_set_last_result(TBM_ERROR_NONE);
 
        TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
 
        old_data = user_data_lookup(&surface->user_data_list, key);
        if (!old_data) {
                TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
+               _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
                _tbm_surface_mutex_unlock();
                return 0;
        }
@@ -1432,11 +1524,13 @@ tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
        tbm_user_data *old_data;
 
        _tbm_surface_mutex_lock();
+       _tbm_set_last_result(TBM_ERROR_NONE);
 
        TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
 
        if (!data) {
                TBM_ERR("error: tbm_surface(%p) key(%lu)\n", surface, key);
+               _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
                _tbm_surface_mutex_unlock();
                return 0;
        }
@@ -1445,6 +1539,7 @@ tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
        old_data = user_data_lookup(&surface->user_data_list, key);
        if (!old_data) {
                TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
+               _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
                _tbm_surface_mutex_unlock();
                return 0;
        }
@@ -1465,12 +1560,14 @@ tbm_surface_internal_delete_user_data(tbm_surface_h surface,
        tbm_user_data *old_data = (void *)0;
 
        _tbm_surface_mutex_lock();
+       _tbm_set_last_result(TBM_ERROR_NONE);
 
        TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
 
        old_data = user_data_lookup(&surface->user_data_list, key);
        if (!old_data) {
                TBM_TRACE_SURFACE_INTERNAL("error: tbm_surface(%p) key(%lu)\n", surface, key);
+               _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);
                _tbm_surface_mutex_unlock();
                return 0;
        }
@@ -1497,6 +1594,7 @@ void
 tbm_surface_internal_set_debug_pid(tbm_surface_h surface, unsigned int pid)
 {
        _tbm_surface_mutex_lock();
+       _tbm_set_last_result(TBM_ERROR_NONE);
 
        TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
 
@@ -1511,8 +1609,11 @@ _tbm_surface_internal_debug_data_create(char *key, char *value)
        tbm_surface_debug_data *debug_data = NULL;
 
        debug_data = calloc(1, sizeof(tbm_surface_debug_data));
-       if (!debug_data)
+       if (!debug_data) {
+               _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
+               TBM_ERR("fail to allocate the debug_data.");
                return NULL;
+       }
 
        if (key) debug_data->key = strdup(key);
        if (value) debug_data->value = strdup(value);
@@ -1528,6 +1629,7 @@ tbm_surface_internal_set_debug_data(tbm_surface_h surface, char *key, char *valu
        tbm_bufmgr bufmgr = NULL;
 
        _tbm_surface_mutex_lock();
+       _tbm_set_last_result(TBM_ERROR_NONE);
 
        TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
        TBM_SURFACE_RETURN_VAL_IF_FAIL(key, 0);
@@ -1695,6 +1797,14 @@ _tbm_surface_internal_dump_file_png(const char *file, const void *data, int widt
                return;
        }
 
+       if (setjmp(png_jmpbuf(pPngStruct))) {
+               /* if png has problem of writing the file, we get here */
+               TBM_ERR("fail to write png file.\n");
+               png_destroy_write_struct(&pPngStruct, &pPngInfo);
+               fclose(fp);
+               return;
+       }
+
        png_init_io(pPngStruct, fp);
        if (format == TBM_FORMAT_XRGB8888) {
                pixel_size = 3;
@@ -2075,7 +2185,7 @@ static char *_tbm_surface_internal_get_keys(tbm_surface_h surface)
                memset(temp_key, 0x00, KEY_LEN + 1);
                bo = surf->bos[i];
                snprintf(temp_key, KEY_LEN, "_%d", tbm_bo_export(bo));
-               strncat(keys, temp_key, KEY_LEN);
+               strncat(keys, temp_key, KEY_LEN + 1);
        }
 
        _tbm_surface_mutex_unlock();
@@ -2136,7 +2246,12 @@ tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type)
                buf_info->info.width = info.width * scale_factor;
                buf_info->info.height = info.height * scale_factor;
                buf_info->info.format = info.format;
-               buf_info->info.bpp = tbm_surface_internal_get_bpp(buf_info->info.format);
+               buf_info->info.bpp = _tbm_surface_internal_get_bpp(buf_info->info.format);
+               if (!buf_info->info.bpp) {
+                       TBM_ERR("fail to get bpp. error(%s)\n", tbm_error_str(tbm_get_last_error()));
+                       tbm_surface_unmap(surface);
+                       return;
+               }
                buf_info->info.num_planes = 1;
                buf_info->info.planes[0].stride = buf_info->info.width * bpp;
                buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp;
@@ -2463,4 +2578,56 @@ tbm_surface_internal_capture_shm_buffer(void *ptr, int w, int h, int stride,
 
        return 1;
 }
+
+int
+tbm_surface_internal_set_damage(tbm_surface_h surface, int x, int y, int width, int height)
+{
+       struct _tbm_surface *surf;
+
+       _tbm_surface_mutex_lock();
+       _tbm_set_last_result(TBM_ERROR_NONE);
+
+       TBM_SURFACE_RETURN_VAL_IF_FAIL(width > 0, 0);
+       TBM_SURFACE_RETURN_VAL_IF_FAIL(height > 0, 0);
+       TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
+
+       surf = (struct _tbm_surface *)surface;
+
+       surf->damage.x = x;
+       surf->damage.y = y;
+       surf->damage.width = width;
+       surf->damage.height = height;
+
+       TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
+                                                       surface, x, y, width, height);
+
+       _tbm_surface_mutex_unlock();
+
+       return 1;
+}
+
+int
+tbm_surface_internal_get_damage(tbm_surface_h surface, int *x, int *y, int *width, int *height)
+{
+       struct _tbm_surface *surf;
+
+       _tbm_surface_mutex_lock();
+       _tbm_set_last_result(TBM_ERROR_NONE);
+
+       TBM_SURFACE_RETURN_VAL_IF_FAIL(_tbm_surface_internal_is_valid(surface), 0);
+
+       surf = (struct _tbm_surface *)surface;
+
+       if (x) *x = surf->damage.x;
+       if (y) *y = surf->damage.y;
+       if (width) *width = surf->damage.width;
+       if (height) *height = surf->damage.height;
+
+       TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) x(%d) y(%d) width(%d) height(%d)\n",
+                                                       surface, surf->damage.x, surf->damage.y, surf->damage.width, surf->damage.height);
+
+       _tbm_surface_mutex_unlock();
+
+       return 1;
+}
 /*LCOV_EXCL_STOP*/