From 65a8648ffaca491aa4d16640f1633f5f0cd0b07a Mon Sep 17 00:00:00 2001 From: Boram Park Date: Fri, 2 Mar 2018 16:38:27 +0900 Subject: [PATCH 01/16] client: add tdm_client_handle_events_timeout Change-Id: Ifebfbe10670f7f8af366e26c8ea8e172f024d6a1 --- client/tdm_client.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++ client/tdm_client.h | 12 ++++++++ include/tdm_common.h | 1 + 3 files changed, 98 insertions(+) diff --git a/client/tdm_client.c b/client/tdm_client.c index e71c691..84b4c07 100644 --- a/client/tdm_client.c +++ b/client/tdm_client.c @@ -42,6 +42,7 @@ #include #include #include +#include #include @@ -570,6 +571,90 @@ tdm_client_handle_events(tdm_client *client) /* LCOV_EXCL_STOP */ } +static int +_tdm_client_poll(struct wl_display *display, short int events, int timeout) +{ + int ret; + struct pollfd pfd[1]; + + pfd[0].fd = wl_display_get_fd(display); + pfd[0].events = events; + do { + ret = poll(pfd, 1, timeout); + } while (ret == -1 && errno == EINTR); + + return ret; +} + +static tdm_error +_tdm_client_dispatch_timeout(tdm_private_client *private_client, int timeout) +{ + int ret; + struct wl_display *display = private_client->display; + + if (wl_display_prepare_read(display) == -1) + return wl_display_dispatch_pending(display); + + while (true) { + ret = wl_display_flush(display); + + if (ret != -1 || errno != EAGAIN) + break; + + if (_tdm_client_poll(display, POLLOUT, -1) == -1) { + wl_display_cancel_read(display); + TDM_ERR("_tdm_client_poll failed"); + return TDM_ERROR_OPERATION_FAILED; + } + } + + /* Don't stop if flushing hits an EPIPE; continue so we can read any + * protocol error that may have triggered it. */ + if (ret < 0 && errno != EPIPE) { + TDM_ERR("ret(%d) errno(%d)", ret, errno); + wl_display_cancel_read(display); + return TDM_ERROR_OPERATION_FAILED; + } + + ret = _tdm_client_poll(display, POLLIN, timeout); + if (ret <= 0) { + wl_display_cancel_read(display); + if (ret == 0) { + TDM_ERR("_tdm_client_poll timeout."); + return TDM_ERROR_TIMEOUT; + } else { + TDM_ERR("_tdm_client_poll failed. (ret:%d)", ret); + return TDM_ERROR_OPERATION_FAILED; + } + } + + if (wl_display_read_events(display) == -1) { + TDM_ERR("wl_display_read_events failed"); + return TDM_ERROR_OPERATION_FAILED; + } + + ret = wl_display_dispatch_pending(display); + + if (ret < 0) { + TDM_ERR("_tdm_client_dispatch_timeout failed"); + return TDM_ERROR_OPERATION_FAILED; + } + + return TDM_ERROR_NONE; +} + +tdm_error +tdm_client_handle_events_timeout(tdm_client *client, int ms_timeout) +{ + tdm_private_client *private_client; + + TDM_RETURN_VAL_IF_FAIL(client != NULL, TDM_ERROR_INVALID_PARAMETER); + + private_client = (tdm_private_client*)client; + + return _tdm_client_dispatch_timeout(private_client, ms_timeout); +} + typedef struct _tdm_client_vblank_temp { tdm_client_vblank_handler2 func; void *user_data; diff --git a/client/tdm_client.h b/client/tdm_client.h index 4ef687b..2b9dc1e 100644 --- a/client/tdm_client.h +++ b/client/tdm_client.h @@ -117,6 +117,18 @@ tdm_error tdm_client_handle_events(tdm_client *client); /** + * @brief Handle the events of the given file descriptor with millisecond timeout + * @details + * -1: infinite. 0: return immediately. Otherwise, waiting for ms_timeout milliseconds. + * @param[in] client A TDM client object + * @param[in] ms_timeout timeout value. + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + * @see #tdm_client_get_fd + */ +tdm_error +tdm_client_handle_events_timeout(tdm_client *client, int ms_timeout); + +/** * @brief @b Deprecated. Wait for VBLANK. * @deprecated * @details After interval vblanks, a client vblank handler will be called. diff --git a/include/tdm_common.h b/include/tdm_common.h index 4c264ed..db7e087 100644 --- a/include/tdm_common.h +++ b/include/tdm_common.h @@ -69,6 +69,7 @@ typedef enum { TDM_ERROR_DPMS_OFF = -10, /**< dpms off */ TDM_ERROR_OUTPUT_DISCONNECTED = -11, /**< output disconnected */ TDM_ERROR_PROTOCOL_ERROR = -12, /**< protocol error */ + TDM_ERROR_TIMEOUT = -13, /**< timeout */ } tdm_error; /** -- 2.7.4 From f85ee3f925ce5175638d59fa0324e7f590746668 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 28 Feb 2018 14:47:01 +0900 Subject: [PATCH 02/16] log: remove unused code Change-Id: Id0683906617148ed05423561c3bf5987ad592f37 --- common/tdm_log.c | 15 ++++++--------- include/tdm_log.h | 1 - utests/src/ut_tdm_log.cpp | 4 ---- 3 files changed, 6 insertions(+), 14 deletions(-) diff --git a/common/tdm_log.c b/common/tdm_log.c index 3f6b560..aa3d182 100644 --- a/common/tdm_log.c +++ b/common/tdm_log.c @@ -87,23 +87,20 @@ tdm_log_enable_dlog(unsigned int enable) } EXTERN void -tdm_log_enable_debug(unsigned int enable) -{ - if (enable) - tdm_log_debug_level = TDM_LOG_LEVEL_DBG; - else - tdm_log_debug_level = TDM_LOG_LEVEL_INFO; -} - -EXTERN void tdm_log_set_debug_level(int level) { + const char *str = getenv("TDM_DEBUG_LEVEL"); + if (str) + level = str[0] - '0'; tdm_log_debug_level = level; } EXTERN void tdm_log_set_assert_level(int level) { + const char *str = getenv("TDM_ASSERT_LEVEL"); + if (str) + level = str[0] - '0'; assert_level = level; } diff --git a/include/tdm_log.h b/include/tdm_log.h index b653aa2..5a9fb65 100644 --- a/include/tdm_log.h +++ b/include/tdm_log.h @@ -66,7 +66,6 @@ enum { void tdm_log_enable_color(unsigned int enable); void tdm_log_enable_dlog(unsigned int enable); -void tdm_log_enable_debug(unsigned int enable); void tdm_log_set_debug_level(int level); void tdm_log_set_assert_level(int level); void tdm_log_set_path(const char *path); diff --git a/utests/src/ut_tdm_log.cpp b/utests/src/ut_tdm_log.cpp index 2d4e245..64f6154 100644 --- a/utests/src/ut_tdm_log.cpp +++ b/utests/src/ut_tdm_log.cpp @@ -36,7 +36,6 @@ TEST(TDMLog, logPrintf) { tdm_log_enable_color(1); tdm_log_enable_dlog(0); - tdm_log_enable_debug(1); tdm_log_set_debug_level(2); tdm_log_set_path("/tmp/tdm.log"); tdm_log_print(TDM_LOG_LEVEL_ERR, "utest\n"); @@ -58,7 +57,6 @@ TEST(TDMLog, logDlogNone) { tdm_log_enable_color(0); tdm_log_enable_dlog(1); - tdm_log_enable_debug(0); tdm_log_set_debug_level(0); tdm_log_print(TDM_LOG_LEVEL_ERR, "utest"); tdm_log_print(TDM_LOG_LEVEL_WRN, "utest"); @@ -69,7 +67,6 @@ TEST(TDMLog, logDlogNone) TEST(TDMLog, logDlog) { tdm_log_enable_dlog(1); - tdm_log_enable_debug(1); tdm_log_print(TDM_LOG_LEVEL_ERR, "utest"); tdm_log_print(TDM_LOG_LEVEL_WRN, "utest"); tdm_log_print(TDM_LOG_LEVEL_INFO, "utest"); @@ -79,7 +76,6 @@ TEST(TDMLog, logDlog) TEST(TDMLog, logDlogNormal) { tdm_log_enable_dlog(1); - tdm_log_enable_debug(0); tdm_log_print(TDM_LOG_LEVEL_ERR, "utest"); tdm_log_print(TDM_LOG_LEVEL_WRN, "utest"); tdm_log_print(TDM_LOG_LEVEL_INFO, "utest"); -- 2.7.4 From 174dde585e9e9ad3f34af6160371c70e06ce090e Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 7 Mar 2018 10:18:07 +0900 Subject: [PATCH 03/16] log: add tdm_log_print_stdout Change-Id: I9ee3b16818e868f75b7bb114182f293d94a278bc --- common/tdm_log.c | 54 ++++++++++++++++++++++++++++++++++++------------------ include/tdm_log.h | 2 ++ 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/common/tdm_log.c b/common/tdm_log.c index aa3d182..348ea99 100644 --- a/common/tdm_log.c +++ b/common/tdm_log.c @@ -147,20 +147,50 @@ tdm_log_set_path(const char *path) } } -EXTERN void -tdm_log_print(int level, const char *fmt, ...) +static void +_tdm_log_vprint_stdout(int level, const char *fmt, va_list ap) { - va_list arg; - if (!log_lock_init) { log_lock_init = 1; pthread_mutex_init(&log_lock, NULL); - } if (level > tdm_log_debug_level) return; + char *lvl_str[] = {"TDM_NON", "TDM_ERR", "TDM_WRN", "TDM_INF", "TDM_DBG"}; + char *color[] = {COLOR_RESET, COLOR_RED, COLOR_YELLOW, COLOR_GREEN, COLOR_RESET}; + + pthread_mutex_lock(&log_lock); + + if (color_enable) + printf("%s", color[level]); + printf("[%s]", lvl_str[level]); + if (color_enable) + printf(COLOR_RESET); + vprintf(fmt, ap); + printf("\n"); + pthread_mutex_unlock(&log_lock); +} + + +EXTERN void +tdm_log_print_stdout(int level, const char *fmt, ...) +{ + va_list arg; + va_start(arg, fmt); + _tdm_log_vprint_stdout(level, fmt, arg); + va_end(arg); +} + +EXTERN void +tdm_log_print(int level, const char *fmt, ...) +{ + va_list arg; + + if (level > tdm_log_debug_level) + return; + if (dlog_enable) { log_priority dlog_prio; switch (level) { @@ -183,21 +213,9 @@ tdm_log_print(int level, const char *fmt, ...) __dlog_vprint(LOG_ID_SYSTEM, dlog_prio, LOG_TAG, fmt, arg); va_end(arg); } else { - char *lvl_str[] = {"TDM_NON", "TDM_ERR", "TDM_WRN", "TDM_INF", "TDM_DBG"}; - char *color[] = {COLOR_RESET, COLOR_RED, COLOR_YELLOW, COLOR_GREEN, COLOR_RESET}; - - pthread_mutex_lock(&log_lock); - - if (color_enable) - printf("%s", color[level]); - printf("[%s]", lvl_str[level]); - if (color_enable) - printf(COLOR_RESET); va_start(arg, fmt); - vprintf(fmt, arg); + _tdm_log_vprint_stdout(level, fmt, arg); va_end(arg); - printf("\n"); - pthread_mutex_unlock(&log_lock); } assert(level > assert_level); diff --git a/include/tdm_log.h b/include/tdm_log.h index 5a9fb65..e25f685 100644 --- a/include/tdm_log.h +++ b/include/tdm_log.h @@ -69,7 +69,9 @@ void tdm_log_enable_dlog(unsigned int enable); void tdm_log_set_debug_level(int level); void tdm_log_set_assert_level(int level); void tdm_log_set_path(const char *path); +void tdm_log_print_stdout(int level, const char *fmt, ...); void tdm_log_print(int level, const char *fmt, ...); + void tdm_log_reset(void); extern unsigned int tdm_log_debug_level; -- 2.7.4 From a1cca1d19c5d26aa9dfad12d88a27d0e16cdb606 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 7 Mar 2018 10:19:25 +0900 Subject: [PATCH 04/16] backend: add checking mandatory functions Change-Id: Ib9262959482250f95e43f7016ece3bc96581dce6 --- src/tdm.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/tdm.c b/src/tdm.c index b904755..fca53dd 100644 --- a/src/tdm.c +++ b/src/tdm.c @@ -728,10 +728,20 @@ _tdm_display_check_backend_functions(tdm_private_module *private_module) /* below functions should be implemented in backend side */ TDM_RETURN_VAL_IF_FAIL(func_display != NULL, TDM_ERROR_BAD_MODULE); + TDM_RETURN_VAL_IF_FAIL(func_display->display_get_capability, TDM_ERROR_BAD_MODULE); TDM_RETURN_VAL_IF_FAIL(func_display->display_get_outputs, TDM_ERROR_BAD_MODULE); TDM_RETURN_VAL_IF_FAIL(func_output->output_get_capability, TDM_ERROR_BAD_MODULE); TDM_RETURN_VAL_IF_FAIL(func_output->output_get_layers, TDM_ERROR_BAD_MODULE); + TDM_RETURN_VAL_IF_FAIL(func_output->output_wait_vblank, TDM_ERROR_BAD_MODULE); + TDM_RETURN_VAL_IF_FAIL(func_output->output_set_vblank_handler, TDM_ERROR_BAD_MODULE); + TDM_RETURN_VAL_IF_FAIL(func_output->output_commit, TDM_ERROR_BAD_MODULE); + TDM_RETURN_VAL_IF_FAIL(func_output->output_set_commit_handler, TDM_ERROR_BAD_MODULE); + TDM_RETURN_VAL_IF_FAIL(func_output->output_set_mode, TDM_ERROR_BAD_MODULE); TDM_RETURN_VAL_IF_FAIL(func_layer->layer_get_capability, TDM_ERROR_BAD_MODULE); + TDM_RETURN_VAL_IF_FAIL(func_layer->layer_set_info, TDM_ERROR_BAD_MODULE); + TDM_RETURN_VAL_IF_FAIL(func_layer->layer_get_info, TDM_ERROR_BAD_MODULE); + TDM_RETURN_VAL_IF_FAIL(func_layer->layer_set_buffer, TDM_ERROR_BAD_MODULE); + TDM_RETURN_VAL_IF_FAIL(func_layer->layer_unset_buffer, TDM_ERROR_BAD_MODULE); ret = func_display->display_get_capability(private_module->bdata, &private_module->caps_display); if (ret != TDM_ERROR_NONE) { -- 2.7.4 From 6fff5569f6cd0ff43969a6a57ba841db6afabb92 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 7 Mar 2018 10:20:54 +0900 Subject: [PATCH 05/16] output: correct buffer leak when calling tdm_output_commit without a handler Change-Id: I032d556d6cab02d5bed3076e91fe57ed745a6bd3 --- src/tdm_layer.c | 31 +++++++++++++++---------------- src/tdm_output.c | 3 +++ src/tdm_private.h | 2 ++ 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/tdm_layer.c b/src/tdm_layer.c index f37a948..b36f37f 100644 --- a/src/tdm_layer.c +++ b/src/tdm_layer.c @@ -71,7 +71,6 @@ private_output = private_layer->private_output; \ private_display = private_output->private_display -static void _tdm_layer_free_buffer(tdm_private_layer *private_layer, tdm_private_layer_buffer *layer_buffer); static void _tdm_layer_cb_wait_vblank(tdm_vblank *vblank, tdm_error error, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data); static void _tbm_layer_queue_acquirable_cb(tbm_surface_queue_h surface_queue, void *data); @@ -347,8 +346,8 @@ _tdm_layer_dump_buffer(tdm_layer *layer, tbm_surface_h buffer) } /* LCOV_EXCL_STOP */ -static void -_tdm_layer_free_buffer(tdm_private_layer *private_layer, tdm_private_layer_buffer *layer_buffer) +void +tdm_layer_free_buffer(tdm_private_layer *private_layer, tdm_private_layer_buffer *layer_buffer) { tdm_private_display *private_display; @@ -380,7 +379,7 @@ _tdm_layer_free_all_buffers(tdm_private_layer *private_layer) _tdm_layer_reset_pending_data(private_layer); if (private_layer->waiting_buffer) { - _tdm_layer_free_buffer(private_layer, private_layer->waiting_buffer); + tdm_layer_free_buffer(private_layer, private_layer->waiting_buffer); private_layer->waiting_buffer = NULL; if (tdm_debug_module & TDM_DEBUG_BUFFER) @@ -389,7 +388,7 @@ _tdm_layer_free_all_buffers(tdm_private_layer *private_layer) } if (private_layer->committed_buffer) { - _tdm_layer_free_buffer(private_layer, private_layer->committed_buffer); + tdm_layer_free_buffer(private_layer, private_layer->committed_buffer); private_layer->committed_buffer = NULL; if (tdm_debug_module & TDM_DEBUG_BUFFER) @@ -398,7 +397,7 @@ _tdm_layer_free_all_buffers(tdm_private_layer *private_layer) } if (private_layer->showing_buffer) { - _tdm_layer_free_buffer(private_layer, private_layer->showing_buffer); + tdm_layer_free_buffer(private_layer, private_layer->showing_buffer); private_layer->showing_buffer = NULL; if (tdm_debug_module & TDM_DEBUG_BUFFER) @@ -416,7 +415,7 @@ _tdm_layer_free_all_buffers(tdm_private_layer *private_layer) LIST_FOR_EACH_ENTRY_SAFE(lm, lmm, &clone_list, link) { LIST_DEL(&lm->link); tdm_output_remove_commit_handler_internal(private_output, _tdm_layer_cb_output_commit, lm); - _tdm_layer_free_buffer(private_layer, lm->committed_buffer); + tdm_layer_free_buffer(private_layer, lm->committed_buffer); free(lm); } @@ -429,7 +428,7 @@ _tdm_layer_free_all_buffers(tdm_private_layer *private_layer) LIST_FOR_EACH_ENTRY_SAFE(lm, lmm, &clone_list, link) { LIST_DEL(&lm->link); - _tdm_layer_free_buffer(private_layer, lm->committed_buffer); + tdm_layer_free_buffer(private_layer, lm->committed_buffer); free(lm); } @@ -598,7 +597,7 @@ tdm_layer_committed(tdm_private_layer *private_layer, tdm_private_layer_buffer * TDM_TRACE_ASYNC_END((intptr_t)private_layer, "[LAYER] %d", tbm_bo_export(bo)); } - _tdm_layer_free_buffer(private_layer, private_layer->showing_buffer); + tdm_layer_free_buffer(private_layer, private_layer->showing_buffer); } private_layer->showing_buffer = *committed_buffer; @@ -650,7 +649,7 @@ _tdm_layer_got_output_vblank(tdm_private_output *private_output, unsigned int se lm->func(lm->private_layer, sequence, tv_sec, tv_usec, lm->user_data); _pthread_mutex_lock(&private_display->lock); if (lm->committed_buffer) - _tdm_layer_free_buffer(lm->private_layer, lm->committed_buffer); + tdm_layer_free_buffer(lm->private_layer, lm->committed_buffer); free(lm); } @@ -704,7 +703,7 @@ wait_failed: if (lm->func) lm->func(lm->private_layer, sequence, tv_sec, tv_usec, lm->user_data); _pthread_mutex_lock(&private_display->lock); - _tdm_layer_free_buffer(lm->private_layer, lm->committed_buffer); + tdm_layer_free_buffer(lm->private_layer, lm->committed_buffer); free(lm); } @@ -876,7 +875,7 @@ tdm_layer_commit_pending_data(tdm_private_layer *private_layer) if (ret == TDM_ERROR_NONE) { if (private_layer->waiting_buffer) - _tdm_layer_free_buffer(private_layer, private_layer->waiting_buffer); + tdm_layer_free_buffer(private_layer, private_layer->waiting_buffer); private_layer->waiting_buffer = layer_buffer; private_layer->waiting_buffer->buffer = tdm_buffer_ref_backend(private_layer->pending_buffer); @@ -884,7 +883,7 @@ tdm_layer_commit_pending_data(tdm_private_layer *private_layer) TDM_INFO("layer(%p) waiting_buffer(%p)", private_layer, private_layer->waiting_buffer->buffer); } else - _tdm_layer_free_buffer(private_layer, layer_buffer); + tdm_layer_free_buffer(private_layer, layer_buffer); } done: @@ -1070,7 +1069,7 @@ tdm_layer_remove_commit_handler_internal(tdm_layer *layer, tdm_layer_commit_hand if (lm->func == func && lm->user_data == user_data) { LIST_DEL(&lm->link); tdm_output_remove_commit_handler_internal(private_output, _tdm_layer_cb_output_commit, lm); - _tdm_layer_free_buffer(private_layer, lm->committed_buffer); + tdm_layer_free_buffer(private_layer, lm->committed_buffer); free(lm); break; } @@ -1080,7 +1079,7 @@ tdm_layer_remove_commit_handler_internal(tdm_layer *layer, tdm_layer_commit_hand if (lm->func == func && lm->user_data == user_data) { LIST_DEL(&lm->link); tdm_output_remove_commit_handler_internal(private_output, _tdm_layer_cb_output_commit, lm); - _tdm_layer_free_buffer(private_layer, lm->committed_buffer); + tdm_layer_free_buffer(private_layer, lm->committed_buffer); free(lm); break; } @@ -1223,7 +1222,7 @@ tdm_layer_set_buffer_queue(tdm_layer *layer, tbm_surface_queue_h buffer_queue) } if (private_layer->waiting_buffer) { - _tdm_layer_free_buffer(private_layer, private_layer->waiting_buffer); + tdm_layer_free_buffer(private_layer, private_layer->waiting_buffer); private_layer->waiting_buffer = NULL; if (tdm_debug_module & TDM_DEBUG_BUFFER) diff --git a/src/tdm_output.c b/src/tdm_output.c index f208dfe..03dcd45 100644 --- a/src/tdm_output.c +++ b/src/tdm_output.c @@ -1129,6 +1129,9 @@ tdm_output_commit_internal(tdm_output *output, int sync, tdm_output_commit_handl if (!private_layer->waiting_buffer) continue; + if (private_layer->committed_buffer) + tdm_layer_free_buffer(private_layer, private_layer->committed_buffer); + private_layer->committed_buffer = private_layer->waiting_buffer; private_layer->waiting_buffer = NULL; if (tdm_debug_module & TDM_DEBUG_BUFFER) diff --git a/src/tdm_private.h b/src/tdm_private.h index 4cb34e4..43c639c 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -147,6 +147,8 @@ tdm_error tdm_layer_set_buffer_internal(tdm_private_layer *private_layer, tbm_surface_h buffer); tdm_error tdm_layer_unset_buffer_internal(tdm_private_layer *private_layer); +void +tdm_layer_free_buffer(tdm_private_layer *private_layer, tdm_private_layer_buffer *layer_buffer); tdm_error tdm_vblank_init(tdm_display *dpy); -- 2.7.4 From 182bd92fc2e8a7b9e908a28283adcc600c64c875 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 7 Mar 2018 10:21:19 +0900 Subject: [PATCH 06/16] output: add tdm_output_has_capture_capability Change-Id: Ida5763d36449c1bb7c2734e63bdbf25eb4b0d90b --- include/tdm.h | 9 +++++++++ src/tdm_output.c | 25 +++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/include/tdm.h b/include/tdm.h index 19d30ba..bc1f0ef 100644 --- a/include/tdm.h +++ b/include/tdm.h @@ -548,6 +548,15 @@ tdm_error tdm_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value); /** + * @brief Check if a output object has the capture capability + * @param[in] output A output object + * @param[out] has_capability 1: has the capability, 0: not has the capability + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ +tdm_error +tdm_output_has_capture_capability(tdm_output *output, unsigned int *has_capability); + +/** * @brief Create a capture object of a output object * @param[in] output A output object * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. diff --git a/src/tdm_output.c b/src/tdm_output.c index 03dcd45..15ebd81 100644 --- a/src/tdm_output.c +++ b/src/tdm_output.c @@ -1473,6 +1473,31 @@ tdm_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value) return ret; } +EXTERN tdm_error +tdm_output_has_capture_capability(tdm_output *output, unsigned int *has_capability) +{ + tdm_private_module *private_module; + + OUTPUT_FUNC_ENTRY(); + + TDM_RETURN_VAL_IF_FAIL(has_capability != NULL, TDM_ERROR_INVALID_PARAMETER); + + _pthread_mutex_lock(&private_display->lock); + + private_module = private_output->private_module; + + if (!(private_module->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) + *has_capability = 0; + else if (!(private_module->caps_capture.capabilities & TDM_CAPTURE_CAPABILITY_OUTPUT)) + *has_capability = 0; + else + *has_capability = 1; + + _pthread_mutex_unlock(&private_display->lock); + + return ret; +} + EXTERN tdm_capture * tdm_output_create_capture(tdm_output *output, tdm_error *error) { -- 2.7.4 From 988dbaba7a2c25420eafa70734e22e1c49057686 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 7 Mar 2018 10:14:55 +0900 Subject: [PATCH 07/16] utests: correct pointer type Change-Id: I557633d3d01b90c00005b8e1b51df0e2afc485d7 --- utests/src/ut_tdm_layer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utests/src/ut_tdm_layer.cpp b/utests/src/ut_tdm_layer.cpp index a0713be..5b8042a 100644 --- a/utests/src/ut_tdm_layer.cpp +++ b/utests/src/ut_tdm_layer.cpp @@ -75,7 +75,7 @@ void TDMLayer::SetUp(void) ASSERT_TRUE(count > 0); layer_count += count; - layers = (tdm_layer**)realloc((void*)layers, sizeof(tdm_layer*) * layer_count); + layers = (tdm_layer**)realloc(layers, sizeof(tdm_layer*) * layer_count); ASSERT_TRUE(layers != NULL); for (int l = 0; l < count; l++) { -- 2.7.4 From 77461541c237f97f3b45a5db816fc8759d25aa75 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 7 Mar 2018 11:29:11 +0900 Subject: [PATCH 08/16] package version up to 1.16.0 Change-Id: I4c0c3ba7a7e7fc5ca7b8d618bc873e4d61df53dd --- configure.ac | 2 +- doc/tdm_doc.h | 2 +- packaging/libtdm.spec | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 04bf549..1829d04 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ AC_PREREQ([2.60]) m4_define([tdm_major_version], [1]) -m4_define([tdm_minor_version], [15]) +m4_define([tdm_minor_version], [16]) m4_define([tdm_micro_version], [0]) m4_define([tdm_version], [tdm_major_version.tdm_minor_version.tdm_micro_version]) diff --git a/doc/tdm_doc.h b/doc/tdm_doc.h index d11256f..b7e3529 100644 --- a/doc/tdm_doc.h +++ b/doc/tdm_doc.h @@ -39,7 +39,7 @@ /** * @mainpage TDM * @author Boram Park, boram1288.park@samsung.com - * @version 1.15.0 + * @version 1.16.0 * @par Introduction * TDM stands for Tizen Display Manager. It's the display HAL layer for tizen * display server. It offers the frontend APIs(@ref tdm.h) for a frontend user diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index 9ca1257..2abebe3 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -2,7 +2,7 @@ %define UTEST_GCOV 0 Name: libtdm -Version: 1.15.1 +Version: 1.16.0 Release: 0 Summary: User Library of Tizen Display Manager Group: Development/Libraries -- 2.7.4 From a5be69dc815078b1132eb3291d56cd7ddb85a412 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Thu, 8 Mar 2018 15:39:18 +0900 Subject: [PATCH 09/16] output: add debugging log Change-Id: I0dd4ef4067e18706257619a1cfb2f6dea79f0657 --- src/tdm_output.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tdm_output.c b/src/tdm_output.c index 15ebd81..b846354 100644 --- a/src/tdm_output.c +++ b/src/tdm_output.c @@ -766,6 +766,9 @@ _tdm_output_cb_vblank(tdm_output *output_backend, unsigned int sequence, vblank_handler->sent_to_frontend = 1; + if (tdm_debug_module & TDM_DEBUG_COMMIT) + TDM_INFO("output(%d) wait_vblank: handler(%p)", vblank_handler->private_output->pipe, vblank_handler); + ret = tdm_thread_cb_call(vblank_handler->private_output, &output_vblank.base); TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); } -- 2.7.4 From 1ffe57e554823b255a379390e220eac050417e5a Mon Sep 17 00:00:00 2001 From: Boram Park Date: Thu, 8 Mar 2018 15:39:37 +0900 Subject: [PATCH 10/16] utests: add more tc Change-Id: I304f08c9f390acdfd4a7935be4a404afaa6e6c63 --- utests/src/ut_tdm_output.cpp | 22 ++++++++++++++++++++++ utests/src/ut_tdm_vblank.cpp | 27 +++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/utests/src/ut_tdm_output.cpp b/utests/src/ut_tdm_output.cpp index 4556178..e543a55 100644 --- a/utests/src/ut_tdm_output.cpp +++ b/utests/src/ut_tdm_output.cpp @@ -1334,6 +1334,28 @@ TEST_P(TDMOutput, OutputWaitVblankFewTimesInOneVblank) } } +TEST_P(TDMOutput, OutputWaitVblankBeforeDpmsOff) +{ + TDM_UT_SKIP_FLAG(has_outputs); + + for (int o = 0; o < output_count; o++) { + if (!ut_tdm_output_is_connected(outputs[o])) + continue; + + ASSERT_TRUE(ut_tdm_output_prepare(dpy, outputs[o]) == true); + + for (int t = 0; t < 10; t++) { + bool done = false; + + ASSERT_TRUE(tdm_output_wait_vblank(outputs[o], 1, 0, _ut_tdm_output_done_cb, &done) == TDM_ERROR_NONE); + if (t == 9) + ASSERT_TRUE(tdm_output_set_dpms(outputs[o], TDM_OUTPUT_DPMS_OFF) == TDM_ERROR_NONE); + while(!done) + ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE); + } + } +} + TEST_P(TDMOutput, OutputRemoveVblankHandler) { TDM_UT_SKIP_FLAG(has_outputs); diff --git a/utests/src/ut_tdm_vblank.cpp b/utests/src/ut_tdm_vblank.cpp index a4d9f8b..3b3e8e3 100644 --- a/utests/src/ut_tdm_vblank.cpp +++ b/utests/src/ut_tdm_vblank.cpp @@ -1126,6 +1126,33 @@ TEST_P(TDMVblank, VblankWaitDpmsOff) } } +TEST_P(TDMVblank, VblankWaitBeforeDpmsOff) +{ + TDM_UT_SKIP_FLAG(has_outputs); + + ASSERT_TRUE(TestPrepareOutput() == true); + ASSERT_TRUE(TestCreateVblanks() == true); + + for (int v = 0; v < vblank_count; v++) { + unsigned int temp = 0; + tdm_error ret; + tdm_output *output = tdm_vblank_get_output(vblanks[v], &ret); + ASSERT_TRUE(ret == TDM_ERROR_NONE); + + if (!ut_tdm_output_is_connected(output)) + continue; + + ASSERT_TRUE(ut_tdm_output_unset(dpy, output) == true); + + ASSERT_TRUE(tdm_vblank_wait(vblanks[v], 0, 0, 1, _ut_tdm_vblank_cb, &temp) == TDM_ERROR_NONE); + + ASSERT_TRUE(tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF) == TDM_ERROR_NONE); + + while (temp == 0) + ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE); + } +} + TEST_P(TDMVblank, VblankWaitSetEnableFakeDpmsOff) { TDM_UT_SKIP_FLAG(has_outputs); -- 2.7.4 From 7941cfbc65a4abcdc1e9c45716e0561348b0ed2a Mon Sep 17 00:00:00 2001 From: Boram Park Date: Thu, 8 Mar 2018 21:35:07 +0900 Subject: [PATCH 11/16] thread: checking waiting cb_type if waiting_cb_type != cb_type->type, send cb to other thread if needed. when a thread is waiting status, if other thread tries to send the same type cb as sync, we CAN'T handle it. So we'd better make assert it to find another solution. Change-Id: I06f92b2814a3a4e0d23d9d6df3c8b17526e1175f --- src/tdm_thread.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/tdm_thread.c b/src/tdm_thread.c index db910c2..ca59103 100644 --- a/src/tdm_thread.c +++ b/src/tdm_thread.c @@ -613,6 +613,7 @@ tdm_thread_cb_call(void *object, tdm_thread_cb_base *cb_base) struct list_head *list, *other_list; struct list_head call_list; static pid_t waiting_tid = 0; + static tdm_thread_cb_type waiting_cb_type = TDM_THREAD_CB_NONE; tdm_error ret; TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED); @@ -626,6 +627,10 @@ tdm_thread_cb_call(void *object, tdm_thread_cb_base *cb_base) assert(find_funcs[cb_base->type] != NULL); + /* When there is the previous waiting sync call, the other type sync call CAN't be handlered */ + if (waiting_tid > 0 && cb_base->sync == 1) + assert(waiting_cb_type == cb_base->type); + if (!object) { object = find_funcs[cb_base->type](private_display, cb_base->object_stamp); if (!object) { @@ -670,7 +675,7 @@ tdm_thread_cb_call(void *object, tdm_thread_cb_base *cb_base) assert(LIST_IS_EMPTY(&call_list)); - if (waiting_tid == 0) { + if (waiting_tid == 0 || waiting_cb_type != cb_base->type) { LIST_FOR_EACH_ENTRY_SAFE(cb, hh, other_list, link) { if (cb->object != object || cb->cb_type != cb_base->type || @@ -686,6 +691,7 @@ tdm_thread_cb_call(void *object, tdm_thread_cb_base *cb_base) if (keep_private_thread) { if (cb_base->sync) { waiting_tid = 0; + waiting_cb_type = TDM_THREAD_CB_NONE; pthread_cond_signal(&keep_private_thread->event_cond); if (tdm_debug_module & TDM_DEBUG_THREAD) TDM_INFO("pthread broadcase"); @@ -712,6 +718,8 @@ tdm_thread_cb_call(void *object, tdm_thread_cb_base *cb_base) */ tdm_mutex_locked = 0; waiting_tid = caller_tid; + waiting_cb_type = cb_base->type; + pthread_cond_wait(&keep_private_thread->event_cond, &private_display->lock); tdm_mutex_locked = 1; } -- 2.7.4 From 11b7cf91cd5f44d381bab1e6d5659b9da261a82a Mon Sep 17 00:00:00 2001 From: Boram Park Date: Thu, 8 Mar 2018 21:41:20 +0900 Subject: [PATCH 12/16] package version up to 1.16.1 Change-Id: I2ce18aa2791e733216d174f791cf190fe6d486f1 --- packaging/libtdm.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index 2abebe3..62b46e8 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -2,7 +2,7 @@ %define UTEST_GCOV 0 Name: libtdm -Version: 1.16.0 +Version: 1.16.1 Release: 0 Summary: User Library of Tizen Display Manager Group: Development/Libraries -- 2.7.4 From dd84f199e0e855ca945bae239c152fa22147af53 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 12 Mar 2018 17:13:03 +0900 Subject: [PATCH 13/16] output: seperate output-status and output-dpms change Change-Id: I0fabb65405347dab1f8604827df00be274410091 --- src/tdm.c | 3 +- src/tdm_macro.h | 3 +- src/tdm_output.c | 98 ++++++++++++++++++++++++++++++++++--------------- src/tdm_private_types.h | 16 +++++--- src/tdm_thread.c | 13 ++++--- 5 files changed, 91 insertions(+), 42 deletions(-) diff --git a/src/tdm.c b/src/tdm.c index fca53dd..7d80016 100644 --- a/src/tdm.c +++ b/src/tdm.c @@ -194,7 +194,8 @@ _tdm_display_destroy_private_output(tdm_private_output *private_output) LIST_FOR_EACH_ENTRY_SAFE(h, hh, &private_output->change_handler_list, link) { LIST_DEL(&h->link); - tdm_thread_cb_remove(h->private_output, TDM_THREAD_CB_OUTPUT_CHANGE, NULL, tdm_output_thread_cb_change, h); + tdm_thread_cb_remove(h->private_output, TDM_THREAD_CB_OUTPUT_DPMS, NULL, tdm_output_thread_cb_change, h); + tdm_thread_cb_remove(h->private_output, TDM_THREAD_CB_OUTPUT_STATUS, NULL, tdm_output_thread_cb_change, h); free(h); } diff --git a/src/tdm_macro.h b/src/tdm_macro.h index e681337..80be131 100644 --- a/src/tdm_macro.h +++ b/src/tdm_macro.h @@ -244,7 +244,8 @@ static struct tdm_type_name tdm_cb_type_names[] = { { TDM_THREAD_CB_NONE, "none" }, { TDM_THREAD_CB_OUTPUT_COMMIT, "output-commit" }, { TDM_THREAD_CB_OUTPUT_VBLANK, "output-vblank" }, - { TDM_THREAD_CB_OUTPUT_CHANGE, "output-change" }, + { TDM_THREAD_CB_OUTPUT_STATUS, "output-status" }, + { TDM_THREAD_CB_OUTPUT_DPMS, "output-dpms" }, { TDM_THREAD_CB_PP_DONE, "pp-done" }, { TDM_THREAD_CB_CAPTURE_DONE, "capture-done" }, { TDM_THREAD_CB_VBLANK_SW, "vblank-sw" }, diff --git a/src/tdm_output.c b/src/tdm_output.c index b846354..e6eed12 100644 --- a/src/tdm_output.c +++ b/src/tdm_output.c @@ -146,7 +146,9 @@ tdm_output_init(tdm_private_display *private_display) { tdm_thread_cb_set_find_func(TDM_THREAD_CB_OUTPUT_COMMIT, tdm_display_find_output_stamp); tdm_thread_cb_set_find_func(TDM_THREAD_CB_OUTPUT_VBLANK, tdm_display_find_output_stamp); - tdm_thread_cb_set_find_func(TDM_THREAD_CB_OUTPUT_CHANGE, tdm_display_find_output_stamp); + tdm_thread_cb_set_find_func(TDM_THREAD_CB_OUTPUT_STATUS, tdm_display_find_output_stamp); + tdm_thread_cb_set_find_func(TDM_THREAD_CB_OUTPUT_DPMS, tdm_display_find_output_stamp); + return TDM_ERROR_NONE; } @@ -226,34 +228,68 @@ INTERN void tdm_output_thread_cb_change(tdm_private_display *private_display, void *object, tdm_thread_cb_base *cb_base, void *user_data) { tdm_private_output *private_output = object; - tdm_thread_cb_output_change *output_change = (tdm_thread_cb_output_change *)cb_base; tdm_private_output_change_handler *change_handler = user_data; + tdm_output_change_type type = TDM_OUTPUT_CHANGE_CONNECTION; + tdm_value value = {.u32 = 0 }; TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED()); assert(change_handler->owner_tid == syscall(SYS_gettid)); + if (cb_base->type == TDM_THREAD_CB_OUTPUT_STATUS) { + tdm_thread_cb_output_status *output_status = (tdm_thread_cb_output_status *)cb_base; + type = TDM_OUTPUT_CHANGE_CONNECTION; + value.u32 = output_status->status; + } else if (cb_base->type == TDM_THREAD_CB_OUTPUT_DPMS) { + tdm_thread_cb_output_dpms *output_dpms = (tdm_thread_cb_output_dpms *)cb_base; + type = TDM_OUTPUT_CHANGE_DPMS; + value.u32 = output_dpms->dpms; + } else { + TDM_NEVER_GET_HERE(); + return; + } + _pthread_mutex_unlock(&private_display->lock); - change_handler->func(private_output, output_change->type, output_change->value, change_handler->user_data); + change_handler->func(private_output, type, value, change_handler->user_data); _pthread_mutex_lock(&private_display->lock); + } static tdm_error -_tdm_output_call_thread_cb_change(tdm_private_output *private_output, tdm_output_change_type type, tdm_value value) +_tdm_output_call_thread_cb_status(tdm_private_output *private_output, tdm_output_conn_status status) { - tdm_thread_cb_output_change output_change; + tdm_thread_cb_output_status output_status; tdm_error ret; - memset(&output_change, 0, sizeof output_change); - output_change.base.type = TDM_THREAD_CB_OUTPUT_CHANGE; - output_change.base.length = sizeof output_change; - output_change.base.object_stamp = private_output->stamp; - output_change.base.data = NULL; - output_change.base.sync = 1; - output_change.type = type; - output_change.value = value; + memset(&output_status, 0, sizeof output_status); + output_status.base.type = TDM_THREAD_CB_OUTPUT_STATUS; + output_status.base.length = sizeof output_status; + output_status.base.object_stamp = private_output->stamp; + output_status.base.data = NULL; + output_status.base.sync = 1; + output_status.status = status; - ret = tdm_thread_cb_call(private_output, &output_change.base); + ret = tdm_thread_cb_call(private_output, &output_status.base); + TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); + + return TDM_ERROR_NONE; +} + +static tdm_error +_tdm_output_call_thread_cb_dpms(tdm_private_output *private_output, tdm_output_dpms dpms) +{ + tdm_thread_cb_output_dpms output_dpms; + tdm_error ret; + + memset(&output_dpms, 0, sizeof output_dpms); + output_dpms.base.type = TDM_THREAD_CB_OUTPUT_DPMS; + output_dpms.base.length = sizeof output_dpms; + output_dpms.base.object_stamp = private_output->stamp; + output_dpms.base.data = NULL; + output_dpms.base.sync = 0; + output_dpms.dpms = dpms; + + ret = tdm_thread_cb_call(private_output, &output_dpms.base); TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); return TDM_ERROR_NONE; @@ -263,7 +299,6 @@ INTERN void tdm_output_cb_status(tdm_output *output_backend, tdm_output_conn_status status, void *user_data) { tdm_private_output *private_output = user_data; - tdm_value value; tdm_error ret; TDM_RETURN_IF_FAIL(private_output); @@ -278,9 +313,7 @@ tdm_output_cb_status(tdm_output *output_backend, tdm_output_conn_status status, private_output->caps.status = status; } - value.u32 = status; - - ret = _tdm_output_call_thread_cb_change(private_output, TDM_OUTPUT_CHANGE_CONNECTION, value); + ret = _tdm_output_call_thread_cb_status(private_output, status); TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); } @@ -288,7 +321,6 @@ INTERN void tdm_output_cb_dpms(tdm_output *output_backend, tdm_output_dpms dpms, void *user_data) { tdm_private_output *private_output = user_data; - tdm_value value; tdm_error ret; TDM_INFO("output(%d) %s", private_output->pipe, tdm_status_str(dpms)); @@ -297,9 +329,7 @@ tdm_output_cb_dpms(tdm_output *output_backend, tdm_output_dpms dpms, void *user_ private_output->waiting_dpms_change = 0; TDM_INFO("output(%d) dpms async '%s' done", private_output->pipe, tdm_dpms_str(dpms)); - value.u32 = dpms; - - ret = _tdm_output_call_thread_cb_change(private_output, TDM_OUTPUT_CHANGE_DPMS, value); + ret = _tdm_output_call_thread_cb_dpms(private_output, dpms); TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); } @@ -332,10 +362,21 @@ tdm_output_add_change_handler(tdm_output *output, /* LCOV_EXCL_STOP */ } - ret = tdm_thread_cb_add(private_output, TDM_THREAD_CB_OUTPUT_CHANGE, NULL, tdm_output_thread_cb_change, change_handler); + ret = tdm_thread_cb_add(private_output, TDM_THREAD_CB_OUTPUT_DPMS, NULL, tdm_output_thread_cb_change, change_handler); + if (ret != TDM_ERROR_NONE) { + /* LCOV_EXCL_START */ + TDM_ERR("tdm_thread_cb_add failed"); + free(change_handler); + _pthread_mutex_unlock(&private_display->lock); + return TDM_ERROR_OPERATION_FAILED; + /* LCOV_EXCL_STOP */ + } + + ret = tdm_thread_cb_add(private_output, TDM_THREAD_CB_OUTPUT_STATUS, NULL, tdm_output_thread_cb_change, change_handler); if (ret != TDM_ERROR_NONE) { /* LCOV_EXCL_START */ TDM_ERR("tdm_thread_cb_add failed"); + tdm_thread_cb_remove(private_output, TDM_THREAD_CB_OUTPUT_DPMS, NULL, tdm_output_thread_cb_change, change_handler); free(change_handler); _pthread_mutex_unlock(&private_display->lock); return TDM_ERROR_OPERATION_FAILED; @@ -375,7 +416,8 @@ tdm_output_remove_change_handler(tdm_output *output, if (change_handler->func != func || change_handler->user_data != user_data) continue; - tdm_thread_cb_remove(private_output, TDM_THREAD_CB_OUTPUT_CHANGE, NULL, tdm_output_thread_cb_change, change_handler); + tdm_thread_cb_remove(private_output, TDM_THREAD_CB_OUTPUT_DPMS, NULL, tdm_output_thread_cb_change, change_handler); + tdm_thread_cb_remove(private_output, TDM_THREAD_CB_OUTPUT_STATUS, NULL, tdm_output_thread_cb_change, change_handler); LIST_DEL(&change_handler->link); free(change_handler); @@ -1304,10 +1346,8 @@ tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value) done: if (ret == TDM_ERROR_NONE) { if (private_output->current_dpms_value != dpms_value) { - tdm_value value; private_output->current_dpms_value = dpms_value; - value.u32 = dpms_value; - _tdm_output_call_thread_cb_change(private_output, TDM_OUTPUT_CHANGE_DPMS, value); + _tdm_output_call_thread_cb_dpms(private_output, dpms_value); TDM_INFO("output(%d) dpms '%s' done", private_output->pipe, tdm_dpms_str(dpms_value)); } } else { @@ -1448,13 +1488,11 @@ tdm_output_get_dpms_internal(tdm_output *output, tdm_output_dpms *dpms_value) /* checking with backend's value */ if (*dpms_value != private_output->current_dpms_value) { - tdm_value value; TDM_ERR("output(%d) dpms changed suddenly: %s -> %s", private_output->pipe, tdm_dpms_str(private_output->current_dpms_value), tdm_dpms_str(*dpms_value)); private_output->current_dpms_value = *dpms_value; - value.u32 = *dpms_value; - _tdm_output_call_thread_cb_change(private_output, TDM_OUTPUT_CHANGE_DPMS, value); + _tdm_output_call_thread_cb_dpms(private_output, *dpms_value); } return ret; diff --git a/src/tdm_private_types.h b/src/tdm_private_types.h index d1c132d..a5b4423 100644 --- a/src/tdm_private_types.h +++ b/src/tdm_private_types.h @@ -449,7 +449,8 @@ typedef enum { TDM_THREAD_CB_NONE, TDM_THREAD_CB_OUTPUT_COMMIT, TDM_THREAD_CB_OUTPUT_VBLANK, - TDM_THREAD_CB_OUTPUT_CHANGE, + TDM_THREAD_CB_OUTPUT_STATUS, + TDM_THREAD_CB_OUTPUT_DPMS, TDM_THREAD_CB_PP_DONE, TDM_THREAD_CB_CAPTURE_DONE, TDM_THREAD_CB_VBLANK_SW, @@ -461,7 +462,8 @@ typedef enum { typedef struct _tdm_thread_cb_base tdm_thread_cb_base; typedef struct _tdm_thread_cb_output_vblank tdm_thread_cb_output_commit; typedef struct _tdm_thread_cb_output_vblank tdm_thread_cb_output_vblank; -typedef struct _tdm_thread_cb_output_change tdm_thread_cb_output_change; +typedef struct _tdm_thread_cb_output_dpms tdm_thread_cb_output_dpms; +typedef struct _tdm_thread_cb_output_status tdm_thread_cb_output_status; typedef struct _tdm_thread_cb_pp_done tdm_thread_cb_pp_done; typedef struct _tdm_thread_cb_capture_done tdm_thread_cb_capture_done; typedef struct _tdm_thread_cb_vblank_sw tdm_thread_cb_vblank_sw; @@ -483,10 +485,14 @@ struct _tdm_thread_cb_output_vblank { unsigned int tv_usec; }; -struct _tdm_thread_cb_output_change { +struct _tdm_thread_cb_output_status { tdm_thread_cb_base base; - tdm_output_change_type type; - tdm_value value; + tdm_output_conn_status status; +}; + +struct _tdm_thread_cb_output_dpms { + tdm_thread_cb_base base; + tdm_output_dpms dpms; }; struct _tdm_thread_cb_pp_done { diff --git a/src/tdm_thread.c b/src/tdm_thread.c index ca59103..b183c59 100644 --- a/src/tdm_thread.c +++ b/src/tdm_thread.c @@ -437,7 +437,8 @@ tdm_thread_handle_cb(tdm_private_loop *private_loop) switch (base->type) { case TDM_THREAD_CB_OUTPUT_COMMIT: case TDM_THREAD_CB_OUTPUT_VBLANK: - case TDM_THREAD_CB_OUTPUT_CHANGE: + case TDM_THREAD_CB_OUTPUT_STATUS: + case TDM_THREAD_CB_OUTPUT_DPMS: case TDM_THREAD_CB_PP_DONE: case TDM_THREAD_CB_CAPTURE_DONE: case TDM_THREAD_CB_VBLANK_SW: @@ -620,16 +621,18 @@ tdm_thread_cb_call(void *object, tdm_thread_cb_base *cb_base) TDM_RETURN_VAL_IF_FAIL(cb_base != NULL, TDM_ERROR_INVALID_PARAMETER); TDM_RETURN_VAL_IF_FAIL(cb_base->type > 0, TDM_ERROR_INVALID_PARAMETER); TDM_RETURN_VAL_IF_FAIL(cb_base->length > 0, TDM_ERROR_INVALID_PARAMETER); - TDM_RETURN_VAL_IF_FAIL(cb_base->sync == 0 || cb_base->sync == 1, TDM_ERROR_INVALID_PARAMETER); TDM_RETURN_VAL_IF_FAIL(cb_base->object_stamp > 0, TDM_ERROR_INVALID_PARAMETER); caller_tid = syscall(SYS_gettid); assert(find_funcs[cb_base->type] != NULL); - /* When there is the previous waiting sync call, the other type sync call CAN't be handlered */ - if (waiting_tid > 0 && cb_base->sync == 1) - assert(waiting_cb_type == cb_base->type); + /* handling only output-status as sync */ + if (cb_base->type == TDM_THREAD_CB_OUTPUT_STATUS) { + TDM_RETURN_VAL_IF_FAIL(cb_base->sync == 1, TDM_ERROR_INVALID_PARAMETER); + } else { + TDM_RETURN_VAL_IF_FAIL(cb_base->sync == 0, TDM_ERROR_INVALID_PARAMETER); + } if (!object) { object = find_funcs[cb_base->type](private_display, cb_base->object_stamp); -- 2.7.4 From 352656cd6d668485334def211527f1c817a3317a Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 12 Mar 2018 17:42:25 +0900 Subject: [PATCH 14/16] package version up to 1.16.2 Change-Id: Id92045c2da6777f7efd18dfb7d05caca73b4d04e --- packaging/libtdm.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index 62b46e8..e90f82c 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -2,7 +2,7 @@ %define UTEST_GCOV 0 Name: libtdm -Version: 1.16.1 +Version: 1.16.2 Release: 0 Summary: User Library of Tizen Display Manager Group: Development/Libraries -- 2.7.4 From 1832b50e8e4186f8be0cd04c5f3c6bc7d2e260e4 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 13 Mar 2018 12:12:00 +0900 Subject: [PATCH 15/16] layer: add a missed callback Change-Id: Ia7b2b6a467a1ef7531e5f4be51f58f559c8ae97a --- src/tdm_layer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tdm_layer.c b/src/tdm_layer.c index b36f37f..df7693a 100644 --- a/src/tdm_layer.c +++ b/src/tdm_layer.c @@ -946,7 +946,7 @@ _tdm_layer_commit(tdm_layer *layer, tdm_layer_commit_handler func, void *user_da if (_tdm_layer_commit_possible(private_layer)) { /* add to layer_commit_handler_list */ LIST_ADDTAIL(&layer_commit_handler->link, &private_output->layer_commit_handler_list); - ret = tdm_output_commit_internal(private_layer->private_output, 0, NULL, NULL); + ret = tdm_output_commit_internal(private_layer->private_output, 0, _tdm_layer_cb_output_commit, layer_commit_handler); TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, commit_failed); if (tdm_debug_module & TDM_DEBUG_COMMIT) -- 2.7.4 From a87e1609d7c2be6fafbfba39fd930adcc0d23491 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 13 Mar 2018 12:12:24 +0900 Subject: [PATCH 16/16] output: add thread_cb even if func is null Change-Id: I64eb5588a02ef5d351e9e7debaf7faf00b40f558 --- src/tdm_output.c | 52 +++++++++++++++++++++++++--------------------------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/src/tdm_output.c b/src/tdm_output.c index e6eed12..652e262 100644 --- a/src/tdm_output.c +++ b/src/tdm_output.c @@ -1129,35 +1129,33 @@ tdm_output_commit_internal(tdm_output *output, int sync, tdm_output_commit_handl TDM_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret); if (!TDM_OUTPUT_DPMS_VSYNC_IS_OFF(dpms_value)) { - if (func) { - if (!private_output->regist_commit_cb) { - private_output->regist_commit_cb = 1; - ret = func_output->output_set_commit_handler(private_output->output_backend, _tdm_output_cb_commit); - TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, commit_failed); - } - - output_commit_handler = calloc(1, sizeof(tdm_private_output_commit_handler)); - if (!output_commit_handler) { - /* LCOV_EXCL_START */ - TDM_ERR("failed: alloc memory"); - return TDM_ERROR_OUT_OF_MEMORY; - /* LCOV_EXCL_STOP */ - } - - ret = tdm_thread_cb_add(private_output, TDM_THREAD_CB_OUTPUT_COMMIT, output_commit_handler, _tdm_output_thread_cb_commit, NULL); - if (ret != TDM_ERROR_NONE) { - TDM_ERR("tdm_thread_cb_add failed"); - free(output_commit_handler); - return ret; - } - - LIST_ADDTAIL(&output_commit_handler->link, &private_output->output_commit_handler_list); - output_commit_handler->private_output = private_output; - output_commit_handler->func = func; - output_commit_handler->user_data = user_data; - output_commit_handler->owner_tid = syscall(SYS_gettid); + if (!private_output->regist_commit_cb) { + private_output->regist_commit_cb = 1; + ret = func_output->output_set_commit_handler(private_output->output_backend, _tdm_output_cb_commit); + TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, commit_failed); } + output_commit_handler = calloc(1, sizeof(tdm_private_output_commit_handler)); + if (!output_commit_handler) { + /* LCOV_EXCL_START */ + TDM_ERR("failed: alloc memory"); + return TDM_ERROR_OUT_OF_MEMORY; + /* LCOV_EXCL_STOP */ + } + + ret = tdm_thread_cb_add(private_output, TDM_THREAD_CB_OUTPUT_COMMIT, output_commit_handler, _tdm_output_thread_cb_commit, NULL); + if (ret != TDM_ERROR_NONE) { + TDM_ERR("tdm_thread_cb_add failed"); + free(output_commit_handler); + return ret; + } + + LIST_ADDTAIL(&output_commit_handler->link, &private_output->output_commit_handler_list); + output_commit_handler->private_output = private_output; + output_commit_handler->func = func; + output_commit_handler->user_data = user_data; + output_commit_handler->owner_tid = syscall(SYS_gettid); + ret = func_output->output_commit(private_output->output_backend, sync, output_commit_handler); TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, commit_failed); -- 2.7.4