1 /**************************************************************************
5 * Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
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>
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:
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
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.
34 **************************************************************************/
40 #include "tdm_private.h"
44 #define DISPLAY_FUNC_ENTRY() \
45 tdm_private_display *private_display; \
46 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
47 TDM_RETURN_VAL_IF_FAIL(dpy != NULL, TDM_ERROR_INVALID_PARAMETER); \
48 TDM_RETURN_VAL_IF_FAIL(tdm_display_is_valid(dpy), TDM_ERROR_INVALID_PARAMETER); \
49 private_display = (tdm_private_display*)dpy;
51 #define DISPLAY_FUNC_ENTRY_ERROR() \
52 tdm_private_display *private_display; \
53 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
54 TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(dpy != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \
55 TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(tdm_display_is_valid(dpy), TDM_ERROR_INVALID_PARAMETER, NULL); \
56 private_display = (tdm_private_display*)dpy;
59 tdm_display_get_capabilities(tdm_display *dpy,
60 tdm_display_capability *capabilities)
64 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
66 _pthread_mutex_lock(&private_display->lock);
68 *capabilities = private_display->capabilities;
70 _pthread_mutex_unlock(&private_display->lock);
76 tdm_display_get_pp_capabilities(tdm_display *dpy,
77 tdm_pp_capability *capabilities)
81 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
83 _pthread_mutex_lock(&private_display->lock);
85 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
87 TDM_ERR("no pp capability");
88 _pthread_mutex_unlock(&private_display->lock);
89 return TDM_ERROR_NO_CAPABILITY;
93 *capabilities = private_display->caps_pp.capabilities;
95 _pthread_mutex_unlock(&private_display->lock);
101 tdm_display_get_pp_available_formats(tdm_display *dpy,
102 const tbm_format **formats, int *count)
104 DISPLAY_FUNC_ENTRY();
106 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
107 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
109 _pthread_mutex_lock(&private_display->lock);
111 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
112 /* LCOV_EXCL_START */
113 TDM_ERR("no pp capability");
114 _pthread_mutex_unlock(&private_display->lock);
115 return TDM_ERROR_NO_CAPABILITY;
119 *formats = (const tbm_format *)private_display->caps_pp.formats;
120 *count = private_display->caps_pp.format_count;
122 _pthread_mutex_unlock(&private_display->lock);
128 tdm_display_get_pp_available_size(tdm_display *dpy, int *min_w, int *min_h,
129 int *max_w, int *max_h, int *preferred_align)
131 DISPLAY_FUNC_ENTRY();
133 _pthread_mutex_lock(&private_display->lock);
135 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
136 /* LCOV_EXCL_START */
137 TDM_ERR("no pp capability");
138 _pthread_mutex_unlock(&private_display->lock);
139 return TDM_ERROR_NO_CAPABILITY;
144 *min_w = TDM_FRONT_VALUE(private_display->caps_pp.min_w);
146 *min_h = TDM_FRONT_VALUE(private_display->caps_pp.min_h);
148 *max_w = TDM_FRONT_VALUE(private_display->caps_pp.max_w);
150 *max_h = TDM_FRONT_VALUE(private_display->caps_pp.max_h);
152 *preferred_align = TDM_FRONT_VALUE(private_display->caps_pp.preferred_align);
154 _pthread_mutex_unlock(&private_display->lock);
160 tdm_display_get_capture_capabilities(tdm_display *dpy,
161 tdm_capture_capability *capabilities)
163 DISPLAY_FUNC_ENTRY();
165 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
167 _pthread_mutex_lock(&private_display->lock);
169 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) {
170 /* LCOV_EXCL_START */
171 TDM_ERR("no capture capability");
172 _pthread_mutex_unlock(&private_display->lock);
173 return TDM_ERROR_NO_CAPABILITY;
177 *capabilities = private_display->caps_capture.capabilities;
179 _pthread_mutex_unlock(&private_display->lock);
185 tdm_display_get_catpure_available_formats(tdm_display *dpy,
186 const tbm_format **formats, int *count)
188 DISPLAY_FUNC_ENTRY();
190 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
191 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
193 _pthread_mutex_lock(&private_display->lock);
195 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) {
196 /* LCOV_EXCL_START */
197 TDM_ERR("no capture capability");
198 _pthread_mutex_unlock(&private_display->lock);
199 return TDM_ERROR_NO_CAPABILITY;
203 *formats = (const tbm_format *)private_display->caps_capture.formats;
204 *count = private_display->caps_capture.format_count;
206 _pthread_mutex_unlock(&private_display->lock);
212 tdm_display_get_capture_available_size(tdm_display *dpy, int *min_w, int *min_h,
213 int *max_w, int *max_h, int *preferred_align)
215 DISPLAY_FUNC_ENTRY();
217 _pthread_mutex_lock(&private_display->lock);
219 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) {
220 /* LCOV_EXCL_START */
221 TDM_ERR("no capture capability");
222 _pthread_mutex_unlock(&private_display->lock);
223 return TDM_ERROR_NO_CAPABILITY;
228 *min_w = TDM_FRONT_VALUE(private_display->caps_capture.min_w);
230 *min_h = TDM_FRONT_VALUE(private_display->caps_capture.min_h);
232 *max_w = TDM_FRONT_VALUE(private_display->caps_capture.max_w);
234 *max_h = TDM_FRONT_VALUE(private_display->caps_capture.max_h);
236 *preferred_align = TDM_FRONT_VALUE(private_display->caps_capture.preferred_align);
238 _pthread_mutex_unlock(&private_display->lock);
244 tdm_display_get_max_layer_count(tdm_display *dpy, int *max_count)
246 DISPLAY_FUNC_ENTRY();
248 TDM_RETURN_VAL_IF_FAIL(max_count != NULL, TDM_ERROR_INVALID_PARAMETER);
250 _pthread_mutex_lock(&private_display->lock);
252 *max_count = TDM_FRONT_VALUE(private_display->caps_display.max_layer_count);
254 _pthread_mutex_unlock(&private_display->lock);
260 tdm_display_get_output_count(tdm_display *dpy, int *count)
262 tdm_private_output *private_output = NULL;
264 DISPLAY_FUNC_ENTRY();
266 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
268 _pthread_mutex_lock(&private_display->lock);
271 LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link)
275 /* LCOV_EXCL_START */
276 _pthread_mutex_unlock(&private_display->lock);
277 return TDM_ERROR_NONE;
281 _pthread_mutex_unlock(&private_display->lock);
288 tdm_display_get_output(tdm_display *dpy, int index, tdm_error *error)
290 tdm_private_output *private_output = NULL;
292 DISPLAY_FUNC_ENTRY_ERROR();
294 _pthread_mutex_lock(&private_display->lock);
297 *error = TDM_ERROR_NONE;
299 LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link) {
300 if (private_output->index == index) {
301 _pthread_mutex_unlock(&private_display->lock);
302 return private_output;
306 _pthread_mutex_unlock(&private_display->lock);
312 tdm_display_get_fd(tdm_display *dpy, int *fd)
314 DISPLAY_FUNC_ENTRY();
316 TDM_RETURN_VAL_IF_FAIL(fd != NULL, TDM_ERROR_INVALID_PARAMETER);
318 _pthread_mutex_lock(&private_display->lock);
320 if (tdm_thread_is_running())
321 *fd = tdm_thread_get_fd(private_display->private_loop);
323 *fd = tdm_event_loop_get_fd(private_display);
325 _pthread_mutex_unlock(&private_display->lock);
331 tdm_display_handle_events(tdm_display *dpy)
336 DISPLAY_FUNC_ENTRY();
338 ret = tdm_display_get_fd(dpy, &fd);
339 TDM_RETURN_VAL_IF_FAIL(fd >= 0, ret);
345 if (tdm_debug_module & TDM_DEBUG_THREAD)
346 TDM_INFO("fd(%d) polling in", fd);
348 while (poll(&fds, 1, -1) < 0) {
349 /* LCOV_EXCL_START */
350 if (errno == EINTR || errno == EAGAIN) /* normal case */
353 TDM_ERR("poll failed: %m");
354 return TDM_ERROR_OPERATION_FAILED;
359 if (tdm_debug_module & TDM_DEBUG_THREAD)
360 TDM_INFO("fd(%d) polling out", fd);
362 if (tdm_thread_is_running())
363 ret = tdm_thread_handle_cb(private_display->private_loop);
365 ret = tdm_event_loop_dispatch(private_display);
371 tdm_display_get_backend_info(tdm_display *dpy, const char **name,
372 const char **vendor, int *major, int *minor)
374 tdm_backend_module *module_data;
376 DISPLAY_FUNC_ENTRY();
378 _pthread_mutex_lock(&private_display->lock);
380 module_data = private_display->module_data;
383 *name = module_data->name;
385 *vendor = module_data->vendor;
387 *major = TDM_BACKEND_GET_ABI_MAJOR(module_data->abi_version);
389 *minor = TDM_BACKEND_GET_ABI_MINOR(module_data->abi_version);
391 _pthread_mutex_unlock(&private_display->lock);
397 tdm_display_create_pp(tdm_display *dpy, tdm_error *error)
401 DISPLAY_FUNC_ENTRY_ERROR();
403 _pthread_mutex_lock(&private_display->lock);
405 pp = (tdm_pp *)tdm_pp_create_internal(private_display, error);
407 _pthread_mutex_unlock(&private_display->lock);