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 {
48 tdm_buffer_release_handler release_func;
49 tdm_buffer_destroy_handler destroy_func;
52 struct list_head link;
53 } tdm_buffer_func_info;
55 typedef struct _tdm_buffer_info {
58 /* ref_count for backend */
59 int backend_ref_count;
61 struct list_head release_funcs;
62 struct list_head destroy_funcs;
64 struct list_head link;
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) {
77 LIST_DEL(&func_info->link);
81 LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->destroy_funcs, link)
82 func_info->destroy_func(buf_info->buffer, func_info->user_data);
84 LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->destroy_funcs, link) {
85 LIST_DEL(&func_info->link);
89 LIST_DEL(&buf_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);
106 buf_info = calloc(1, sizeof(tdm_buffer_info));
107 TDM_RETURN_VAL_IF_FAIL(buf_info != NULL, NULL);
109 buf_info->buffer = buffer;
111 LIST_INITHEAD(&buf_info->release_funcs);
112 LIST_INITHEAD(&buf_info->destroy_funcs);
113 LIST_INITHEAD(&buf_info->link);
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,
148 tdm_buffer_release_handler func, void *user_data)
150 tdm_buffer_info *buf_info;
151 tdm_buffer_func_info *func_info = NULL, *next = NULL;
153 TDM_RETURN_IF_FAIL(buffer != NULL);
154 TDM_RETURN_IF_FAIL(func != NULL);
156 buf_info = _tdm_buffer_get_info(buffer);
157 TDM_RETURN_IF_FAIL(buf_info != NULL);
159 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) {
203 tbm_surface_internal_ref(buffer);
204 func_info->release_func(buffer, func_info->user_data);
205 tbm_surface_internal_unref(buffer);
210 tdm_buffer_add_destroy_handler(tbm_surface_h buffer,
211 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,
235 tdm_buffer_destroy_handler func, void *user_data)
237 tdm_buffer_info *buf_info;
238 tdm_buffer_func_info *func_info = NULL, *next = NULL;
240 TDM_RETURN_IF_FAIL(buffer != NULL);
241 TDM_RETURN_IF_FAIL(func != NULL);
243 buf_info = _tdm_buffer_get_info(buffer);
244 TDM_RETURN_IF_FAIL(buf_info != NULL);
246 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);
258 tdm_buffer_add_list(struct list_head *list, tbm_surface_h buffer)
260 tdm_buffer_info *buf_info;
262 TDM_RETURN_IF_FAIL(list != NULL);
263 TDM_RETURN_IF_FAIL(buffer != NULL);
265 buf_info = _tdm_buffer_get_info(buffer);
266 TDM_RETURN_IF_FAIL(buf_info != NULL);
268 if (buf_info->link.prev != buf_info->link.next) {
269 TDM_ERR("%p already added other list\n", buffer);
273 LIST_ADD(&buf_info->link, list);
277 tdm_buffer_remove_list(struct list_head *list, tbm_surface_h buffer)
279 tdm_buffer_info *buf_info, *b = NULL, *bb = NULL;
281 TDM_RETURN_IF_FAIL(list != NULL);
286 buf_info = _tdm_buffer_get_info(buffer);
287 TDM_RETURN_IF_FAIL(buf_info != NULL);
289 LIST_FOR_EACH_ENTRY_SAFE(b, bb, list, link) {
291 LIST_DEL(&buf_info->link);
298 tdm_buffer_dump_list(struct list_head *list, char *str, int len)
300 tdm_buffer_info *buf_info = NULL;
302 TDM_RETURN_IF_FAIL(list != NULL);
304 LIST_FOR_EACH_ENTRY(buf_info, list, link) {
306 int l = snprintf(str, len, " %p", buf_info->buffer);