From acfa6e7e5c2ac270c7f67c8c0a0364379db28e26 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Sat, 4 Mar 2017 23:07:12 +0900 Subject: [PATCH 01/16] output: use tdm_output_get_dpms_internal to get the DPMS value. To make sure that the backend's output_get_dpms is called inside of a function because it can change the current_dpms_value variable. Change-Id: I207213776aa90033c2e03068ef86ff7d1986ce31 --- src/tdm_output.c | 44 +++++++++++++++++++++++--------------------- src/tdm_private.h | 3 +++ 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/src/tdm_output.c b/src/tdm_output.c index 1eaaae7..6b83f36 100644 --- a/src/tdm_output.c +++ b/src/tdm_output.c @@ -816,20 +816,7 @@ tdm_output_commit_internal(tdm_output *output, int sync, tdm_output_commit_handl return TDM_ERROR_NOT_IMPLEMENTED; } - if (!func_output->output_get_dpms) { - dpms_value = private_output->current_dpms_value; - } else { - ret = func_output->output_get_dpms(private_output->output_backend, &dpms_value); - if (ret != TDM_ERROR_NONE) { - TDM_ERR("output_get_dpms failed"); - dpms_value = TDM_OUTPUT_DPMS_OFF; - } - - if (dpms_value != private_output->current_dpms_value) { - private_output->current_dpms_value = dpms_value; - TDM_WRN("current_dpms_value changed: %s", tdm_dpms_str(dpms_value)); - } - } + tdm_output_get_dpms_internal(output, &dpms_value); if (dpms_value == TDM_OUTPUT_DPMS_ON) { if (func) { @@ -1111,32 +1098,47 @@ tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value) return ret; } -EXTERN tdm_error -tdm_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value) +INTERN tdm_error +tdm_output_get_dpms_internal(tdm_output *output, tdm_output_dpms *dpms_value) { tdm_func_output *func_output; OUTPUT_FUNC_ENTRY(); - TDM_RETURN_VAL_IF_FAIL(dpms_value != NULL, TDM_ERROR_INVALID_PARAMETER); - - _pthread_mutex_lock(&private_display->lock); + TDM_RETURN_VAL_IF_FAIL(private_output != NULL, TDM_ERROR_INVALID_PARAMETER); func_output = &private_display->func_output; if (!func_output->output_get_dpms) { *dpms_value = private_output->current_dpms_value; - _pthread_mutex_unlock(&private_display->lock); TDM_WRN("not implemented!!"); return TDM_ERROR_NONE; } ret = func_output->output_get_dpms(private_output->output_backend, dpms_value); + if (ret != TDM_ERROR_NONE) { + TDM_ERR("output_get_dpms failed"); + *dpms_value = TDM_OUTPUT_DPMS_OFF; + } if (*dpms_value != private_output->current_dpms_value) { private_output->current_dpms_value = *dpms_value; - TDM_WRN("current_dpms_value changed: %s", tdm_dpms_str(*dpms_value)); + TDM_ERR("output(%d) dpms changed suddenly: %s", private_output->pipe, tdm_dpms_str(*dpms_value)); } + return ret; +} + +EXTERN tdm_error +tdm_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value) +{ + OUTPUT_FUNC_ENTRY(); + + TDM_RETURN_VAL_IF_FAIL(dpms_value != NULL, TDM_ERROR_INVALID_PARAMETER); + + _pthread_mutex_lock(&private_display->lock); + + ret = tdm_output_get_dpms_internal(output, dpms_value); + _pthread_mutex_unlock(&private_display->lock); return ret; diff --git a/src/tdm_private.h b/src/tdm_private.h index 8279903..eb5e531 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -424,6 +424,9 @@ tdm_output_wait_vblank_add_front(tdm_output *output, int interval, int sync, tdm_output_vblank_handler func, void *user_data); tdm_error tdm_output_commit_internal(tdm_output *output, int sync, tdm_output_commit_handler func, void *user_data); +tdm_error +tdm_output_get_dpms_internal(tdm_output *output, tdm_output_dpms *dpms_value); + void tdm_layer_committed(tdm_private_layer *private_layer, tdm_private_layer_buffer **committed_buffer); -- 2.7.4 From 7bb3c48979d29544276b671b545b2a9b593ff1c0 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Sat, 4 Mar 2017 23:09:47 +0900 Subject: [PATCH 02/16] layer: call the layer commit handlers once tdm_layer_commit returns success Once _tdm_layer_commit returns success, the layer commit handler MUST be called always. That is, even if we get error in _tdm_layer_got_output_vblank() function for some reasons, the layer commit handler MUST be called. Change-Id: Ia251061c965a9dec89ed655266bb23667a097e5e --- src/tdm_layer.c | 37 ++++++++++++++++++++++++++++++------- src/tdm_output.c | 3 +++ 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/src/tdm_layer.c b/src/tdm_layer.c index d677f16..f127664 100644 --- a/src/tdm_layer.c +++ b/src/tdm_layer.c @@ -568,13 +568,15 @@ _tdm_layer_got_output_vblank(tdm_private_output *private_output, unsigned int se if (tdm_debug_module & TDM_DEBUG_COMMIT) TDM_INFO("layer commit: output(%d) commit", private_output->pipe); - /* tdm_vblank APIs is for server. it should be called in unlock status*/ - if (!private_output->layer_waiting_vblank) { - _pthread_mutex_unlock(&private_display->lock); - ret = tdm_vblank_wait(private_output->vblank, 0, 0, 1, _tdm_layer_cb_wait_vblank, private_output); - _pthread_mutex_lock(&private_display->lock); - TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, wait_failed); - private_output->layer_waiting_vblank = 1; + if (private_output->current_dpms_value == TDM_OUTPUT_DPMS_ON) { + /* tdm_vblank APIs is for server. it should be called in unlock status*/ + if (!private_output->layer_waiting_vblank) { + _pthread_mutex_unlock(&private_display->lock); + ret = tdm_vblank_wait(private_output->vblank, 0, 0, 1, _tdm_layer_cb_wait_vblank, private_output); + _pthread_mutex_lock(&private_display->lock); + TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, wait_failed); + private_output->layer_waiting_vblank = 1; + } } if (tdm_debug_module & TDM_DEBUG_COMMIT) @@ -585,13 +587,30 @@ _tdm_layer_got_output_vblank(tdm_private_output *private_output, unsigned int se LIST_ADDTAIL(&lm->link, &private_output->layer_commit_handler_list); } + if (private_output->current_dpms_value != TDM_OUTPUT_DPMS_ON) { + TDM_WRN("TDM_OUTPUT_DPMS_OFF. Directly call vblank callback."); + _pthread_mutex_unlock(&private_display->lock); + _tdm_layer_cb_wait_vblank(private_output->vblank, 0, 0, 0, 0, private_output); + _pthread_mutex_lock(&private_display->lock); + } + return; wait_failed: + /* CAUTION: Once _tdm_layer_commit returns success, the layer commit handler MUST be called always. + * That is, even if we get error in _tdm_layer_got_output_vblank() function for some reasons, + * the layer commit handler MUST be called. + */ LIST_FOR_EACH_ENTRY_SAFE(lm, lmm, &pending_clone_list, link) { + TDM_WRN("Directly call layer commit handlers: ret(%d)\n", ret); LIST_DEL(&lm->link); + _pthread_mutex_unlock(&private_display->lock); + 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); free(lm); } + return; } @@ -699,6 +718,10 @@ _tdm_layer_commit_possible(tdm_private_layer *private_layer) return 0; } +/* CAUTION: Once _tdm_layer_commit returns success, the layer commit handler MUST be called always. + * That is, even if we get error in _tdm_layer_got_output_vblank() function for some reasons, + * the layer commit handler MUST be called. + */ static tdm_error _tdm_layer_commit(tdm_layer *layer, tdm_layer_commit_handler func, void *user_data) { diff --git a/src/tdm_output.c b/src/tdm_output.c index 6b83f36..7654873 100644 --- a/src/tdm_output.c +++ b/src/tdm_output.c @@ -849,6 +849,9 @@ tdm_output_commit_internal(tdm_output *output, int sync, tdm_output_commit_handl private_output->pipe, output_commit_handler, func, user_data); } + /* Even if DPMS is off, committed_buffer should be changed because it will be referred + * for tdm_layer_committed() function. + */ LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) { if (!private_layer->waiting_buffer) continue; -- 2.7.4 From 0948d93638eac4dc6909704c3255cebf6af4ac45 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Sat, 4 Mar 2017 23:11:09 +0900 Subject: [PATCH 03/16] log: enhance debugging log for DPMS change Change-Id: I77ad1ebcc5b9f2b6434970446d429cdd26640fe5 --- src/tdm_output.c | 8 ++++++++ src/tdm_vblank.c | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/tdm_output.c b/src/tdm_output.c index 7654873..1b85566 100644 --- a/src/tdm_output.c +++ b/src/tdm_output.c @@ -144,6 +144,8 @@ tdm_output_cb_status(tdm_output *output_backend, tdm_output_conn_status status, tdm_thread_cb_output_status output_status; tdm_error ret; + TDM_INFO("output(%d) %s", private_output->pipe, tdm_status_str(status)); + _tdm_output_update(output_backend, user_data); output_status.base.type = TDM_THREAD_CB_OUTPUT_STATUS; @@ -164,6 +166,8 @@ tdm_output_cb_status(tdm_output *output_backend, tdm_output_conn_status status, return; } + TDM_INFO("output(%d) %s", private_output->pipe, tdm_status_str(status)); + if (!tdm_thread_is_running()) _tdm_output_update(output_backend, user_data); @@ -1014,6 +1018,8 @@ tdm_output_cb_dpms(tdm_output *output_backend, tdm_output_dpms dpms, void *user_ private_output->current_dpms_value = dpms; + TDM_INFO("output(%d) dpms %s", private_output->pipe, tdm_dpms_str(dpms)); + value.u32 = dpms; tdm_output_call_change_handler_internal(private_output, &private_output->change_handler_list_main, @@ -1059,6 +1065,7 @@ tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value) if (!func_output->output_set_dpms) { _pthread_mutex_unlock(&private_display->lock); private_output->current_dpms_value = dpms_value; + TDM_INFO("output(%d) dpms %s", private_output->pipe, tdm_dpms_str(dpms_value)); TDM_WRN("not implemented!!"); return TDM_ERROR_NONE; } @@ -1082,6 +1089,7 @@ tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value) tdm_value value; private_output->current_dpms_value = dpms_value; + TDM_INFO("output(%d) dpms %s", private_output->pipe, tdm_dpms_str(dpms_value)); value.u32 = dpms_value; tdm_output_call_change_handler_internal(private_output, diff --git a/src/tdm_vblank.c b/src/tdm_vblank.c index 1ecb5ca..d92e902 100644 --- a/src/tdm_vblank.c +++ b/src/tdm_vblank.c @@ -305,7 +305,7 @@ _tdm_vblank_cb_output_change(tdm_output *output, tdm_output_change_type type, case TDM_OUTPUT_CHANGE_DPMS: if (private_vblank->dpms == value.u32) break; - VIN("dpms %s", tdm_dpms_str(value.u32)); + VDB("dpms %s", tdm_dpms_str(value.u32)); private_vblank->dpms = value.u32; private_vblank->check_HW_or_SW = 1; if (private_vblank->dpms != TDM_OUTPUT_DPMS_ON) { @@ -316,7 +316,7 @@ _tdm_vblank_cb_output_change(tdm_output *output, tdm_output_change_type type, } break; case TDM_OUTPUT_CHANGE_CONNECTION: - VIN("output %s", tdm_status_str(value.u32)); + VDB("output %s", tdm_status_str(value.u32)); if (value.u32 == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) _tdm_vblank_free_HW_wait(private_vblank, 0, 0); break; -- 2.7.4 From 24548acabc4c9021a5a8c932a2d1f8c3525ebfb6 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 7 Mar 2017 16:56:25 +0900 Subject: [PATCH 04/16] output: support to remove the commit & vblank handler Change-Id: I36a569d4e6fdc018fb188444c3ca10f082c4c672 --- include/tdm.h | 20 +++++++++++++++++ src/tdm_output.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/tdm_private.h | 5 +++++ 3 files changed, 89 insertions(+) diff --git a/include/tdm.h b/include/tdm.h index 91cabef..3d17d4b 100644 --- a/include/tdm.h +++ b/include/tdm.h @@ -486,6 +486,26 @@ tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func, void *user_data); /** + * @brief Remove the user vblank handler + * @param[in] output A output object + * @param[in] func A user vblank handler + * @param[in] user_data The user data + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ +tdm_error +tdm_output_remove_vblank_handler(tdm_output *output, tdm_output_vblank_handler func, void *user_data); + +/** + * @brief Remove the user commit handler + * @param[in] output A output object + * @param[in] func A user commit handler + * @param[in] user_data The user data + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ +tdm_error +tdm_output_remove_commit_handler(tdm_output *output, tdm_output_commit_handler func, void *user_data); + +/** * @brief Set one of available modes of a output object * @param[in] output A output object * @param[in] mode A output mode diff --git a/src/tdm_output.c b/src/tdm_output.c index 1b85566..cb5045c 100644 --- a/src/tdm_output.c +++ b/src/tdm_output.c @@ -803,6 +803,70 @@ tdm_output_wait_vblank_add_front(tdm_output *output, int interval, int sync, return ret; } +INTERN void +tdm_output_remove_vblank_handler_internal(tdm_output *output, tdm_output_vblank_handler func, void *user_data) +{ + tdm_private_output *private_output = (tdm_private_output*)output; + tdm_private_vblank_handler *v = NULL; + + TDM_RETURN_IF_FAIL(private_output != NULL); + + LIST_FOR_EACH_ENTRY(v, &private_output->vblank_handler_list, link) { + if (v->func == func && v->user_data == user_data) { + /* only set func & user_data to NULL. It will be freed when an event occurs */ + v->func = NULL; + v->user_data = NULL; + break; + } + } +} + +INTERN void +tdm_output_remove_commit_handler_internal(tdm_output *output, tdm_output_commit_handler func, void *user_data) +{ + tdm_private_output *private_output = (tdm_private_output*)output; + tdm_private_output_commit_handler *c = NULL; + + TDM_RETURN_IF_FAIL(private_output != NULL); + + LIST_FOR_EACH_ENTRY(c, &private_output->output_commit_handler_list, link) { + if (c->func == func && c->user_data == user_data) { + /* only set func & user_data to NULL. It will be freed when an event occurs */ + c->func = NULL; + c->user_data = NULL; + break; + } + } +} + +EXTERN tdm_error +tdm_output_remove_vblank_handler(tdm_output *output, tdm_output_vblank_handler func, void *user_data) +{ + OUTPUT_FUNC_ENTRY(); + + _pthread_mutex_lock(&private_display->lock); + + tdm_output_remove_vblank_handler_internal(output, func, user_data); + + _pthread_mutex_unlock(&private_display->lock); + + return ret; +} + +EXTERN tdm_error +tdm_output_remove_commit_handler(tdm_output *output, tdm_output_commit_handler func, void *user_data) +{ + OUTPUT_FUNC_ENTRY(); + + _pthread_mutex_lock(&private_display->lock); + + tdm_output_remove_commit_handler_internal(output, func, user_data); + + _pthread_mutex_unlock(&private_display->lock); + + return ret; +} + INTERN tdm_error tdm_output_commit_internal(tdm_output *output, int sync, tdm_output_commit_handler func, void *user_data) { diff --git a/src/tdm_private.h b/src/tdm_private.h index eb5e531..13e0610 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -428,6 +428,11 @@ tdm_error tdm_output_get_dpms_internal(tdm_output *output, tdm_output_dpms *dpms_value); void +tdm_output_remove_vblank_handler_internal(tdm_output *output, tdm_output_vblank_handler func, void *user_data); +void +tdm_output_remove_commit_handler_internal(tdm_output *output, tdm_output_commit_handler func, void *user_data); + +void tdm_layer_committed(tdm_private_layer *private_layer, tdm_private_layer_buffer **committed_buffer); void -- 2.7.4 From 6f772b6c6e723f4de301ce363c1b63c3abeaf1b4 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 7 Mar 2017 17:36:43 +0900 Subject: [PATCH 05/16] vblank: remove the vblank handler when wait_info freed If not removed, it makes the crash when the vblank handler is called for the freed wait_info. Change-Id: I07b168da39d1ff9f4e5effe69b99dd249d976027 --- src/tdm_vblank.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/tdm_vblank.c b/src/tdm_vblank.c index d92e902..662204f 100644 --- a/src/tdm_vblank.c +++ b/src/tdm_vblank.c @@ -146,6 +146,9 @@ static double stamp = 0; static tdm_error _tdm_vblank_cb_vblank_SW(void *user_data); static tdm_error _tdm_vblank_wait_SW(tdm_vblank_wait_info *wait_info); +static void _tdm_vblank_cb_vblank_HW(tdm_output *output, unsigned int sequence, + unsigned int tv_sec, unsigned int tv_usec, + void *user_data); #if 0 static void @@ -206,7 +209,7 @@ _tdm_vblank_check_valid_wait(tdm_vblank_wait_info *wait_info) pthread_mutex_lock(&valid_list_lock); LIST_FOR_EACH_ENTRY(w, &valid_wait_list, valid_link) { - if (w->stamp == wait_info->stamp) { + if (w == wait_info) { pthread_mutex_unlock(&valid_list_lock); return 1; } @@ -272,6 +275,7 @@ _tdm_vblank_change_to_SW(tdm_private_vblank *private_vblank) LIST_FOR_EACH_ENTRY_SAFE(w, ww, &private_vblank->HW_wait_list, link) { LIST_DEL(&w->link); + tdm_output_remove_vblank_handler_internal(private_vblank->output, _tdm_vblank_cb_vblank_HW, w); w->type = VBLANK_TYPE_SW_FAKE; _tdm_vblank_wait_SW(w); } @@ -285,6 +289,7 @@ _tdm_vblank_free_HW_wait(tdm_private_vblank *private_vblank, tdm_error error, un LIST_FOR_EACH_ENTRY_SAFE(w, ww, &private_vblank->HW_wait_list, link) { LIST_DEL(&w->link); _tdm_vblank_valid_list_del(&w->valid_link); + tdm_output_remove_vblank_handler_internal(private_vblank->output, _tdm_vblank_cb_vblank_HW, w); if (call_cb && w->func) w->func(private_vblank, error, 0, 0, 0, w->user_data); @@ -1015,6 +1020,7 @@ tdm_vblank_wait(tdm_vblank *vblank, unsigned int req_sec, unsigned int req_usec, if (ret != TDM_ERROR_NONE) { LIST_DEL(&wait_info->link); _tdm_vblank_valid_list_del(&wait_info->valid_link); + tdm_output_remove_vblank_handler_internal(private_vblank->output, _tdm_vblank_cb_vblank_HW, wait_info); free(wait_info); return ret; } -- 2.7.4 From 9e2fe2dcabf0e4be9d434a88d022134a9fe679db Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 7 Mar 2017 17:49:33 +0900 Subject: [PATCH 06/16] package version up to 1.6.9 Change-Id: Ic0b49e444558d4fb643a765af7ddc1bc274c4b80 --- packaging/libtdm.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index f2f21dd..2288105 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -1,7 +1,7 @@ %bcond_with utest Name: libtdm -Version: 1.6.8 +Version: 1.6.9 Release: 0 Summary: User Library of Tizen Display Manager Group: Development/Libraries -- 2.7.4 From c56f34834a7b26e39b78f8495df66833d121a42e Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 7 Mar 2017 18:42:31 +0900 Subject: [PATCH 07/16] layer: remove the commit handler when all resource are freed Change-Id: I0f8afee8189a806cf4014faace4c09cdde8d51f1 --- src/tdm_layer.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tdm_layer.c b/src/tdm_layer.c index f127664..070e485 100644 --- a/src/tdm_layer.c +++ b/src/tdm_layer.c @@ -79,6 +79,8 @@ static void _tdm_layer_cb_wait_vblank(tdm_vblank *vblank, tdm_error error, unsig 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); static void _tbm_layer_queue_destroy_cb(tbm_surface_queue_h surface_queue, void *data); +static void _tdm_layer_cb_output_commit(tdm_output *output, unsigned int sequence, + unsigned int tv_sec, unsigned int tv_usec, void *user_data); EXTERN tdm_error tdm_layer_get_capabilities(tdm_layer *layer, tdm_layer_capability *capabilities) @@ -359,6 +361,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); free(lm); } -- 2.7.4 From a2d43b6b32d6246ec71bb611a69fbe0031196c89 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 7 Mar 2017 18:43:18 +0900 Subject: [PATCH 08/16] layer: support to remove the commit handler Change-Id: I732e0ffbe44b47d195fcec3ecbff3b2221e6de09 --- include/tdm.h | 10 ++++++++++ src/tdm_layer.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/tdm_private.h | 2 ++ 3 files changed, 56 insertions(+) diff --git a/include/tdm.h b/include/tdm.h index 3d17d4b..63700a7 100644 --- a/include/tdm.h +++ b/include/tdm.h @@ -686,6 +686,16 @@ tdm_error tdm_layer_is_committing(tdm_layer *layer, unsigned int *committing); /** + * @brief Remove the user commit handler + * @param[in] layer A layer object + * @param[in] func A user commit handler + * @param[in] user_data The user data + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ +tdm_error +tdm_layer_remove_commit_handler(tdm_layer *layer, tdm_layer_commit_handler func, void *user_data); + +/** * @brief Get a displaying TDM buffer from a layer object * @details A displaying TDM buffer is a current showing buffer on screen * that is set to layer object and applied output object of a layer object. diff --git a/src/tdm_layer.c b/src/tdm_layer.c index 070e485..a0ce0c0 100644 --- a/src/tdm_layer.c +++ b/src/tdm_layer.c @@ -862,6 +862,50 @@ tdm_layer_is_committing(tdm_layer *layer, unsigned int *committing) return ret; } +INTERN void +tdm_layer_remove_commit_handler_internal(tdm_layer *layer, tdm_layer_commit_handler func, void *user_data) +{ + tdm_private_layer *private_layer = (tdm_private_layer*)layer; + tdm_private_output *private_output = private_layer->private_output; + tdm_private_layer_commit_handler *lm = NULL, *lmm = NULL; + + TDM_RETURN_IF_FAIL(private_layer != NULL); + + LIST_FOR_EACH_ENTRY_SAFE(lm, lmm, &private_output->layer_commit_handler_list, link) { + 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); + free(lm); + break; + } + } + + LIST_FOR_EACH_ENTRY_SAFE(lm, lmm, &private_output->pending_commit_handler_list, link) { + 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); + free(lm); + break; + } + } +} + +EXTERN tdm_error +tdm_layer_remove_commit_handler(tdm_layer *layer, tdm_layer_commit_handler func, void *user_data) +{ + LAYER_FUNC_ENTRY(); + + _pthread_mutex_lock(&private_display->lock); + + tdm_layer_remove_commit_handler_internal(layer, func, user_data); + + _pthread_mutex_unlock(&private_display->lock); + + return ret; +} + EXTERN tbm_surface_h tdm_layer_get_displaying_buffer(tdm_layer *layer, tdm_error *error) { diff --git a/src/tdm_private.h b/src/tdm_private.h index 13e0610..2a92f24 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -431,6 +431,8 @@ void tdm_output_remove_vblank_handler_internal(tdm_output *output, tdm_output_vblank_handler func, void *user_data); void tdm_output_remove_commit_handler_internal(tdm_output *output, tdm_output_commit_handler func, void *user_data); +void +tdm_layer_remove_commit_handler_internal(tdm_layer *layer, tdm_layer_commit_handler func, void *user_data); void tdm_layer_committed(tdm_private_layer *private_layer, tdm_private_layer_buffer **committed_buffer); -- 2.7.4 From 2108f7ad1953a67bf9b8ed227d373734b411f33d Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 7 Mar 2017 19:57:11 +0900 Subject: [PATCH 09/16] package version up to 1.6.10 Change-Id: I3e0e98825a48f5ab2ac9d1ee1330e64beb3b3b56 --- packaging/libtdm.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index 2288105..3490e93 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -1,7 +1,7 @@ %bcond_with utest Name: libtdm -Version: 1.6.9 +Version: 1.6.10 Release: 0 Summary: User Library of Tizen Display Manager Group: Development/Libraries -- 2.7.4 From 250a7e4d9123f883d016b3f02a8e994b7056364e Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 8 Mar 2017 10:05:40 +0900 Subject: [PATCH 10/16] layer: init local variable Change-Id: I73bb6e3f2ae443b4d571395e13b5eae39d2d9c94 --- 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 a0ce0c0..9897c5c 100644 --- a/src/tdm_layer.c +++ b/src/tdm_layer.c @@ -523,7 +523,7 @@ _tdm_layer_got_output_vblank(tdm_private_output *private_output, unsigned int se tdm_private_layer_commit_handler *lm = NULL, *lmm = NULL; tdm_private_display *private_display; struct list_head clone_list, pending_clone_list; - tdm_error ret; + tdm_error ret = TDM_ERROR_NONE; private_display = private_output->private_display; -- 2.7.4 From eac85d37abc6cb4190e3fc8be70c10e7b9252b65 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 8 Mar 2017 17:48:37 +0900 Subject: [PATCH 11/16] output: don't call output_get_dpms in case of commit-per-vblank disabled Change-Id: I3e1b57d58b6a71586a247b7611dd592baa2ad73e --- src/tdm_output.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/tdm_output.c b/src/tdm_output.c index cb5045c..4fae5b0 100644 --- a/src/tdm_output.c +++ b/src/tdm_output.c @@ -884,7 +884,13 @@ tdm_output_commit_internal(tdm_output *output, int sync, tdm_output_commit_handl return TDM_ERROR_NOT_IMPLEMENTED; } - tdm_output_get_dpms_internal(output, &dpms_value); + /* TODO: this is ugly. But before using tdm_output_get_dpms_internal, we have + * to check if all backends's DPMS operation has no problem. + */ + if (private_display->commit_per_vblank) + tdm_output_get_dpms_internal(output, &dpms_value); + else + dpms_value = private_output->current_dpms_value; if (dpms_value == TDM_OUTPUT_DPMS_ON) { if (func) { -- 2.7.4 From 676eff0de1cf6f8d931a58e5f217747fae739b3a Mon Sep 17 00:00:00 2001 From: Boram Park Date: Thu, 9 Mar 2017 12:58:11 +0900 Subject: [PATCH 12/16] output: don't refresh current_dpms_value in case of commit-per-vblank disabled Change-Id: I76bef3fa002e1112faa3a1ad17a23d2dc5ea624e --- src/tdm_output.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/tdm_output.c b/src/tdm_output.c index 4fae5b0..62ba065 100644 --- a/src/tdm_output.c +++ b/src/tdm_output.c @@ -1201,10 +1201,13 @@ tdm_output_get_dpms_internal(tdm_output *output, tdm_output_dpms *dpms_value) *dpms_value = TDM_OUTPUT_DPMS_OFF; } - 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)); - } + /* TODO: this is ugly. But we have to check if all backends's DPMS operation has no problem. */ + if (private_display->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)); + } return ret; } -- 2.7.4 From df95f0935605e97ab39eb824042b267b9dbbc3da Mon Sep 17 00:00:00 2001 From: Boram Park Date: Thu, 9 Mar 2017 12:58:58 +0900 Subject: [PATCH 13/16] package version up to 1.6.11 Change-Id: I33a8efdb08ce79a280fc52476b3b7999f52c188c --- packaging/libtdm.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index 3490e93..c25bbea 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -1,7 +1,7 @@ %bcond_with utest Name: libtdm -Version: 1.6.10 +Version: 1.6.11 Release: 0 Summary: User Library of Tizen Display Manager Group: Development/Libraries -- 2.7.4 From 3b4c7ee3db7bd71ad143b1b518cb1740587bb010 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Thu, 9 Mar 2017 13:17:11 +0900 Subject: [PATCH 14/16] package version up to 1.6.12 to upload patch to server again Change-Id: I62aceb2224fa19e41849123d6ede17c0f4726f42 --- packaging/libtdm.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index c25bbea..80d8ac5 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -1,7 +1,7 @@ %bcond_with utest Name: libtdm -Version: 1.6.11 +Version: 1.6.12 Release: 0 Summary: User Library of Tizen Display Manager Group: Development/Libraries -- 2.7.4 From 4e56dc7fe08b6582fa5041c80196879aab43646d Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Wed, 22 Mar 2017 16:13:05 +0900 Subject: [PATCH 15/16] use %license macro to copy the COPYING file. Change-Id: I66b44ad1d92bf2db69cd7215ae16d5eca309e46e --- packaging/libtdm.spec | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index 80d8ac5..7debb4c 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -79,8 +79,6 @@ make -C ut check %install rm -rf %{buildroot} -mkdir -p %{buildroot}/%{TZ_SYS_RO_SHARE}/license -cp -af COPYING %{buildroot}/%{TZ_SYS_RO_SHARE}/license/%{name} %make_install %__mkdir_p %{buildroot}%{_unitdir} @@ -109,7 +107,7 @@ rm -f %{_unitdir_user}/basic.target.wants/tdm-socket-user.path %files %manifest %{name}.manifest %defattr(-,root,root,-) -%{TZ_SYS_RO_SHARE}/license/%{name} +%license COPYING %{_libdir}/libtdm.so.* %attr(750,root,root) %{_bindir}/tdm-monitor %{_unitdir}/tdm-socket.path @@ -136,7 +134,7 @@ rm -f %{_unitdir_user}/basic.target.wants/tdm-socket-user.path %files client %manifest %{name}.manifest %defattr(-,root,root,-) -%{TZ_SYS_RO_SHARE}/license/%{name} +%license COPYING %{_libdir}/libtdm-client.so.* %files client-devel -- 2.7.4 From 6d4a432c4b9b8a7047555bf8c217bc97be3f4db4 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Thu, 23 Mar 2017 15:51:33 +0900 Subject: [PATCH 16/16] event_loop: set the user func and data before calling wayland API. The user func can be called at the line of wl api by the backend implementation Change-Id: Idfc19afa17f584531ef37834c592f59f803d2823 --- src/tdm_event_loop.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/tdm_event_loop.c b/src/tdm_event_loop.c index 29a9763..a2cac7e 100644 --- a/src/tdm_event_loop.c +++ b/src/tdm_event_loop.c @@ -324,6 +324,10 @@ tdm_event_loop_add_fd_handler(tdm_display *dpy, int fd, tdm_event_loop_mask mask if (mask & TDM_EVENT_LOOP_WRITABLE) wl_mask |= WL_EVENT_WRITABLE; + fd_source->private_display = private_display; + fd_source->func = func; + fd_source->user_data = user_data; + fd_source->base.wl_source = wl_event_loop_add_fd(private_loop->wl_loop, fd, wl_mask, _tdm_event_loop_fd_func, fd_source); @@ -334,10 +338,6 @@ tdm_event_loop_add_fd_handler(tdm_display *dpy, int fd, tdm_event_loop_mask mask return NULL; } - fd_source->private_display = private_display; - fd_source->func = func; - fd_source->user_data = user_data; - if (error) *error = TDM_ERROR_NONE; @@ -411,6 +411,10 @@ tdm_event_loop_add_timer_handler(tdm_display *dpy, tdm_event_loop_timer_handler timer_source = calloc(1, sizeof(tdm_event_loop_source_timer)); TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(timer_source, TDM_ERROR_OUT_OF_MEMORY, NULL); + timer_source->private_display = private_display; + timer_source->func = func; + timer_source->user_data = user_data; + timer_source->base.wl_source = wl_event_loop_add_timer(private_loop->wl_loop, _tdm_event_loop_timer_func, timer_source); @@ -421,10 +425,6 @@ tdm_event_loop_add_timer_handler(tdm_display *dpy, tdm_event_loop_timer_handler return NULL; } - timer_source->private_display = private_display; - timer_source->func = func; - timer_source->user_data = user_data; - if (error) *error = TDM_ERROR_NONE; -- 2.7.4