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);
199 _pthread_mutex_unlock(&private_display->lock);
205 tdm_hwc_window_set_buffer(tdm_hwc_window *hwc_window, tbm_surface_h buffer)
207 tdm_func_hwc_window *func_hwc_window;
209 HWC_WINDOW_FUNC_ENTRY();
211 _pthread_mutex_lock(&private_display->lock);
213 if ((tdm_debug_dump & TDM_DUMP_FLAG_WINDOW) && buffer) {
214 /* LCOV_EXCL_START */
215 char str[TDM_PATH_LEN];
217 snprintf(str, TDM_PATH_LEN, "window_%d_%03d", private_output->index, i++);
218 tdm_helper_dump_buffer_str(buffer, tdm_debug_dump_dir, str);
222 func_hwc_window = &private_display->func_hwc_window;
224 if (!func_hwc_window->hwc_window_set_buffer) {
225 /* LCOV_EXCL_START */
226 _pthread_mutex_unlock(&private_display->lock);
227 TDM_ERR("not implemented!!");
228 return TDM_ERROR_NOT_IMPLEMENTED;
232 ret = func_hwc_window->hwc_window_set_buffer(private_hwc_window->hwc_window_backend, buffer);
234 _pthread_mutex_unlock(&private_display->lock);
240 tdm_hwc_window_unset_buffer(tdm_hwc_window *hwc_window)
242 tdm_func_hwc_window *func_hwc_window;
244 HWC_WINDOW_FUNC_ENTRY();
246 _pthread_mutex_lock(&private_display->lock);
248 func_hwc_window = &private_display->func_hwc_window;
250 if (!func_hwc_window->hwc_window_unset_buffer) {
251 /* LCOV_EXCL_START */
252 _pthread_mutex_unlock(&private_display->lock);
253 TDM_ERR("not implemented!!");
254 return TDM_ERROR_NOT_IMPLEMENTED;
258 ret = func_hwc_window->hwc_window_unset_buffer(private_hwc_window->hwc_window_backend);
260 _pthread_mutex_unlock(&private_display->lock);
265 INTERN tdm_hwc_window *
266 tdm_hwc_window_create_internal(tdm_private_output *private_output, int is_video,
269 tdm_private_display *private_display = private_output->private_display;
270 tdm_func_output *func_output = &private_display->func_output;
271 tdm_private_hwc_window *private_hwc_window = NULL;
272 tdm_hwc_window *hwc_window_backend = NULL;
273 tdm_error ret = TDM_ERROR_NONE;
275 TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), NULL);
278 if (!func_output->output_hwc_create_window) {
279 /* LCOV_EXCL_START */
281 *error = TDM_ERROR_BAD_MODULE;
286 hwc_window_backend = func_output->output_hwc_create_window(
287 private_output->output_backend, &ret);
288 if (ret != TDM_ERROR_NONE) {
294 if (!func_output->output_hwc_create_video_window) {
295 /* LCOV_EXCL_START */
297 *error = TDM_ERROR_NOT_IMPLEMENTED;
302 hwc_window_backend = func_output->output_hwc_create_video_window(
303 private_output->output_backend, &ret);
304 if (ret != TDM_ERROR_NONE) {
311 private_hwc_window = calloc(1, sizeof(tdm_private_hwc_window));
312 if (!private_hwc_window) {
313 /* LCOV_EXCL_START */
314 TDM_ERR("failed: alloc memory");
315 func_output->output_hwc_destroy_window(private_output->output_backend, hwc_window_backend);
317 *error = TDM_ERROR_OUT_OF_MEMORY;
322 LIST_ADD(&private_hwc_window->link, &private_output->hwc_window_list);
324 private_hwc_window->private_display = private_display;
325 private_hwc_window->private_output = private_output;
326 private_hwc_window->hwc_window_backend = hwc_window_backend;
328 TDM_DBG("hwc_window(%p) create", private_hwc_window);
331 *error = TDM_ERROR_NONE;
333 return private_hwc_window;
337 tdm_hwc_window_destroy_internal(tdm_private_hwc_window * private_hwc_window)
339 tdm_private_display *private_display;
340 tdm_private_output *private_output;
341 tdm_func_output *func_output;
343 TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED);
345 if (!private_hwc_window)
346 return TDM_ERROR_OPERATION_FAILED;
348 private_display = private_hwc_window->private_display;
349 private_output = private_hwc_window->private_output;
351 LIST_DEL(&private_hwc_window->link);
353 func_output = &private_display->func_output;
354 func_output->output_hwc_destroy_window(private_output->output_backend, private_hwc_window->hwc_window_backend);
356 free(private_hwc_window);
357 return TDM_ERROR_NONE;
361 tdm_hwc_window_set_flags(tdm_hwc_window *hwc_window, tdm_hwc_window_flag flags)
363 tdm_func_hwc_window *func_hwc_window = NULL;
365 HWC_WINDOW_FUNC_ENTRY();
367 _pthread_mutex_lock(&private_display->lock);
369 func_hwc_window = &private_display->func_hwc_window;
371 if (!func_hwc_window->hwc_window_set_flags) {
372 /* LCOV_EXCL_START */
373 _pthread_mutex_unlock(&private_display->lock);
374 TDM_ERR("not implemented!!");
375 return TDM_ERROR_NOT_IMPLEMENTED;
379 ret = func_hwc_window->hwc_window_set_flags(private_hwc_window->hwc_window_backend, flags);
381 _pthread_mutex_unlock(&private_display->lock);
387 tdm_hwc_window_unset_flags(tdm_hwc_window *hwc_window, tdm_hwc_window_flag flags)
389 tdm_func_hwc_window *func_hwc_window = NULL;
391 HWC_WINDOW_FUNC_ENTRY();
393 _pthread_mutex_lock(&private_display->lock);
395 func_hwc_window = &private_display->func_hwc_window;
397 if (!func_hwc_window->hwc_window_unset_flags) {
398 /* LCOV_EXCL_START */
399 _pthread_mutex_unlock(&private_display->lock);
400 TDM_ERR("not implemented!!");
401 return TDM_ERROR_NOT_IMPLEMENTED;
405 ret = func_hwc_window->hwc_window_unset_flags(private_hwc_window->hwc_window_backend, flags);
407 _pthread_mutex_unlock(&private_display->lock);
413 _tdm_hwc_window_layer_commit_handler(tdm_layer *layer, unsigned int sequence,
414 unsigned int tv_sec, unsigned int tv_usec,
417 tdm_private_hwc_window_commit_handler *hwc_window_commit_handler = (tdm_private_hwc_window_commit_handler *)user_data;
418 tdm_hwc_window_commit_handler func = hwc_window_commit_handler->func;
419 tdm_hwc_window *hwc_window = (tdm_hwc_window *)hwc_window_commit_handler->private_hwc_window;
420 void *data = hwc_window_commit_handler->user_data;
422 func(hwc_window, sequence, tv_sec, tv_usec, data);
424 free(hwc_window_commit_handler);
428 tdm_hwc_window_commit(tdm_hwc_window *hwc_window, tdm_hwc_window_commit_handler func, void *user_data)
430 tdm_func_hwc_window *func_hwc_window = NULL;
431 tdm_private_hwc_window_commit_handler *hwc_window_commit_handler;
432 tdm_layer *layer = NULL;
433 tdm_private_layer *private_layer;
434 tdm_info_layer *info_layer;
435 tdm_hwc_window_info window_info;
436 tbm_surface_h buffer;
438 HWC_WINDOW_FUNC_ENTRY();
440 _pthread_mutex_lock(&private_display->lock);
442 func_hwc_window = &private_display->func_hwc_window;
444 if (!func_hwc_window->hwc_window_get_layer) {
445 /* LCOV_EXCL_START */
446 _pthread_mutex_unlock(&private_display->lock);
447 TDM_ERR("not implemented!!");
448 return TDM_ERROR_NOT_IMPLEMENTED;
452 layer = func_hwc_window->hwc_window_get_layer(private_hwc_window->hwc_window_backend,
455 /* LCOV_EXCL_START */
456 _pthread_mutex_unlock(&private_display->lock);
457 TDM_ERR("no assigned layer!!");
458 return TDM_ERROR_INVALID_PARAMETER;
462 private_layer = (tdm_private_layer*)layer;
464 buffer = func_hwc_window->hwc_window_get_buffer(private_hwc_window->hwc_window_backend,
467 ret = tdm_layer_set_buffer_internal(private_layer, buffer);
469 ret = tdm_layer_unset_buffer_internal(private_layer);
470 if (ret != TDM_ERROR_NONE) {
471 /* LCOV_EXCL_START */
472 TDM_ERR("failed: layer set buffer(window)");
477 ret = func_hwc_window->hwc_window_get_info(private_hwc_window->hwc_window_backend,
479 if (ret != TDM_ERROR_NONE) {
480 /* LCOV_EXCL_START */
481 TDM_ERR("failed: commit layer(window)");
486 info_layer = (tdm_info_layer *)&window_info;
487 ret = tdm_layer_set_info_internal(private_layer, info_layer);
488 if (ret != TDM_ERROR_NONE) {
489 /* LCOV_EXCL_START */
490 TDM_ERR("failed: layer set info(window)");
495 hwc_window_commit_handler = calloc(1, sizeof(tdm_private_hwc_window_commit_handler));
496 if (!hwc_window_commit_handler) {
497 /* LCOV_EXCL_START */
498 TDM_ERR("failed: alloc memory");
499 return TDM_ERROR_OUT_OF_MEMORY;
503 hwc_window_commit_handler->private_hwc_window = private_hwc_window;
504 hwc_window_commit_handler->func = func;
505 hwc_window_commit_handler->user_data = user_data;
507 ret = tdm_layer_commit_internal(private_layer, _tdm_hwc_window_layer_commit_handler, user_data);
508 if (ret != TDM_ERROR_NONE) {
509 /* LCOV_EXCL_START */
510 TDM_ERR("failed: commit layer(window)");
511 free(hwc_window_commit_handler);
516 _pthread_mutex_unlock(&private_display->lock);
522 tdm_hwc_window_video_get_capability(tdm_hwc_window *hwc_window,
523 tdm_hwc_window_video_capability *video_capability)
525 tdm_func_hwc_window *func_hwc_window = NULL;
527 HWC_WINDOW_FUNC_ENTRY();
529 TDM_RETURN_VAL_IF_FAIL(video_capability != NULL, TDM_ERROR_INVALID_PARAMETER);
531 _pthread_mutex_lock(&private_display->lock);
533 func_hwc_window = &private_display->func_hwc_window;
535 if (!func_hwc_window->hwc_window_video_get_capability) {
536 /* LCOV_EXCL_START */
537 _pthread_mutex_unlock(&private_display->lock);
538 TDM_ERR("not implemented!!");
539 return TDM_ERROR_NOT_IMPLEMENTED;
543 ret = func_hwc_window->hwc_window_video_get_capability(private_hwc_window->hwc_window_backend,
546 _pthread_mutex_unlock(&private_display->lock);
552 tdm_hwc_window_video_get_available_properties(tdm_hwc_window *hwc_window,
553 const tdm_prop **props, int *count)
555 tdm_func_hwc_window *func_hwc_window = NULL;
557 HWC_WINDOW_FUNC_ENTRY();
559 TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
560 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
562 _pthread_mutex_lock(&private_display->lock);
564 func_hwc_window = &private_display->func_hwc_window;
566 if (!func_hwc_window->hwc_window_video_get_available_properties) {
567 /* LCOV_EXCL_START */
568 _pthread_mutex_unlock(&private_display->lock);
569 TDM_ERR("not implemented!!");
570 return TDM_ERROR_NOT_IMPLEMENTED;
574 ret = func_hwc_window->hwc_window_video_get_available_properties(private_hwc_window->hwc_window_backend,
577 _pthread_mutex_unlock(&private_display->lock);
583 tdm_hwc_window_video_get_property(tdm_hwc_window *hwc_window,
584 unsigned int id, tdm_value *value)
586 tdm_func_hwc_window *func_hwc_window = NULL;
588 HWC_WINDOW_FUNC_ENTRY();
590 TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
592 _pthread_mutex_lock(&private_display->lock);
594 func_hwc_window = &private_display->func_hwc_window;
596 if (!func_hwc_window->hwc_window_video_get_property) {
597 /* LCOV_EXCL_START */
598 _pthread_mutex_unlock(&private_display->lock);
599 TDM_ERR("not implemented!!");
600 return TDM_ERROR_NOT_IMPLEMENTED;
604 ret = func_hwc_window->hwc_window_video_get_property(private_hwc_window->hwc_window_backend,
607 _pthread_mutex_unlock(&private_display->lock);
613 tdm_hwc_window_video_set_property(tdm_hwc_window *hwc_window,
614 unsigned int id, tdm_value value)
616 tdm_func_hwc_window *func_hwc_window = NULL;
618 HWC_WINDOW_FUNC_ENTRY();
620 _pthread_mutex_lock(&private_display->lock);
622 func_hwc_window = &private_display->func_hwc_window;
624 if (!func_hwc_window->hwc_window_video_set_property) {
625 /* LCOV_EXCL_START */
626 _pthread_mutex_unlock(&private_display->lock);
627 TDM_ERR("not implemented!!");
628 return TDM_ERROR_NOT_IMPLEMENTED;
632 ret = func_hwc_window->hwc_window_video_set_property(private_hwc_window->hwc_window_backend,
635 _pthread_mutex_unlock(&private_display->lock);