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)) {
87 TDM_ERR("no pp capability");
88 _pthread_mutex_unlock(&private_display->lock);
89 return TDM_ERROR_NO_CAPABILITY;
92 *capabilities = private_display->caps_pp.capabilities;
94 _pthread_mutex_unlock(&private_display->lock);
100 tdm_display_get_pp_available_formats(tdm_display *dpy,
101 const tbm_format **formats, int *count)
103 DISPLAY_FUNC_ENTRY();
105 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
106 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
108 _pthread_mutex_lock(&private_display->lock);
110 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
111 TDM_ERR("no pp capability");
112 _pthread_mutex_unlock(&private_display->lock);
113 return TDM_ERROR_NO_CAPABILITY;
116 *formats = (const tbm_format *)private_display->caps_pp.formats;
117 *count = private_display->caps_pp.format_count;
119 _pthread_mutex_unlock(&private_display->lock);
125 tdm_display_get_pp_available_size(tdm_display *dpy, int *min_w, int *min_h,
126 int *max_w, int *max_h, int *preferred_align)
128 DISPLAY_FUNC_ENTRY();
130 _pthread_mutex_lock(&private_display->lock);
132 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
133 TDM_ERR("no pp capability");
134 _pthread_mutex_unlock(&private_display->lock);
135 return TDM_ERROR_NO_CAPABILITY;
139 *min_w = TDM_FRONT_VALUE(private_display->caps_pp.min_w);
141 *min_h = TDM_FRONT_VALUE(private_display->caps_pp.min_h);
143 *max_w = TDM_FRONT_VALUE(private_display->caps_pp.max_w);
145 *max_h = TDM_FRONT_VALUE(private_display->caps_pp.max_h);
147 *preferred_align = TDM_FRONT_VALUE(private_display->caps_pp.preferred_align);
149 _pthread_mutex_unlock(&private_display->lock);
155 tdm_display_get_capture_capabilities(tdm_display *dpy,
156 tdm_capture_capability *capabilities)
158 DISPLAY_FUNC_ENTRY();
160 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
162 _pthread_mutex_lock(&private_display->lock);
164 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) {
165 TDM_ERR("no capture capability");
166 _pthread_mutex_unlock(&private_display->lock);
167 return TDM_ERROR_NO_CAPABILITY;
170 *capabilities = private_display->caps_capture.capabilities;
172 _pthread_mutex_unlock(&private_display->lock);
178 tdm_display_get_catpure_available_formats(tdm_display *dpy,
179 const tbm_format **formats, int *count)
181 DISPLAY_FUNC_ENTRY();
183 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
184 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
186 _pthread_mutex_lock(&private_display->lock);
188 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) {
189 TDM_ERR("no capture capability");
190 _pthread_mutex_unlock(&private_display->lock);
191 return TDM_ERROR_NO_CAPABILITY;
194 *formats = (const tbm_format *)private_display->caps_capture.formats;
195 *count = private_display->caps_capture.format_count;
197 _pthread_mutex_unlock(&private_display->lock);
203 tdm_display_get_capture_available_size(tdm_display *dpy, int *min_w, int *min_h,
204 int *max_w, int *max_h, int *preferred_align)
206 DISPLAY_FUNC_ENTRY();
208 _pthread_mutex_lock(&private_display->lock);
210 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) {
211 TDM_ERR("no capture capability");
212 _pthread_mutex_unlock(&private_display->lock);
213 return TDM_ERROR_NO_CAPABILITY;
217 *min_w = TDM_FRONT_VALUE(private_display->caps_capture.min_w);
219 *min_h = TDM_FRONT_VALUE(private_display->caps_capture.min_h);
221 *max_w = TDM_FRONT_VALUE(private_display->caps_capture.max_w);
223 *max_h = TDM_FRONT_VALUE(private_display->caps_capture.max_h);
225 *preferred_align = TDM_FRONT_VALUE(private_display->caps_capture.preferred_align);
227 _pthread_mutex_unlock(&private_display->lock);
233 tdm_display_get_max_layer_count(tdm_display *dpy, int *max_count)
235 DISPLAY_FUNC_ENTRY();
237 TDM_RETURN_VAL_IF_FAIL(max_count != NULL, TDM_ERROR_INVALID_PARAMETER);
239 _pthread_mutex_lock(&private_display->lock);
241 *max_count = TDM_FRONT_VALUE(private_display->caps_display.max_layer_count);
243 _pthread_mutex_unlock(&private_display->lock);
249 tdm_display_get_output_count(tdm_display *dpy, int *count)
251 tdm_private_output *private_output = NULL;
253 DISPLAY_FUNC_ENTRY();
255 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
257 _pthread_mutex_lock(&private_display->lock);
260 LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link)
264 _pthread_mutex_unlock(&private_display->lock);
265 return TDM_ERROR_NONE;
268 _pthread_mutex_unlock(&private_display->lock);
275 tdm_display_get_output(tdm_display *dpy, int index, tdm_error *error)
277 tdm_private_output *private_output = NULL;
279 DISPLAY_FUNC_ENTRY_ERROR();
281 _pthread_mutex_lock(&private_display->lock);
284 *error = TDM_ERROR_NONE;
286 LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link) {
287 if (private_output->index == index) {
288 _pthread_mutex_unlock(&private_display->lock);
289 return private_output;
293 _pthread_mutex_unlock(&private_display->lock);
299 tdm_display_get_fd(tdm_display *dpy, int *fd)
301 DISPLAY_FUNC_ENTRY();
303 TDM_RETURN_VAL_IF_FAIL(fd != NULL, TDM_ERROR_INVALID_PARAMETER);
305 _pthread_mutex_lock(&private_display->lock);
307 if (tdm_thread_is_running())
308 *fd = tdm_thread_get_fd(private_display->private_loop);
310 *fd = tdm_event_loop_get_fd(private_display);
312 _pthread_mutex_unlock(&private_display->lock);
318 tdm_display_handle_events(tdm_display *dpy)
323 DISPLAY_FUNC_ENTRY();
325 ret = tdm_display_get_fd(dpy, &fd);
326 TDM_RETURN_VAL_IF_FAIL(fd >= 0, ret);
332 if (tdm_debug_module & TDM_DEBUG_THREAD)
333 TDM_INFO("fd(%d) polling in", fd);
335 while (poll(&fds, 1, -1) < 0) {
336 if (errno == EINTR || errno == EAGAIN) /* normal case */
339 TDM_ERR("poll failed: %m");
340 return TDM_ERROR_OPERATION_FAILED;
344 if (tdm_debug_module & TDM_DEBUG_THREAD)
345 TDM_INFO("fd(%d) polling out", fd);
347 if (tdm_thread_is_running())
348 ret = tdm_thread_handle_cb(private_display->private_loop);
350 ret = tdm_event_loop_dispatch(private_display);
356 tdm_display_get_backend_info(tdm_display *dpy, const char **name,
357 const char **vendor, int *major, int *minor)
359 tdm_backend_module *module_data;
361 DISPLAY_FUNC_ENTRY();
363 _pthread_mutex_lock(&private_display->lock);
365 module_data = private_display->module_data;
368 *name = module_data->name;
370 *vendor = module_data->vendor;
372 *major = TDM_BACKEND_GET_ABI_MAJOR(module_data->abi_version);
374 *minor = TDM_BACKEND_GET_ABI_MINOR(module_data->abi_version);
376 _pthread_mutex_unlock(&private_display->lock);
382 tdm_display_create_pp(tdm_display *dpy, tdm_error *error)
386 DISPLAY_FUNC_ENTRY_ERROR();
388 _pthread_mutex_lock(&private_display->lock);
390 pp = (tdm_pp *)tdm_pp_create_internal(private_display, error);
392 _pthread_mutex_unlock(&private_display->lock);