1 /**************************************************************************
5 Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
7 Contact: Eunchul Kim <chulspro.kim@samsung.com>,
8 JinYoung Jeon <jy0.jeon@samsung.com>,
9 Taeheon Kim <th908.kim@samsung.com>,
10 YoungJun Cho <yj44.cho@samsung.com>,
11 SooChan Lim <sc1.lim@samsung.com>,
12 Boram Park <sc1.lim@samsung.com>
14 Permission is hereby granted, free of charge, to any person obtaining a
15 copy of this software and associated documentation files (the
16 "Software"), to deal in the Software without restriction, including
17 without limitation the rights to use, copy, modify, merge, publish,
18 distribute, sub license, and/or sell copies of the Software, and to
19 permit persons to whom the Software is furnished to do so, subject to
20 the following conditions:
22 The above copyright notice and this permission notice (including the
23 next paragraph) shall be included in all copies or substantial portions
26 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
27 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
29 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
30 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
31 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
32 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 **************************************************************************/
41 #include "tdm_private.h"
44 static int tdm_buffer_key;
45 #define TDM_BUFFER_KEY ((unsigned long)&tdm_buffer_key)
47 typedef struct _tdm_buffer_func_info
49 tdm_buffer_release_handler release_func;
50 tdm_buffer_destroy_handler destroy_func;
53 struct list_head link;
54 } tdm_buffer_func_info;
56 typedef struct _tdm_buffer_info
60 /* ref_count for backend */
61 int backend_ref_count;
63 struct list_head release_funcs;
64 struct list_head destroy_funcs;
68 _tdm_buffer_destroy_info(void *user_data)
70 tdm_buffer_info *buf_info = (tdm_buffer_info*)user_data;
71 tdm_buffer_func_info *func_info = NULL, *next = NULL;
73 if (buf_info->backend_ref_count > 0)
76 LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->release_funcs, link)
78 LIST_DEL(&func_info->link);
82 LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->destroy_funcs, link)
83 func_info->destroy_func(buf_info->buffer, func_info->user_data);
85 LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->destroy_funcs, link)
87 LIST_DEL(&func_info->link);
94 static tdm_buffer_info*
95 _tdm_buffer_get_info(tbm_surface_h buffer)
97 tdm_buffer_info *buf_info = NULL;
100 bo = tbm_surface_internal_get_bo(buffer, 0);
101 TDM_RETURN_VAL_IF_FAIL(bo != NULL, NULL);
103 tbm_bo_get_user_data(bo, TDM_BUFFER_KEY, (void**)&buf_info);
107 buf_info = calloc(1, sizeof(tdm_buffer_info));
108 TDM_RETURN_VAL_IF_FAIL(buffer != NULL, NULL);
110 buf_info->buffer = buffer;
112 LIST_INITHEAD(&buf_info->release_funcs);
113 LIST_INITHEAD(&buf_info->destroy_funcs);
115 tbm_bo_add_user_data(bo, TDM_BUFFER_KEY, _tdm_buffer_destroy_info);
116 tbm_bo_set_user_data(bo, TDM_BUFFER_KEY, buf_info);
123 tdm_buffer_add_release_handler(tbm_surface_h buffer,
124 tdm_buffer_release_handler func, void *user_data)
126 tdm_buffer_info *buf_info;
127 tdm_buffer_func_info *func_info;
129 TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER);
130 TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER);
132 buf_info = _tdm_buffer_get_info(buffer);
133 TDM_RETURN_VAL_IF_FAIL(buf_info != NULL, TDM_ERROR_OUT_OF_MEMORY);
135 func_info = calloc(1, sizeof(tdm_buffer_func_info));
136 TDM_RETURN_VAL_IF_FAIL(func_info != NULL, TDM_ERROR_OUT_OF_MEMORY);
138 func_info->release_func = func;
139 func_info->user_data = user_data;
141 LIST_ADD(&func_info->link, &buf_info->release_funcs);
143 return TDM_ERROR_NONE;
147 tdm_buffer_remove_release_handler(tbm_surface_h buffer, tdm_buffer_release_handler func, void *user_data)
149 tdm_buffer_info *buf_info;
150 tdm_buffer_func_info *func_info = NULL, *next = NULL;
152 TDM_RETURN_IF_FAIL(buffer != NULL);
153 TDM_RETURN_IF_FAIL(func != NULL);
155 buf_info = _tdm_buffer_get_info(buffer);
156 TDM_RETURN_IF_FAIL(buf_info != NULL);
158 LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->release_funcs, link)
160 if (func_info->release_func != func || func_info->user_data != user_data)
163 LIST_DEL(&func_info->link);
172 tdm_buffer_ref_backend(tbm_surface_h buffer)
174 tdm_buffer_info *buf_info;
176 TDM_RETURN_VAL_IF_FAIL(buffer != NULL, NULL);
178 buf_info = _tdm_buffer_get_info(buffer);
179 TDM_RETURN_VAL_IF_FAIL(buf_info != NULL, NULL);
181 buf_info->backend_ref_count++;
187 tdm_buffer_unref_backend(tbm_surface_h buffer)
189 tdm_buffer_info *buf_info;
190 tdm_buffer_func_info *func_info = NULL, *next = NULL;
192 TDM_RETURN_IF_FAIL(buffer != NULL);
194 buf_info = _tdm_buffer_get_info(buffer);
195 TDM_RETURN_IF_FAIL(buf_info != NULL);
197 buf_info->backend_ref_count--;
199 if (buf_info->backend_ref_count > 0)
202 LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->release_funcs, link)
204 tbm_surface_internal_ref(buffer);
205 func_info->release_func(buffer, func_info->user_data);
206 tbm_surface_internal_unref(buffer);
211 tdm_buffer_add_destroy_handler(tbm_surface_h buffer, tdm_buffer_destroy_handler func, void *user_data)
213 tdm_buffer_info *buf_info;
214 tdm_buffer_func_info *func_info;
216 TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER);
217 TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER);
219 buf_info = _tdm_buffer_get_info(buffer);
220 TDM_RETURN_VAL_IF_FAIL(buf_info != NULL, TDM_ERROR_OUT_OF_MEMORY);
222 func_info = calloc(1, sizeof(tdm_buffer_func_info));
223 TDM_RETURN_VAL_IF_FAIL(func_info != NULL, TDM_ERROR_OUT_OF_MEMORY);
225 func_info->destroy_func = func;
226 func_info->user_data = user_data;
228 LIST_ADD(&func_info->link, &buf_info->destroy_funcs);
230 return TDM_ERROR_NONE;
234 tdm_buffer_remove_destroy_handler(tbm_surface_h buffer, tdm_buffer_destroy_handler func, void *user_data)
236 tdm_buffer_info *buf_info;
237 tdm_buffer_func_info *func_info = NULL, *next = NULL;
239 TDM_RETURN_IF_FAIL(buffer != NULL);
240 TDM_RETURN_IF_FAIL(func != NULL);
242 buf_info = _tdm_buffer_get_info(buffer);
243 TDM_RETURN_IF_FAIL(buf_info != NULL);
245 LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->destroy_funcs, link)
247 if (func_info->destroy_func != func || func_info->user_data != user_data)
250 LIST_DEL(&func_info->link);