1 /**************************************************************************
5 * Copyright 2018 Samsung Electronics co., Ltd. All Rights Reserved.
7 * Contact: SooChan Lim <sc1.lim@samsung.com>,
8 * Boram Park <boram1288.park@samsung.com>,
9 * Changyeon Lee <cyeon.lee@samsung.com>,
10 * Sangjin Lee <lsj119@samsung.com>
12 * Permission is hereby granted, free of charge, to any person obtaining a
13 * copy of this software and associated documentation files (the
14 * "Software"), to deal in the Software without restriction, including
15 * without limitation the rights to use, copy, modify, merge, publish,
16 * distribute, sub license, and/or sell copies of the Software, and to
17 * permit persons to whom the Software is furnished to do so, subject to
18 * the following conditions:
20 * The above copyright notice and this permission notice (including the
21 * next paragraph) shall be included in all copies or substantial portions
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
27 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
28 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
29 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
30 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 **************************************************************************/
38 #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 *private_hwc; \
48 tdm_private_hwc_window *private_hwc_window; \
49 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
50 TDM_RETURN_VAL_IF_FAIL(hwc_window != NULL, TDM_ERROR_INVALID_PARAMETER); \
51 private_hwc_window = (tdm_private_hwc_window*)hwc_window; \
52 private_hwc = private_hwc_window->private_hwc; \
53 TDM_RETURN_VAL_IF_FAIL(private_hwc != NULL, TDM_ERROR_INVALID_PARAMETER); \
54 private_output = private_hwc->private_output; \
55 TDM_RETURN_VAL_IF_FAIL(private_output != NULL, TDM_ERROR_INVALID_PARAMETER); \
56 private_display = private_output->private_display
58 #define HWC_WINDOW_FUNC_ENTRY_ERROR() \
59 tdm_private_display *private_display; \
60 tdm_private_output *private_output; \
61 tdm_private_hwc *private_hwc; \
62 tdm_private_hwc_window *private_hwc_window; \
63 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
64 TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(hwc_window != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \
65 private_hwc_window = (tdm_private_hwc_window*)hwc_window; \
66 private_hwc = private_hwc_window->private_hwc; \
67 TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(private_hwc != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \
68 private_output = private_hwc->private_output; \
69 TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(private_output != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \
70 private_display = private_output->private_display
72 #define HWC_WINDOW_FUNC_ENTRY_VOID_RETURN() \
73 tdm_private_display *private_display; \
74 tdm_private_output *private_output; \
75 tdm_private_hwc *private_hwc; \
76 tdm_private_hwc_window *private_hwc_window; \
77 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
78 TDM_RETURN_IF_FAIL(hwc_window != NULL); \
79 private_hwc_window = (tdm_private_hwc_window*)hwc_window; \
80 private_hwc = private_hwc_window->private_hwc; \
81 TDM_RETURN_IF_FAIL(private_hwc != NULL); \
82 private_output = private_hwc->private_output; \
83 TDM_RETURN_IF_FAIL(private_output != NULL); \
84 private_display = private_output->private_display
87 INTERN tdm_hwc_window *
88 tdm_hwc_window_create_internal(tdm_private_hwc *private_hwc, tdm_error *error)
90 tdm_private_output *private_output = private_hwc->private_output;
91 tdm_private_module *private_module = private_output->private_module;
92 tdm_func_hwc *func_hwc = &private_module->func_hwc;
93 tdm_private_hwc_window *private_hwc_window = NULL;
94 tdm_hwc_window *hwc_window_backend = NULL;
95 tdm_error ret = TDM_ERROR_NONE;
97 TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), NULL);
99 if (!private_module->use_hal_tdm) {
100 if (!func_hwc->hwc_create_window) {
101 /* LCOV_EXCL_START */
103 *error = TDM_ERROR_BAD_MODULE;
109 private_hwc_window = calloc(1, sizeof(tdm_private_hwc_window));
110 if (!private_hwc_window) {
111 /* LCOV_EXCL_START */
112 TDM_ERR("failed: alloc memory");
114 *error = TDM_ERROR_OUT_OF_MEMORY;
118 if (private_module->use_hal_tdm)
119 hwc_window_backend = (tdm_hwc_window *)hal_tdm_hwc_create_window((hal_tdm_hwc *)private_hwc->hwc_backend, (hal_tdm_error *)&ret);
121 hwc_window_backend = func_hwc->hwc_create_window(private_hwc->hwc_backend, &ret);
122 if (ret != TDM_ERROR_NONE) {
123 free(private_hwc_window);
129 LIST_ADD(&private_hwc_window->link, &private_hwc->hwc_window_list);
131 private_hwc_window->private_hwc = private_hwc;
132 private_hwc_window->hwc_window_backend = hwc_window_backend;
134 TDM_DBG("hwc_window(%p) create", private_hwc_window);
137 *error = TDM_ERROR_NONE;
139 return private_hwc_window;
143 tdm_hwc_window_destroy_internal(tdm_private_hwc_window *private_hwc_window)
145 tdm_private_output *private_output;
146 tdm_private_module *private_module;
147 tdm_private_hwc *private_hwc;
148 tdm_func_hwc_window *func_hwc_window;
150 TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
152 if (!private_hwc_window)
155 private_hwc = private_hwc_window->private_hwc;
156 private_output = private_hwc->private_output;
157 private_module = private_output->private_module;
158 func_hwc_window = &private_module->func_hwc_window;
160 LIST_DEL(&private_hwc_window->link);
162 if (private_module->use_hal_tdm)
163 hal_tdm_hwc_window_destroy((hal_tdm_hwc_window *)private_hwc_window->hwc_window_backend);
165 func_hwc_window->hwc_window_destroy(private_hwc_window->hwc_window_backend);
167 free(private_hwc_window);
171 tdm_hwc_window_destroy(tdm_hwc_window *hwc_window)
173 tdm_private_display *private_display;
174 tdm_private_output *private_output;
175 tdm_private_hwc *private_hwc;
176 tdm_private_hwc_window *private_hwc_window;
181 private_hwc_window = (tdm_private_hwc_window *)hwc_window;
182 private_hwc = private_hwc_window->private_hwc;
183 private_output = private_hwc->private_output;
184 private_display = private_output->private_display;
186 _pthread_mutex_lock(&private_display->lock);
188 tdm_hwc_window_destroy_internal(hwc_window);
190 _pthread_mutex_unlock(&private_display->lock);
193 EXTERN tbm_surface_queue_h
194 tdm_hwc_window_acquire_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error)
196 tdm_private_module *private_module;
197 tdm_func_hwc_window *func_hwc_window = NULL;
198 tbm_surface_queue_h queue = NULL;
200 HWC_WINDOW_FUNC_ENTRY_ERROR();
202 _pthread_mutex_lock(&private_display->lock);
204 private_module = private_output->private_module;
205 func_hwc_window = &private_module->func_hwc_window;
207 if (private_module->use_hal_tdm) {
208 queue = hal_tdm_hwc_window_acquire_buffer_queue((hal_tdm_hwc_window *)private_hwc_window->hwc_window_backend, (hal_tdm_error *)error);
210 if (!func_hwc_window->hwc_window_acquire_buffer_queue) {
211 /* LCOV_EXCL_START */
212 _pthread_mutex_unlock(&private_display->lock);
213 TDM_WRN("not implemented!!");
215 *error = TDM_ERROR_NOT_IMPLEMENTED;
219 queue = func_hwc_window->hwc_window_acquire_buffer_queue(private_hwc_window->hwc_window_backend, error);
221 _pthread_mutex_unlock(&private_display->lock);
227 tdm_hwc_window_release_buffer_queue(tdm_hwc_window *hwc_window, tbm_surface_queue_h queue)
229 tdm_private_module *private_module;
230 tdm_func_hwc_window *func_hwc_window = NULL;
231 tdm_private_display *private_display;
232 tdm_private_output *private_output;
233 tdm_private_hwc *private_hwc;
234 tdm_private_hwc_window *private_hwc_window;
239 private_hwc_window = (tdm_private_hwc_window *)hwc_window;
240 private_hwc = private_hwc_window->private_hwc;
241 private_output = private_hwc->private_output;
242 private_display = private_output->private_display;
244 TDM_RETURN_IF_FAIL(queue != NULL);
246 _pthread_mutex_lock(&private_display->lock);
248 private_module = private_output->private_module;
249 func_hwc_window = &private_module->func_hwc_window;
251 if (private_module->use_hal_tdm) {
252 hal_tdm_hwc_window_release_buffer_queue((hal_tdm_hwc_window *)private_hwc_window->hwc_window_backend, queue);
254 if (!func_hwc_window->hwc_window_release_buffer_queue) {
255 _pthread_mutex_unlock(&private_display->lock);
256 TDM_WRN("not implemented!!");
260 func_hwc_window->hwc_window_release_buffer_queue(private_hwc_window->hwc_window_backend, queue);
262 _pthread_mutex_unlock(&private_display->lock);
268 tdm_hwc_window_set_composition_type(tdm_hwc_window *hwc_window,
269 tdm_hwc_window_composition composition_type)
271 tdm_private_module *private_module;
272 tdm_func_hwc_window *func_hwc_window = NULL;
274 HWC_WINDOW_FUNC_ENTRY();
275 TDM_RETURN_VAL_IF_FAIL(composition_type >= TDM_HWC_WIN_COMPOSITION_NONE, TDM_ERROR_INVALID_PARAMETER);
276 TDM_RETURN_VAL_IF_FAIL(composition_type <= TDM_HWC_WIN_COMPOSITION_VIDEO, TDM_ERROR_INVALID_PARAMETER);
278 _pthread_mutex_lock(&private_display->lock);
280 private_module = private_output->private_module;
281 func_hwc_window = &private_module->func_hwc_window;
283 if (private_module->use_hal_tdm) {
284 ret = (tdm_error)hal_tdm_hwc_window_set_composition_type((hal_tdm_hwc_window *)private_hwc_window->hwc_window_backend,
285 (tdm_hwc_window_composition)composition_type);
287 if (!func_hwc_window->hwc_window_set_composition_type) {
288 _pthread_mutex_unlock(&private_display->lock);
289 TDM_WRN("not implemented!!");
290 return TDM_ERROR_NOT_IMPLEMENTED;
293 ret = func_hwc_window->hwc_window_set_composition_type(private_hwc_window->hwc_window_backend, composition_type);
295 if (ret == TDM_ERROR_NONE)
296 private_hwc_window->composition_type = composition_type;
298 _pthread_mutex_unlock(&private_display->lock);
304 tdm_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_region damage)
306 tdm_private_module *private_module;
307 tdm_func_hwc_window *func_hwc_window = NULL;
309 HWC_WINDOW_FUNC_ENTRY();
310 if (damage.num_rects > 0)
311 TDM_RETURN_VAL_IF_FAIL(damage.rects != NULL, TDM_ERROR_INVALID_PARAMETER);
313 _pthread_mutex_lock(&private_display->lock);
315 private_module = private_output->private_module;
316 func_hwc_window = &private_module->func_hwc_window;
318 if (private_module->use_hal_tdm) {
319 hal_tdm_region hdamage;
320 memcpy(&hdamage, &damage, sizeof(hal_tdm_region));
321 ret = (tdm_error)hal_tdm_hwc_window_set_buffer_damage((hal_tdm_hwc_window *)private_hwc_window->hwc_window_backend, hdamage);
323 if (!func_hwc_window->hwc_window_set_buffer_damage) {
324 _pthread_mutex_unlock(&private_display->lock);
325 TDM_WRN("not implemented!!");
326 return TDM_ERROR_NOT_IMPLEMENTED;
329 ret = func_hwc_window->hwc_window_set_buffer_damage(private_hwc_window->hwc_window_backend, damage);
331 _pthread_mutex_unlock(&private_display->lock);
338 tdm_hwc_window_set_info(tdm_hwc_window *hwc_window, tdm_hwc_window_info *info)
340 tdm_private_module *private_module;
341 tdm_func_hwc_window *func_hwc_window = NULL;
344 HWC_WINDOW_FUNC_ENTRY();
346 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
348 _pthread_mutex_lock(&private_display->lock);
350 private_module = private_output->private_module;
351 func_hwc_window = &private_module->func_hwc_window;
353 if (!private_module->use_hal_tdm) {
354 if (!func_hwc_window->hwc_window_set_info) {
355 _pthread_mutex_unlock(&private_display->lock);
356 TDM_WRN("not implemented!!");
357 return TDM_ERROR_NOT_IMPLEMENTED;
361 if (info->src_config.format)
362 snprintf(fmtstr, 128, "%c%c%c%c", FOURCC_STR(info->src_config.format));
364 snprintf(fmtstr, 128, "NONE");
366 TDM_INFO("hwc_window(%p) info: src(%dx%d %d,%d %dx%d %s) dst(%d,%d %dx%d) trans(%d)",
367 private_hwc_window, info->src_config.size.h, info->src_config.size.v,
368 info->src_config.pos.x, info->src_config.pos.y,
369 info->src_config.pos.w, info->src_config.pos.h,
371 info->dst_pos.x, info->dst_pos.y,
372 info->dst_pos.w, info->dst_pos.h,
375 if (private_module->use_hal_tdm)
376 ret = hal_tdm_hwc_window_set_info((hal_tdm_hwc_window *)private_hwc_window->hwc_window_backend, (hal_tdm_hwc_window_info *)info);
378 ret = func_hwc_window->hwc_window_set_info(private_hwc_window->hwc_window_backend, info);
380 _pthread_mutex_unlock(&private_display->lock);
386 tdm_hwc_window_set_buffer(tdm_hwc_window *hwc_window, tbm_surface_h buffer)
388 tdm_private_module *private_module;
389 tdm_func_hwc_window *func_hwc_window;
391 HWC_WINDOW_FUNC_ENTRY();
393 _pthread_mutex_lock(&private_display->lock);
395 if ((tdm_debug_dump & TDM_DUMP_FLAG_WINDOW) && buffer) {
396 char str[TDM_PATH_LEN];
398 snprintf(str, TDM_PATH_LEN, "window_%d_%03d", private_output->index, i++);
399 tdm_helper_dump_buffer_str(buffer, tdm_debug_dump_dir, str);
402 private_module = private_output->private_module;
403 func_hwc_window = &private_module->func_hwc_window;
405 if (private_module->use_hal_tdm) {
406 ret = hal_tdm_hwc_window_set_buffer((hal_tdm_hwc_window *)private_hwc_window->hwc_window_backend, buffer);
408 if (!func_hwc_window->hwc_window_set_buffer) {
409 _pthread_mutex_unlock(&private_display->lock);
410 TDM_WRN("not implemented!!");
411 return TDM_ERROR_NOT_IMPLEMENTED;
414 ret = func_hwc_window->hwc_window_set_buffer(private_hwc_window->hwc_window_backend, buffer);
416 if (ret == TDM_ERROR_NONE)
417 private_hwc_window->display_buffer = buffer;
419 _pthread_mutex_unlock(&private_display->lock);
425 tdm_hwc_window_set_acquire_fence(tdm_hwc_window *hwc_window, int acquire_fence)
427 tdm_private_module *private_module;
428 tdm_func_hwc_window *func_hwc_window;
430 HWC_WINDOW_FUNC_ENTRY();
432 _pthread_mutex_lock(&private_display->lock);
434 private_module = private_output->private_module;
435 func_hwc_window = &private_module->func_hwc_window;
437 if (private_module->use_hal_tdm) {
438 ret = hal_tdm_hwc_window_set_acquire_fence((hal_tdm_hwc_window *)private_hwc_window->hwc_window_backend, acquire_fence);
440 if (!func_hwc_window->hwc_window_set_acquire_fence) {
441 _pthread_mutex_unlock(&private_display->lock);
442 TDM_WRN("not implemented!!");
443 return TDM_ERROR_NOT_IMPLEMENTED;
446 ret = func_hwc_window->hwc_window_set_acquire_fence(private_hwc_window->hwc_window_backend, acquire_fence);
448 _pthread_mutex_unlock(&private_display->lock);
454 tdm_hwc_window_get_property(tdm_hwc_window *hwc_window, unsigned int id, tdm_value *value)
456 tdm_private_module *private_module;
457 tdm_func_hwc_window *func_hwc_window = NULL;
459 HWC_WINDOW_FUNC_ENTRY();
461 TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
463 _pthread_mutex_lock(&private_display->lock);
465 private_module = private_output->private_module;
466 func_hwc_window = &private_module->func_hwc_window;
468 if (private_module->use_hal_tdm) {
469 hal_tdm_value hvalue;
470 ret = hal_tdm_hwc_window_get_property((hal_tdm_hwc_window *)private_hwc_window->hwc_window_backend, id, &hvalue);
471 if (ret == TDM_ERROR_NONE)
472 memcpy(&value->ptr, &hvalue.ptr, sizeof(tdm_value));
474 if (!func_hwc_window->hwc_window_get_property) {
475 /* LCOV_EXCL_START */
476 _pthread_mutex_unlock(&private_display->lock);
477 TDM_WRN("not implemented!!");
478 return TDM_ERROR_NOT_IMPLEMENTED;
481 ret = func_hwc_window->hwc_window_get_property(private_hwc_window->hwc_window_backend, id, value);
483 _pthread_mutex_unlock(&private_display->lock);
489 tdm_hwc_window_set_property(tdm_hwc_window *hwc_window, unsigned int id, tdm_value value)
491 tdm_private_module *private_module;
492 tdm_func_hwc_window *func_hwc_window = NULL;
494 HWC_WINDOW_FUNC_ENTRY();
496 _pthread_mutex_lock(&private_display->lock);
498 private_module = private_output->private_module;
499 func_hwc_window = &private_module->func_hwc_window;
501 if (private_module->use_hal_tdm) {
502 hal_tdm_value hvalue;
503 memcpy(&hvalue.ptr, &value.ptr, sizeof(hal_tdm_value));
504 ret = hal_tdm_hwc_window_set_property((hal_tdm_hwc_window *)private_hwc_window->hwc_window_backend, id, hvalue);
506 if (!func_hwc_window->hwc_window_set_property) {
507 /* LCOV_EXCL_START */
508 _pthread_mutex_unlock(&private_display->lock);
509 TDM_WRN("not implemented!!");
510 return TDM_ERROR_NOT_IMPLEMENTED;
513 ret = func_hwc_window->hwc_window_set_property(private_hwc_window->hwc_window_backend, id, value);
515 _pthread_mutex_unlock(&private_display->lock);
521 tdm_hwc_window_get_constraints(tdm_hwc_window *hwc_window, int *constraints)
523 tdm_private_module *private_module;
524 tdm_func_hwc_window *func_hwc_window = NULL;
526 HWC_WINDOW_FUNC_ENTRY();
528 _pthread_mutex_lock(&private_display->lock);
530 private_module = private_output->private_module;
531 func_hwc_window = &private_module->func_hwc_window;
533 if (private_module->use_hal_tdm) {
534 ret = hal_tdm_hwc_window_get_constraints((hal_tdm_hwc_window *)private_hwc_window->hwc_window_backend, constraints);
536 if (!func_hwc_window->hwc_window_get_constraints) {
537 _pthread_mutex_unlock(&private_display->lock);
538 TDM_WRN("not implemented!!");
539 return TDM_ERROR_NOT_IMPLEMENTED;
542 ret = func_hwc_window->hwc_window_get_constraints(private_hwc_window->hwc_window_backend, constraints);
544 _pthread_mutex_unlock(&private_display->lock);
550 tdm_hwc_window_set_name(tdm_hwc_window *hwc_window, const char *name)
552 tdm_private_module *private_module;
553 tdm_func_hwc_window *func_hwc_window = NULL;
555 HWC_WINDOW_FUNC_ENTRY();
557 _pthread_mutex_lock(&private_display->lock);
559 private_module = private_output->private_module;
560 func_hwc_window = &private_module->func_hwc_window;
562 if (private_module->use_hal_tdm) {
563 ret = hal_tdm_hwc_window_set_name((hal_tdm_hwc_window *)private_hwc_window->hwc_window_backend, name);
565 if (!func_hwc_window->hwc_window_set_name) {
566 _pthread_mutex_unlock(&private_display->lock);
567 TDM_WRN("not implemented!!");
568 return TDM_ERROR_NOT_IMPLEMENTED;
571 ret = func_hwc_window->hwc_window_set_name(private_hwc_window->hwc_window_backend, name);
573 _pthread_mutex_unlock(&private_display->lock);
579 tdm_hwc_window_set_cursor_image(tdm_hwc_window *hwc_window, int width, int height, int stride, void *ptr)
581 tdm_private_module *private_module;
582 tdm_func_hwc_window *func_hwc_window = NULL;
584 HWC_WINDOW_FUNC_ENTRY();
586 _pthread_mutex_lock(&private_display->lock);
588 private_module = private_output->private_module;
589 func_hwc_window = &private_module->func_hwc_window;
591 if (private_module->use_hal_tdm) {
592 ret = hal_tdm_hwc_window_set_cursor_image((hal_tdm_hwc_window *)private_hwc_window->hwc_window_backend, width, height, stride, ptr);
594 if (!func_hwc_window->hwc_window_set_cursor_image) {
595 _pthread_mutex_unlock(&private_display->lock);
596 TDM_WRN("not implemented!!");
597 return TDM_ERROR_NOT_IMPLEMENTED;
600 ret = func_hwc_window->hwc_window_set_cursor_image(private_hwc_window->hwc_window_backend, width, height, stride, ptr);
602 _pthread_mutex_unlock(&private_display->lock);