first draft
[platform/core/uifw/libtdm.git] / src / tdm_pp.c
1 /**************************************************************************
2
3 libtdm
4
5 Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
6
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>
13
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:
21
22 The above copyright notice and this permission notice (including the
23 next paragraph) shall be included in all copies or substantial portions
24 of the Software.
25
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.
33
34 **************************************************************************/
35
36 #ifdef HAVE_CONFIG_H
37 #include "config.h"
38 #endif
39
40 #include "tdm.h"
41 #include "tdm_backend.h"
42 #include "tdm_private.h"
43
44 #define PP_FUNC_ENTRY() \
45     tdm_func_pp *func_pp; \
46     tdm_private_display *private_display; \
47     tdm_private_pp *private_pp; \
48     tdm_error ret = TDM_ERROR_NONE; \
49     TDM_RETURN_VAL_IF_FAIL(pp != NULL, TDM_ERROR_INVALID_PARAMETER); \
50     private_pp = (tdm_private_pp*)pp; \
51     private_display = private_pp->private_display; \
52     func_pp = private_pp->func_pp
53
54 static void
55 _tdm_pp_cb_done(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst, void *user_data)
56 {
57     tdm_buffer_unref_backend(tdm_buffer_get(src));
58     tdm_buffer_unref_backend(tdm_buffer_get(dst));
59 }
60
61 INTERN tdm_private_pp*
62 tdm_pp_create_internal(tdm_private_display *private_display, tdm_error *error)
63 {
64     tdm_func_display *func_display;
65     tdm_func_pp *func_pp;
66     tdm_private_pp *private_pp = NULL;
67     tdm_pp *pp = NULL;
68     tdm_error ret = TDM_ERROR_NONE;
69
70     func_display = &private_display->func_display;
71     func_pp = &private_display->func_pp;
72
73     if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP))
74     {
75         TDM_ERR("no pp capability");
76         if (error)
77             *error = TDM_ERROR_BAD_REQUEST;
78         return NULL;
79     }
80
81     pp = func_display->display_create_pp(private_display->bdata, &ret);
82     if (ret != TDM_ERROR_NONE)
83     {
84         if (error)
85             *error = ret;
86         return NULL;
87     }
88
89     private_pp = calloc(1, sizeof(tdm_private_pp));
90     if (!private_pp)
91     {
92         TDM_ERR("failed: alloc memory");
93         func_pp->pp_destroy(pp);
94         if (error)
95             *error = TDM_ERROR_OUT_OF_MEMORY;
96         return NULL;
97     }
98
99     ret = func_pp->pp_set_done_handler(pp, _tdm_pp_cb_done, private_pp);
100     if (ret != TDM_ERROR_NONE)
101     {
102         TDM_ERR("set pp_done_handler failed");
103         func_pp->pp_destroy(pp);
104         if (error)
105             *error = ret;
106         return NULL;
107     }
108
109     LIST_ADD(&private_pp->link, &private_display->pp_list);
110     private_pp->func_pp = func_pp;
111     private_pp->private_display = private_display;
112     private_pp->pp = pp;
113
114     if (error)
115         *error = TDM_ERROR_NONE;
116
117     return private_pp;
118 }
119
120 INTERN void
121 tdm_pp_destroy_internal(tdm_private_pp *private_pp)
122 {
123     tdm_func_pp *func_pp;
124
125     if (!private_pp)
126         return;
127
128     func_pp = private_pp->func_pp;
129
130     LIST_DEL(&private_pp->link);
131
132     func_pp->pp_destroy(private_pp->pp);
133
134     free(private_pp);
135 }
136
137 EXTERN void
138 tdm_pp_destroy(tdm_pp *pp)
139 {
140     tdm_private_display *private_display;
141     tdm_private_pp *private_pp;
142
143     if (!pp)
144         return;
145
146     private_pp = (tdm_private_pp*)pp;
147     private_display = private_pp->private_display;
148
149     pthread_mutex_lock(&private_display->lock);
150     tdm_pp_destroy_internal(private_pp);
151     pthread_mutex_unlock(&private_display->lock);
152 }
153
154 EXTERN tdm_error
155 tdm_pp_set_property(tdm_pp *pp, unsigned int id, tdm_value value)
156 {
157     PP_FUNC_ENTRY();
158
159     pthread_mutex_lock(&private_display->lock);
160
161     if (!func_pp->pp_set_property)
162     {
163         pthread_mutex_unlock(&private_display->lock);
164         return TDM_ERROR_NONE;
165     }
166
167     ret = func_pp->pp_set_property(private_pp->pp, id, value);
168
169     pthread_mutex_unlock(&private_display->lock);
170
171     return ret;
172 }
173
174 EXTERN tdm_error
175 tdm_pp_get_property(tdm_pp *pp, unsigned int id, tdm_value *value)
176 {
177     PP_FUNC_ENTRY();
178
179     TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
180
181     pthread_mutex_lock(&private_display->lock);
182
183     if (!func_pp->pp_get_property)
184     {
185         pthread_mutex_unlock(&private_display->lock);
186         return TDM_ERROR_NONE;
187     }
188
189     ret = func_pp->pp_get_property(private_pp->pp, id, value);
190
191     pthread_mutex_unlock(&private_display->lock);
192
193     return ret;
194 }
195
196 EXTERN tdm_error
197 tdm_pp_set_info(tdm_pp *pp, tdm_info_pp *info)
198 {
199     PP_FUNC_ENTRY();
200
201     TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
202
203     pthread_mutex_lock(&private_display->lock);
204
205     if (!func_pp->pp_set_info)
206     {
207         pthread_mutex_unlock(&private_display->lock);
208         return TDM_ERROR_NONE;
209     }
210
211     ret = func_pp->pp_set_info(private_pp->pp, info);
212
213     pthread_mutex_unlock(&private_display->lock);
214
215     return ret;
216 }
217
218 EXTERN tdm_error
219 tdm_pp_attach(tdm_pp *pp, tdm_buffer *src, tdm_buffer *dst)
220 {
221     PP_FUNC_ENTRY();
222
223     TDM_RETURN_VAL_IF_FAIL(src != NULL, TDM_ERROR_INVALID_PARAMETER);
224     TDM_RETURN_VAL_IF_FAIL(dst != NULL, TDM_ERROR_INVALID_PARAMETER);
225
226     pthread_mutex_lock(&private_display->lock);
227
228     if (!func_pp->pp_attach)
229     {
230         pthread_mutex_unlock(&private_display->lock);
231         return TDM_ERROR_NONE;
232     }
233
234     tdm_buffer_ref_backend(src);
235     tdm_buffer_ref_backend(dst);
236     ret = func_pp->pp_attach(private_pp->pp,
237                              tdm_buffer_get_surface(src),
238                              tdm_buffer_get_surface(dst));
239
240     pthread_mutex_unlock(&private_display->lock);
241
242     return ret;
243 }
244
245 EXTERN tdm_error
246 tdm_pp_commit(tdm_pp *pp)
247 {
248     PP_FUNC_ENTRY();
249
250     pthread_mutex_lock(&private_display->lock);
251
252     if (!func_pp->pp_commit)
253     {
254         pthread_mutex_unlock(&private_display->lock);
255         return TDM_ERROR_NONE;
256     }
257
258     ret = func_pp->pp_commit(private_pp->pp);
259
260     pthread_mutex_unlock(&private_display->lock);
261
262     return ret;
263 }