add excluding coverage comments for tdm_display.c
[platform/core/uifw/libtdm.git] / src / tdm_display.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 #include "tdm_helper.h"
44
45 #define COUNT_MAX   10
46
47 #define DISPLAY_FUNC_ENTRY() \
48         tdm_private_display *private_display; \
49         tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
50         TDM_RETURN_VAL_IF_FAIL(dpy != NULL, TDM_ERROR_INVALID_PARAMETER); \
51         private_display = (tdm_private_display*)dpy;
52
53 #define DISPLAY_FUNC_ENTRY_ERROR() \
54         tdm_private_display *private_display; \
55         tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
56         TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(dpy != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \
57         private_display = (tdm_private_display*)dpy;
58
59 EXTERN tdm_error
60 tdm_display_get_capabilities(tdm_display *dpy,
61                                                          tdm_display_capability *capabilities)
62 {
63         DISPLAY_FUNC_ENTRY();
64
65         TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
66
67         _pthread_mutex_lock(&private_display->lock);
68
69         *capabilities = private_display->capabilities;
70
71         _pthread_mutex_unlock(&private_display->lock);
72
73         return ret;
74 }
75
76 EXTERN tdm_error
77 tdm_display_get_pp_capabilities(tdm_display *dpy,
78                                                                 tdm_pp_capability *capabilities)
79 {
80         DISPLAY_FUNC_ENTRY();
81
82         TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
83
84         _pthread_mutex_lock(&private_display->lock);
85
86         if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
87                 /* LCOV_EXCL_START */
88                 TDM_ERR("no pp capability");
89                 _pthread_mutex_unlock(&private_display->lock);
90                 return TDM_ERROR_NO_CAPABILITY;
91                 /* LCOV_EXCL_STOP */
92         }
93
94         *capabilities = private_display->caps_pp.capabilities;
95
96         _pthread_mutex_unlock(&private_display->lock);
97
98         return ret;
99 }
100
101 EXTERN tdm_error
102 tdm_display_get_pp_available_formats(tdm_display *dpy,
103                                                                          const tbm_format **formats, int *count)
104 {
105         DISPLAY_FUNC_ENTRY();
106
107         TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
108         TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
109
110         _pthread_mutex_lock(&private_display->lock);
111
112         if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
113                 /* LCOV_EXCL_START */
114                 TDM_ERR("no pp capability");
115                 _pthread_mutex_unlock(&private_display->lock);
116                 return TDM_ERROR_NO_CAPABILITY;
117                 /* LCOV_EXCL_STOP */
118         }
119
120         *formats = (const tbm_format *)private_display->caps_pp.formats;
121         *count = private_display->caps_pp.format_count;
122
123         _pthread_mutex_unlock(&private_display->lock);
124
125         return ret;
126 }
127
128 EXTERN tdm_error
129 tdm_display_get_pp_available_size(tdm_display *dpy, int *min_w, int *min_h,
130                                                                   int *max_w, int *max_h, int *preferred_align)
131 {
132         DISPLAY_FUNC_ENTRY();
133
134         _pthread_mutex_lock(&private_display->lock);
135
136         if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
137                 /* LCOV_EXCL_START */
138                 TDM_ERR("no pp capability");
139                 _pthread_mutex_unlock(&private_display->lock);
140                 return TDM_ERROR_NO_CAPABILITY;
141                 /* LCOV_EXCL_STOP */
142         }
143
144         if (min_w)
145                 *min_w = TDM_FRONT_VALUE(private_display->caps_pp.min_w);
146         if (min_h)
147                 *min_h = TDM_FRONT_VALUE(private_display->caps_pp.min_h);
148         if (max_w)
149                 *max_w = TDM_FRONT_VALUE(private_display->caps_pp.max_w);
150         if (max_h)
151                 *max_h = TDM_FRONT_VALUE(private_display->caps_pp.max_h);
152         if (preferred_align)
153                 *preferred_align = TDM_FRONT_VALUE(private_display->caps_pp.preferred_align);
154
155         _pthread_mutex_unlock(&private_display->lock);
156
157         return ret;
158 }
159
160 EXTERN tdm_error
161 tdm_display_get_capture_capabilities(tdm_display *dpy,
162                                                                          tdm_capture_capability *capabilities)
163 {
164         DISPLAY_FUNC_ENTRY();
165
166         TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
167
168         _pthread_mutex_lock(&private_display->lock);
169
170         if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) {
171                 /* LCOV_EXCL_START */
172                 TDM_ERR("no capture capability");
173                 _pthread_mutex_unlock(&private_display->lock);
174                 return TDM_ERROR_NO_CAPABILITY;
175                 /* LCOV_EXCL_STOP */
176         }
177
178         *capabilities = private_display->caps_capture.capabilities;
179
180         _pthread_mutex_unlock(&private_display->lock);
181
182         return ret;
183 }
184
185 EXTERN tdm_error
186 tdm_display_get_catpure_available_formats(tdm_display *dpy,
187                 const tbm_format **formats, int *count)
188 {
189         DISPLAY_FUNC_ENTRY();
190
191         TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
192         TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
193
194         _pthread_mutex_lock(&private_display->lock);
195
196         if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) {
197                 /* LCOV_EXCL_START */
198                 TDM_ERR("no capture capability");
199                 _pthread_mutex_unlock(&private_display->lock);
200                 return TDM_ERROR_NO_CAPABILITY;
201                 /* LCOV_EXCL_STOP */
202         }
203
204         *formats = (const tbm_format *)private_display->caps_capture.formats;
205         *count = private_display->caps_capture.format_count;
206
207         _pthread_mutex_unlock(&private_display->lock);
208
209         return ret;
210 }
211
212 EXTERN tdm_error
213 tdm_display_get_capture_available_size(tdm_display *dpy, int *min_w, int *min_h,
214                                                                            int *max_w, int *max_h, int *preferred_align)
215 {
216         DISPLAY_FUNC_ENTRY();
217
218         _pthread_mutex_lock(&private_display->lock);
219
220         if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) {
221                 /* LCOV_EXCL_START */
222                 TDM_ERR("no capture capability");
223                 _pthread_mutex_unlock(&private_display->lock);
224                 return TDM_ERROR_NO_CAPABILITY;
225                 /* LCOV_EXCL_STOP */
226         }
227
228         if (min_w)
229                 *min_w = TDM_FRONT_VALUE(private_display->caps_capture.min_w);
230         if (min_h)
231                 *min_h = TDM_FRONT_VALUE(private_display->caps_capture.min_h);
232         if (max_w)
233                 *max_w = TDM_FRONT_VALUE(private_display->caps_capture.max_w);
234         if (max_h)
235                 *max_h = TDM_FRONT_VALUE(private_display->caps_capture.max_h);
236         if (preferred_align)
237                 *preferred_align = TDM_FRONT_VALUE(private_display->caps_capture.preferred_align);
238
239         _pthread_mutex_unlock(&private_display->lock);
240
241         return ret;
242 }
243
244 EXTERN tdm_error
245 tdm_display_get_max_layer_count(tdm_display *dpy, int *max_count)
246 {
247         DISPLAY_FUNC_ENTRY();
248
249         TDM_RETURN_VAL_IF_FAIL(max_count != NULL, TDM_ERROR_INVALID_PARAMETER);
250
251         _pthread_mutex_lock(&private_display->lock);
252
253         *max_count = TDM_FRONT_VALUE(private_display->caps_display.max_layer_count);
254
255         _pthread_mutex_unlock(&private_display->lock);
256
257         return ret;
258 }
259
260 EXTERN tdm_error
261 tdm_display_get_output_count(tdm_display *dpy, int *count)
262 {
263         tdm_private_output *private_output = NULL;
264
265         DISPLAY_FUNC_ENTRY();
266
267         TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
268
269         _pthread_mutex_lock(&private_display->lock);
270
271         *count = 0;
272         LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link)
273         (*count)++;
274
275         if (*count == 0) {
276                 /* LCOV_EXCL_START */
277                 _pthread_mutex_unlock(&private_display->lock);
278                 return TDM_ERROR_NONE;
279                 /* LCOV_EXCL_STOP */
280         }
281
282         _pthread_mutex_unlock(&private_display->lock);
283
284         return ret;
285 }
286
287
288 EXTERN tdm_output *
289 tdm_display_get_output(tdm_display *dpy, int index, tdm_error *error)
290 {
291         tdm_private_output *private_output = NULL;
292
293         DISPLAY_FUNC_ENTRY_ERROR();
294
295         _pthread_mutex_lock(&private_display->lock);
296
297         if (error)
298                 *error = TDM_ERROR_NONE;
299
300         LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link) {
301                 if (private_output->index == index) {
302                         _pthread_mutex_unlock(&private_display->lock);
303                         return private_output;
304                 }
305         }
306
307         _pthread_mutex_unlock(&private_display->lock);
308
309         return NULL;
310 }
311
312 EXTERN tdm_error
313 tdm_display_get_fd(tdm_display *dpy, int *fd)
314 {
315         DISPLAY_FUNC_ENTRY();
316
317         TDM_RETURN_VAL_IF_FAIL(fd != NULL, TDM_ERROR_INVALID_PARAMETER);
318
319         _pthread_mutex_lock(&private_display->lock);
320
321         if (tdm_thread_is_running())
322                 *fd = tdm_thread_get_fd(private_display->private_loop);
323         else
324                 *fd = tdm_event_loop_get_fd(private_display);
325
326         _pthread_mutex_unlock(&private_display->lock);
327
328         return ret;
329 }
330
331 EXTERN tdm_error
332 tdm_display_handle_events(tdm_display *dpy)
333 {
334         struct pollfd fds;
335         int fd = -1;
336
337         DISPLAY_FUNC_ENTRY();
338
339         ret = tdm_display_get_fd(dpy, &fd);
340         TDM_RETURN_VAL_IF_FAIL(fd >= 0, ret);
341
342         fds.events = POLLIN;
343         fds.fd = fd;
344         fds.revents = 0;
345
346         if (tdm_debug_module & TDM_DEBUG_THREAD)
347                 TDM_INFO("fd(%d) polling in", fd);
348
349         while (poll(&fds, 1, -1) < 0) {
350                 /* LCOV_EXCL_START */
351                 if (errno == EINTR || errno == EAGAIN)  /* normal case */
352                         continue;
353                 else {
354                         TDM_ERR("poll failed: %m");
355                         return TDM_ERROR_OPERATION_FAILED;
356                 }
357                 /* LCOV_EXCL_STOP */
358         }
359
360         if (tdm_debug_module & TDM_DEBUG_THREAD)
361                 TDM_INFO("fd(%d) polling out", fd);
362
363         if (tdm_thread_is_running())
364                 ret = tdm_thread_handle_cb(private_display->private_loop);
365         else
366                 ret = tdm_event_loop_dispatch(private_display);
367
368         return ret;
369 }
370
371 EXTERN tdm_error
372 tdm_display_get_backend_info(tdm_display *dpy, const char **name,
373                                                          const char **vendor, int *major, int *minor)
374 {
375         tdm_backend_module *module_data;
376
377         DISPLAY_FUNC_ENTRY();
378
379         _pthread_mutex_lock(&private_display->lock);
380
381         module_data = private_display->module_data;
382
383         if (name)
384                 *name = module_data->name;
385         if (vendor)
386                 *vendor = module_data->vendor;
387         if (major)
388                 *major = TDM_BACKEND_GET_ABI_MAJOR(module_data->abi_version);
389         if (minor)
390                 *minor = TDM_BACKEND_GET_ABI_MINOR(module_data->abi_version);
391
392         _pthread_mutex_unlock(&private_display->lock);
393
394         return ret;
395 }
396
397 EXTERN tdm_pp *
398 tdm_display_create_pp(tdm_display *dpy, tdm_error *error)
399 {
400         tdm_pp *pp;
401
402         DISPLAY_FUNC_ENTRY_ERROR();
403
404         _pthread_mutex_lock(&private_display->lock);
405
406         pp = (tdm_pp *)tdm_pp_create_internal(private_display, error);
407
408         _pthread_mutex_unlock(&private_display->lock);
409
410         return pp;
411 }