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 private_display = (tdm_private_display*)dpy;
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;
60 tdm_display_get_capabilities(tdm_display *dpy,
61 tdm_display_capability *capabilities)
65 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
67 _pthread_mutex_lock(&private_display->lock);
69 *capabilities = private_display->capabilities;
71 _pthread_mutex_unlock(&private_display->lock);
77 tdm_display_get_pp_capabilities(tdm_display *dpy,
78 tdm_pp_capability *capabilities)
82 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
84 _pthread_mutex_lock(&private_display->lock);
86 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
88 TDM_ERR("no pp capability");
89 _pthread_mutex_unlock(&private_display->lock);
90 return TDM_ERROR_NO_CAPABILITY;
94 *capabilities = private_display->caps_pp.capabilities;
96 _pthread_mutex_unlock(&private_display->lock);
102 tdm_display_get_pp_available_formats(tdm_display *dpy,
103 const tbm_format **formats, int *count)
105 DISPLAY_FUNC_ENTRY();
107 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
108 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
110 _pthread_mutex_lock(&private_display->lock);
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;
120 *formats = (const tbm_format *)private_display->caps_pp.formats;
121 *count = private_display->caps_pp.format_count;
123 _pthread_mutex_unlock(&private_display->lock);
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)
132 DISPLAY_FUNC_ENTRY();
134 _pthread_mutex_lock(&private_display->lock);
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;
145 *min_w = TDM_FRONT_VALUE(private_display->caps_pp.min_w);
147 *min_h = TDM_FRONT_VALUE(private_display->caps_pp.min_h);
149 *max_w = TDM_FRONT_VALUE(private_display->caps_pp.max_w);
151 *max_h = TDM_FRONT_VALUE(private_display->caps_pp.max_h);
153 *preferred_align = TDM_FRONT_VALUE(private_display->caps_pp.preferred_align);
155 _pthread_mutex_unlock(&private_display->lock);
161 tdm_display_get_capture_capabilities(tdm_display *dpy,
162 tdm_capture_capability *capabilities)
164 DISPLAY_FUNC_ENTRY();
166 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
168 _pthread_mutex_lock(&private_display->lock);
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;
178 *capabilities = private_display->caps_capture.capabilities;
180 _pthread_mutex_unlock(&private_display->lock);
186 tdm_display_get_catpure_available_formats(tdm_display *dpy,
187 const tbm_format **formats, int *count)
189 DISPLAY_FUNC_ENTRY();
191 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
192 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
194 _pthread_mutex_lock(&private_display->lock);
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;
204 *formats = (const tbm_format *)private_display->caps_capture.formats;
205 *count = private_display->caps_capture.format_count;
207 _pthread_mutex_unlock(&private_display->lock);
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)
216 DISPLAY_FUNC_ENTRY();
218 _pthread_mutex_lock(&private_display->lock);
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;
229 *min_w = TDM_FRONT_VALUE(private_display->caps_capture.min_w);
231 *min_h = TDM_FRONT_VALUE(private_display->caps_capture.min_h);
233 *max_w = TDM_FRONT_VALUE(private_display->caps_capture.max_w);
235 *max_h = TDM_FRONT_VALUE(private_display->caps_capture.max_h);
237 *preferred_align = TDM_FRONT_VALUE(private_display->caps_capture.preferred_align);
239 _pthread_mutex_unlock(&private_display->lock);
245 tdm_display_get_max_layer_count(tdm_display *dpy, int *max_count)
247 DISPLAY_FUNC_ENTRY();
249 TDM_RETURN_VAL_IF_FAIL(max_count != NULL, TDM_ERROR_INVALID_PARAMETER);
251 _pthread_mutex_lock(&private_display->lock);
253 *max_count = TDM_FRONT_VALUE(private_display->caps_display.max_layer_count);
255 _pthread_mutex_unlock(&private_display->lock);
261 tdm_display_get_output_count(tdm_display *dpy, int *count)
263 tdm_private_output *private_output = NULL;
265 DISPLAY_FUNC_ENTRY();
267 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
269 _pthread_mutex_lock(&private_display->lock);
272 LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link)
276 /* LCOV_EXCL_START */
277 _pthread_mutex_unlock(&private_display->lock);
278 return TDM_ERROR_NONE;
282 _pthread_mutex_unlock(&private_display->lock);
289 tdm_display_get_output(tdm_display *dpy, int index, tdm_error *error)
291 tdm_private_output *private_output = NULL;
293 DISPLAY_FUNC_ENTRY_ERROR();
295 _pthread_mutex_lock(&private_display->lock);
298 *error = TDM_ERROR_NONE;
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;
307 _pthread_mutex_unlock(&private_display->lock);
313 tdm_display_get_fd(tdm_display *dpy, int *fd)
315 DISPLAY_FUNC_ENTRY();
317 TDM_RETURN_VAL_IF_FAIL(fd != NULL, TDM_ERROR_INVALID_PARAMETER);
319 _pthread_mutex_lock(&private_display->lock);
321 if (tdm_thread_is_running())
322 *fd = tdm_thread_get_fd(private_display->private_loop);
324 *fd = tdm_event_loop_get_fd(private_display);
326 _pthread_mutex_unlock(&private_display->lock);
332 tdm_display_handle_events(tdm_display *dpy)
337 DISPLAY_FUNC_ENTRY();
339 ret = tdm_display_get_fd(dpy, &fd);
340 TDM_RETURN_VAL_IF_FAIL(fd >= 0, ret);
346 if (tdm_debug_module & TDM_DEBUG_THREAD)
347 TDM_INFO("fd(%d) polling in", fd);
349 while (poll(&fds, 1, -1) < 0) {
350 /* LCOV_EXCL_START */
351 if (errno == EINTR || errno == EAGAIN) /* normal case */
354 TDM_ERR("poll failed: %m");
355 return TDM_ERROR_OPERATION_FAILED;
360 if (tdm_debug_module & TDM_DEBUG_THREAD)
361 TDM_INFO("fd(%d) polling out", fd);
363 if (tdm_thread_is_running())
364 ret = tdm_thread_handle_cb(private_display->private_loop);
366 ret = tdm_event_loop_dispatch(private_display);
372 tdm_display_get_backend_info(tdm_display *dpy, const char **name,
373 const char **vendor, int *major, int *minor)
375 tdm_backend_module *module_data;
377 DISPLAY_FUNC_ENTRY();
379 _pthread_mutex_lock(&private_display->lock);
381 module_data = private_display->module_data;
384 *name = module_data->name;
386 *vendor = module_data->vendor;
388 *major = TDM_BACKEND_GET_ABI_MAJOR(module_data->abi_version);
390 *minor = TDM_BACKEND_GET_ABI_MINOR(module_data->abi_version);
392 _pthread_mutex_unlock(&private_display->lock);
398 tdm_display_create_pp(tdm_display *dpy, tdm_error *error)
402 DISPLAY_FUNC_ENTRY_ERROR();
404 _pthread_mutex_lock(&private_display->lock);
406 pp = (tdm_pp *)tdm_pp_create_internal(private_display, error);
408 _pthread_mutex_unlock(&private_display->lock);