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 HWC_WINDOW_FUNC_ENTRY() \
45 tdm_private_display *private_display; \
46 tdm_private_output *private_output; \
47 tdm_private_hwc_window *private_hwc_window; \
48 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
49 TDM_RETURN_VAL_IF_FAIL(hwc_window != NULL, TDM_ERROR_INVALID_PARAMETER); \
50 private_hwc_window = (tdm_private_hwc_window*)hwc_window; \
51 private_output = private_hwc_window->private_output; \
52 private_display = private_output->private_display
54 #define HWC_WINDOW_FUNC_ENTRY_ERROR() \
55 tdm_private_display *private_display; \
56 tdm_private_output *private_output; \
57 tdm_private_hwc_window *private_hwc_window; \
58 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
59 TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(hwc_window != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \
60 private_hwc_window = (tdm_private_hwc_window*)hwc_window; \
61 private_output = private_hwc_window->private_output; \
62 private_display = private_output->private_display
64 #define HWC_WINDOW_FUNC_ENTRY_VOID_RETURN() \
65 tdm_private_display *private_display; \
66 tdm_private_output *private_output; \
67 tdm_private_hwc_window *private_hwc_window; \
68 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
69 TDM_RETURN_IF_FAIL(hwc_window != NULL); \
70 private_hwc_window = (tdm_private_hwc_window*)hwc_window; \
71 private_output = private_hwc_window->private_output; \
72 private_display = private_output->private_display
75 tdm_hwc_window_get_tbm_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error)
77 tdm_func_hwc_window *func_hwc_window = NULL;
78 tbm_surface_queue_h queue = NULL;
80 HWC_WINDOW_FUNC_ENTRY_ERROR();
82 _pthread_mutex_lock(&private_display->lock);
84 func_hwc_window = &private_display->func_hwc_window;
86 if (!func_hwc_window->hwc_window_get_tbm_buffer_queue) {
88 _pthread_mutex_unlock(&private_display->lock);
89 TDM_ERR("not implemented!!");
91 *error = TDM_ERROR_NOT_IMPLEMENTED;
96 queue = func_hwc_window->hwc_window_get_tbm_buffer_queue(private_hwc_window->hwc_window_backend, error);
98 _pthread_mutex_unlock(&private_display->lock);
104 tdm_hwc_window_set_composition_type(tdm_hwc_window *hwc_window,
105 tdm_hwc_window_composition composition_type)
107 tdm_func_hwc_window *func_hwc_window = NULL;
109 HWC_WINDOW_FUNC_ENTRY();
110 TDM_RETURN_VAL_IF_FAIL(composition_type >= TDM_COMPOSITION_NONE, TDM_ERROR_INVALID_PARAMETER);
111 TDM_RETURN_VAL_IF_FAIL(composition_type <= TDM_COMPOSITION_VIDEO, TDM_ERROR_INVALID_PARAMETER);
113 _pthread_mutex_lock(&private_display->lock);
115 func_hwc_window = &private_display->func_hwc_window;
117 if (!func_hwc_window->hwc_window_set_composition_type) {
118 /* LCOV_EXCL_START */
119 _pthread_mutex_unlock(&private_display->lock);
120 TDM_ERR("not implemented!!");
121 return TDM_ERROR_NOT_IMPLEMENTED;
125 ret = func_hwc_window->hwc_window_set_composition_type(private_hwc_window->hwc_window_backend, composition_type);
127 _pthread_mutex_unlock(&private_display->lock);
133 tdm_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_hwc_region damage)
135 tdm_func_hwc_window *func_hwc_window = NULL;
137 HWC_WINDOW_FUNC_ENTRY();
138 if (damage.num_rects > 0)
139 TDM_RETURN_VAL_IF_FAIL(damage.rects != NULL, TDM_ERROR_INVALID_PARAMETER);
141 _pthread_mutex_lock(&private_display->lock);
143 func_hwc_window = &private_display->func_hwc_window;
145 if (!func_hwc_window->hwc_window_set_buffer_damage) {
146 /* LCOV_EXCL_START */
147 _pthread_mutex_unlock(&private_display->lock);
148 TDM_ERR("not implemented!!");
149 return TDM_ERROR_NOT_IMPLEMENTED;
153 ret = func_hwc_window->hwc_window_set_buffer_damage(private_hwc_window->hwc_window_backend, damage);
155 _pthread_mutex_unlock(&private_display->lock);
162 tdm_hwc_window_set_info(tdm_hwc_window *hwc_window, tdm_hwc_window_info *info)
164 tdm_func_hwc_window *func_hwc_window = NULL;
167 HWC_WINDOW_FUNC_ENTRY();
169 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
171 _pthread_mutex_lock(&private_display->lock);
173 func_hwc_window = &private_display->func_hwc_window;
175 if (!func_hwc_window->hwc_window_set_info) {
176 /* LCOV_EXCL_START */
177 _pthread_mutex_unlock(&private_display->lock);
178 TDM_ERR("not implemented!!");
179 return TDM_ERROR_NOT_IMPLEMENTED;
183 if (info->src_config.format)
184 snprintf(fmtstr, 128, "%c%c%c%c", FOURCC_STR(info->src_config.format));
186 snprintf(fmtstr, 128, "NONE");
188 TDM_INFO("hwc_window(%p) info: src(%dx%d %d,%d %dx%d %s) dst(%d,%d %dx%d) trans(%d)",
189 private_hwc_window, info->src_config.size.h, info->src_config.size.v,
190 info->src_config.pos.x, info->src_config.pos.y,
191 info->src_config.pos.w, info->src_config.pos.h,
193 info->dst_pos.x, info->dst_pos.y,
194 info->dst_pos.w, info->dst_pos.h,
197 ret = func_hwc_window->hwc_window_set_info(private_hwc_window->hwc_window_backend, info);
198 if (ret == TDM_ERROR_NONE) {
199 if (memcmp(&private_hwc_window->info, info, sizeof(tdm_hwc_window_info)) != 0)
200 private_hwc_window->info = *info;
203 _pthread_mutex_unlock(&private_display->lock);
209 tdm_hwc_window_set_buffer(tdm_hwc_window *hwc_window, tbm_surface_h buffer)
211 tdm_func_hwc_window *func_hwc_window;
213 HWC_WINDOW_FUNC_ENTRY();
215 _pthread_mutex_lock(&private_display->lock);
217 if ((tdm_debug_dump & TDM_DUMP_FLAG_WINDOW) && buffer) {
218 /* LCOV_EXCL_START */
219 char str[TDM_PATH_LEN];
221 snprintf(str, TDM_PATH_LEN, "window_%d_%03d", private_output->index, i++);
222 tdm_helper_dump_buffer_str(buffer, tdm_debug_dump_dir, str);
226 func_hwc_window = &private_display->func_hwc_window;
228 if (!func_hwc_window->hwc_window_set_buffer) {
229 /* LCOV_EXCL_START */
230 _pthread_mutex_unlock(&private_display->lock);
231 TDM_ERR("not implemented!!");
232 return TDM_ERROR_NOT_IMPLEMENTED;
236 ret = func_hwc_window->hwc_window_set_buffer(private_hwc_window->hwc_window_backend, buffer);
237 if (ret == TDM_ERROR_NONE)
238 private_hwc_window->buffer = buffer;
240 _pthread_mutex_unlock(&private_display->lock);
245 INTERN tdm_hwc_window *
246 tdm_hwc_window_create_internal(tdm_private_output *private_output, int is_video,
249 tdm_private_display *private_display = private_output->private_display;
250 tdm_func_output *func_output = &private_display->func_output;
251 tdm_private_hwc_window *private_hwc_window = NULL;
252 tdm_hwc_window *hwc_window_backend = NULL;
253 tdm_error ret = TDM_ERROR_NONE;
255 TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), NULL);
258 if (!func_output->output_hwc_create_window) {
259 /* LCOV_EXCL_START */
261 *error = TDM_ERROR_BAD_MODULE;
266 hwc_window_backend = func_output->output_hwc_create_window(
267 private_output->output_backend, &ret);
268 if (ret != TDM_ERROR_NONE) {
274 if (!func_output->output_hwc_create_video_window) {
275 /* LCOV_EXCL_START */
277 *error = TDM_ERROR_NOT_IMPLEMENTED;
282 hwc_window_backend = func_output->output_hwc_create_video_window(
283 private_output->output_backend, &ret);
284 if (ret != TDM_ERROR_NONE) {
291 private_hwc_window = calloc(1, sizeof(tdm_private_hwc_window));
292 if (!private_hwc_window) {
293 /* LCOV_EXCL_START */
294 TDM_ERR("failed: alloc memory");
295 func_output->output_hwc_destroy_window(private_output->output_backend, hwc_window_backend);
297 *error = TDM_ERROR_OUT_OF_MEMORY;
302 LIST_ADD(&private_hwc_window->link, &private_output->hwc_window_list);
304 private_hwc_window->private_display = private_display;
305 private_hwc_window->private_output = private_output;
306 private_hwc_window->hwc_window_backend = hwc_window_backend;
308 TDM_DBG("hwc_window(%p) create", private_hwc_window);
311 *error = TDM_ERROR_NONE;
313 return private_hwc_window;
317 tdm_hwc_window_destroy_internal(tdm_private_hwc_window * private_hwc_window)
319 tdm_private_display *private_display;
320 tdm_private_output *private_output;
321 tdm_func_output *func_output;
323 TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED);
325 if (!private_hwc_window)
326 return TDM_ERROR_OPERATION_FAILED;
328 private_display = private_hwc_window->private_display;
329 private_output = private_hwc_window->private_output;
331 LIST_DEL(&private_hwc_window->link);
333 func_output = &private_display->func_output;
334 func_output->output_hwc_destroy_window(private_output->output_backend, private_hwc_window->hwc_window_backend);
336 free(private_hwc_window);
337 return TDM_ERROR_NONE;
341 tdm_hwc_window_set_flags(tdm_hwc_window *hwc_window, tdm_hwc_window_flag flags)
343 tdm_func_hwc_window *func_hwc_window = NULL;
345 HWC_WINDOW_FUNC_ENTRY();
347 _pthread_mutex_lock(&private_display->lock);
349 func_hwc_window = &private_display->func_hwc_window;
351 if (!func_hwc_window->hwc_window_set_flags) {
352 /* LCOV_EXCL_START */
353 _pthread_mutex_unlock(&private_display->lock);
354 TDM_ERR("not implemented!!");
355 return TDM_ERROR_NOT_IMPLEMENTED;
359 ret = func_hwc_window->hwc_window_set_flags(private_hwc_window->hwc_window_backend, flags);
361 _pthread_mutex_unlock(&private_display->lock);
367 tdm_hwc_window_unset_flags(tdm_hwc_window *hwc_window, tdm_hwc_window_flag flags)
369 tdm_func_hwc_window *func_hwc_window = NULL;
371 HWC_WINDOW_FUNC_ENTRY();
373 _pthread_mutex_lock(&private_display->lock);
375 func_hwc_window = &private_display->func_hwc_window;
377 if (!func_hwc_window->hwc_window_unset_flags) {
378 /* LCOV_EXCL_START */
379 _pthread_mutex_unlock(&private_display->lock);
380 TDM_ERR("not implemented!!");
381 return TDM_ERROR_NOT_IMPLEMENTED;
385 ret = func_hwc_window->hwc_window_unset_flags(private_hwc_window->hwc_window_backend, flags);
387 _pthread_mutex_unlock(&private_display->lock);
393 _tdm_hwc_window_layer_commit_handler(tdm_layer *layer, unsigned int sequence,
394 unsigned int tv_sec, unsigned int tv_usec,
397 tdm_private_hwc_window_commit_handler *hwc_window_commit_handler = (tdm_private_hwc_window_commit_handler *)user_data;
398 tdm_hwc_window_commit_handler func = hwc_window_commit_handler->func;
399 tdm_hwc_window *hwc_window = (tdm_hwc_window *)hwc_window_commit_handler->private_hwc_window;
400 void *data = hwc_window_commit_handler->user_data;
402 func(hwc_window, sequence, tv_sec, tv_usec, data);
404 free(hwc_window_commit_handler);
408 tdm_hwc_window_commit(tdm_hwc_window *hwc_window, tdm_hwc_window_commit_handler func, void *user_data)
410 tdm_func_hwc_window *func_hwc_window = NULL;
411 tdm_private_hwc_window_commit_handler *hwc_window_commit_handler;
412 tdm_layer *layer = NULL;
413 tdm_private_layer *private_layer;
414 tdm_info_layer *info_layer;
416 HWC_WINDOW_FUNC_ENTRY();
418 _pthread_mutex_lock(&private_display->lock);
420 func_hwc_window = &private_display->func_hwc_window;
422 if (!func_hwc_window->hwc_window_get_layer) {
423 /* LCOV_EXCL_START */
424 _pthread_mutex_unlock(&private_display->lock);
425 TDM_ERR("not implemented!!");
426 return TDM_ERROR_NOT_IMPLEMENTED;
430 layer = func_hwc_window->hwc_window_get_layer(private_hwc_window->hwc_window_backend,
433 /* LCOV_EXCL_START */
434 _pthread_mutex_unlock(&private_display->lock);
435 TDM_ERR("no assigned layer!!");
436 return TDM_ERROR_INVALID_PARAMETER;
440 private_layer = (tdm_private_layer*)layer;
442 info_layer = (tdm_info_layer *)&private_window->info;
443 ret = tdm_layer_set_info_internal(private_layer, info_layer);
444 if (ret != TDM_ERROR_NONE) {
445 /* LCOV_EXCL_START */
446 TDM_ERR("failed: layer set info(window)");
451 if (private_window->buffer)
452 ret = tdm_layer_set_buffer_internal(private_layer, private_window->buffer);
454 ret = tdm_layer_unset_buffer_internal(private_layer);
455 if (ret != TDM_ERROR_NONE) {
456 /* LCOV_EXCL_START */
457 TDM_ERR("failed: layer set info(window)");
462 hwc_window_commit_handler = calloc(1, sizeof(tdm_private_hwc_window_commit_handler));
463 if (!hwc_window_commit_handler) {
464 /* LCOV_EXCL_START */
465 TDM_ERR("failed: alloc memory");
466 return TDM_ERROR_OUT_OF_MEMORY;
470 hwc_window_commit_handler->private_hwc_window = private_hwc_window;
471 hwc_window_commit_handler->func = func;
472 hwc_window_commit_handler->user_data = user_data;
474 ret = tdm_layer_commit_internal(private_layer, _tdm_hwc_window_layer_commit_handler, user_data);
475 if (ret != TDM_ERROR_NONE) {
476 /* LCOV_EXCL_START */
477 TDM_ERR("failed: commit layer(window)");
478 free(hwc_window_commit_handler);
483 _pthread_mutex_unlock(&private_display->lock);
489 tdm_hwc_window_video_get_capability(tdm_hwc_window *hwc_window,
490 tdm_hwc_window_video_capability *video_capability)
492 tdm_func_hwc_window *func_hwc_window = NULL;
494 HWC_WINDOW_FUNC_ENTRY();
496 TDM_RETURN_VAL_IF_FAIL(video_capability != NULL, TDM_ERROR_INVALID_PARAMETER);
498 _pthread_mutex_lock(&private_display->lock);
500 func_hwc_window = &private_display->func_hwc_window;
502 if (!func_hwc_window->hwc_window_video_get_capability) {
503 /* LCOV_EXCL_START */
504 _pthread_mutex_unlock(&private_display->lock);
505 TDM_ERR("not implemented!!");
506 return TDM_ERROR_NOT_IMPLEMENTED;
510 ret = func_hwc_window->hwc_window_video_get_capability(private_hwc_window->hwc_window_backend,
513 _pthread_mutex_unlock(&private_display->lock);
519 tdm_hwc_window_video_get_available_properties(tdm_hwc_window *hwc_window,
520 const tdm_prop **props, int *count)
522 tdm_func_hwc_window *func_hwc_window = NULL;
524 HWC_WINDOW_FUNC_ENTRY();
526 TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
527 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
529 _pthread_mutex_lock(&private_display->lock);
531 func_hwc_window = &private_display->func_hwc_window;
533 if (!func_hwc_window->hwc_window_video_get_available_properties) {
534 /* LCOV_EXCL_START */
535 _pthread_mutex_unlock(&private_display->lock);
536 TDM_ERR("not implemented!!");
537 return TDM_ERROR_NOT_IMPLEMENTED;
541 ret = func_hwc_window->hwc_window_video_get_available_properties(private_hwc_window->hwc_window_backend,
544 _pthread_mutex_unlock(&private_display->lock);
550 tdm_hwc_window_video_get_property(tdm_hwc_window *hwc_window,
551 unsigned int id, tdm_value *value)
553 tdm_func_hwc_window *func_hwc_window = NULL;
555 HWC_WINDOW_FUNC_ENTRY();
557 TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
559 _pthread_mutex_lock(&private_display->lock);
561 func_hwc_window = &private_display->func_hwc_window;
563 if (!func_hwc_window->hwc_window_video_get_property) {
564 /* LCOV_EXCL_START */
565 _pthread_mutex_unlock(&private_display->lock);
566 TDM_ERR("not implemented!!");
567 return TDM_ERROR_NOT_IMPLEMENTED;
571 ret = func_hwc_window->hwc_window_video_get_property(private_hwc_window->hwc_window_backend,
574 _pthread_mutex_unlock(&private_display->lock);
580 tdm_hwc_window_video_set_property(tdm_hwc_window *hwc_window,
581 unsigned int id, tdm_value value)
583 tdm_func_hwc_window *func_hwc_window = NULL;
585 HWC_WINDOW_FUNC_ENTRY();
587 _pthread_mutex_lock(&private_display->lock);
589 func_hwc_window = &private_display->func_hwc_window;
591 if (!func_hwc_window->hwc_window_video_set_property) {
592 /* LCOV_EXCL_START */
593 _pthread_mutex_unlock(&private_display->lock);
594 TDM_ERR("not implemented!!");
595 return TDM_ERROR_NOT_IMPLEMENTED;
599 ret = func_hwc_window->hwc_window_video_set_property(private_hwc_window->hwc_window_backend,
602 _pthread_mutex_unlock(&private_display->lock);