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