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 <boram1288.park@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"
46 #define HWC_WINDOW_FUNC_ENTRY() \
47 tdm_private_display *private_display; \
48 tdm_private_output *private_output; \
49 tdm_private_hwc_window *private_hwc_window; \
50 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
51 TDM_RETURN_VAL_IF_FAIL(hwc_window != NULL, TDM_ERROR_INVALID_PARAMETER); \
52 private_hwc_window = (tdm_private_hwc_window*)hwc_window; \
53 private_output = private_hwc_window->private_output; \
54 private_display = private_output->private_display
56 #define HWC_WINDOW_FUNC_ENTRY_ERROR() \
57 tdm_private_display *private_display; \
58 tdm_private_output *private_output; \
59 tdm_private_hwc_window *private_hwc_window; \
60 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
61 TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(hwc_window != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \
62 private_hwc_window = (tdm_private_hwc_window*)hwc_window; \
63 private_output = private_hwc_window->private_output; \
64 private_display = private_output->private_display
66 #define HWC_WINDOW_FUNC_ENTRY_VOID_RETURN() \
67 tdm_private_display *private_display; \
68 tdm_private_output *private_output; \
69 tdm_private_hwc_window *private_hwc_window; \
70 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
71 TDM_RETURN_IF_FAIL(hwc_window != NULL); \
72 private_hwc_window = (tdm_private_hwc_window*)hwc_window; \
73 private_output = private_hwc_window->private_output; \
74 private_display = private_output->private_display
77 tdm_hwc_window_get_tbm_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error)
79 tdm_private_module *private_module;
80 tdm_func_hwc_window *func_hwc_window = NULL;
81 tbm_surface_queue_h queue = NULL;
83 HWC_WINDOW_FUNC_ENTRY_ERROR();
85 _pthread_mutex_lock(&private_display->lock);
87 private_module = private_output->private_module;
88 func_hwc_window = &private_module->func_hwc_window;
90 if (!func_hwc_window->hwc_window_get_tbm_buffer_queue) {
91 _pthread_mutex_unlock(&private_display->lock);
92 TDM_WRN("not implemented!!");
94 *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 _pthread_mutex_unlock(&private_display->lock);
123 TDM_WRN("not implemented!!");
124 return TDM_ERROR_NOT_IMPLEMENTED;
127 ret = func_hwc_window->hwc_window_set_composition_type(private_hwc_window->hwc_window_backend, composition_type);
129 _pthread_mutex_unlock(&private_display->lock);
135 tdm_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_hwc_region damage)
137 tdm_private_module *private_module;
138 tdm_func_hwc_window *func_hwc_window = NULL;
140 HWC_WINDOW_FUNC_ENTRY();
141 if (damage.num_rects > 0)
142 TDM_RETURN_VAL_IF_FAIL(damage.rects != NULL, TDM_ERROR_INVALID_PARAMETER);
144 _pthread_mutex_lock(&private_display->lock);
146 private_module = private_output->private_module;
147 func_hwc_window = &private_module->func_hwc_window;
149 if (!func_hwc_window->hwc_window_set_buffer_damage) {
150 _pthread_mutex_unlock(&private_display->lock);
151 TDM_WRN("not implemented!!");
152 return TDM_ERROR_NOT_IMPLEMENTED;
155 ret = func_hwc_window->hwc_window_set_buffer_damage(private_hwc_window->hwc_window_backend, damage);
157 _pthread_mutex_unlock(&private_display->lock);
164 tdm_hwc_window_set_info(tdm_hwc_window *hwc_window, tdm_hwc_window_info *info)
166 tdm_private_module *private_module;
167 tdm_func_hwc_window *func_hwc_window = NULL;
170 HWC_WINDOW_FUNC_ENTRY();
172 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
174 _pthread_mutex_lock(&private_display->lock);
176 private_module = private_output->private_module;
177 func_hwc_window = &private_module->func_hwc_window;
179 if (!func_hwc_window->hwc_window_set_info) {
180 _pthread_mutex_unlock(&private_display->lock);
181 TDM_WRN("not implemented!!");
182 return TDM_ERROR_NOT_IMPLEMENTED;
185 if (info->src_config.format)
186 snprintf(fmtstr, 128, "%c%c%c%c", FOURCC_STR(info->src_config.format));
188 snprintf(fmtstr, 128, "NONE");
190 TDM_INFO("hwc_window(%p) info: src(%dx%d %d,%d %dx%d %s) dst(%d,%d %dx%d) trans(%d)",
191 private_hwc_window, info->src_config.size.h, info->src_config.size.v,
192 info->src_config.pos.x, info->src_config.pos.y,
193 info->src_config.pos.w, info->src_config.pos.h,
195 info->dst_pos.x, info->dst_pos.y,
196 info->dst_pos.w, info->dst_pos.h,
199 ret = func_hwc_window->hwc_window_set_info(private_hwc_window->hwc_window_backend, info);
201 _pthread_mutex_unlock(&private_display->lock);
207 tdm_hwc_window_set_buffer(tdm_hwc_window *hwc_window, tbm_surface_h buffer)
209 tdm_private_module *private_module;
210 tdm_func_hwc_window *func_hwc_window;
212 HWC_WINDOW_FUNC_ENTRY();
214 _pthread_mutex_lock(&private_display->lock);
216 if ((tdm_debug_dump & TDM_DUMP_FLAG_WINDOW) && buffer) {
217 char str[TDM_PATH_LEN];
219 snprintf(str, TDM_PATH_LEN, "window_%d_%03d", private_output->index, i++);
220 tdm_helper_dump_buffer_str(buffer, tdm_debug_dump_dir, str);
223 private_module = private_output->private_module;
224 func_hwc_window = &private_module->func_hwc_window;
226 if (!func_hwc_window->hwc_window_set_buffer) {
227 _pthread_mutex_unlock(&private_display->lock);
228 TDM_WRN("not implemented!!");
229 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_private_module *private_module;
243 tdm_func_hwc_window *func_hwc_window;
245 HWC_WINDOW_FUNC_ENTRY();
247 _pthread_mutex_lock(&private_display->lock);
249 private_module = private_output->private_module;
250 func_hwc_window = &private_module->func_hwc_window;
252 if (!func_hwc_window->hwc_window_unset_buffer) {
253 _pthread_mutex_unlock(&private_display->lock);
254 TDM_ERR("not implemented!!");
255 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_private_module *private_module = private_output->private_module;
271 tdm_func_output *func_output = &private_module->func_output;
272 tdm_private_hwc_window *private_hwc_window = NULL;
273 tdm_hwc_window *hwc_window_backend = NULL;
274 tdm_error ret = TDM_ERROR_NONE;
276 TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), NULL);
279 if (!func_output->output_hwc_create_window) {
281 *error = TDM_ERROR_BAD_MODULE;
285 hwc_window_backend = func_output->output_hwc_create_window(
286 private_output->output_backend, &ret);
287 if (ret != TDM_ERROR_NONE) {
293 if (!func_output->output_hwc_create_video_window) {
295 *error = TDM_ERROR_NOT_IMPLEMENTED;
299 hwc_window_backend = func_output->output_hwc_create_video_window(
300 private_output->output_backend, &ret);
301 if (ret != TDM_ERROR_NONE) {
308 private_hwc_window = calloc(1, sizeof(tdm_private_hwc_window));
309 if (!private_hwc_window) {
310 TDM_ERR("failed: alloc memory");
311 func_output->output_hwc_destroy_window(private_output->output_backend, hwc_window_backend);
313 *error = TDM_ERROR_OUT_OF_MEMORY;
317 LIST_ADD(&private_hwc_window->link, &private_output->hwc_window_list);
319 private_hwc_window->private_display = private_display;
320 private_hwc_window->private_output = private_output;
321 private_hwc_window->hwc_window_backend = hwc_window_backend;
323 TDM_DBG("hwc_window(%p) create", private_hwc_window);
326 *error = TDM_ERROR_NONE;
328 return private_hwc_window;
332 tdm_hwc_window_destroy_internal(tdm_private_hwc_window * private_hwc_window)
334 tdm_private_output *private_output;
335 tdm_private_module *private_module;
336 tdm_func_output *func_output;
338 TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED);
340 if (!private_hwc_window)
341 return TDM_ERROR_OPERATION_FAILED;
343 private_output = private_hwc_window->private_output;
344 private_module = private_output->private_module;
346 LIST_DEL(&private_hwc_window->link);
348 func_output = &private_module->func_output;
349 func_output->output_hwc_destroy_window(private_output->output_backend, private_hwc_window->hwc_window_backend);
351 free(private_hwc_window);
352 return TDM_ERROR_NONE;
356 tdm_hwc_window_set_flags(tdm_hwc_window *hwc_window, tdm_hwc_window_flag flags)
358 tdm_private_module *private_module;
359 tdm_func_hwc_window *func_hwc_window = NULL;
361 HWC_WINDOW_FUNC_ENTRY();
363 _pthread_mutex_lock(&private_display->lock);
365 private_module = private_output->private_module;
366 func_hwc_window = &private_module->func_hwc_window;
368 if (!func_hwc_window->hwc_window_set_flags) {
369 _pthread_mutex_unlock(&private_display->lock);
370 TDM_WRN("not implemented!!");
371 return TDM_ERROR_NOT_IMPLEMENTED;
374 ret = func_hwc_window->hwc_window_set_flags(private_hwc_window->hwc_window_backend, flags);
376 _pthread_mutex_unlock(&private_display->lock);
382 tdm_hwc_window_unset_flags(tdm_hwc_window *hwc_window, tdm_hwc_window_flag flags)
384 tdm_private_module *private_module;
385 tdm_func_hwc_window *func_hwc_window = NULL;
387 HWC_WINDOW_FUNC_ENTRY();
389 _pthread_mutex_lock(&private_display->lock);
391 private_module = private_output->private_module;
392 func_hwc_window = &private_module->func_hwc_window;
394 if (!func_hwc_window->hwc_window_unset_flags) {
395 _pthread_mutex_unlock(&private_display->lock);
396 TDM_WRN("not implemented!!");
397 return TDM_ERROR_NOT_IMPLEMENTED;
400 ret = func_hwc_window->hwc_window_unset_flags(private_hwc_window->hwc_window_backend, flags);
402 _pthread_mutex_unlock(&private_display->lock);
408 _tdm_hwc_window_layer_commit_handler(tdm_layer *layer, unsigned int sequence,
409 unsigned int tv_sec, unsigned int tv_usec,
412 tdm_private_hwc_window_commit_handler *hwc_window_commit_handler = (tdm_private_hwc_window_commit_handler *)user_data;
413 tdm_hwc_window_commit_handler func = hwc_window_commit_handler->func;
414 tdm_hwc_window *hwc_window = (tdm_hwc_window *)hwc_window_commit_handler->private_hwc_window;
415 void *data = hwc_window_commit_handler->user_data;
417 func(hwc_window, sequence, tv_sec, tv_usec, data);
419 free(hwc_window_commit_handler);
423 tdm_hwc_window_commit(tdm_hwc_window *hwc_window, tdm_hwc_window_commit_handler func, void *user_data)
425 tdm_private_module *private_module;
426 tdm_func_hwc_window *func_hwc_window = NULL;
427 tdm_private_hwc_window_commit_handler *hwc_window_commit_handler;
428 tdm_layer *layer = NULL;
429 tdm_private_layer *private_layer;
430 tdm_info_layer *info_layer;
431 tdm_hwc_window_info window_info;
432 tbm_surface_h buffer;
434 HWC_WINDOW_FUNC_ENTRY();
436 _pthread_mutex_lock(&private_display->lock);
438 private_module = private_output->private_module;
439 func_hwc_window = &private_module->func_hwc_window;
441 if (!func_hwc_window->hwc_window_get_layer) {
442 _pthread_mutex_unlock(&private_display->lock);
443 TDM_ERR("not implemented!!");
444 return TDM_ERROR_NOT_IMPLEMENTED;
447 layer = func_hwc_window->hwc_window_get_layer(private_hwc_window->hwc_window_backend,
450 _pthread_mutex_unlock(&private_display->lock);
451 TDM_ERR("no assigned layer!!");
452 return TDM_ERROR_INVALID_PARAMETER;
455 private_layer = (tdm_private_layer*)layer;
457 buffer = func_hwc_window->hwc_window_get_buffer(private_hwc_window->hwc_window_backend,
460 ret = tdm_layer_set_buffer_internal(private_layer, buffer);
462 ret = tdm_layer_unset_buffer_internal(private_layer);
463 if (ret != TDM_ERROR_NONE) {
464 TDM_ERR("failed: layer set buffer(window)");
465 _pthread_mutex_unlock(&private_display->lock);
469 ret = func_hwc_window->hwc_window_get_info(private_hwc_window->hwc_window_backend,
471 if (ret != TDM_ERROR_NONE) {
472 TDM_ERR("failed: commit layer(window)");
473 _pthread_mutex_unlock(&private_display->lock);
477 info_layer = (tdm_info_layer *)&window_info;
478 ret = tdm_layer_set_info_internal(private_layer, info_layer);
479 if (ret != TDM_ERROR_NONE) {
480 TDM_ERR("failed: layer set info(window)");
481 _pthread_mutex_unlock(&private_display->lock);
485 hwc_window_commit_handler = calloc(1, sizeof(tdm_private_hwc_window_commit_handler));
486 if (!hwc_window_commit_handler) {
487 TDM_ERR("failed: alloc memory");
488 _pthread_mutex_unlock(&private_display->lock);
489 return TDM_ERROR_OUT_OF_MEMORY;
492 hwc_window_commit_handler->private_hwc_window = private_hwc_window;
493 hwc_window_commit_handler->func = func;
494 hwc_window_commit_handler->user_data = user_data;
496 ret = tdm_layer_commit_internal(private_layer, _tdm_hwc_window_layer_commit_handler, hwc_window_commit_handler);
497 if (ret != TDM_ERROR_NONE) {
498 TDM_ERR("failed: commit layer(window)");
499 free(hwc_window_commit_handler);
500 _pthread_mutex_unlock(&private_display->lock);
504 _pthread_mutex_unlock(&private_display->lock);
510 tdm_hwc_window_video_get_capability(tdm_hwc_window *hwc_window,
511 tdm_hwc_window_video_capability *video_capability)
513 tdm_private_module *private_module;
514 tdm_func_hwc_window *func_hwc_window = NULL;
516 HWC_WINDOW_FUNC_ENTRY();
518 TDM_RETURN_VAL_IF_FAIL(video_capability != NULL, TDM_ERROR_INVALID_PARAMETER);
520 _pthread_mutex_lock(&private_display->lock);
522 private_module = private_output->private_module;
523 func_hwc_window = &private_module->func_hwc_window;
525 if (!func_hwc_window->hwc_window_video_get_capability) {
526 _pthread_mutex_unlock(&private_display->lock);
527 TDM_WRN("not implemented!!");
528 return TDM_ERROR_NOT_IMPLEMENTED;
531 ret = func_hwc_window->hwc_window_video_get_capability(private_hwc_window->hwc_window_backend,
534 _pthread_mutex_unlock(&private_display->lock);
540 tdm_hwc_window_video_get_available_properties(tdm_hwc_window *hwc_window,
541 const tdm_prop **props, int *count)
543 tdm_private_module *private_module;
544 tdm_func_hwc_window *func_hwc_window = NULL;
546 HWC_WINDOW_FUNC_ENTRY();
548 TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
549 TDM_RETURN_VAL_IF_FAIL(count != 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_available_properties) {
557 _pthread_mutex_unlock(&private_display->lock);
558 TDM_WRN("not implemented!!");
559 return TDM_ERROR_NOT_IMPLEMENTED;
562 ret = func_hwc_window->hwc_window_video_get_available_properties(private_hwc_window->hwc_window_backend,
565 _pthread_mutex_unlock(&private_display->lock);
571 tdm_hwc_window_video_get_property(tdm_hwc_window *hwc_window,
572 unsigned int id, tdm_value *value)
574 tdm_private_module *private_module;
575 tdm_func_hwc_window *func_hwc_window = NULL;
577 HWC_WINDOW_FUNC_ENTRY();
579 TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
581 _pthread_mutex_lock(&private_display->lock);
583 private_module = private_output->private_module;
584 func_hwc_window = &private_module->func_hwc_window;
586 if (!func_hwc_window->hwc_window_video_get_property) {
587 _pthread_mutex_unlock(&private_display->lock);
588 TDM_WRN("not implemented!!");
589 return TDM_ERROR_NOT_IMPLEMENTED;
592 ret = func_hwc_window->hwc_window_video_get_property(private_hwc_window->hwc_window_backend,
595 _pthread_mutex_unlock(&private_display->lock);
601 tdm_hwc_window_video_set_property(tdm_hwc_window *hwc_window,
602 unsigned int id, tdm_value value)
604 tdm_private_module *private_module;
605 tdm_func_hwc_window *func_hwc_window = NULL;
607 HWC_WINDOW_FUNC_ENTRY();
609 _pthread_mutex_lock(&private_display->lock);
611 private_module = private_output->private_module;
612 func_hwc_window = &private_module->func_hwc_window;
614 if (!func_hwc_window->hwc_window_video_set_property) {
615 _pthread_mutex_unlock(&private_display->lock);
616 TDM_WRN("not implemented!!");
617 return TDM_ERROR_NOT_IMPLEMENTED;
620 ret = func_hwc_window->hwc_window_video_set_property(private_hwc_window->hwc_window_backend,
623 _pthread_mutex_unlock(&private_display->lock);