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 **************************************************************************/
41 #include "tdm_backend.h"
42 #include "tdm_private.h"
43 #include "tdm_helper.h"
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 TDM_RETURN_VAL_IF_FAIL(tdm_display_is_valid(dpy), TDM_ERROR_INVALID_PARAMETER); \
52 private_display = (tdm_private_display*)dpy;
54 #define DISPLAY_FUNC_ENTRY_ERROR() \
55 tdm_private_display *private_display; \
56 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
57 TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(dpy != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \
58 TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(tdm_display_is_valid(dpy), TDM_ERROR_INVALID_PARAMETER, NULL); \
59 private_display = (tdm_private_display*)dpy;
62 tdm_display_get_capabilities(tdm_display *dpy,
63 tdm_display_capability *capabilities)
67 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
69 _pthread_mutex_lock(&private_display->lock);
71 *capabilities = private_display->capabilities;
73 _pthread_mutex_unlock(&private_display->lock);
79 tdm_display_get_pp_capabilities(tdm_display *dpy,
80 tdm_pp_capability *capabilities)
84 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
86 _pthread_mutex_lock(&private_display->lock);
88 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
90 TDM_ERR("no pp capability");
91 _pthread_mutex_unlock(&private_display->lock);
92 return TDM_ERROR_NO_CAPABILITY;
96 *capabilities = private_display->caps_pp.capabilities;
98 _pthread_mutex_unlock(&private_display->lock);
104 tdm_display_get_pp_available_formats(tdm_display *dpy,
105 const tbm_format **formats, int *count)
107 DISPLAY_FUNC_ENTRY();
109 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
110 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
112 _pthread_mutex_lock(&private_display->lock);
114 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
115 /* LCOV_EXCL_START */
116 TDM_ERR("no pp capability");
117 _pthread_mutex_unlock(&private_display->lock);
118 return TDM_ERROR_NO_CAPABILITY;
122 *formats = (const tbm_format *)private_display->caps_pp.formats;
123 *count = private_display->caps_pp.format_count;
125 _pthread_mutex_unlock(&private_display->lock);
131 tdm_display_get_pp_available_size(tdm_display *dpy, int *min_w, int *min_h,
132 int *max_w, int *max_h, int *preferred_align)
134 DISPLAY_FUNC_ENTRY();
136 _pthread_mutex_lock(&private_display->lock);
138 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
139 /* LCOV_EXCL_START */
140 TDM_ERR("no pp capability");
141 _pthread_mutex_unlock(&private_display->lock);
142 return TDM_ERROR_NO_CAPABILITY;
147 *min_w = TDM_FRONT_VALUE(private_display->caps_pp.min_w);
149 *min_h = TDM_FRONT_VALUE(private_display->caps_pp.min_h);
151 *max_w = TDM_FRONT_VALUE(private_display->caps_pp.max_w);
153 *max_h = TDM_FRONT_VALUE(private_display->caps_pp.max_h);
155 *preferred_align = TDM_FRONT_VALUE(private_display->caps_pp.preferred_align);
157 _pthread_mutex_unlock(&private_display->lock);
163 tdm_display_get_capture_capabilities(tdm_display *dpy,
164 tdm_capture_capability *capabilities)
166 DISPLAY_FUNC_ENTRY();
168 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
170 _pthread_mutex_lock(&private_display->lock);
172 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) {
173 /* LCOV_EXCL_START */
174 TDM_ERR("no capture capability");
175 _pthread_mutex_unlock(&private_display->lock);
176 return TDM_ERROR_NO_CAPABILITY;
180 *capabilities = private_display->caps_capture.capabilities;
182 _pthread_mutex_unlock(&private_display->lock);
188 tdm_display_get_catpure_available_formats(tdm_display *dpy,
189 const tbm_format **formats, int *count)
191 DISPLAY_FUNC_ENTRY();
193 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
194 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
196 _pthread_mutex_lock(&private_display->lock);
198 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) {
199 /* LCOV_EXCL_START */
200 TDM_ERR("no capture capability");
201 _pthread_mutex_unlock(&private_display->lock);
202 return TDM_ERROR_NO_CAPABILITY;
206 *formats = (const tbm_format *)private_display->caps_capture.formats;
207 *count = private_display->caps_capture.format_count;
209 _pthread_mutex_unlock(&private_display->lock);
215 tdm_display_get_capture_available_size(tdm_display *dpy, int *min_w, int *min_h,
216 int *max_w, int *max_h, int *preferred_align)
218 DISPLAY_FUNC_ENTRY();
220 _pthread_mutex_lock(&private_display->lock);
222 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) {
223 /* LCOV_EXCL_START */
224 TDM_ERR("no capture capability");
225 _pthread_mutex_unlock(&private_display->lock);
226 return TDM_ERROR_NO_CAPABILITY;
231 *min_w = TDM_FRONT_VALUE(private_display->caps_capture.min_w);
233 *min_h = TDM_FRONT_VALUE(private_display->caps_capture.min_h);
235 *max_w = TDM_FRONT_VALUE(private_display->caps_capture.max_w);
237 *max_h = TDM_FRONT_VALUE(private_display->caps_capture.max_h);
239 *preferred_align = TDM_FRONT_VALUE(private_display->caps_capture.preferred_align);
241 _pthread_mutex_unlock(&private_display->lock);
247 tdm_display_get_max_layer_count(tdm_display *dpy, int *max_count)
249 DISPLAY_FUNC_ENTRY();
251 TDM_RETURN_VAL_IF_FAIL(max_count != NULL, TDM_ERROR_INVALID_PARAMETER);
253 _pthread_mutex_lock(&private_display->lock);
255 *max_count = TDM_FRONT_VALUE(private_display->caps_display.max_layer_count);
257 _pthread_mutex_unlock(&private_display->lock);
263 tdm_display_get_output_count(tdm_display *dpy, int *count)
265 tdm_private_output *private_output = NULL;
267 DISPLAY_FUNC_ENTRY();
269 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
271 _pthread_mutex_lock(&private_display->lock);
274 LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link)
278 /* LCOV_EXCL_START */
279 _pthread_mutex_unlock(&private_display->lock);
280 return TDM_ERROR_NONE;
284 _pthread_mutex_unlock(&private_display->lock);
291 tdm_display_get_output(tdm_display *dpy, int index, tdm_error *error)
293 tdm_private_output *private_output = NULL;
295 DISPLAY_FUNC_ENTRY_ERROR();
297 _pthread_mutex_lock(&private_display->lock);
300 *error = TDM_ERROR_NONE;
302 LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link) {
303 if (private_output->index == index) {
304 _pthread_mutex_unlock(&private_display->lock);
305 return private_output;
309 _pthread_mutex_unlock(&private_display->lock);
315 tdm_display_get_fd(tdm_display *dpy, int *fd)
317 DISPLAY_FUNC_ENTRY();
319 TDM_RETURN_VAL_IF_FAIL(fd != NULL, TDM_ERROR_INVALID_PARAMETER);
321 _pthread_mutex_lock(&private_display->lock);
323 if (tdm_thread_is_running())
324 *fd = tdm_thread_get_fd(private_display->private_loop);
326 *fd = tdm_event_loop_get_fd(private_display);
328 _pthread_mutex_unlock(&private_display->lock);
334 tdm_display_handle_events(tdm_display *dpy)
339 DISPLAY_FUNC_ENTRY();
341 ret = tdm_display_get_fd(dpy, &fd);
342 TDM_RETURN_VAL_IF_FAIL(fd >= 0, ret);
348 if (tdm_debug_module & TDM_DEBUG_THREAD)
349 TDM_INFO("fd(%d) polling in", fd);
351 while (poll(&fds, 1, -1) < 0) {
352 /* LCOV_EXCL_START */
353 if (errno == EINTR || errno == EAGAIN) /* normal case */
356 TDM_ERR("poll failed: %m");
357 return TDM_ERROR_OPERATION_FAILED;
362 if (tdm_debug_module & TDM_DEBUG_THREAD)
363 TDM_INFO("fd(%d) polling out", fd);
365 if (tdm_thread_is_running())
366 ret = tdm_thread_handle_cb(private_display->private_loop);
368 ret = tdm_event_loop_dispatch(private_display);
374 tdm_display_get_backend_info(tdm_display *dpy, const char **name,
375 const char **vendor, int *major, int *minor)
377 tdm_backend_module *module_data;
379 DISPLAY_FUNC_ENTRY();
381 _pthread_mutex_lock(&private_display->lock);
383 module_data = private_display->module_data;
386 *name = module_data->name;
388 *vendor = module_data->vendor;
390 *major = TDM_BACKEND_GET_ABI_MAJOR(module_data->abi_version);
392 *minor = TDM_BACKEND_GET_ABI_MINOR(module_data->abi_version);
394 _pthread_mutex_unlock(&private_display->lock);
400 tdm_display_create_pp(tdm_display *dpy, tdm_error *error)
404 DISPLAY_FUNC_ENTRY_ERROR();
406 _pthread_mutex_lock(&private_display->lock);
408 pp = (tdm_pp *)tdm_pp_create_internal(private_display, error);
410 _pthread_mutex_unlock(&private_display->lock);