From c9ba88e06d0e859dc19b54f807351b82bbdc1f86 Mon Sep 17 00:00:00 2001 From: Junkyeong Kim Date: Sat, 20 Feb 2021 17:36:10 +0900 Subject: [PATCH] add surface destroy callback add/remove api Change-Id: I1e94f5e33599f074f423f3ad81ad2964aeb5c56d Signed-off-by: Junkyeong Kim --- include/tbm_surface_internal.h | 22 ++++++++++++ src/tbm_bufmgr_int.h | 11 +++++- src/tbm_surface_internal.c | 82 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 114 insertions(+), 1 deletion(-) diff --git a/include/tbm_surface_internal.h b/include/tbm_surface_internal.h index 9454a36..ef30de5 100644 --- a/include/tbm_surface_internal.h +++ b/include/tbm_surface_internal.h @@ -544,6 +544,28 @@ int tbm_surface_internal_set_damage(tbm_surface_h surface, int x, int y, int wid */ int tbm_surface_internal_get_damage(tbm_surface_h surface, int *x, int *y, int *width, int *height); +/** + * @brief Definition for the Tizen buffer surface destroy callback function + */ +typedef void (*tbm_surface_internal_destroy_handler)(tbm_surface_h surface, void *user_data); + +/** + * @brief Set destroy callback function of surface + * @param[in] surface : a tbm surface + * @param[in] func : a destory callback function + * @param[in] user_data : a user data + * @return 1 if success, otherwise 0. + */ +int tbm_surface_internal_add_destroy_handler(tbm_surface_h surface, tbm_surface_internal_destroy_handler func, void *user_data); + +/** + * @brief Unset destroy callback function of surface + * @param[in] surface : a tbm surface + * @param[in] func : a destory callback function + * @param[in] user_data : a user data + */ +void tbm_surface_internal_remove_destroy_handler(tbm_surface_h surface, tbm_surface_internal_destroy_handler func, void *user_data); + #ifdef __cplusplus } #endif diff --git a/src/tbm_bufmgr_int.h b/src/tbm_bufmgr_int.h index 85a9be1..fdbb16c 100644 --- a/src/tbm_bufmgr_int.h +++ b/src/tbm_bufmgr_int.h @@ -246,10 +246,12 @@ struct _tbm_surface { struct list_head item_link; /* link of surface */ - struct list_head user_data_list; /* list of the user_date in surface */ + struct list_head user_data_list; /* list of the user_data in surface */ struct list_head debug_data_list; /* list of debug data */ + struct list_head destroy_funcs; /* list of destory callback function */ + struct { int x; int y; @@ -275,6 +277,13 @@ typedef struct { struct list_head item_link; } tbm_surface_debug_data; +typedef struct _tbm_surface_destroy_func_info { + tbm_surface_internal_destroy_handler destroy_func; + void *user_data; + + struct list_head item_link; +} tbm_surface_destroy_func_info; + tbm_bufmgr _tbm_bufmgr_get_bufmgr(void); int _tbm_bo_set_surface(tbm_bo bo, tbm_surface_h surface); int _tbm_surface_is_valid(tbm_surface_h surface); diff --git a/src/tbm_surface_internal.c b/src/tbm_surface_internal.c index 433dcc4..df57c42 100644 --- a/src/tbm_surface_internal.c +++ b/src/tbm_surface_internal.c @@ -346,6 +346,18 @@ _tbm_surface_internal_destroy(tbm_surface_h surface) tbm_bufmgr bufmgr = surface->bufmgr; tbm_user_data *old_data = NULL, *tmp = NULL; tbm_surface_debug_data *debug_old_data = NULL, *debug_tmp = NULL; + tbm_surface_destroy_func_info *func_info = NULL, *func_next = NULL; + + if (!LIST_IS_EMPTY(&surface->destroy_funcs)) { + LIST_FOR_EACH_ENTRY_SAFE(func_info, func_next, &surface->destroy_funcs, item_link) { + func_info->destroy_func(surface, func_info->user_data); + } + TBM_DBG("free destroy_funcs %p\n", surface); + LIST_FOR_EACH_ENTRY_SAFE(func_info, func_next, &surface->destroy_funcs, item_link) { + LIST_DEL(&func_info->item_link); + free(func_info); + } + } /* destory the user_data_list */ if (!LIST_IS_EMPTY(&surface->user_data_list)) { @@ -899,6 +911,7 @@ tbm_surface_internal_create_with_flags(int width, int height, 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); @@ -1041,6 +1054,7 @@ tbm_surface_internal_create_with_bos(tbm_surface_info_s *info, 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); @@ -2624,4 +2638,72 @@ tbm_surface_internal_get_damage(tbm_surface_h surface, int *x, int *y, int *widt 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(); +} /*LCOV_EXCL_STOP*/ -- 2.7.4