add surface destroy callback add/remove api 48/253948/4
authorJunkyeong Kim <jk0430.kim@samsung.com>
Sat, 20 Feb 2021 08:36:10 +0000 (17:36 +0900)
committerJunkyeong Kim <jk0430.kim@samsung.com>
Mon, 22 Feb 2021 07:12:37 +0000 (16:12 +0900)
Change-Id: I1e94f5e33599f074f423f3ad81ad2964aeb5c56d
Signed-off-by: Junkyeong Kim <jk0430.kim@samsung.com>
include/tbm_surface_internal.h
src/tbm_bufmgr_int.h
src/tbm_surface_internal.c

index 9454a36..ef30de5 100644 (file)
@@ -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
index 85a9be1..fdbb16c 100644 (file)
@@ -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);
index 433dcc4..df57c42 100644 (file)
@@ -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*/