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;
56 _tdm_buffer_destroy_info(void *user_data)
58 tdm_buffer_info *buf_info = (tdm_buffer_info *)user_data;
59 tdm_buffer_func_info *func_info = NULL, *next = NULL;
61 if (buf_info->backend_ref_count > 0) {
64 TDM_INFO("%p", buf_info->buffer);
67 LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->release_funcs, link) {
68 LIST_DEL(&func_info->link);
72 LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->destroy_funcs, link)
73 func_info->destroy_func(buf_info->buffer, func_info->user_data);
75 LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->destroy_funcs, link) {
76 LIST_DEL(&func_info->link);
81 TDM_INFO("%p destroyed", buf_info->buffer);
87 tdm_buffer_get_info(tbm_surface_h buffer)
89 tdm_buffer_info *buf_info = NULL;
92 bo = tbm_surface_internal_get_bo(buffer, 0);
93 TDM_RETURN_VAL_IF_FAIL(bo != NULL, NULL);
95 tbm_bo_get_user_data(bo, TDM_BUFFER_KEY, (void **)&buf_info);
98 buf_info = calloc(1, sizeof(tdm_buffer_info));
99 TDM_RETURN_VAL_IF_FAIL(buf_info != NULL, NULL);
101 buf_info->buffer = buffer;
103 LIST_INITHEAD(&buf_info->release_funcs);
104 LIST_INITHEAD(&buf_info->destroy_funcs);
105 LIST_INITHEAD(&buf_info->link);
107 tbm_bo_add_user_data(bo, TDM_BUFFER_KEY, _tdm_buffer_destroy_info);
108 tbm_bo_set_user_data(bo, TDM_BUFFER_KEY, buf_info);
110 if (tdm_debug_buffer)
111 TDM_INFO("%p created", buf_info->buffer);
118 tdm_buffer_add_release_handler(tbm_surface_h buffer,
119 tdm_buffer_release_handler func, void *user_data)
121 tdm_buffer_info *buf_info;
122 tdm_buffer_func_info *func_info;
124 TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER);
125 TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER);
127 buf_info = tdm_buffer_get_info(buffer);
128 TDM_RETURN_VAL_IF_FAIL(buf_info != NULL, TDM_ERROR_OUT_OF_MEMORY);
130 func_info = calloc(1, sizeof(tdm_buffer_func_info));
131 TDM_RETURN_VAL_IF_FAIL(func_info != NULL, TDM_ERROR_OUT_OF_MEMORY);
133 func_info->release_func = func;
134 func_info->user_data = user_data;
136 LIST_ADD(&func_info->link, &buf_info->release_funcs);
138 return TDM_ERROR_NONE;
142 tdm_buffer_remove_release_handler(tbm_surface_h buffer,
143 tdm_buffer_release_handler func, void *user_data)
145 tdm_buffer_info *buf_info;
146 tdm_buffer_func_info *func_info = NULL, *next = NULL;
148 TDM_RETURN_IF_FAIL(buffer != NULL);
149 TDM_RETURN_IF_FAIL(func != NULL);
151 buf_info = tdm_buffer_get_info(buffer);
152 TDM_RETURN_IF_FAIL(buf_info != NULL);
154 LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->release_funcs, link) {
155 if (func_info->release_func != func || func_info->user_data != user_data)
158 LIST_DEL(&func_info->link);
167 tdm_buffer_ref_backend(tbm_surface_h buffer)
169 tdm_buffer_info *buf_info;
171 TDM_RETURN_VAL_IF_FAIL(buffer != NULL, NULL);
173 buf_info = tdm_buffer_get_info(buffer);
174 TDM_RETURN_VAL_IF_FAIL(buf_info != NULL, NULL);
176 buf_info->backend_ref_count++;
177 tbm_surface_internal_ref(buffer);
183 tdm_buffer_unref_backend(tbm_surface_h buffer)
185 tdm_buffer_info *buf_info;
186 tdm_buffer_func_info *func_info = NULL, *next = NULL;
188 TDM_RETURN_IF_FAIL(buffer != NULL);
190 buf_info = tdm_buffer_get_info(buffer);
191 TDM_RETURN_IF_FAIL(buf_info != NULL);
193 buf_info->backend_ref_count--;
194 if (buf_info->backend_ref_count > 0) {
195 tbm_surface_internal_unref(buffer);
199 LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->release_funcs, link) {
200 tbm_surface_internal_ref(buffer);
201 func_info->release_func(buffer, func_info->user_data);
202 tbm_surface_internal_unref(buffer);
205 tbm_surface_internal_unref(buffer);
209 tdm_buffer_add_destroy_handler(tbm_surface_h buffer,
210 tdm_buffer_destroy_handler func, void *user_data)
212 tdm_buffer_info *buf_info;
213 tdm_buffer_func_info *func_info;
215 TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER);
216 TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER);
218 buf_info = tdm_buffer_get_info(buffer);
219 TDM_RETURN_VAL_IF_FAIL(buf_info != NULL, TDM_ERROR_OUT_OF_MEMORY);
221 func_info = calloc(1, sizeof(tdm_buffer_func_info));
222 TDM_RETURN_VAL_IF_FAIL(func_info != NULL, TDM_ERROR_OUT_OF_MEMORY);
224 func_info->destroy_func = func;
225 func_info->user_data = user_data;
227 LIST_ADD(&func_info->link, &buf_info->destroy_funcs);
229 return TDM_ERROR_NONE;
233 tdm_buffer_remove_destroy_handler(tbm_surface_h buffer,
234 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) {
246 if (func_info->destroy_func != func || func_info->user_data != user_data)
249 LIST_DEL(&func_info->link);
257 tdm_buffer_list_get_first_entry(struct list_head *list)
259 tdm_buffer_info *buf_info = NULL;
261 TDM_RETURN_VAL_IF_FAIL(list != NULL, NULL);
263 buf_info = container_of((list)->next, buf_info, link);
265 return buf_info->buffer;
269 tdm_buffer_list_dump(struct list_head *list)
271 tdm_buffer_info *buf_info = NULL;
273 int len = sizeof (str);
275 TDM_RETURN_IF_FAIL(list != NULL);
278 LIST_FOR_EACH_ENTRY(buf_info, list, link) {
280 int l = snprintf(p, len, " %p", buf_info->buffer);
288 TDM_INFO("\t %s", str);