1bcbd1a0206a1c000cd5dd0cdd45cdd501931f9d
[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,
56                      void *user_data)
57 {
58         tdm_private_capture *private_capture = user_data;
59         tdm_private_display *private_display = private_capture->private_display;
60         int lock_after_cb_done = 0;
61         int ret;
62
63         ret = pthread_mutex_trylock(&private_display->lock);
64         if (ret == 0)
65                 pthread_mutex_unlock(&private_display->lock);
66         else  if (ret == EBUSY) {
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,
79                                    tdm_error *error)
80 {
81         tdm_private_display *private_display = private_output->private_display;
82         tdm_func_output *func_output = &private_display->func_output;
83         tdm_func_capture *func_capture = &private_display->func_capture;
84         tdm_private_capture *private_capture = NULL;
85         tdm_capture *capture_backend = NULL;
86         tdm_error ret = TDM_ERROR_NONE;
87
88         if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) {
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(
96                                   private_output->output_backend, &ret);
97         if (ret != TDM_ERROR_NONE) {
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                 TDM_ERR("failed: alloc memory");
106                 func_capture->capture_destroy(capture_backend);
107                 if (error)
108                         *error = TDM_ERROR_OUT_OF_MEMORY;
109                 return NULL;
110         }
111
112         ret = func_capture->capture_set_done_handler(capture_backend,
113                         _tdm_caputre_cb_done, private_capture);
114         if (ret != TDM_ERROR_NONE) {
115                 TDM_ERR("set capture_done_handler failed");
116                 func_capture->capture_destroy(capture_backend);
117                 if (error)
118                         *error = ret;
119                 return NULL;
120         }
121
122         LIST_ADD(&private_capture->link, &private_output->capture_list);
123         private_capture->target = TDM_CAPTURE_TARGET_OUTPUT;
124         private_capture->private_display = private_display;
125         private_capture->private_output = private_output;
126         private_capture->private_layer = NULL;
127         private_capture->capture_backend = capture_backend;
128
129         if (error)
130                 *error = TDM_ERROR_NONE;
131
132         return private_capture;
133 }
134
135 INTERN tdm_private_capture *
136 tdm_capture_create_layer_internal(tdm_private_layer *private_layer,
137                                   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                 TDM_ERR("no capture capability");
149                 if (error)
150                         *error = TDM_ERROR_NO_CAPABILITY;
151                 return NULL;
152         }
153
154         capture_backend = func_layer->layer_create_capture(private_layer->layer_backend,
155                           &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                 TDM_ERR("failed: alloc memory");
162                 func_capture->capture_destroy(capture_backend);
163                 if (error)
164                         *error = TDM_ERROR_OUT_OF_MEMORY;
165                 return NULL;
166         }
167
168         LIST_ADD(&private_capture->link, &private_output->capture_list);
169         private_capture->target = TDM_CAPTURE_TARGET_LAYER;
170         private_capture->private_display = private_display;
171         private_capture->private_output = private_output;
172         private_capture->private_layer = private_layer;
173         private_capture->capture_backend = capture_backend;
174
175         if (error)
176                 *error = TDM_ERROR_NONE;
177
178         return private_capture;
179 }
180
181 INTERN void
182 tdm_capture_destroy_internal(tdm_private_capture *private_capture)
183 {
184         tdm_func_capture *func_capture;
185
186         if (!private_capture)
187                 return;
188
189         LIST_DEL(&private_capture->link);
190
191         func_capture = &private_capture->private_display->func_capture;
192         func_capture->capture_destroy(private_capture->capture_backend);
193
194         free(private_capture);
195 }
196
197 EXTERN void
198 tdm_capture_destroy(tdm_capture *capture)
199 {
200         tdm_private_capture *private_capture = capture;
201         tdm_private_display *private_display;
202
203         if (!private_capture)
204                 return;
205
206         private_display = private_capture->private_display;
207
208         pthread_mutex_lock(&private_display->lock);
209         tdm_capture_destroy_internal(private_capture);
210         pthread_mutex_unlock(&private_display->lock);
211 }
212
213 EXTERN tdm_error
214 tdm_capture_set_info(tdm_capture *capture, tdm_info_capture *info)
215 {
216         CAPTURE_FUNC_ENTRY();
217
218         TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
219
220         pthread_mutex_lock(&private_display->lock);
221
222         if (!func_capture->capture_set_info) {
223                 pthread_mutex_unlock(&private_display->lock);
224                 return TDM_ERROR_NONE;
225         }
226
227         ret = func_capture->capture_set_info(private_capture->capture_backend, info);
228
229         pthread_mutex_unlock(&private_display->lock);
230
231         return ret;
232 }
233
234 EXTERN tdm_error
235 tdm_capture_attach(tdm_capture *capture, tbm_surface_h buffer)
236 {
237         CAPTURE_FUNC_ENTRY();
238
239         TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER);
240
241         pthread_mutex_lock(&private_display->lock);
242
243         if (!func_capture->capture_attach) {
244                 pthread_mutex_unlock(&private_display->lock);
245                 return TDM_ERROR_NONE;
246         }
247
248         tdm_buffer_ref_backend(buffer);
249         ret = func_capture->capture_attach(private_capture->capture_backend, buffer);
250
251         pthread_mutex_unlock(&private_display->lock);
252
253         return ret;
254 }
255
256 EXTERN tdm_error
257 tdm_capture_commit(tdm_capture *capture)
258 {
259         CAPTURE_FUNC_ENTRY();
260
261         pthread_mutex_lock(&private_display->lock);
262
263         if (!func_capture->capture_commit) {
264                 pthread_mutex_unlock(&private_display->lock);
265                 return TDM_ERROR_NONE;
266         }
267
268         ret = func_capture->capture_commit(private_capture->capture_backend);
269
270         pthread_mutex_unlock(&private_display->lock);
271
272         return ret;
273 }