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_private_module *private_module;
78 tdm_func_hwc_window *func_hwc_window = NULL;
79 tbm_surface_queue_h queue = NULL;
81 HWC_WINDOW_FUNC_ENTRY_ERROR();
83 _pthread_mutex_lock(&private_display->lock);
85 private_module = private_output->private_module;
86 func_hwc_window = &private_module->func_hwc_window;
88 if (!func_hwc_window->hwc_window_get_tbm_buffer_queue) {
90 _pthread_mutex_unlock(&private_display->lock);
91 TDM_WRN("not implemented!!");
93 *error = TDM_ERROR_NOT_IMPLEMENTED;
98 queue = func_hwc_window->hwc_window_get_tbm_buffer_queue(private_hwc_window->hwc_window_backend, error);
100 _pthread_mutex_unlock(&private_display->lock);
106 tdm_hwc_window_set_composition_type(tdm_hwc_window *hwc_window,
107 tdm_hwc_window_composition composition_type)
109 tdm_private_module *private_module;
110 tdm_func_hwc_window *func_hwc_window = NULL;
112 HWC_WINDOW_FUNC_ENTRY();
113 TDM_RETURN_VAL_IF_FAIL(composition_type >= TDM_COMPOSITION_NONE, TDM_ERROR_INVALID_PARAMETER);
114 TDM_RETURN_VAL_IF_FAIL(composition_type <= TDM_COMPOSITION_VIDEO, TDM_ERROR_INVALID_PARAMETER);
116 _pthread_mutex_lock(&private_display->lock);
118 private_module = private_output->private_module;
119 func_hwc_window = &private_module->func_hwc_window;
121 if (!func_hwc_window->hwc_window_set_composition_type) {
122 /* LCOV_EXCL_START */
123 _pthread_mutex_unlock(&private_display->lock);
124 TDM_WRN("not implemented!!");
125 return TDM_ERROR_NOT_IMPLEMENTED;
129 ret = func_hwc_window->hwc_window_set_composition_type(private_hwc_window->hwc_window_backend, composition_type);
131 _pthread_mutex_unlock(&private_display->lock);
137 tdm_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_hwc_region damage)
139 tdm_private_module *private_module;
140 tdm_func_hwc_window *func_hwc_window = NULL;
142 HWC_WINDOW_FUNC_ENTRY();
143 if (damage.num_rects > 0)
144 TDM_RETURN_VAL_IF_FAIL(damage.rects != NULL, TDM_ERROR_INVALID_PARAMETER);
146 _pthread_mutex_lock(&private_display->lock);
148 private_module = private_output->private_module;
149 func_hwc_window = &private_module->func_hwc_window;
151 if (!func_hwc_window->hwc_window_set_buffer_damage) {
152 /* LCOV_EXCL_START */
153 _pthread_mutex_unlock(&private_display->lock);
154 TDM_WRN("not implemented!!");
155 return TDM_ERROR_NOT_IMPLEMENTED;
159 ret = func_hwc_window->hwc_window_set_buffer_damage(private_hwc_window->hwc_window_backend, damage);
161 _pthread_mutex_unlock(&private_display->lock);
168 tdm_hwc_window_set_info(tdm_hwc_window *hwc_window, tdm_hwc_window_info *info)
170 tdm_private_module *private_module;
171 tdm_func_hwc_window *func_hwc_window = NULL;
174 HWC_WINDOW_FUNC_ENTRY();
176 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
178 _pthread_mutex_lock(&private_display->lock);
180 private_module = private_output->private_module;
181 func_hwc_window = &private_module->func_hwc_window;
183 if (!func_hwc_window->hwc_window_set_info) {
184 /* LCOV_EXCL_START */
185 _pthread_mutex_unlock(&private_display->lock);
186 TDM_WRN("not implemented!!");
187 return TDM_ERROR_NOT_IMPLEMENTED;
191 if (info->src_config.format)
192 snprintf(fmtstr, 128, "%c%c%c%c", FOURCC_STR(info->src_config.format));
194 snprintf(fmtstr, 128, "NONE");
196 TDM_INFO("hwc_window(%p) info: src(%dx%d %d,%d %dx%d %s) dst(%d,%d %dx%d) trans(%d)",
197 private_hwc_window, info->src_config.size.h, info->src_config.size.v,
198 info->src_config.pos.x, info->src_config.pos.y,
199 info->src_config.pos.w, info->src_config.pos.h,
201 info->dst_pos.x, info->dst_pos.y,
202 info->dst_pos.w, info->dst_pos.h,
205 ret = func_hwc_window->hwc_window_set_info(private_hwc_window->hwc_window_backend, info);
207 _pthread_mutex_unlock(&private_display->lock);
213 tdm_hwc_window_set_buffer(tdm_hwc_window *hwc_window, tbm_surface_h buffer)
215 tdm_private_module *private_module;
216 tdm_func_hwc_window *func_hwc_window;
218 HWC_WINDOW_FUNC_ENTRY();
220 _pthread_mutex_lock(&private_display->lock);
222 if ((tdm_debug_dump & TDM_DUMP_FLAG_WINDOW) && buffer) {
223 /* LCOV_EXCL_START */
224 char str[TDM_PATH_LEN];
226 snprintf(str, TDM_PATH_LEN, "window_%d_%03d", private_output->index, i++);
227 tdm_helper_dump_buffer_str(buffer, tdm_debug_dump_dir, str);
231 private_module = private_output->private_module;
232 func_hwc_window = &private_module->func_hwc_window;
234 if (!func_hwc_window->hwc_window_set_buffer) {
235 /* LCOV_EXCL_START */
236 _pthread_mutex_unlock(&private_display->lock);
237 TDM_WRN("not implemented!!");
238 return TDM_ERROR_NOT_IMPLEMENTED;
242 ret = func_hwc_window->hwc_window_set_buffer(private_hwc_window->hwc_window_backend, buffer);
244 _pthread_mutex_unlock(&private_display->lock);
250 tdm_hwc_window_unset_buffer(tdm_hwc_window *hwc_window)
252 tdm_private_module *private_module;
253 tdm_func_hwc_window *func_hwc_window;
255 HWC_WINDOW_FUNC_ENTRY();
257 _pthread_mutex_lock(&private_display->lock);
259 private_module = private_output->private_module;
260 func_hwc_window = &private_module->func_hwc_window;
262 if (!func_hwc_window->hwc_window_unset_buffer) {
263 /* LCOV_EXCL_START */
264 _pthread_mutex_unlock(&private_display->lock);
265 TDM_ERR("not implemented!!");
266 return TDM_ERROR_NOT_IMPLEMENTED;
270 ret = func_hwc_window->hwc_window_unset_buffer(private_hwc_window->hwc_window_backend);
272 _pthread_mutex_unlock(&private_display->lock);
277 INTERN tdm_hwc_window *
278 tdm_hwc_window_create_internal(tdm_private_output *private_output, int is_video,
281 tdm_private_display *private_display = private_output->private_display;
282 tdm_private_module *private_module = private_output->private_module;
283 tdm_func_output *func_output = &private_module->func_output;
284 tdm_private_hwc_window *private_hwc_window = NULL;
285 tdm_hwc_window *hwc_window_backend = NULL;
286 tdm_error ret = TDM_ERROR_NONE;
288 TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), NULL);
291 if (!func_output->output_hwc_create_window) {
292 /* LCOV_EXCL_START */
294 *error = TDM_ERROR_BAD_MODULE;
299 hwc_window_backend = func_output->output_hwc_create_window(
300 private_output->output_backend, &ret);
301 if (ret != TDM_ERROR_NONE) {
307 if (!func_output->output_hwc_create_video_window) {
308 /* LCOV_EXCL_START */
310 *error = TDM_ERROR_NOT_IMPLEMENTED;
315 hwc_window_backend = func_output->output_hwc_create_video_window(
316 private_output->output_backend, &ret);
317 if (ret != TDM_ERROR_NONE) {
324 private_hwc_window = calloc(1, sizeof(tdm_private_hwc_window));
325 if (!private_hwc_window) {
326 /* LCOV_EXCL_START */
327 TDM_ERR("failed: alloc memory");
328 func_output->output_hwc_destroy_window(private_output->output_backend, hwc_window_backend);
330 *error = TDM_ERROR_OUT_OF_MEMORY;
335 LIST_ADD(&private_hwc_window->link, &private_output->hwc_window_list);
337 private_hwc_window->private_display = private_display;
338 private_hwc_window->private_output = private_output;
339 private_hwc_window->hwc_window_backend = hwc_window_backend;
341 TDM_DBG("hwc_window(%p) create", private_hwc_window);
344 *error = TDM_ERROR_NONE;
346 return private_hwc_window;
350 tdm_hwc_window_destroy_internal(tdm_private_hwc_window * private_hwc_window)
352 tdm_private_output *private_output;
353 tdm_private_module *private_module;
354 tdm_func_output *func_output;
356 TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED);
358 if (!private_hwc_window)
359 return TDM_ERROR_OPERATION_FAILED;
361 private_output = private_hwc_window->private_output;
362 private_module = private_output->private_module;
364 LIST_DEL(&private_hwc_window->link);
366 func_output = &private_module->func_output;
367 func_output->output_hwc_destroy_window(private_output->output_backend, private_hwc_window->hwc_window_backend);
369 free(private_hwc_window);
370 return TDM_ERROR_NONE;
374 tdm_hwc_window_set_flags(tdm_hwc_window *hwc_window, tdm_hwc_window_flag flags)
376 tdm_private_module *private_module;
377 tdm_func_hwc_window *func_hwc_window = NULL;
379 HWC_WINDOW_FUNC_ENTRY();
381 _pthread_mutex_lock(&private_display->lock);
383 private_module = private_output->private_module;
384 func_hwc_window = &private_module->func_hwc_window;
386 if (!func_hwc_window->hwc_window_set_flags) {
387 /* LCOV_EXCL_START */
388 _pthread_mutex_unlock(&private_display->lock);
389 TDM_WRN("not implemented!!");
390 return TDM_ERROR_NOT_IMPLEMENTED;
394 ret = func_hwc_window->hwc_window_set_flags(private_hwc_window->hwc_window_backend, flags);
396 _pthread_mutex_unlock(&private_display->lock);
402 tdm_hwc_window_unset_flags(tdm_hwc_window *hwc_window, tdm_hwc_window_flag flags)
404 tdm_private_module *private_module;
405 tdm_func_hwc_window *func_hwc_window = NULL;
407 HWC_WINDOW_FUNC_ENTRY();
409 _pthread_mutex_lock(&private_display->lock);
411 private_module = private_output->private_module;
412 func_hwc_window = &private_module->func_hwc_window;
414 if (!func_hwc_window->hwc_window_unset_flags) {
415 /* LCOV_EXCL_START */
416 _pthread_mutex_unlock(&private_display->lock);
417 TDM_WRN("not implemented!!");
418 return TDM_ERROR_NOT_IMPLEMENTED;
422 ret = func_hwc_window->hwc_window_unset_flags(private_hwc_window->hwc_window_backend, flags);
424 _pthread_mutex_unlock(&private_display->lock);
430 _tdm_hwc_window_layer_commit_handler(tdm_layer *layer, unsigned int sequence,
431 unsigned int tv_sec, unsigned int tv_usec,
434 tdm_private_hwc_window_commit_handler *hwc_window_commit_handler = (tdm_private_hwc_window_commit_handler *)user_data;
435 tdm_hwc_window_commit_handler func = hwc_window_commit_handler->func;
436 tdm_hwc_window *hwc_window = (tdm_hwc_window *)hwc_window_commit_handler->private_hwc_window;
437 void *data = hwc_window_commit_handler->user_data;
439 func(hwc_window, sequence, tv_sec, tv_usec, data);
441 free(hwc_window_commit_handler);
445 tdm_hwc_window_commit(tdm_hwc_window *hwc_window, tdm_hwc_window_commit_handler func, void *user_data)
447 tdm_private_module *private_module;
448 tdm_func_hwc_window *func_hwc_window = NULL;
449 tdm_private_hwc_window_commit_handler *hwc_window_commit_handler;
450 tdm_layer *layer = NULL;
451 tdm_private_layer *private_layer;
452 tdm_info_layer *info_layer;
453 tdm_hwc_window_info window_info;
454 tbm_surface_h buffer;
456 HWC_WINDOW_FUNC_ENTRY();
458 _pthread_mutex_lock(&private_display->lock);
460 private_module = private_output->private_module;
461 func_hwc_window = &private_module->func_hwc_window;
463 if (!func_hwc_window->hwc_window_get_layer) {
464 /* LCOV_EXCL_START */
465 _pthread_mutex_unlock(&private_display->lock);
466 TDM_ERR("not implemented!!");
467 return TDM_ERROR_NOT_IMPLEMENTED;
471 layer = func_hwc_window->hwc_window_get_layer(private_hwc_window->hwc_window_backend,
474 /* LCOV_EXCL_START */
475 _pthread_mutex_unlock(&private_display->lock);
476 TDM_ERR("no assigned layer!!");
477 return TDM_ERROR_INVALID_PARAMETER;
481 private_layer = (tdm_private_layer*)layer;
483 buffer = func_hwc_window->hwc_window_get_buffer(private_hwc_window->hwc_window_backend,
486 ret = tdm_layer_set_buffer_internal(private_layer, buffer);
488 ret = tdm_layer_unset_buffer_internal(private_layer);
489 if (ret != TDM_ERROR_NONE) {
490 /* LCOV_EXCL_START */
491 TDM_ERR("failed: layer set buffer(window)");
496 ret = func_hwc_window->hwc_window_get_info(private_hwc_window->hwc_window_backend,
498 if (ret != TDM_ERROR_NONE) {
499 /* LCOV_EXCL_START */
500 TDM_ERR("failed: commit layer(window)");
505 info_layer = (tdm_info_layer *)&window_info;
506 ret = tdm_layer_set_info_internal(private_layer, info_layer);
507 if (ret != TDM_ERROR_NONE) {
508 /* LCOV_EXCL_START */
509 TDM_ERR("failed: layer set info(window)");
514 hwc_window_commit_handler = calloc(1, sizeof(tdm_private_hwc_window_commit_handler));
515 if (!hwc_window_commit_handler) {
516 /* LCOV_EXCL_START */
517 TDM_ERR("failed: alloc memory");
518 return TDM_ERROR_OUT_OF_MEMORY;
522 hwc_window_commit_handler->private_hwc_window = private_hwc_window;
523 hwc_window_commit_handler->func = func;
524 hwc_window_commit_handler->user_data = user_data;
526 ret = tdm_layer_commit_internal(private_layer, _tdm_hwc_window_layer_commit_handler, hwc_window_commit_handler);
527 if (ret != TDM_ERROR_NONE) {
528 /* LCOV_EXCL_START */
529 TDM_ERR("failed: commit layer(window)");
530 free(hwc_window_commit_handler);
535 _pthread_mutex_unlock(&private_display->lock);
541 tdm_hwc_window_video_get_capability(tdm_hwc_window *hwc_window,
542 tdm_hwc_window_video_capability *video_capability)
544 tdm_private_module *private_module;
545 tdm_func_hwc_window *func_hwc_window = NULL;
547 HWC_WINDOW_FUNC_ENTRY();
549 TDM_RETURN_VAL_IF_FAIL(video_capability != NULL, TDM_ERROR_INVALID_PARAMETER);
551 _pthread_mutex_lock(&private_display->lock);
553 private_module = private_output->private_module;
554 func_hwc_window = &private_module->func_hwc_window;
556 if (!func_hwc_window->hwc_window_video_get_capability) {
557 /* LCOV_EXCL_START */
558 _pthread_mutex_unlock(&private_display->lock);
559 TDM_WRN("not implemented!!");
560 return TDM_ERROR_NOT_IMPLEMENTED;
564 ret = func_hwc_window->hwc_window_video_get_capability(private_hwc_window->hwc_window_backend,
567 _pthread_mutex_unlock(&private_display->lock);
573 tdm_hwc_window_video_get_available_properties(tdm_hwc_window *hwc_window,
574 const tdm_prop **props, int *count)
576 tdm_private_module *private_module;
577 tdm_func_hwc_window *func_hwc_window = NULL;
579 HWC_WINDOW_FUNC_ENTRY();
581 TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
582 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
584 _pthread_mutex_lock(&private_display->lock);
586 private_module = private_output->private_module;
587 func_hwc_window = &private_module->func_hwc_window;
589 if (!func_hwc_window->hwc_window_video_get_available_properties) {
590 /* LCOV_EXCL_START */
591 _pthread_mutex_unlock(&private_display->lock);
592 TDM_WRN("not implemented!!");
593 return TDM_ERROR_NOT_IMPLEMENTED;
597 ret = func_hwc_window->hwc_window_video_get_available_properties(private_hwc_window->hwc_window_backend,
600 _pthread_mutex_unlock(&private_display->lock);
606 tdm_hwc_window_video_get_property(tdm_hwc_window *hwc_window,
607 unsigned int id, tdm_value *value)
609 tdm_private_module *private_module;
610 tdm_func_hwc_window *func_hwc_window = NULL;
612 HWC_WINDOW_FUNC_ENTRY();
614 TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
616 _pthread_mutex_lock(&private_display->lock);
618 private_module = private_output->private_module;
619 func_hwc_window = &private_module->func_hwc_window;
621 if (!func_hwc_window->hwc_window_video_get_property) {
622 /* LCOV_EXCL_START */
623 _pthread_mutex_unlock(&private_display->lock);
624 TDM_WRN("not implemented!!");
625 return TDM_ERROR_NOT_IMPLEMENTED;
629 ret = func_hwc_window->hwc_window_video_get_property(private_hwc_window->hwc_window_backend,
632 _pthread_mutex_unlock(&private_display->lock);
638 tdm_hwc_window_video_set_property(tdm_hwc_window *hwc_window,
639 unsigned int id, tdm_value value)
641 tdm_private_module *private_module;
642 tdm_func_hwc_window *func_hwc_window = NULL;
644 HWC_WINDOW_FUNC_ENTRY();
646 _pthread_mutex_lock(&private_display->lock);
648 private_module = private_output->private_module;
649 func_hwc_window = &private_module->func_hwc_window;
651 if (!func_hwc_window->hwc_window_video_set_property) {
652 /* LCOV_EXCL_START */
653 _pthread_mutex_unlock(&private_display->lock);
654 TDM_WRN("not implemented!!");
655 return TDM_ERROR_NOT_IMPLEMENTED;
659 ret = func_hwc_window->hwc_window_video_set_property(private_hwc_window->hwc_window_backend,
662 _pthread_mutex_unlock(&private_display->lock);