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"
44 #define PP_FUNC_ENTRY() \
45 tdm_func_pp *func_pp; \
46 tdm_private_display *private_display; \
47 tdm_private_pp *private_pp; \
48 tdm_error ret = TDM_ERROR_NONE; \
49 TDM_RETURN_VAL_IF_FAIL(pp != NULL, TDM_ERROR_INVALID_PARAMETER); \
50 private_pp = (tdm_private_pp*)pp; \
51 private_display = private_pp->private_display; \
52 func_pp = &private_display->func_pp
55 _tdm_pp_cb_done(tdm_pp *pp_backend, tbm_surface_h src, tbm_surface_h dst,
58 tdm_private_pp *private_pp = user_data;
59 tdm_private_display *private_display = private_pp->private_display;
60 int lock_after_cb_done = 0;
63 ret = pthread_mutex_trylock(&private_display->lock);
65 pthread_mutex_unlock(&private_display->lock);
66 else if (ret == EBUSY) {
67 pthread_mutex_unlock(&private_display->lock);
68 lock_after_cb_done = 1;
72 TDM_INFO("done: %p", src);
74 tdm_buffer_remove_list(&private_pp->buffer_list, src);
76 tdm_buffer_unref_backend(src);
77 tdm_buffer_unref_backend(dst);
79 if (lock_after_cb_done)
80 pthread_mutex_lock(&private_display->lock);
83 INTERN tdm_private_pp *
84 tdm_pp_create_internal(tdm_private_display *private_display, tdm_error *error)
86 tdm_func_display *func_display;
88 tdm_private_pp *private_pp = NULL;
89 tdm_pp *pp_backend = NULL;
90 tdm_error ret = TDM_ERROR_NONE;
92 func_display = &private_display->func_display;
93 func_pp = &private_display->func_pp;
95 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
96 TDM_ERR("no pp capability");
98 *error = TDM_ERROR_NO_CAPABILITY;
102 pp_backend = func_display->display_create_pp(private_display->bdata, &ret);
103 if (ret != TDM_ERROR_NONE) {
109 private_pp = calloc(1, sizeof(tdm_private_pp));
111 TDM_ERR("failed: alloc memory");
112 func_pp->pp_destroy(pp_backend);
114 *error = TDM_ERROR_OUT_OF_MEMORY;
118 ret = func_pp->pp_set_done_handler(pp_backend, _tdm_pp_cb_done, private_pp);
119 if (ret != TDM_ERROR_NONE) {
120 TDM_ERR("set pp_done_handler failed");
121 func_pp->pp_destroy(pp_backend);
127 LIST_ADD(&private_pp->link, &private_display->pp_list);
128 private_pp->private_display = private_display;
129 private_pp->pp_backend = pp_backend;
131 LIST_INITHEAD(&private_pp->buffer_list);
134 *error = TDM_ERROR_NONE;
140 tdm_pp_destroy_internal(tdm_private_pp *private_pp)
142 tdm_func_pp *func_pp;
147 func_pp = &private_pp->private_display->func_pp;
149 LIST_DEL(&private_pp->link);
151 func_pp->pp_destroy(private_pp->pp_backend);
153 if (!LIST_IS_EMPTY(&private_pp->buffer_list)) {
154 char str[256] = {0,};
155 tdm_buffer_dump_list(&private_pp->buffer_list, str, 256);
157 TDM_WRN("not finished: %s buffers", str);
164 tdm_pp_destroy(tdm_pp *pp)
166 tdm_private_pp *private_pp = pp;
167 tdm_private_display *private_display;
172 private_display = private_pp->private_display;
174 pthread_mutex_lock(&private_display->lock);
175 tdm_pp_destroy_internal(private_pp);
176 pthread_mutex_unlock(&private_display->lock);
180 tdm_pp_set_info(tdm_pp *pp, tdm_info_pp *info)
184 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
186 pthread_mutex_lock(&private_display->lock);
188 if (!func_pp->pp_set_info) {
189 pthread_mutex_unlock(&private_display->lock);
190 return TDM_ERROR_NONE;
193 TDM_INFO("pp info: src(%dx%d %d,%d %dx%d %c%c%c%c) dst(%dx%d %d,%d %dx%d %c%c%c%c) trans(%d) sync(%d) flags(%x)",
194 info->src_config.size.h, info->src_config.size.v,
195 info->src_config.pos.x, info->src_config.pos.y,
196 info->src_config.pos.w, info->src_config.pos.h,
197 FOURCC_STR(info->src_config.format),
198 info->dst_config.size.h, info->dst_config.size.v,
199 info->dst_config.pos.x, info->dst_config.pos.y,
200 info->dst_config.pos.w, info->dst_config.pos.h,
201 FOURCC_STR(info->dst_config.format),
202 info->transform, info->sync, info->flags);
204 ret = func_pp->pp_set_info(private_pp->pp_backend, info);
206 pthread_mutex_unlock(&private_display->lock);
212 tdm_pp_attach(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst)
216 TDM_RETURN_VAL_IF_FAIL(src != NULL, TDM_ERROR_INVALID_PARAMETER);
217 TDM_RETURN_VAL_IF_FAIL(dst != NULL, TDM_ERROR_INVALID_PARAMETER);
219 pthread_mutex_lock(&private_display->lock);
221 if (!func_pp->pp_attach) {
222 pthread_mutex_unlock(&private_display->lock);
223 return TDM_ERROR_NONE;
226 tdm_buffer_ref_backend(src);
227 tdm_buffer_ref_backend(dst);
228 ret = func_pp->pp_attach(private_pp->pp_backend, src, dst);
230 if (ret == TDM_ERROR_NONE)
231 tdm_buffer_add_list(&private_pp->buffer_list, src);
233 if (tdm_debug_buffer) {
234 char str[256] = {0,};
235 tdm_buffer_dump_list(&private_pp->buffer_list, str, 256);
236 TDM_INFO("attached: %s", str);
239 pthread_mutex_unlock(&private_display->lock);
245 tdm_pp_commit(tdm_pp *pp)
249 pthread_mutex_lock(&private_display->lock);
251 if (!func_pp->pp_commit) {
252 pthread_mutex_unlock(&private_display->lock);
253 return TDM_ERROR_NONE;
256 ret = func_pp->pp_commit(private_pp->pp_backend);
258 pthread_mutex_unlock(&private_display->lock);