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;
66 _tdm_buffer_destroy_info(void *user_data)
68 tdm_buffer_info *buf_info = (tdm_buffer_info *)user_data;
69 tdm_buffer_func_info *func_info = NULL, *next = NULL;
71 if (buf_info->backend_ref_count > 0)
74 LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->release_funcs, link) {
75 LIST_DEL(&func_info->link);
79 LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->destroy_funcs, link)
80 func_info->destroy_func(buf_info->buffer, func_info->user_data);
82 LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->destroy_funcs, link) {
83 LIST_DEL(&func_info->link);
90 static tdm_buffer_info *
91 _tdm_buffer_get_info(tbm_surface_h buffer)
93 tdm_buffer_info *buf_info = NULL;
96 bo = tbm_surface_internal_get_bo(buffer, 0);
97 TDM_RETURN_VAL_IF_FAIL(bo != NULL, NULL);
99 tbm_bo_get_user_data(bo, TDM_BUFFER_KEY, (void **)&buf_info);
102 buf_info = calloc(1, sizeof(tdm_buffer_info));
103 TDM_RETURN_VAL_IF_FAIL(buf_info != NULL, NULL);
105 buf_info->buffer = buffer;
107 LIST_INITHEAD(&buf_info->release_funcs);
108 LIST_INITHEAD(&buf_info->destroy_funcs);
110 tbm_bo_add_user_data(bo, TDM_BUFFER_KEY, _tdm_buffer_destroy_info);
111 tbm_bo_set_user_data(bo, TDM_BUFFER_KEY, buf_info);
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++;
182 tdm_buffer_unref_backend(tbm_surface_h buffer)
184 tdm_buffer_info *buf_info;
185 tdm_buffer_func_info *func_info = NULL, *next = NULL;
187 TDM_RETURN_IF_FAIL(buffer != NULL);
189 buf_info = _tdm_buffer_get_info(buffer);
190 TDM_RETURN_IF_FAIL(buf_info != NULL);
192 buf_info->backend_ref_count--;
194 if (buf_info->backend_ref_count > 0)
197 LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->release_funcs, link) {
198 tbm_surface_internal_ref(buffer);
199 func_info->release_func(buffer, func_info->user_data);
200 tbm_surface_internal_unref(buffer);
205 tdm_buffer_add_destroy_handler(tbm_surface_h buffer,
206 tdm_buffer_destroy_handler func, void *user_data)
208 tdm_buffer_info *buf_info;
209 tdm_buffer_func_info *func_info;
211 TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER);
212 TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER);
214 buf_info = _tdm_buffer_get_info(buffer);
215 TDM_RETURN_VAL_IF_FAIL(buf_info != NULL, TDM_ERROR_OUT_OF_MEMORY);
217 func_info = calloc(1, sizeof(tdm_buffer_func_info));
218 TDM_RETURN_VAL_IF_FAIL(func_info != NULL, TDM_ERROR_OUT_OF_MEMORY);
220 func_info->destroy_func = func;
221 func_info->user_data = user_data;
223 LIST_ADD(&func_info->link, &buf_info->destroy_funcs);
225 return TDM_ERROR_NONE;
229 tdm_buffer_remove_destroy_handler(tbm_surface_h buffer,
230 tdm_buffer_destroy_handler func, void *user_data)
232 tdm_buffer_info *buf_info;
233 tdm_buffer_func_info *func_info = NULL, *next = NULL;
235 TDM_RETURN_IF_FAIL(buffer != NULL);
236 TDM_RETURN_IF_FAIL(func != NULL);
238 buf_info = _tdm_buffer_get_info(buffer);
239 TDM_RETURN_IF_FAIL(buf_info != NULL);
241 LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->destroy_funcs, link) {
242 if (func_info->destroy_func != func || func_info->user_data != user_data)
245 LIST_DEL(&func_info->link);