+
+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;
+}
+
+int
+tbm_surface_internal_add_destroy_handler(tbm_surface_h surface, tbm_surface_internal_destroy_handler func, void *user_data)
+{
+ struct _tbm_surface *surf;
+ tbm_surface_destroy_func_info *func_info = 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(func != NULL, 0);
+
+ surf = (struct _tbm_surface *)surface;
+ LIST_FOR_EACH_ENTRY(func_info, &surf->destroy_funcs, item_link) {
+ if (func_info->destroy_func == func && func_info->user_data == user_data) {
+ TBM_ERR("can't add twice");
+ _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
+ _tbm_surface_mutex_unlock();
+ return 0;
+ }
+ }
+
+ func_info = calloc(1, sizeof(tbm_surface_destroy_func_info));
+ if (func_info == NULL) {
+ TBM_ERR("alloc failed");
+ _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
+ _tbm_surface_mutex_unlock();
+ return 0;
+ }
+
+ func_info->destroy_func = func;
+ func_info->user_data = user_data;
+
+ LIST_ADDTAIL(&func_info->item_link, &surf->destroy_funcs);
+
+ _tbm_surface_mutex_unlock();
+
+ return 1;
+}
+
+void
+tbm_surface_internal_remove_destroy_handler(tbm_surface_h surface, tbm_surface_internal_destroy_handler func, void *user_data)
+{
+ struct _tbm_surface *surf;
+ tbm_surface_destroy_func_info *func_info = NULL, *next = NULL;
+
+ _tbm_surface_mutex_lock();
+ _tbm_set_last_result(TBM_ERROR_NONE);
+
+ TBM_SURFACE_RETURN_IF_FAIL(_tbm_surface_internal_is_valid(surface));
+ TBM_SURFACE_RETURN_IF_FAIL(func != NULL);
+
+ surf = (struct _tbm_surface *)surface;
+ LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &surf->destroy_funcs, item_link) {
+ if (func_info->destroy_func != func || func_info->user_data != user_data)
+ continue;
+
+ LIST_DEL(&func_info->item_link);
+ free(func_info);
+
+ _tbm_surface_mutex_unlock();
+
+ return;
+ }
+
+ _tbm_surface_mutex_unlock();
+}
+
+tbm_surface_buffer_data *
+tbm_surface_internal_export(tbm_surface_h surface, tbm_error_e *error)
+{
+ tbm_surface_buffer_data *buffer_data = NULL;
+ struct _tbm_surface *surf;
+ struct _tbm_bufmgr *bufmgr;
+
+ _tbm_surface_mutex_lock();
+
+ surf = (struct _tbm_surface *)surface;
+ TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(_tbm_surface_internal_is_valid(surface), NULL, *error, TBM_ERROR_INVALID_PARAMETER);
+
+ bufmgr = surf->bufmgr;
+ TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr != NULL, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
+
+ // this function supports when it comes to be use_hal.
+ TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr->use_hal_tbm, NULL, *error, TBM_ERROR_NOT_SUPPORTED);
+
+ // export a surface
+ buffer_data = (tbm_surface_buffer_data *)hal_tbm_surface_export((hal_tbm_surface *)surf->hal_surface,
+ (hal_tbm_error *)error);
+ TBM_SURFACE_RETURN_VAL_ERR_IF_FAIL(buffer_data != NULL, NULL, *error);
+
+ TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p) buffer_data(%p)", surface, buffer_data);
+
+ if (error)
+ *error = TBM_ERROR_NONE;
+
+ _tbm_set_last_result(TBM_ERROR_NONE);
+ _tbm_surface_mutex_unlock();
+
+ return buffer_data;
+}
+
+tbm_surface_h
+tbm_surface_internal_import(tbm_surface_info_s *surface_info, tbm_surface_buffer_data *buffer_data, tbm_error_e *error)
+{
+ struct _tbm_surface *surf;
+ struct _tbm_bufmgr *bufmgr;
+
+ _tbm_surface_mutex_lock();
+
+ bufmgr = g_surface_bufmgr;
+ TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr != NULL, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
+
+ // this function supports when it comes to be use_hal.
+ TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr->use_hal_tbm, NULL, *error, TBM_ERROR_NOT_SUPPORTED);
+
+ TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(surface_info != NULL, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
+ TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(surface_info->width > 0, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
+ TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(surface_info->height > 0, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
+ TBM_SURFACE_RETURN_VAL_SET_ERR_IF_FAIL(buffer_data != NULL, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
+
+ // import a surface
+ surf = _tbm_surface_internal_hal_tbm_import_surface(bufmgr,
+ (int)surface_info->width,
+ (int)surface_info->height,
+ (int)surface_info->format,
+ buffer_data,
+ error);
+ TBM_SURFACE_RETURN_VAL_ERR_IF_FAIL(surf != NULL, NULL, *error);
+
+ LIST_INITHEAD(&surf->user_data_list);
+ LIST_INITHEAD(&surf->debug_data_list);
+ LIST_INITHEAD(&surf->destroy_funcs);
+
+ LIST_ADD(&surf->item_link, &bufmgr->surf_list);
+
+ TBM_TRACE_SURFACE_INTERNAL("tbm_surface(%p)", surf);
+
+ if (error)
+ *error = TBM_ERROR_NONE;
+
+ _tbm_set_last_result(TBM_ERROR_NONE);
+ _tbm_surface_mutex_unlock();
+
+ return (tbm_surface_h)surf;
+}
+