change buffer type from tdm_buffer to tbm_surface
[platform/core/uifw/libtdm.git] / src / tdm_capture.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 CAPTURE_FUNC_ENTRY() \
45     tdm_func_capture *func_capture; \
46     tdm_private_display *private_display; \
47     tdm_private_capture *private_capture; \
48     tdm_error ret = TDM_ERROR_NONE; \
49     TDM_RETURN_VAL_IF_FAIL(capture != NULL, TDM_ERROR_INVALID_PARAMETER); \
50     private_capture = (tdm_private_capture*)capture; \
51     private_display = private_capture->private_display; \
52     func_capture = private_capture->func_capture
53
54 static void
55 _tdm_caputre_cb_done(tdm_capture *capture_backend, tbm_surface_h buffer, void *user_data)
56 {
57     tdm_private_capture *private_capture = user_data;
58     tdm_private_display *private_display = private_capture->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(buffer);
72
73     if (lock_after_cb_done)
74         pthread_mutex_lock(&private_display->lock);
75 }
76
77 INTERN tdm_private_capture*
78 tdm_capture_create_output_internal(tdm_private_output *private_output, tdm_error *error)
79 {
80     tdm_private_display *private_display;
81     tdm_func_display *func_display;
82     tdm_func_capture *func_capture;
83     tdm_private_capture *private_capture = NULL;
84     tdm_capture *capture_backend = NULL;
85     tdm_error ret = TDM_ERROR_NONE;
86
87     private_display = private_output->private_display;
88     func_display = &private_display->func_display;
89     func_capture = &private_display->func_capture;
90
91     if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE))
92     {
93         TDM_ERR("no capture capability");
94         if (error)
95             *error = TDM_ERROR_BAD_REQUEST;
96         return NULL;
97     }
98
99     capture_backend = func_display->output_create_capture(private_output->output_backend, &ret);
100     if (ret != TDM_ERROR_NONE)
101     {
102         if (error)
103             *error = ret;
104         return NULL;
105     }
106
107     private_capture = calloc(1, sizeof(tdm_private_capture));
108     if (!private_capture)
109     {
110         TDM_ERR("failed: alloc memory");
111         func_capture->capture_destroy(capture_backend);
112         if (error)
113             *error = TDM_ERROR_OUT_OF_MEMORY;
114         return NULL;
115     }
116
117     ret = func_capture->capture_set_done_handler(capture_backend, _tdm_caputre_cb_done, private_capture);
118     if (ret != TDM_ERROR_NONE)
119     {
120         TDM_ERR("set capture_done_handler failed");
121         func_capture->capture_destroy(capture_backend);
122         if (error)
123             *error = ret;
124         return NULL;
125     }
126
127     LIST_ADD(&private_capture->link, &private_output->capture_list);
128     private_capture->func_capture = func_capture;
129     private_capture->target = TDM_CAPTURE_TARGET_OUTPUT;
130     private_capture->private_display = private_display;
131     private_capture->private_output = private_output;
132     private_capture->private_layer = NULL;
133     private_capture->capture_backend = capture_backend;
134
135     if (error)
136         *error = TDM_ERROR_NONE;
137
138     return private_capture;
139 }
140
141 INTERN tdm_private_capture*
142 tdm_capture_create_layer_internal(tdm_private_layer *private_layer, tdm_error *error)
143 {
144     tdm_private_display *private_display;
145     tdm_private_output *private_output;
146     tdm_func_display *func_display;
147     tdm_func_capture *func_capture;
148     tdm_private_capture *private_capture = NULL;
149     tdm_capture *capture_backend = NULL;
150     tdm_error ret = TDM_ERROR_NONE;
151
152     private_output = private_layer->private_output;
153     private_display = private_output->private_display;
154     func_display = &private_display->func_display;
155     func_capture = &private_display->func_capture;
156
157     if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE))
158     {
159         TDM_ERR("no capture capability");
160         if (error)
161             *error = TDM_ERROR_BAD_REQUEST;
162         return NULL;
163     }
164
165     capture_backend = func_display->layer_create_capture(private_layer->layer_backend, &ret);
166     if (ret != TDM_ERROR_NONE)
167         return NULL;
168
169     private_capture = calloc(1, sizeof(tdm_private_capture));
170     if (!private_capture)
171     {
172         TDM_ERR("failed: alloc memory");
173         func_capture->capture_destroy(capture_backend);
174         if (error)
175             *error = TDM_ERROR_OUT_OF_MEMORY;
176         return NULL;
177     }
178
179     LIST_ADD(&private_capture->link, &private_output->capture_list);
180     private_capture->target = TDM_CAPTURE_TARGET_LAYER;
181     private_capture->func_capture = func_capture;
182     private_capture->private_display = private_display;
183     private_capture->private_output = private_output;
184     private_capture->private_layer = private_layer;
185     private_capture->capture_backend = capture_backend;
186
187     if (error)
188         *error = TDM_ERROR_NONE;
189
190     return private_capture;
191 }
192
193 INTERN void
194 tdm_capture_destroy_internal(tdm_private_capture *private_capture)
195 {
196     tdm_func_capture *func_capture;
197
198     if (!private_capture)
199         return;
200
201     LIST_DEL(&private_capture->link);
202
203     func_capture = private_capture->func_capture;
204     func_capture->capture_destroy(private_capture->capture_backend);
205
206     free(private_capture);
207 }
208
209 EXTERN void
210 tdm_capture_destroy(tdm_capture *capture)
211 {
212     tdm_private_capture *private_capture = capture;
213     tdm_private_display *private_display;
214
215     if (!private_capture)
216         return;
217
218     private_display = private_capture->private_display;
219
220     pthread_mutex_lock(&private_display->lock);
221     tdm_capture_destroy_internal(private_capture);
222     pthread_mutex_unlock(&private_display->lock);
223 }
224
225 EXTERN tdm_error
226 tdm_capture_set_info(tdm_capture *capture, tdm_info_capture *info)
227 {
228     CAPTURE_FUNC_ENTRY();
229
230     TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
231
232     pthread_mutex_lock(&private_display->lock);
233
234     if (!func_capture->capture_set_info)
235     {
236         pthread_mutex_unlock(&private_display->lock);
237         return TDM_ERROR_NONE;
238     }
239
240     ret = func_capture->capture_set_info(private_capture->capture_backend, info);
241
242     pthread_mutex_unlock(&private_display->lock);
243
244     return ret;
245 }
246
247 EXTERN tdm_error
248 tdm_capture_attach(tdm_capture *capture, tbm_surface_h buffer)
249 {
250     CAPTURE_FUNC_ENTRY();
251
252     TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER);
253
254     pthread_mutex_lock(&private_display->lock);
255
256     if (!func_capture->capture_attach)
257     {
258         pthread_mutex_unlock(&private_display->lock);
259         return TDM_ERROR_NONE;
260     }
261
262     tdm_buffer_ref_backend(buffer);
263     ret = func_capture->capture_attach(private_capture->capture_backend, buffer);
264
265     pthread_mutex_unlock(&private_display->lock);
266
267     return ret;
268 }
269
270 EXTERN tdm_error
271 tdm_capture_commit(tdm_capture *capture)
272 {
273     CAPTURE_FUNC_ENTRY();
274
275     pthread_mutex_lock(&private_display->lock);
276
277     if (!func_capture->capture_commit)
278     {
279         pthread_mutex_unlock(&private_display->lock);
280         return TDM_ERROR_NONE;
281     }
282
283     ret = func_capture->capture_commit(private_capture->capture_backend);
284
285     pthread_mutex_unlock(&private_display->lock);
286
287     return ret;
288 }