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"
40 #define HWC_FUNC_ENTRY() \
41 tdm_private_display *private_display; \
42 tdm_private_output *private_output; \
43 tdm_private_hwc *private_hwc; \
44 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
45 TDM_RETURN_VAL_IF_FAIL(hwc != NULL, TDM_ERROR_INVALID_PARAMETER); \
46 private_hwc = (tdm_private_hwc*)hwc; \
47 private_output = private_hwc->private_output; \
48 TDM_RETURN_VAL_IF_FAIL(private_output != NULL, TDM_ERROR_INVALID_PARAMETER); \
49 private_display = private_output->private_display
51 #define HWC_FUNC_ENTRY_ERROR() \
52 tdm_private_display *private_display; \
53 tdm_private_output *private_output; \
54 tdm_private_hwc *private_hwc; \
55 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
56 TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(hwc != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \
57 private_hwc = (tdm_private_hwc*)hwc; \
58 private_output = private_hwc->private_output; \
59 TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(private_output != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \
60 private_display = private_output->private_display
62 #define HWC_FUNC_ENTRY_VOID_RETURN() \
63 tdm_private_display *private_display; \
64 tdm_private_output *private_output; \
65 tdm_private_hwc *private_hwc; \
66 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
67 TDM_RETURN_IF_FAIL(hwc != NULL); \
68 private_hwc = (tdm_private_hwc*)hwc; \
69 private_output = private_hwc->private_output; \
70 TDM_RETURN_IF_FAIL(private_output != NULL); \
71 private_display = private_output->private_display
74 static tdm_private_hwc_window *
75 _tdm_hwc_find_private_hwc_window(tdm_private_hwc *private_hwc, tdm_hwc_window *hwc_window_backend)
77 tdm_private_hwc_window *private_hwc_window = NULL;
79 LIST_FOR_EACH_ENTRY(private_hwc_window, &private_hwc->hwc_window_list, link) {
80 if (private_hwc_window->hwc_window_backend == hwc_window_backend)
81 return private_hwc_window;
88 _tdm_hwc_thread_cb_commit(tdm_private_display *private_display, void *object,
89 tdm_thread_cb_base *cb_base, void *user_data)
91 tdm_thread_cb_hwc_commit *hwc_commit = (tdm_thread_cb_hwc_commit *)cb_base;
92 tdm_private_hwc_commit_handler *hwc_commit_handler = hwc_commit->base.data;
93 tdm_private_hwc *private_hwc = object;
95 TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
97 if (!hwc_commit_handler)
100 assert(hwc_commit_handler->owner_tid == syscall(SYS_gettid));
102 tdm_thread_cb_remove(private_hwc, TDM_THREAD_CB_HWC_COMMIT, hwc_commit_handler,
103 _tdm_hwc_thread_cb_commit, NULL);
105 LIST_DEL(&hwc_commit_handler->link);
107 if (tdm_debug_module & TDM_DEBUG_COMMIT) {
108 TDM_INFO("----------------------------------------- hwc(%d) committed", private_hwc->index);
109 TDM_INFO("handler(%p)", hwc_commit_handler);
112 /* LCOV_EXCL_START */
113 if (private_display->print_fps) {
114 double curr = tdm_helper_get_time();
115 if (private_hwc->fps_stamp == 0) {
116 private_hwc->fps_stamp = curr;
117 } else if ((curr - private_hwc->fps_stamp) > 1.0) {
118 TDM_INFO("hwc(%p,%d) fps: %d",
119 private_hwc, private_hwc->index, private_hwc->fps_count);
120 private_hwc->fps_count = 0;
121 private_hwc->fps_stamp = curr;
123 private_hwc->fps_count++;
124 } else if (private_hwc->fps_stamp != 0) {
125 private_hwc->fps_stamp = 0;
126 private_hwc->fps_count = 0;
130 if (hwc_commit_handler->func) {
131 _pthread_mutex_unlock(&private_display->lock);
132 hwc_commit_handler->func(private_hwc,
133 hwc_commit->sequence,
136 hwc_commit_handler->user_data);
137 _pthread_mutex_lock(&private_display->lock);
140 free(hwc_commit_handler);
142 if (tdm_debug_module & TDM_DEBUG_COMMIT)
143 TDM_INFO("-----------------------------------------...");
147 _tdm_hwc_cb_commit(tdm_hwc *hwc_backend, unsigned int sequence,
148 unsigned int tv_sec, unsigned int tv_usec, void *user_data)
150 tdm_private_hwc_commit_handler *hwc_commit_handler = user_data;
151 tdm_private_hwc *private_hwc;
152 tdm_thread_cb_hwc_commit hwc_commit;
155 if (hwc_commit_handler)
156 private_hwc = hwc_commit_handler->private_hwc;
158 private_hwc = tdm_display_find_private_hwc(tdm_display_get(), hwc_backend);
160 memset(&hwc_commit, 0, sizeof hwc_commit);
161 hwc_commit.base.type = TDM_THREAD_CB_HWC_COMMIT;
162 hwc_commit.base.length = sizeof hwc_commit;
163 hwc_commit.base.object_stamp = private_hwc->stamp;
164 hwc_commit.base.data = hwc_commit_handler;
165 hwc_commit.base.sync = 0;
166 hwc_commit.sequence = sequence;
167 hwc_commit.tv_sec = tv_sec;
168 hwc_commit.tv_usec = tv_usec;
170 ret = tdm_thread_cb_call(private_hwc, &hwc_commit.base, 1);
171 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
175 tdm_hwc_init(tdm_private_display *private_display)
177 tdm_thread_cb_set_find_func(TDM_THREAD_CB_HWC_COMMIT, tdm_display_find_hwc_stamp);
179 return TDM_ERROR_NONE;
182 EXTERN tdm_hwc_window *
183 tdm_hwc_create_window(tdm_hwc *hwc, tdm_error *error)
185 tdm_hwc_window *hwc_window = NULL;
187 HWC_FUNC_ENTRY_ERROR();
189 _pthread_mutex_lock(&private_display->lock);
191 hwc_window = (tdm_hwc_window *)tdm_hwc_window_create_internal(private_hwc, error);
193 _pthread_mutex_unlock(&private_display->lock);
199 tdm_hwc_get_video_supported_formats(tdm_hwc *hwc, const tbm_format **formats, int *count)
201 tdm_private_module *private_module;
202 tdm_func_hwc *func_hwc;
206 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
207 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
209 _pthread_mutex_lock(&private_display->lock);
211 private_module = private_output->private_module;
212 func_hwc = &private_module->func_hwc;
214 if (!func_hwc->hwc_get_video_supported_formats) {
215 /* LCOV_EXCL_START */
216 _pthread_mutex_unlock(&private_display->lock);
217 TDM_WRN("not implemented!!");
218 return TDM_ERROR_NOT_IMPLEMENTED;
222 ret = func_hwc->hwc_get_video_supported_formats(private_hwc->hwc_backend, formats, count);
224 _pthread_mutex_unlock(&private_display->lock);
230 tdm_hwc_get_video_available_properties(tdm_hwc *hwc, const tdm_prop **props, int *count)
232 tdm_private_module *private_module;
233 tdm_func_hwc *func_hwc = NULL;
237 TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
238 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
240 _pthread_mutex_lock(&private_display->lock);
242 private_module = private_output->private_module;
243 func_hwc = &private_module->func_hwc;
245 if (!func_hwc->hwc_get_video_available_properties) {
246 /* LCOV_EXCL_START */
247 _pthread_mutex_unlock(&private_display->lock);
248 TDM_WRN("not implemented!!");
249 return TDM_ERROR_NOT_IMPLEMENTED;
253 ret = func_hwc->hwc_get_video_available_properties(private_hwc->hwc_backend, props, count);
255 _pthread_mutex_unlock(&private_display->lock);
261 tdm_hwc_get_capabilities(tdm_hwc *hwc, tdm_hwc_capability *capabilities)
263 tdm_private_module *private_module;
264 tdm_func_hwc *func_hwc;
268 _pthread_mutex_lock(&private_display->lock);
270 private_module = private_output->private_module;
271 func_hwc = &private_module->func_hwc;
273 if (!func_hwc->hwc_get_capabilities) {
274 _pthread_mutex_unlock(&private_display->lock);
275 TDM_WRN("not implemented!!");
276 return TDM_ERROR_NOT_IMPLEMENTED;
279 ret = func_hwc->hwc_get_capabilities(private_hwc->hwc_backend, capabilities);
281 _pthread_mutex_unlock(&private_display->lock);
287 tdm_hwc_get_available_properties(tdm_hwc *hwc, const tdm_prop **props, int *count)
289 tdm_private_module *private_module;
290 tdm_func_hwc *func_hwc = NULL;
294 TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
295 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
297 _pthread_mutex_lock(&private_display->lock);
299 private_module = private_output->private_module;
300 func_hwc = &private_module->func_hwc;
302 if (!func_hwc->hwc_get_available_properties) {
303 /* LCOV_EXCL_START */
304 _pthread_mutex_unlock(&private_display->lock);
305 TDM_WRN("not implemented!!");
306 return TDM_ERROR_NOT_IMPLEMENTED;
310 ret = func_hwc->hwc_get_available_properties(private_hwc->hwc_backend, props, count);
312 _pthread_mutex_unlock(&private_display->lock);
317 EXTERN tbm_surface_queue_h
318 tdm_hwc_get_client_target_buffer_queue(tdm_hwc *hwc, tdm_error *error)
320 tdm_private_module *private_module;
321 tdm_func_hwc *func_hwc = NULL;
322 tbm_surface_queue_h queue = NULL;
324 HWC_FUNC_ENTRY_ERROR();
326 _pthread_mutex_lock(&private_display->lock);
328 private_module = private_hwc->private_module;
329 func_hwc = &private_module->func_hwc;
331 if (!func_hwc->hwc_get_client_target_buffer_queue) {
332 /* LCOV_EXCL_START */
333 _pthread_mutex_unlock(&private_display->lock);
334 TDM_WRN("not implemented!!");
339 queue = func_hwc->hwc_get_client_target_buffer_queue(private_hwc->hwc_backend, error);
341 _pthread_mutex_unlock(&private_display->lock);
347 tdm_hwc_set_client_target_buffer(tdm_hwc *hwc, tbm_surface_h target_buffer, tdm_region damage)
349 tdm_private_module *private_module;
350 tdm_func_hwc *func_hwc = NULL;
354 _pthread_mutex_lock(&private_display->lock);
356 if (tdm_debug_dump & TDM_DUMP_FLAG_WINDOW) {
357 /* LCOV_EXCL_START */
358 char str[TDM_PATH_LEN];
360 snprintf(str, TDM_PATH_LEN, "target_window_%03d", i++);
361 tdm_helper_dump_buffer_str(target_buffer, tdm_debug_dump_dir, str);
365 private_module = private_hwc->private_module;
366 func_hwc = &private_module->func_hwc;
368 if (!func_hwc->hwc_set_client_target_buffer) {
369 /* LCOV_EXCL_START */
370 _pthread_mutex_unlock(&private_display->lock);
371 TDM_WRN("not implemented!!");
372 return TDM_ERROR_NOT_IMPLEMENTED;
376 ret = func_hwc->hwc_set_client_target_buffer(private_hwc->hwc_backend, target_buffer, damage);
378 if (private_hwc->display_target_buffer) {
379 if (private_hwc->display_target_buffer != target_buffer) {
380 tbm_surface_internal_unref(private_hwc->display_target_buffer);
381 private_hwc->display_target_buffer = target_buffer;
383 tbm_surface_internal_ref(private_hwc->display_target_buffer);
387 private_hwc->display_target_buffer = target_buffer;
388 tbm_surface_internal_ref(private_hwc->display_target_buffer);
392 _pthread_mutex_unlock(&private_display->lock);
399 tdm_hwc_validate(tdm_hwc *hwc, tdm_hwc_window **composited_wnds, uint32_t num_wnds, uint32_t *num_types)
401 tdm_private_module *private_module;
402 tdm_func_hwc *func_hwc = NULL;
403 tdm_private_hwc_window **composited_wnds_frontend = NULL;
404 tdm_hwc_window **composited_wnds_backend = NULL;
409 TDM_RETURN_VAL_IF_FAIL(num_types != NULL, TDM_ERROR_INVALID_PARAMETER);
411 _pthread_mutex_lock(&private_display->lock);
413 private_module = private_hwc->private_module;
414 func_hwc = &private_module->func_hwc;
416 if (!func_hwc->hwc_validate) {
417 /* LCOV_EXCL_START */
418 _pthread_mutex_unlock(&private_display->lock);
419 TDM_WRN("not implemented!!");
420 return TDM_ERROR_NOT_IMPLEMENTED;
425 ret = func_hwc->hwc_validate(private_hwc->hwc_backend, NULL, 0, num_types);
427 _pthread_mutex_unlock(&private_display->lock);
431 composited_wnds_backend = calloc(num_wnds, sizeof(tdm_hwc_window *));
432 if (!composited_wnds_backend) {
433 /* LCOV_EXCL_START */
434 _pthread_mutex_unlock(&private_display->lock);
435 return TDM_ERROR_OUT_OF_MEMORY;
439 composited_wnds_frontend = (tdm_private_hwc_window **)composited_wnds;
441 for (i = 0; i < num_wnds; i++)
442 composited_wnds_backend[i] = composited_wnds_frontend[i]->hwc_window_backend;
444 ret = func_hwc->hwc_validate(private_hwc->hwc_backend, composited_wnds_backend,
445 num_wnds, num_types);
447 free(composited_wnds_backend);
449 _pthread_mutex_unlock(&private_display->lock);
455 tdm_hwc_get_changed_composition_types(tdm_hwc *hwc, uint32_t *num_elements,
456 tdm_hwc_window **hwc_window,
457 tdm_hwc_window_composition *composition_types)
459 tdm_private_module *private_module;
460 tdm_func_hwc *func_hwc = NULL;
461 tdm_private_hwc_window * private_hwc_window = NULL;
466 TDM_RETURN_VAL_IF_FAIL(num_elements != NULL, TDM_ERROR_INVALID_PARAMETER);
468 _pthread_mutex_lock(&private_display->lock);
470 private_module = private_hwc->private_module;
471 func_hwc = &private_module->func_hwc;
473 if (!func_hwc->hwc_get_changed_composition_types) {
474 /* LCOV_EXCL_START */
475 _pthread_mutex_unlock(&private_display->lock);
476 TDM_WRN("not implemented!!");
477 return TDM_ERROR_NOT_IMPLEMENTED;
481 ret = func_hwc->hwc_get_changed_composition_types(private_hwc->hwc_backend,
482 num_elements, hwc_window, composition_types);
483 if (ret != TDM_ERROR_NONE) {
484 /* LCOV_EXCL_START */
485 _pthread_mutex_unlock(&private_display->lock);
490 if (hwc_window == NULL || composition_types == NULL) {
491 _pthread_mutex_unlock(&private_display->lock);
492 return TDM_ERROR_NONE;
495 for (i = 0; i < *num_elements; i++) {
496 private_hwc_window = _tdm_hwc_find_private_hwc_window(private_hwc, hwc_window[i]);
497 if (private_hwc_window == NULL) {
498 /* LCOV_EXCL_START */
499 TDM_ERR("failed! This should never happen!");
500 tdm_hwc_window_destroy_internal(private_hwc_window);
502 _pthread_mutex_unlock(&private_display->lock);
503 return TDM_ERROR_OPERATION_FAILED;
507 hwc_window[i] = (tdm_hwc_window*)private_hwc_window;
510 _pthread_mutex_unlock(&private_display->lock);
516 tdm_hwc_accept_validation(tdm_hwc *hwc)
518 tdm_private_module *private_module;
519 tdm_func_hwc *func_hwc = NULL;
523 _pthread_mutex_lock(&private_display->lock);
525 private_module = private_hwc->private_module;
526 func_hwc = &private_module->func_hwc;
528 if (!func_hwc->hwc_validate) {
529 /* LCOV_EXCL_START */
530 _pthread_mutex_unlock(&private_display->lock);
531 TDM_WRN("not implemented!!");
532 return TDM_ERROR_NOT_IMPLEMENTED;
536 ret = func_hwc->hwc_accept_validation(private_hwc->hwc_backend);
538 _pthread_mutex_unlock(&private_display->lock);
544 tdm_hwc_commit(tdm_hwc *hwc, int sync, tdm_hwc_commit_handler func, void *user_data)
546 tdm_private_module *private_module;
547 tdm_func_hwc *func_hwc = NULL;
548 tdm_private_hwc_commit_handler *hwc_commit_handler = NULL;
549 tdm_private_voutput *private_voutput = NULL;
550 tdm_private_voutput_commit_handler *voutput_commit_handler = NULL;
554 _pthread_mutex_lock(&private_display->lock);
556 private_module = private_hwc->private_module;
557 func_hwc = &private_module->func_hwc;
559 if (!func_hwc->hwc_commit) {
560 /* LCOV_EXCL_START */
561 TDM_WRN("not implemented!!");
562 _pthread_mutex_unlock(&private_display->lock);
563 return TDM_ERROR_NOT_IMPLEMENTED;
567 //TODO: I am not sure yet whether we have to check the dpms at hwc_commit.
569 /* check if the dpms is off */
570 if (TDM_OUTPUT_DPMS_VSYNC_IS_OFF(private_output->current_dpms_value)) {
571 TDM_ERR("hwc(%d) dpms: %s", private_hwc->index,
572 tdm_dpms_str(private_output->current_dpms_value));
573 _pthread_mutex_unlock(&private_display->lock);
574 return TDM_ERROR_DPMS_OFF;
578 if (tdm_debug_module & TDM_DEBUG_COMMIT)
579 TDM_INFO("hwc(%d) commit", private_hwc->index);
581 if (private_module == private_display->virtual_module) {
582 if (!private_output->private_voutput) {
583 TDM_ERR("virtual module but don't have voutput");
584 _pthread_mutex_unlock(&private_display->lock);
585 return TDM_ERROR_BAD_MODULE;
589 if (!private_hwc->regist_commit_cb) {
590 private_hwc->regist_commit_cb = 1;
591 ret = func_hwc->hwc_set_commit_handler(private_hwc->hwc_backend, _tdm_hwc_cb_commit);
592 /* LCOV_EXCL_START */
593 if (ret != TDM_ERROR_NONE) {
594 private_hwc->regist_commit_cb = 0;
595 TDM_ERR("hwc(%d) fail to set hwc_set_commit_handler", private_hwc->index);
596 _pthread_mutex_unlock(&private_display->lock);
602 hwc_commit_handler = calloc(1, sizeof(tdm_private_hwc_commit_handler));
603 if (!hwc_commit_handler) {
604 /* LCOV_EXCL_START */
605 TDM_ERR("failed: alloc memory");
606 _pthread_mutex_unlock(&private_display->lock);
607 return TDM_ERROR_OUT_OF_MEMORY;
611 ret = tdm_thread_cb_add(private_hwc, TDM_THREAD_CB_HWC_COMMIT, hwc_commit_handler,
612 _tdm_hwc_thread_cb_commit, NULL);
613 if (ret != TDM_ERROR_NONE) {
614 TDM_ERR("tdm_thread_cb_add failed");
615 free(hwc_commit_handler);
616 _pthread_mutex_unlock(&private_display->lock);
620 LIST_ADDTAIL(&hwc_commit_handler->link, &private_hwc->hwc_commit_handler_list);
621 hwc_commit_handler->private_hwc = private_hwc;
622 hwc_commit_handler->func = func;
623 hwc_commit_handler->user_data = user_data;
624 hwc_commit_handler->owner_tid = syscall(SYS_gettid);
626 if (private_module == private_display->virtual_module) {
627 private_voutput = private_output->private_voutput;
629 if (LIST_LENGTH(&private_voutput->voutput_commit_handler_list) != 0) {
630 voutput_commit_handler = LIST_FIRST_ENTRY(&private_voutput->voutput_commit_handler_list, tdm_private_voutput_commit_handler, link);
631 voutput_commit_handler->user_data = private_hwc->display_target_buffer;
635 ret = func_hwc->hwc_commit(private_hwc->hwc_backend, sync, hwc_commit_handler);
636 TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, commit_failed);
638 if (tdm_debug_module & TDM_DEBUG_COMMIT)
639 TDM_INFO("hwc(%d) backend commit: handle(%p) func(%p) user_data(%p)",
640 private_hwc->index, hwc_commit_handler, func, user_data);
642 _pthread_mutex_unlock(&private_display->lock);
647 /* LCOV_EXCL_START */
648 if (hwc_commit_handler) {
649 tdm_thread_cb_remove(private_hwc, TDM_THREAD_CB_HWC_COMMIT, hwc_commit_handler,
650 _tdm_hwc_thread_cb_commit, NULL);
651 LIST_DEL(&hwc_commit_handler->link);
652 free(hwc_commit_handler);
655 _pthread_mutex_unlock(&private_display->lock);
662 tdm_hwc_set_property(tdm_hwc *hwc, uint32_t id, tdm_value value)
664 tdm_private_module *private_module;
665 tdm_func_hwc *func_hwc = NULL;
669 _pthread_mutex_lock(&private_display->lock);
671 private_module = private_hwc->private_module;
672 func_hwc = &private_module->func_hwc;
674 if (!func_hwc->hwc_set_property) {
675 /* LCOV_EXCL_START */
676 _pthread_mutex_unlock(&private_display->lock);
677 TDM_WRN("not implemented!!");
678 return TDM_ERROR_NOT_IMPLEMENTED;
682 ret = func_hwc->hwc_set_property(private_hwc->hwc_backend, id, value);
684 _pthread_mutex_unlock(&private_display->lock);
690 tdm_hwc_get_property(tdm_hwc *hwc, uint32_t id, tdm_value *value)
692 tdm_private_module *private_module;
693 tdm_func_hwc *func_hwc = NULL;
697 _pthread_mutex_lock(&private_display->lock);
699 private_module = private_hwc->private_module;
700 func_hwc = &private_module->func_hwc;
702 if (!func_hwc->hwc_get_property) {
703 /* LCOV_EXCL_START */
704 _pthread_mutex_unlock(&private_display->lock);
705 TDM_WRN("not implemented!!");
706 return TDM_ERROR_NOT_IMPLEMENTED;
710 ret = func_hwc->hwc_get_property(private_hwc->hwc_backend, id, value);
712 _pthread_mutex_unlock(&private_display->lock);