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