From be04ecdb64268497ae8cf66c8e04ae9e3faeb7b3 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 28 Nov 2017 17:04:54 +0900 Subject: [PATCH] dpms: update current_dpms_value if failed to set Change-Id: I3de160985a6631c058d0e0fac59bcad673abd43e --- src/tdm_output.c | 104 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 64 insertions(+), 40 deletions(-) diff --git a/src/tdm_output.c b/src/tdm_output.c index 34fb0c6..2e0b705 100644 --- a/src/tdm_output.c +++ b/src/tdm_output.c @@ -1114,6 +1114,45 @@ _tdm_output_dpms_changed_timeout(void *user_data) return TDM_ERROR_NONE; } +static tdm_error +tdm_output_call_dpms_change_handler(tdm_output *output) +{ + tdm_private_output *private_output = (tdm_private_output*)output; + tdm_value value; + + /** Use timer to call the output change callback of the sub-thread. + * The output change callback of tdm_server and tdm_vblank was called + * in the main thread. And it made the multi thread issue. If we use + * the timer, we can call the sub-thread's output change callback in + * sub-thread. + */ + if (!private_output->dpms_changed_timer) { + private_output->dpms_changed_timer = + tdm_event_loop_add_timer_handler(private_output->private_display, + _tdm_output_dpms_changed_timeout, private_output, NULL); + if (!private_output->dpms_changed_timer) { + /* LCOV_EXCL_START */ + TDM_ERR("can't create dpms timer!!"); + return TDM_ERROR_OUT_OF_MEMORY; + /* LCOV_EXCL_STOP */ + } + } + + value.u32 = private_output->current_dpms_value; + tdm_output_call_change_handler_internal(private_output, + &private_output->change_handler_list_main, + TDM_OUTPUT_CHANGE_DPMS, + value, 0); + + if (!LIST_IS_EMPTY(&private_output->change_handler_list_sub)) { + tdm_error ret = tdm_event_loop_source_timer_update(private_output->dpms_changed_timer, 1); + if (ret != TDM_ERROR_NONE) + TDM_NEVER_GET_HERE(); + } + + return TDM_ERROR_NONE; +} + /* LCOV_EXCL_START */ INTERN void tdm_output_cb_dpms(tdm_output *output_backend, tdm_output_dpms dpms, void *user_data) @@ -1181,25 +1220,6 @@ tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value) return TDM_ERROR_BAD_REQUEST; } - /** Use timer to call the output change callback of the sub-thread. - * The output change callback of tdm_server and tdm_vblank was called - * in the main thread. And it made the multi thread issue. If we use - * the timer, we can call the sub-thread's output change callback in - * sub-thread. - */ - if (!private_output->dpms_changed_timer) { - private_output->dpms_changed_timer = - tdm_event_loop_add_timer_handler(private_output->private_display, - _tdm_output_dpms_changed_timeout, private_output, NULL); - if (!private_output->dpms_changed_timer) { - /* LCOV_EXCL_START */ - TDM_ERR("can't create dpms timer!!"); - _pthread_mutex_unlock(&private_display->lock); - return TDM_ERROR_OUT_OF_MEMORY; - /* LCOV_EXCL_STOP */ - } - } - func_output = &private_display->func_output; TDM_INFO("output(%d) dpms '%s'", private_output->pipe, tdm_dpms_str(dpms_value)); @@ -1216,22 +1236,18 @@ tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value) done: if (ret == TDM_ERROR_NONE) { - tdm_value value; - - private_output->current_dpms_value = dpms_value; - TDM_INFO("output(%d) dpms '%s' done", private_output->pipe, tdm_dpms_str(dpms_value)); + if (private_output->current_dpms_value != dpms_value) { + private_output->current_dpms_value = dpms_value; + TDM_INFO("output(%d) dpms '%s' done", private_output->pipe, tdm_dpms_str(dpms_value)); + tdm_output_call_dpms_change_handler(output); + } + } else { + tdm_output_dpms temp = TDM_OUTPUT_DPMS_OFF; - value.u32 = dpms_value; - tdm_output_call_change_handler_internal(private_output, - &private_output->change_handler_list_main, - TDM_OUTPUT_CHANGE_DPMS, - value, 0); + /* update current_dpms_value forcely */ + tdm_output_get_dpms_internal(output, &temp); - if (!LIST_IS_EMPTY(&private_output->change_handler_list_sub)) { - ret = tdm_event_loop_source_timer_update(private_output->dpms_changed_timer, 1); - if (ret != TDM_ERROR_NONE) - TDM_NEVER_GET_HERE(); - } + TDM_ERR("output(%d) set_dpms failed: dpms '%s'", private_output->pipe, tdm_dpms_str(temp)); } _pthread_mutex_unlock(&private_display->lock); @@ -1293,6 +1309,13 @@ tdm_output_set_dpms_async(tdm_output *output, tdm_output_dpms dpms_value) if (ret == TDM_ERROR_NONE) { private_output->waiting_dpms_change = 1; TDM_INFO("output(%d) dpms async '%s' waiting", private_output->pipe, tdm_dpms_str(dpms_value)); + } else { + tdm_output_dpms temp = TDM_OUTPUT_DPMS_OFF; + + /* update current_dpms_value forcely */ + tdm_output_get_dpms_internal(output, &temp); + + TDM_ERR("output(%d) set_dpms_async failed: dpms '%s'", private_output->pipe, tdm_dpms_str(temp)); } _pthread_mutex_unlock(&private_display->lock); @@ -1337,13 +1360,14 @@ tdm_output_get_dpms_internal(tdm_output *output, tdm_output_dpms *dpms_value) /* LCOV_EXCL_STOP */ } - /* TODO: this is ugly. But we have to check if all backends's DPMS operation has no problem. */ - if (private_output->commit_per_vblank) - if (*dpms_value != private_output->current_dpms_value) { - private_output->current_dpms_value = *dpms_value; - TDM_ERR("output(%d) dpms changed suddenly: %s", - private_output->pipe, tdm_dpms_str(*dpms_value)); - } + /* checking with backend's value */ + if (*dpms_value != private_output->current_dpms_value) { + TDM_ERR("output(%d) dpms changed suddenly: %s -> %s", + private_output->pipe, private_output->current_dpms_value, + tdm_dpms_str(*dpms_value)); + private_output->current_dpms_value = *dpms_value; + tdm_output_call_dpms_change_handler(output); + } return ret; } -- 2.7.4