change buffer type from tdm_buffer to tbm_surface
[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_backend, tbm_surface_h src, tbm_surface_h dst, void *user_data)
56 {
57     tdm_private_pp *private_pp = user_data;
58     tdm_private_display *private_display = private_pp->private_display;
59     int lock_after_cb_done = 0;
60     int ret;
61
62     ret = pthread_mutex_trylock(&private_display->lock);
63     if (ret == 0)
64         pthread_mutex_unlock(&private_display->lock);
65     else  if (ret == EBUSY)
66     {
67         pthread_mutex_unlock(&private_display->lock);
68         lock_after_cb_done = 1;
69     }
70
71     tdm_buffer_unref_backend(src);
72     tdm_buffer_unref_backend(dst);
73
74     if (lock_after_cb_done)
75         pthread_mutex_lock(&private_display->lock);
76 }
77
78 INTERN tdm_private_pp*
79 tdm_pp_create_internal(tdm_private_display *private_display, tdm_error *error)
80 {
81     tdm_func_display *func_display;
82     tdm_func_pp *func_pp;
83     tdm_private_pp *private_pp = NULL;
84     tdm_pp *pp_backend = NULL;
85     tdm_error ret = TDM_ERROR_NONE;
86
87     func_display = &private_display->func_display;
88     func_pp = &private_display->func_pp;
89
90     if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP))
91     {
92         TDM_ERR("no pp capability");
93         if (error)
94             *error = TDM_ERROR_BAD_REQUEST;
95         return NULL;
96     }
97
98     pp_backend = func_display->display_create_pp(private_display->bdata, &ret);
99     if (ret != TDM_ERROR_NONE)
100     {
101         if (error)
102             *error = ret;
103         return NULL;
104     }
105
106     private_pp = calloc(1, sizeof(tdm_private_pp));
107     if (!private_pp)
108     {
109         TDM_ERR("failed: alloc memory");
110         func_pp->pp_destroy(pp_backend);
111         if (error)
112             *error = TDM_ERROR_OUT_OF_MEMORY;
113         return NULL;
114     }
115
116     ret = func_pp->pp_set_done_handler(pp_backend, _tdm_pp_cb_done, private_pp);
117     if (ret != TDM_ERROR_NONE)
118     {
119         TDM_ERR("set pp_done_handler failed");
120         func_pp->pp_destroy(pp_backend);
121         if (error)
122             *error = ret;
123         return NULL;
124     }
125
126     LIST_ADD(&private_pp->link, &private_display->pp_list);
127     private_pp->func_pp = func_pp;
128     private_pp->private_display = private_display;
129     private_pp->pp_backend = pp_backend;
130
131     if (error)
132         *error = TDM_ERROR_NONE;
133
134     return private_pp;
135 }
136
137 INTERN void
138 tdm_pp_destroy_internal(tdm_private_pp *private_pp)
139 {
140     tdm_func_pp *func_pp;
141
142     if (!private_pp)
143         return;
144
145     func_pp = private_pp->func_pp;
146
147     LIST_DEL(&private_pp->link);
148
149     func_pp->pp_destroy(private_pp->pp_backend);
150
151     free(private_pp);
152 }
153
154 EXTERN void
155 tdm_pp_destroy(tdm_pp *pp)
156 {
157     tdm_private_pp *private_pp = pp;
158     tdm_private_display *private_display;
159
160     if (!private_pp)
161         return;
162
163     private_display = private_pp->private_display;
164
165     pthread_mutex_lock(&private_display->lock);
166     tdm_pp_destroy_internal(private_pp);
167     pthread_mutex_unlock(&private_display->lock);
168 }
169
170 EXTERN tdm_error
171 tdm_pp_set_info(tdm_pp *pp, tdm_info_pp *info)
172 {
173     PP_FUNC_ENTRY();
174
175     TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
176
177     pthread_mutex_lock(&private_display->lock);
178
179     if (!func_pp->pp_set_info)
180     {
181         pthread_mutex_unlock(&private_display->lock);
182         return TDM_ERROR_NONE;
183     }
184
185     ret = func_pp->pp_set_info(private_pp->pp_backend, info);
186
187     pthread_mutex_unlock(&private_display->lock);
188
189     return ret;
190 }
191
192 EXTERN tdm_error
193 tdm_pp_attach(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst)
194 {
195     PP_FUNC_ENTRY();
196
197     TDM_RETURN_VAL_IF_FAIL(src != NULL, TDM_ERROR_INVALID_PARAMETER);
198     TDM_RETURN_VAL_IF_FAIL(dst != NULL, TDM_ERROR_INVALID_PARAMETER);
199
200     pthread_mutex_lock(&private_display->lock);
201
202     if (!func_pp->pp_attach)
203     {
204         pthread_mutex_unlock(&private_display->lock);
205         return TDM_ERROR_NONE;
206     }
207
208     tdm_buffer_ref_backend(src);
209     tdm_buffer_ref_backend(dst);
210     ret = func_pp->pp_attach(private_pp->pp_backend, src, dst);
211
212     pthread_mutex_unlock(&private_display->lock);
213
214     return ret;
215 }
216
217 EXTERN tdm_error
218 tdm_pp_commit(tdm_pp *pp)
219 {
220     PP_FUNC_ENTRY();
221
222     pthread_mutex_lock(&private_display->lock);
223
224     if (!func_pp->pp_commit)
225     {
226         pthread_mutex_unlock(&private_display->lock);
227         return TDM_ERROR_NONE;
228     }
229
230     ret = func_pp->pp_commit(private_pp->pp_backend);
231
232     pthread_mutex_unlock(&private_display->lock);
233
234     return ret;
235 }