From c2c4980b27f69239b3e7af5aa7102d652223a4f5 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 28 Nov 2017 11:08:49 +0900 Subject: [PATCH 01/16] dpms: add more description Change-Id: Ic8f325d92cdf57cac88f11e0436a378d238fb9c9 --- include/tdm_common.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/tdm_common.h b/include/tdm_common.h index 637d883..f353216 100644 --- a/include/tdm_common.h +++ b/include/tdm_common.h @@ -214,10 +214,10 @@ typedef enum { * @details bit compatible with the libdrm definitions. */ typedef enum { - TDM_OUTPUT_DPMS_ON, /**< On */ - TDM_OUTPUT_DPMS_STANDBY, /**< StandBy */ - TDM_OUTPUT_DPMS_SUSPEND, /**< Suspend */ - TDM_OUTPUT_DPMS_OFF, /**< Off */ + TDM_OUTPUT_DPMS_ON, /**< On, Vsync On */ + TDM_OUTPUT_DPMS_STANDBY, /**< StandBy, Vsync On */ + TDM_OUTPUT_DPMS_SUSPEND, /**< Suspend, Vsync Off */ + TDM_OUTPUT_DPMS_OFF, /**< Off, Vsync Off */ } tdm_output_dpms; /** -- 2.7.4 From 3bcc94eb47f4f3472cee98da566029d01129d1e5 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 28 Nov 2017 15:48:45 +0900 Subject: [PATCH 02/16] dpms: allow setting the same value twice Change-Id: I2a039987785c20cacb88be254ced2948cf23cbef --- src/tdm_output.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/tdm_output.c b/src/tdm_output.c index 7449637..34fb0c6 100644 --- a/src/tdm_output.c +++ b/src/tdm_output.c @@ -1181,11 +1181,6 @@ tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value) return TDM_ERROR_BAD_REQUEST; } - if (private_output->current_dpms_value == dpms_value) { - _pthread_mutex_unlock(&private_display->lock); - return TDM_ERROR_NONE; - } - /** 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 @@ -1267,11 +1262,6 @@ tdm_output_set_dpms_async(tdm_output *output, tdm_output_dpms dpms_value) return TDM_ERROR_BAD_REQUEST; } - if (private_output->current_dpms_value == dpms_value) { - _pthread_mutex_unlock(&private_display->lock); - return TDM_ERROR_NONE; - } - func_output = &private_display->func_output; if (!func_output->output_set_dpms_handler) { TDM_ERR("not implemented: output_set_dpms_handler"); -- 2.7.4 From be04ecdb64268497ae8cf66c8e04ae9e3faeb7b3 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 28 Nov 2017 17:04:54 +0900 Subject: [PATCH 03/16] 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 From 5ba1ef1e99fb076f54d6a92cd4997ab13c381835 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 28 Nov 2017 11:47:13 +0900 Subject: [PATCH 04/16] dpms: add macro to check dpms status Change-Id: I5b3f14d081203395c4fd7e781f216f4871a16bf6 --- client/tdm_client.c | 8 ++++---- src/tdm_capture.c | 4 +++- src/tdm_layer.c | 8 ++++---- src/tdm_macro.h | 6 ++++++ src/tdm_output.c | 18 ++++++------------ src/tdm_vblank.c | 8 ++++---- 6 files changed, 27 insertions(+), 25 deletions(-) diff --git a/client/tdm_client.c b/client/tdm_client.c index 3e9176a..6153187 100644 --- a/client/tdm_client.c +++ b/client/tdm_client.c @@ -906,8 +906,8 @@ tdm_client_vblank_wait(tdm_client_vblank *vblank, unsigned int interval, tdm_cli TDM_ERR("output disconnected"); return TDM_ERROR_OUTPUT_DISCONNECTED; } - if (private_output->dpms != TDM_OUTPUT_DPMS_ON) { - TDM_ERR("dpms off"); + if (TDM_OUTPUT_DPMS_VSYNC_IS_OFF(private_output->dpms)) { + TDM_ERR("dpms %s", tdm_dpms_str(private_output->dpms)); return TDM_ERROR_DPMS_OFF; } } @@ -999,8 +999,8 @@ tdm_client_vblank_wait_seq(tdm_client_vblank *vblank, unsigned int sequence, TDM_ERR("output disconnected"); return TDM_ERROR_OUTPUT_DISCONNECTED; } - if (private_output->dpms != TDM_OUTPUT_DPMS_ON) { - TDM_ERR("dpms off"); + if (TDM_OUTPUT_DPMS_VSYNC_IS_OFF(private_output->dpms)) { + TDM_ERR("dpms %s", tdm_dpms_str(private_output->dpms)); return TDM_ERROR_DPMS_OFF; } } diff --git a/src/tdm_capture.c b/src/tdm_capture.c index 751056b..bfb9e40 100644 --- a/src/tdm_capture.c +++ b/src/tdm_capture.c @@ -561,7 +561,9 @@ tdm_capture_commit(tdm_capture *capture) _pthread_mutex_lock(&private_display->lock); private_output = private_capture->private_output; - if (private_output->current_dpms_value > TDM_OUTPUT_DPMS_ON) { + + /* TODO: possible when standby mode? can't decide it yet. no scenario. */ + if (TDM_OUTPUT_DPMS_VSYNC_IS_OFF(private_output->current_dpms_value)) { TDM_ERR("output(%d) dpms: %s", private_output->pipe, tdm_dpms_str(private_output->current_dpms_value)); _pthread_mutex_unlock(&private_display->lock); diff --git a/src/tdm_layer.c b/src/tdm_layer.c index cca078e..5d3d1c9 100644 --- a/src/tdm_layer.c +++ b/src/tdm_layer.c @@ -595,7 +595,7 @@ _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); - if (private_output->current_dpms_value == TDM_OUTPUT_DPMS_ON) { + if (!TDM_OUTPUT_DPMS_VSYNC_IS_OFF(private_output->current_dpms_value)) { /* 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); @@ -614,8 +614,8 @@ _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."); + if (TDM_OUTPUT_DPMS_VSYNC_IS_OFF(private_output->current_dpms_value)) { + TDM_WRN("dpms %s. Directly call vblank callback.", tdm_dpms_str(private_output->current_dpms_value)); _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); @@ -934,7 +934,7 @@ tdm_layer_commit(tdm_layer *layer, tdm_layer_commit_handler func, void *user_dat private_output->commit_type = TDM_COMMIT_TYPE_LAYER; } - if (private_output->current_dpms_value > TDM_OUTPUT_DPMS_ON) { + if (TDM_OUTPUT_DPMS_VSYNC_IS_OFF(private_output->current_dpms_value)) { TDM_ERR("layer(%p)'s output(%d) dpms: %s", layer, private_output->pipe, tdm_dpms_str(private_output->current_dpms_value)); _pthread_mutex_unlock(&private_display->lock); diff --git a/src/tdm_macro.h b/src/tdm_macro.h index 504315a..775354e 100644 --- a/src/tdm_macro.h +++ b/src/tdm_macro.h @@ -159,6 +159,12 @@ extern "C" { #define TDM_SWAP(a, b) ({ int t; t = a; a = b; b = t; }) #define TDM_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) +/* can't export VSYNC macro because we can't define the exact meaning of vsync off + * at this time. Does committing in standy mode work? Doesn't committing in suspend mode work? + */ +#define TDM_OUTPUT_DPMS_VSYNC_OFF_MASK 0x2 +#define TDM_OUTPUT_DPMS_VSYNC_IS_OFF(dpms) ((dpms) & TDM_OUTPUT_DPMS_VSYNC_OFF_MASK) + struct tdm_type_name { int type; const char *name; diff --git a/src/tdm_output.c b/src/tdm_output.c index 2e0b705..42dfe87 100644 --- a/src/tdm_output.c +++ b/src/tdm_output.c @@ -814,7 +814,7 @@ tdm_output_wait_vblank(tdm_output *output, int interval, int sync, _pthread_mutex_lock(&private_display->lock); - if (private_output->current_dpms_value > TDM_OUTPUT_DPMS_ON) { + if (TDM_OUTPUT_DPMS_VSYNC_IS_OFF(private_output->current_dpms_value)) { TDM_WRN("output(%d) dpms: %s", private_output->pipe, tdm_dpms_str(private_output->current_dpms_value)); _pthread_mutex_unlock(&private_display->lock); @@ -837,7 +837,7 @@ tdm_output_wait_vblank_add_front(tdm_output *output, int interval, int sync, _pthread_mutex_lock(&private_display->lock); - if (private_output->current_dpms_value > TDM_OUTPUT_DPMS_ON) { + if (TDM_OUTPUT_DPMS_VSYNC_IS_OFF(private_output->current_dpms_value)) { TDM_WRN("output(%d) dpms: %s", private_output->pipe, tdm_dpms_str(private_output->current_dpms_value)); _pthread_mutex_unlock(&private_display->lock); @@ -940,7 +940,7 @@ tdm_output_commit_internal(tdm_output *output, int sync, tdm_output_commit_handl ret = tdm_output_get_dpms_internal(output, &dpms_value); TDM_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret); - if (dpms_value == TDM_OUTPUT_DPMS_ON) { + if (!TDM_OUTPUT_DPMS_VSYNC_IS_OFF(dpms_value)) { if (func) { if (!private_output->regist_commit_cb) { private_output->regist_commit_cb = 1; @@ -988,8 +988,8 @@ tdm_output_commit_internal(tdm_output *output, int sync, tdm_output_commit_handl private_layer->committed_buffer->buffer); } - if (dpms_value != TDM_OUTPUT_DPMS_ON) { - TDM_WRN("TDM_OUTPUT_DPMS_OFF. Directly call commit handler instead of commit."); + if (TDM_OUTPUT_DPMS_VSYNC_IS_OFF(dpms_value)) { + TDM_WRN("dpms %s. Directly call commit handler instead of commit.", tdm_dpms_str(dpms_value)); if (func) func(output, 0, 0, 0, user_data); } @@ -1030,7 +1030,7 @@ tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func, return TDM_ERROR_BAD_REQUEST; } - if (private_output->current_dpms_value > TDM_OUTPUT_DPMS_ON) { + if (TDM_OUTPUT_DPMS_VSYNC_IS_OFF(private_output->current_dpms_value)) { TDM_ERR("output(%d) dpms: %s", private_output->pipe, tdm_dpms_str(private_output->current_dpms_value)); _pthread_mutex_unlock(&private_display->lock); @@ -1209,9 +1209,6 @@ tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value) tdm_func_output *func_output; OUTPUT_FUNC_ENTRY(); - if (dpms_value > TDM_OUTPUT_DPMS_OFF) - dpms_value = TDM_OUTPUT_DPMS_OFF; - _pthread_mutex_lock(&private_display->lock); if (private_output->waiting_dpms_change) { @@ -1267,9 +1264,6 @@ tdm_output_set_dpms_async(tdm_output *output, tdm_output_dpms dpms_value) return TDM_ERROR_BAD_REQUEST; } - if (dpms_value > TDM_OUTPUT_DPMS_OFF) - dpms_value = TDM_OUTPUT_DPMS_OFF; - _pthread_mutex_lock(&private_display->lock); if (private_output->waiting_dpms_change) { diff --git a/src/tdm_vblank.c b/src/tdm_vblank.c index 2701456..e7b79b5 100644 --- a/src/tdm_vblank.c +++ b/src/tdm_vblank.c @@ -365,7 +365,7 @@ _tdm_vblank_cb_output_change(tdm_output *output, tdm_output_change_type type, case TDM_OUTPUT_CHANGE_DPMS: VIN("dpms %s", tdm_dpms_str(value.u32)); private_vblank->check_HW_or_SW = 1; - if (value.u32 != TDM_OUTPUT_DPMS_ON) { + if (TDM_OUTPUT_DPMS_VSYNC_IS_OFF(value.u32)) { if (private_vblank->enable_fake) _tdm_vblank_change_to_SW(private_vblank); else @@ -1081,8 +1081,8 @@ tdm_vblank_wait(tdm_vblank *vblank, unsigned int req_sec, unsigned int req_usec, VER("can't wait a vblank: output disconnected"); return TDM_ERROR_OUTPUT_DISCONNECTED; } - if (dpms != TDM_OUTPUT_DPMS_ON) { - VER("can't wait a vblank: DPMS off"); + if (TDM_OUTPUT_DPMS_VSYNC_IS_OFF(dpms)) { + VER("can't wait a vblank: DPMS %s", tdm_dpms_str(dpms)); return TDM_ERROR_DPMS_OFF; } } @@ -1134,7 +1134,7 @@ tdm_vblank_wait(tdm_vblank *vblank, unsigned int req_sec, unsigned int req_usec, */ if (private_vblank->vrefresh % fps) wait_info->type = VBLANK_TYPE_SW; - else if (dpms == TDM_OUTPUT_DPMS_OFF || + else if (TDM_OUTPUT_DPMS_VSYNC_IS_OFF(dpms) || private_vblank->connection == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) wait_info->type = VBLANK_TYPE_SW_FAKE; else if (private_vblank->offset == 0) -- 2.7.4 From eecb74a2f3a111578d833ade42f33f5d21e540d3 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 29 Nov 2017 15:20:28 +0900 Subject: [PATCH 05/16] dpms: handling extended DPMS modes Change-Id: Ic847321b932625daa6b357ffd435ec719d140ad9 --- client/tdm_client.c | 7 +++++++ include/tdm_common.h | 6 +++++- src/tdm_macro.h | 1 + src/tdm_output.c | 26 ++++++++++++++++++++++++++ 4 files changed, 39 insertions(+), 1 deletion(-) diff --git a/client/tdm_client.c b/client/tdm_client.c index 6153187..a855e8f 100644 --- a/client/tdm_client.c +++ b/client/tdm_client.c @@ -274,6 +274,13 @@ _tdm_client_output_cb_dpms(void *data, struct wl_tdm_output *wl_tdm_output, uint TDM_RETURN_IF_FAIL(private_output != NULL); + /* If value is extended value, we handle it as DPMS on in client side + * The extended DPMS value is valid only in server side. + * Or, need to export to client side also? + */ + if (value > TDM_OUTPUT_DPMS_OFF) + value = TDM_OUTPUT_DPMS_ON; + if (private_output->dpms == value) return; diff --git a/include/tdm_common.h b/include/tdm_common.h index f353216..d087fc8 100644 --- a/include/tdm_common.h +++ b/include/tdm_common.h @@ -87,11 +87,15 @@ typedef enum { /** * @brief The output capability enumeration * @details - * @remark + * If a backend module provides #TDM_OUTPUT_CAPABILITY_EXTENDED_DPMS, we can set + * an extended DPMS mode to an output which a backend module supports. + * Don't use the low-4bit for an extended DPMS mode value. It's used for default + * DPMS modes. */ typedef enum { TDM_OUTPUT_CAPABILITY_ASYNC_DPMS = (1 << 0), /**< if a outupt supports asynchronous DPMS operation */ TDM_OUTPUT_CAPABILITY_HWC = (1 << 1), /**< if a outupt supports hwc operation @since 2.0.0*/ + TDM_OUTPUT_CAPABILITY_EXTENDED_DPMS = (1 << 2), /**< if a outupt supports extended DPMS operation @since 2.0.0 */ } tdm_output_capability; /** diff --git a/src/tdm_macro.h b/src/tdm_macro.h index 775354e..9a99ae3 100644 --- a/src/tdm_macro.h +++ b/src/tdm_macro.h @@ -162,6 +162,7 @@ extern "C" { /* can't export VSYNC macro because we can't define the exact meaning of vsync off * at this time. Does committing in standy mode work? Doesn't committing in suspend mode work? */ +#define TDM_OUTPUT_DPMS_DEFAULT_MASK 0xF #define TDM_OUTPUT_DPMS_VSYNC_OFF_MASK 0x2 #define TDM_OUTPUT_DPMS_VSYNC_IS_OFF(dpms) ((dpms) & TDM_OUTPUT_DPMS_VSYNC_OFF_MASK) diff --git a/src/tdm_output.c b/src/tdm_output.c index 42dfe87..9188c9c 100644 --- a/src/tdm_output.c +++ b/src/tdm_output.c @@ -1209,6 +1209,19 @@ tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value) tdm_func_output *func_output; OUTPUT_FUNC_ENTRY(); + if (dpms_value > TDM_OUTPUT_DPMS_OFF) { + if (dpms_value & TDM_OUTPUT_DPMS_DEFAULT_MASK) { + TDM_ERR("Don't use the low-4bit for an extended DPMS mode: dpms_value(%x)", dpms_value); + return TDM_ERROR_BAD_REQUEST; + } + + if (!(private_output->caps.capabilities & TDM_OUTPUT_CAPABILITY_EXTENDED_DPMS)) { + TDM_ERR("output(%d) doesn't support the extended DPMS control: '%s'", + private_output->pipe, tdm_dpms_str(dpms_value)); + return TDM_ERROR_BAD_REQUEST; + } + } + _pthread_mutex_lock(&private_display->lock); if (private_output->waiting_dpms_change) { @@ -1264,6 +1277,19 @@ tdm_output_set_dpms_async(tdm_output *output, tdm_output_dpms dpms_value) return TDM_ERROR_BAD_REQUEST; } + if (dpms_value > TDM_OUTPUT_DPMS_OFF) { + if (dpms_value & TDM_OUTPUT_DPMS_DEFAULT_MASK) { + TDM_ERR("Don't use the low-4bit for an extended DPMS mode: dpms_value(%x)", dpms_value); + return TDM_ERROR_BAD_REQUEST; + } + + if (!(private_output->caps.capabilities & TDM_OUTPUT_CAPABILITY_EXTENDED_DPMS)) { + TDM_ERR("output(%d) doesn't support the extended DPMS control: '%s'", + private_output->pipe, tdm_dpms_str(dpms_value)); + return TDM_ERROR_BAD_REQUEST; + } + } + _pthread_mutex_lock(&private_display->lock); if (private_output->waiting_dpms_change) { -- 2.7.4 From 6b18d4c8ac640ade23492994b6f58c8dd9ca00f4 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 29 Nov 2017 15:20:50 +0900 Subject: [PATCH 06/16] dpms: add AOD dpms mode Change-Id: I5cd2bda61b7366fdb91e5867bfaa3e58158fccd5 --- include/tdm_common.h | 1 + src/tdm_macro.h | 1 + 2 files changed, 2 insertions(+) diff --git a/include/tdm_common.h b/include/tdm_common.h index d087fc8..b170c48 100644 --- a/include/tdm_common.h +++ b/include/tdm_common.h @@ -222,6 +222,7 @@ typedef enum { TDM_OUTPUT_DPMS_STANDBY, /**< StandBy, Vsync On */ TDM_OUTPUT_DPMS_SUSPEND, /**< Suspend, Vsync Off */ TDM_OUTPUT_DPMS_OFF, /**< Off, Vsync Off */ + TDM_OUTPUT_DPMS_AOD = 0x10, /**< AOD, Vsync On, extended DPMS mode */ } tdm_output_dpms; /** diff --git a/src/tdm_macro.h b/src/tdm_macro.h index 9a99ae3..a55251e 100644 --- a/src/tdm_macro.h +++ b/src/tdm_macro.h @@ -187,6 +187,7 @@ static struct tdm_type_name tdm_dpms_names[] = { { TDM_OUTPUT_DPMS_STANDBY, "standby" }, { TDM_OUTPUT_DPMS_SUSPEND, "suspend" }, { TDM_OUTPUT_DPMS_OFF, "off" }, + { TDM_OUTPUT_DPMS_AOD, "aod" }, }; TDM_TYPE_NAME_FN(dpms) -- 2.7.4 From 8b10e63206bedc929cbcfcba0845cfc0f42818d8 Mon Sep 17 00:00:00 2001 From: Roman Marchenko Date: Wed, 29 Nov 2017 10:34:45 +0200 Subject: [PATCH 07/16] hwc: add properties for video hwc windows - tdm_hwc_window_video_get_available_properties - tdm_hwc_window_video_get_property - tdm_hwc_window_video_set_property Change-Id: I5a1aed2dab3daee875569f9d1046ad51906c1163 Signed-off-by: Roman Marchenko --- include/tdm.h | 33 +++++++++++++++++++ include/tdm_backend.h | 32 ++++++++++++++++++ src/tdm_hwc_window.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 154 insertions(+) diff --git a/include/tdm.h b/include/tdm.h index 18241c0..85c3226 100644 --- a/include/tdm.h +++ b/include/tdm.h @@ -1039,6 +1039,39 @@ tdm_error tdm_hwc_window_unset_flags(tdm_hwc_window *hwc_window, tdm_hwc_window_flag flags); /** + * @brief Get the available property array of a video hwc window object. + * @param[in] hwc window A video hwc window object + * @param[out] props The available property array + * @param[out] count The count of properties + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ +tdm_error +tdm_hwc_window_video_get_available_properties(tdm_hwc_window *hwc_window, + const tdm_prop **props, int *count); + +/** + * @brief Get the property which has a given id. + * @param[in] hwc window A video hwc window object + * @param[in] id The property id + * @param[out] value The value + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ +tdm_error +tdm_hwc_window_video_get_property(tdm_hwc_window *hwc_window, uint32_t id, + tdm_value *value); + +/** + * @brief Set the property which has a given id. + * @param[in] hwc window A video hwc window object + * @param[in] id The property id + * @param[in] value The value + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ +tdm_error +tdm_hwc_window_video_set_property(tdm_hwc_window *hwc_window, uint32_t id, + tdm_value value); + +/** * @brief Get the window video capability * @param[in] hwc_window A window object * @param[out] video_capability A hwc window video capability diff --git a/include/tdm_backend.h b/include/tdm_backend.h index f189d43..6e96440 100644 --- a/include/tdm_backend.h +++ b/include/tdm_backend.h @@ -914,6 +914,38 @@ typedef struct _tdm_func_window { tdm_error (*hwc_window_video_get_supported_format)(tdm_hwc_window *hwc_window, const tbm_format **formats, int *count); + + /** + * @brief Get the available property array of a video hwc window object. + * @param[in] hwc window A video hwc window object + * @param[out] props The available property array + * @param[out] count The count of properties + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ + tdm_error (*hwc_window_video_get_available_properties)( + tdm_hwc_window *hwc_window, + const tdm_prop **props, int *count); + + /** + * @brief Get the property which has a given id. + * @param[in] hwc window A video hwc window object + * @param[in] id The property id + * @param[out] value The value + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ + tdm_error (*hwc_window_video_get_property)(tdm_hwc_window *hwc_window, + uint32_t id, tdm_value *value); + + /** + * @brief Set the property which has a given id. + * @param[in] hwc window A video hwc window object + * @param[in] id The property id + * @param[in] value The value + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ + tdm_error (*hwc_window_video_set_property)(tdm_hwc_window *hwc_window, + uint32_t id, tdm_value value); + } tdm_func_hwc_window; /** diff --git a/src/tdm_hwc_window.c b/src/tdm_hwc_window.c index 3efe364..1166e5b 100644 --- a/src/tdm_hwc_window.c +++ b/src/tdm_hwc_window.c @@ -482,3 +482,92 @@ tdm_hwc_window_video_get_supported_format(tdm_hwc_window *hwc_window, return ret; } + +EXTERN tdm_error +tdm_hwc_window_video_get_available_properties(tdm_hwc_window *hwc_window, + const tdm_prop **props, int *count) +{ + tdm_func_hwc_window *func_hwc_window = NULL; + + HWC_WINDOW_FUNC_ENTRY(); + + TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER); + TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER); + + _pthread_mutex_lock(&private_display->lock); + + func_hwc_window = &private_display->func_hwc_window; + + if (!func_hwc_window->hwc_window_video_get_available_properties) { + /* LCOV_EXCL_START */ + _pthread_mutex_unlock(&private_display->lock); + TDM_ERR("not implemented!!"); + return TDM_ERROR_NOT_IMPLEMENTED; + /* LCOV_EXCL_STOP */ + } + + ret = func_hwc_window->hwc_window_video_get_available_properties(private_hwc_window->hwc_window_backend, + props, count); + + _pthread_mutex_unlock(&private_display->lock); + + return ret; +} + +EXTERN tdm_error +tdm_hwc_window_video_get_property(tdm_hwc_window *hwc_window, + unsigned int id, tdm_value *value) +{ + tdm_func_hwc_window *func_hwc_window = NULL; + + HWC_WINDOW_FUNC_ENTRY(); + + TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER); + + _pthread_mutex_lock(&private_display->lock); + + func_hwc_window = &private_display->func_hwc_window; + + if (!func_hwc_window->hwc_window_video_get_property) { + /* LCOV_EXCL_START */ + _pthread_mutex_unlock(&private_display->lock); + TDM_ERR("not implemented!!"); + return TDM_ERROR_NOT_IMPLEMENTED; + /* LCOV_EXCL_STOP */ + } + + ret = func_hwc_window->hwc_window_video_get_property(private_hwc_window->hwc_window_backend, + id, value); + + _pthread_mutex_unlock(&private_display->lock); + + return ret; +} + +EXTERN tdm_error +tdm_hwc_window_video_set_property(tdm_hwc_window *hwc_window, + unsigned int id, tdm_value value) +{ + tdm_func_hwc_window *func_hwc_window = NULL; + + HWC_WINDOW_FUNC_ENTRY(); + + _pthread_mutex_lock(&private_display->lock); + + func_hwc_window = &private_display->func_hwc_window; + + if (!func_hwc_window->hwc_window_video_set_property) { + /* LCOV_EXCL_START */ + _pthread_mutex_unlock(&private_display->lock); + TDM_ERR("not implemented!!"); + return TDM_ERROR_NOT_IMPLEMENTED; + /* LCOV_EXCL_STOP */ + } + + ret = func_hwc_window->hwc_window_video_set_property(private_hwc_window->hwc_window_backend, + id, value); + + _pthread_mutex_unlock(&private_display->lock); + + return ret; +} -- 2.7.4 From fd490a7e890fd9c1dac8f41d78c1f961548cd9e2 Mon Sep 17 00:00:00 2001 From: Roman Marchenko Date: Wed, 29 Nov 2017 10:38:57 +0200 Subject: [PATCH 08/16] hwc: add API function tdm_output_hwc_get_video_supported_formats delete API function tdm_hwc_window_video_get_supported_format Change-Id: I72f7e41f89bbc7f9aee665def673306c1072c992 Signed-off-by: Roman Marchenko --- include/tdm.h | 24 +++++++++++------------- include/tdm_backend.h | 23 ++++++++++------------- src/tdm_hwc_window.c | 32 -------------------------------- src/tdm_output.c | 30 ++++++++++++++++++++++++++++++ utests/src/ut_tdm_hwc_window.cpp | 32 -------------------------------- 5 files changed, 51 insertions(+), 90 deletions(-) diff --git a/include/tdm.h b/include/tdm.h index 85c3226..a0edef6 100644 --- a/include/tdm.h +++ b/include/tdm.h @@ -715,6 +715,17 @@ tbm_surface_queue_h tdm_output_hwc_get_target_buffer_queue(tdm_output *output, tdm_error *error); /** + * @brief Get the supported format array for video hwc windows of a output object. + * @param[in] output A output object + * @param[out] formats The available format array + * @param[out] count The count of formats + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ +tdm_error +tdm_output_hwc_get_video_supported_formats(tdm_layer *layer, const tbm_format **formats, + int *count); + +/** * @brief Get the capabilities of a layer object. * @param[in] layer A layer object * @param[out] capabilities The capabilities of a layer object @@ -1083,19 +1094,6 @@ tdm_hwc_window_video_get_capability(tdm_hwc_window *hwc_window, tdm_hwc_window_video_capability *video_capability); /** - * @brief Get the window video supported format - * @param[in] hwc_window A window object - * @param[out] formats A hwc window supported formats - * @param[out] count A number of the hwc window supported formats - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - * @since 2.0.0 - */ -tdm_error -tdm_hwc_window_video_get_supported_format(tdm_hwc_window *hwc_window, - const tbm_format **formats, - int *count); - -/** * @brief Destroy a pp object * @param[in] pp A pp object * @see tdm_display_create_pp diff --git a/include/tdm_backend.h b/include/tdm_backend.h index 6e96440..51f3d63 100644 --- a/include/tdm_backend.h +++ b/include/tdm_backend.h @@ -660,7 +660,15 @@ typedef struct _tdm_func_output { tbm_surface_queue_h (*output_hwc_get_target_buffer_queue)(tdm_output *output, tdm_error *error); - void (*reserved3)(void); + /** + * @brief Get the supported format array for video hwc windows of a output object. + * @param[in] output A output object + * @param[out] formats The available format array + * @param[out] count The count of formats + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ + tdm_error (*output_hwc_get_video_supported_formats)(tdm_layer *layer, + const tbm_format **formats, int *count); void (*reserved4)(void); void (*reserved5)(void); void (*reserved6)(void); @@ -902,18 +910,7 @@ typedef struct _tdm_func_window { * @return #TDM_ERROR_NONE if success. Otherwise, error value. */ tdm_error (*hwc_window_video_get_capability)(tdm_hwc_window *hwc_window, - tdm_hwc_window_video_capability *video_capability); - - /** - * @brief Get the window video supported format - * @param[in] hwc_window A window object - * @param[out] formats A hwc window supported formats - * @param[out] count A number of the hwc window supported formats - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - */ - tdm_error (*hwc_window_video_get_supported_format)(tdm_hwc_window *hwc_window, - const tbm_format **formats, - int *count); + tdm_hwc_window_video_capability *video_capability); /** * @brief Get the available property array of a video hwc window object. diff --git a/src/tdm_hwc_window.c b/src/tdm_hwc_window.c index 1166e5b..91191b8 100644 --- a/src/tdm_hwc_window.c +++ b/src/tdm_hwc_window.c @@ -452,38 +452,6 @@ tdm_hwc_window_video_get_capability(tdm_hwc_window *hwc_window, } EXTERN tdm_error -tdm_hwc_window_video_get_supported_format(tdm_hwc_window *hwc_window, - const tbm_format **formats, - int *count) -{ - tdm_func_hwc_window *func_hwc_window = NULL; - - HWC_WINDOW_FUNC_ENTRY(); - - TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER); - TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER); - - _pthread_mutex_lock(&private_display->lock); - - func_hwc_window = &private_display->func_hwc_window; - - if (!func_hwc_window->hwc_window_video_get_supported_format) { - /* LCOV_EXCL_START */ - _pthread_mutex_unlock(&private_display->lock); - TDM_ERR("not implemented!!"); - return TDM_ERROR_NOT_IMPLEMENTED; - /* LCOV_EXCL_STOP */ - } - - ret = func_hwc_window->hwc_window_video_get_supported_format(private_hwc_window->hwc_window_backend, - formats, count); - - _pthread_mutex_unlock(&private_display->lock); - - return ret; -} - -EXTERN tdm_error tdm_hwc_window_video_get_available_properties(tdm_hwc_window *hwc_window, const tdm_prop **props, int *count) { diff --git a/src/tdm_output.c b/src/tdm_output.c index 9188c9c..4c1015c 100644 --- a/src/tdm_output.c +++ b/src/tdm_output.c @@ -1730,6 +1730,36 @@ tdm_output_hwc_set_client_target_buffer(tdm_output *output, tbm_surface_h target return ret; } +tdm_error +tdm_output_hwc_get_video_supported_formats(tdm_output *output, const tbm_format **formats, + int *count) +{ + tdm_func_output *func_output; + OUTPUT_FUNC_ENTRY(); + + TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER); + TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER); + + _pthread_mutex_lock(&private_display->lock); + + func_output = &private_display->func_output; + + if (!func_output->output_hwc_get_video_supported_formats) { + /* LCOV_EXCL_START */ + _pthread_mutex_unlock(&private_display->lock); + TDM_ERR("not implemented!!"); + return TDM_ERROR_NOT_IMPLEMENTED; + /* LCOV_EXCL_STOP */ + } + + ret = func_output->output_hwc_get_video_supported_formats( + private_output->output_backend, formats, count); + + _pthread_mutex_unlock(&private_display->lock); + + return ret; +} + INTERN void tdm_output_call_change_handler_internal(tdm_private_output *private_output, struct list_head *change_handler_list, diff --git a/utests/src/ut_tdm_hwc_window.cpp b/utests/src/ut_tdm_hwc_window.cpp index f4c33a5..d712740 100644 --- a/utests/src/ut_tdm_hwc_window.cpp +++ b/utests/src/ut_tdm_hwc_window.cpp @@ -626,38 +626,6 @@ TEST_F(TDMHwcWindow, VideoGetCapabilitySuccessful) } } - -/* tdm_error tdm_hwc_window_video_get_supported_format(tdm_hwc_window *hwc_window, const tbm_format **formats, int *count); */ -TEST_F(TDMHwcWindow, VideoGetSupportedFormatFailNull) -{ - const tbm_format *formats; - int count; - - error = tdm_hwc_window_video_get_supported_format(NULL, &formats, &count); - ASSERT_NE(TDM_ERROR_NONE, error); - - if (hwc_count > 0) { - error = tdm_hwc_window_video_get_supported_format(hwc_wins[0], NULL, &count); - error = tdm_hwc_window_video_get_supported_format(hwc_wins[0], &formats, NULL); - } -} - -TEST_F(TDMHwcWindow, VideoGetSupportedFormatSuccessful) -{ - const tbm_format *formats; - int count; - - for (int i = 0; i < hwc_count; i++) { - /* hwc_window with TDM_COMPOSITION_CLIENT dosn't support tdm_hwc_window_video_get_supported_format()*/ - error = tdm_hwc_window_set_composition_type(hwc_wins[i], TDM_COMPOSITION_CLIENT); - ASSERT_EQ(TDM_ERROR_NONE, error); - error = tdm_hwc_window_video_get_supported_format(hwc_wins[i], &formats, &count); - ASSERT_NE(TDM_ERROR_NONE, error); - - /*TODO:: check format for TDM_COMPOSITION_VIDEO*/ - } -} - /* tdm_error tdm_output_hwc_validate(tdm_output *output, uint32_t *num_types); */ TEST_F(TDMOutputHwc, ValidateFailNull) { -- 2.7.4 From a261642bf9cf15a132983afba5ef28bd13022469 Mon Sep 17 00:00:00 2001 From: Roman Marchenko Date: Wed, 29 Nov 2017 11:46:22 +0200 Subject: [PATCH 09/16] hwc: add the API function tdm_output_hwc_create_video_window instead of TDM_COMPOSITION_VIDEO. Change-Id: If82b18a3d133abbcedb5d9125e18f5d6682e72f0 Signed-off-by: Roman Marchenko --- include/tdm.h | 10 +++++++++ include/tdm_backend.h | 11 +++++++++- include/tdm_types.h | 15 ++++---------- src/tdm_hwc_window.c | 44 ++++++++++++++++++++++++++++------------ src/tdm_output.c | 26 +++++++++++++++++++++++- src/tdm_private.h | 2 +- utests/src/ut_tdm_hwc_window.cpp | 2 -- 7 files changed, 81 insertions(+), 29 deletions(-) diff --git a/include/tdm.h b/include/tdm.h index a0edef6..77866d5 100644 --- a/include/tdm.h +++ b/include/tdm.h @@ -579,6 +579,16 @@ tdm_hwc_window * tdm_output_hwc_create_window(tdm_output *output, tdm_error *error); /** + * @brief Creates a new video window on the given output. + * @param[in] output A output object + * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. + * @return A created window object + * @since 2.0.0 + */ +tdm_hwc_window * +tdm_output_hwc_create_video_window(tdm_output *output, tdm_error *error); + +/** * @brief Destroys the given window. * @param[in] output A output object * @param[in] window the pointer of the window to destroy diff --git a/include/tdm_backend.h b/include/tdm_backend.h index 51f3d63..b1a3657 100644 --- a/include/tdm_backend.h +++ b/include/tdm_backend.h @@ -669,7 +669,16 @@ typedef struct _tdm_func_output { */ tdm_error (*output_hwc_get_video_supported_formats)(tdm_layer *layer, const tbm_format **formats, int *count); - void (*reserved4)(void); + + /** + * @brief Creates a new video window on the given output. + * @param[in] output A output object + * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. + * @return A created window object. If the video abilities isn't accessed return NULL + * @since 2.0.0 + */ + tdm_hwc_window *(*output_hwc_create_video_window)(tdm_output *output, tdm_error *error); + void (*reserved5)(void); void (*reserved6)(void); void (*reserved7)(void); diff --git a/include/tdm_types.h b/include/tdm_types.h index 626c1c3..c64a351 100644 --- a/include/tdm_types.h +++ b/include/tdm_types.h @@ -170,10 +170,10 @@ typedef enum { * a type to the TDM_COMPOSITION_CLIENT_CANDIDATE type. * * This transition can happen only if the window has the TDM_COMPOSITION_DEVICE - * or the TDM_COMPOSITION_VIDEO type already. + * type already. * - * If an user changed type of a window from the TDM_COMPOSITION_DEVICE or the - * TDM_COMPOSITION_VIDEO type to the the TDM_COMPOSITION_CLIENT type, the type + * If an user changed type of a window from the TDM_COMPOSITION_DEVICE + * type to the the TDM_COMPOSITION_CLIENT type, the type * will be rejected to the TDM_COMPOSITION_CLIENT_CANDIDATE type. * * The user has to composite this window itself. @@ -184,7 +184,7 @@ typedef enum { * TDM_COMPOSITION_CLIENT_CANDIDATE type. * * This transitional state is used to get rid of blinking at a transition from - * the TDM_COMPOSITION_DEVICE/TDM_COMPOSITION_VIDEO type to the + * the TDM_COMPOSITION_DEVICE type to the * TDM_COMPOSITION_CLIENT type where the hw has to wait till a buffer, which was * on a hw overlay, get composited to the fb_target and only after this happens * unset(or set another window on) this hw overlay. @@ -224,13 +224,6 @@ typedef enum { * still permit the device to composite the layer. */ TDM_COMPOSITION_CURSOR = 5, - /** The device will handle the composition of this layer through a hardware - * overlay or other similar means. - * - * Upon tdm_output_hwc_validate(), the device may request a change from this type to - * either TDM_COMPOSITION_DEVICE or TDM_COMPOSITION_CLIENT, but it is - * unlikely that content will display correctly in these cases. */ - TDM_COMPOSITION_VIDEO = 6, } tdm_hwc_window_composition; /** diff --git a/src/tdm_hwc_window.c b/src/tdm_hwc_window.c index 91191b8..24b6207 100644 --- a/src/tdm_hwc_window.c +++ b/src/tdm_hwc_window.c @@ -293,7 +293,7 @@ tdm_hwc_window_set_buffer(tdm_hwc_window *hwc_window, tbm_surface_h buffer) } INTERN tdm_hwc_window * -tdm_hwc_window_create_internal(tdm_private_output *private_output, +tdm_hwc_window_create_internal(tdm_private_output *private_output, int is_video, tdm_error *error) { tdm_private_display *private_display = private_output->private_display; @@ -304,20 +304,38 @@ tdm_hwc_window_create_internal(tdm_private_output *private_output, TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), NULL); - if (!func_output->output_hwc_create_window) { - /* LCOV_EXCL_START */ - if (error) - *error = TDM_ERROR_BAD_MODULE; - return NULL; - /* LCOV_EXCL_STOP */ - } + if (!is_video) { + if (!func_output->output_hwc_create_window) { + /* LCOV_EXCL_START */ + if (error) + *error = TDM_ERROR_BAD_MODULE; + return NULL; + /* LCOV_EXCL_STOP */ + } - hwc_window_backend = func_output->output_hwc_create_window( + hwc_window_backend = func_output->output_hwc_create_window( private_output->output_backend, &ret); - if (ret != TDM_ERROR_NONE) { - if (error) - *error = ret; - return NULL; + if (ret != TDM_ERROR_NONE) { + if (error) + *error = ret; + return NULL; + } + } else { + if (!func_output->output_hwc_create_video_window) { + /* LCOV_EXCL_START */ + if (error) + *error = TDM_ERROR_BAD_MODULE; + return NULL; + /* LCOV_EXCL_STOP */ + } + + hwc_window_backend = func_output->output_hwc_create_video_window( + private_output->output_backend, &ret); + if (ret != TDM_ERROR_NONE) { + if (error) + *error = ret; + return NULL; + } } private_hwc_window = calloc(1, sizeof(tdm_private_capture)); diff --git a/src/tdm_output.c b/src/tdm_output.c index 4c1015c..6e08225 100644 --- a/src/tdm_output.c +++ b/src/tdm_output.c @@ -1434,7 +1434,31 @@ tdm_output_hwc_create_window(tdm_output *output, tdm_error *error) _pthread_mutex_lock(&private_display->lock); if (private_output->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC) - hwc_window = (tdm_hwc_window *)tdm_hwc_window_create_internal(private_output, error); + hwc_window = (tdm_hwc_window *)tdm_hwc_window_create_internal(private_output, 0, error); + else { + /* LCOV_EXCL_START */ + TDM_ERR("output(%p) not support HWC", private_output); + if (error) + *error = TDM_ERROR_BAD_REQUEST; + /* LCOV_EXCL_STOP */ + } + + _pthread_mutex_unlock(&private_display->lock); + + return hwc_window; +} + +EXTERN tdm_hwc_window * +tdm_output_hwc_create_video_window(tdm_output *output, tdm_error *error) +{ + tdm_hwc_window *hwc_window = NULL; + + OUTPUT_FUNC_ENTRY_ERROR(); + + _pthread_mutex_lock(&private_display->lock); + + if (private_output->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC) + hwc_window = (tdm_hwc_window *)tdm_hwc_window_create_internal(private_output, 1, error); else { /* LCOV_EXCL_START */ TDM_ERR("output(%p) not support HWC", private_output); diff --git a/src/tdm_private.h b/src/tdm_private.h index 5e63e5c..37cceb0 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -519,7 +519,7 @@ void tdm_pp_destroy_internal(tdm_private_pp *private_pp); tdm_hwc_window * -tdm_hwc_window_create_internal(tdm_private_output *private_output, tdm_error *error); +tdm_hwc_window_create_internal(tdm_private_output *private_output, int is_video, tdm_error *error); tdm_error tdm_hwc_window_destroy_internal(tdm_private_hwc_window * private_hwc_window); diff --git a/utests/src/ut_tdm_hwc_window.cpp b/utests/src/ut_tdm_hwc_window.cpp index d712740..ed12a59 100644 --- a/utests/src/ut_tdm_hwc_window.cpp +++ b/utests/src/ut_tdm_hwc_window.cpp @@ -461,8 +461,6 @@ TEST_F(TDMHwcWindow, SetCompositionTypeSuccessful) ASSERT_EQ(TDM_ERROR_NONE, error); error = tdm_hwc_window_set_composition_type(hwc_wins[i], TDM_COMPOSITION_CURSOR); ASSERT_EQ(TDM_ERROR_NONE, error); - error = tdm_hwc_window_set_composition_type(hwc_wins[i], TDM_COMPOSITION_VIDEO); - ASSERT_EQ(TDM_ERROR_NONE, error); } } -- 2.7.4 From 14941121d563e5116b3a86d1dd8cdb4f0651cd6d Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Mon, 4 Dec 2017 19:02:08 +0900 Subject: [PATCH 10/16] package version up to 1.9.1 Change-Id: I67f467eca26b1669158d1c84f954a70c4272d9eb --- packaging/libtdm.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index d68ef56..b747070 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -1,7 +1,7 @@ %define UTEST_PACKAGE 1 Name: libtdm -Version: 1.9.0 +Version: 1.9.1 Release: 0 Summary: User Library of Tizen Display Manager Group: Development/Libraries -- 2.7.4 From 030654bbc5a0ed6429f9f4a186219dbdbc4d7100 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Thu, 7 Dec 2017 11:16:08 +0900 Subject: [PATCH 11/16] add checking return value Change-Id: I6b5d85ace61d651722c4df2991ff588d74d726bd --- src/tdm_vblank.c | 4 +++- tools/tdm_test_server.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/tdm_vblank.c b/src/tdm_vblank.c index e7b79b5..19c12dd 100644 --- a/src/tdm_vblank.c +++ b/src/tdm_vblank.c @@ -323,8 +323,10 @@ _tdm_vblank_update_output_info(tdm_private_vblank *private_vblank) tdm_output *output = private_vblank->output; tdm_output_conn_status connection = TDM_OUTPUT_CONN_STATUS_DISCONNECTED; unsigned int vrefresh = 0; + tdm_error ret; - tdm_output_get_conn_status(output, &connection); + ret = tdm_output_get_conn_status(output, &connection); + TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); if (connection != TDM_OUTPUT_CONN_STATUS_DISCONNECTED) { const tdm_output_mode *mode = NULL; diff --git a/tools/tdm_test_server.c b/tools/tdm_test_server.c index af3c303..76a437d 100644 --- a/tools/tdm_test_server.c +++ b/tools/tdm_test_server.c @@ -639,7 +639,9 @@ interpret_args(tdm_test_server *data) for (i = 0; i < output_count; i++) { tdm_output *output = tdm_display_get_output(data->display, i, NULL); tdm_output_conn_status status; - tdm_output_get_conn_status(output, &status); + ret = tdm_output_get_conn_status(output, &status); + TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE); + if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) continue; o = calloc(1, sizeof * o); -- 2.7.4 From 6c6338dd5b9527db34621319b61d567bad57c226 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 12 Dec 2017 11:44:44 +0900 Subject: [PATCH 12/16] monitor: enhance ttrace option for layer, pp, capture Change-Id: I3c142a49bff04844734137ea912cd5a84a81e05c --- src/tdm.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++ src/tdm_capture.c | 22 +++++++++++++++ src/tdm_layer.c | 21 ++++++++++++-- src/tdm_monitor_server.c | 56 ++++++++------------------------------ src/tdm_pp.c | 28 +++++++++++++++++-- src/tdm_private.h | 16 +++++++++-- src/tdm_server.c | 49 ++++++++++++--------------------- src/tdm_vblank.c | 4 --- 8 files changed, 178 insertions(+), 89 deletions(-) diff --git a/src/tdm.c b/src/tdm.c index 418010c..a66ebad 100644 --- a/src/tdm.c +++ b/src/tdm.c @@ -679,6 +679,8 @@ tdm_display_update(tdm_display *dpy) int tdm_debug_module; int tdm_debug_dump; +int tdm_ttrace_module; +int tdm_ttrace_output; static tdm_private_display *g_private_display; static pthread_mutex_t gLock = PTHREAD_MUTEX_INITIALIZER; @@ -1362,6 +1364,75 @@ enable_fail: } INTERN tdm_error +tdm_display_enable_ttrace(tdm_private_display *private_display, const char *ttrace, int output_id, char *reply, int *len) +{ + char temp[TDM_PATH_LEN]; + char *arg; + char *end; + tdm_output *output; + tdm_error ret; + tdm_output_type type; + + snprintf(temp, TDM_PATH_LEN, "%s", ttrace); + + tdm_ttrace_output = output_id; + tdm_ttrace_module = 0; + + output = tdm_display_get_output(private_display, output_id, &ret); + if (!output) { + TDM_SNPRINTF(reply, len, "can't find the output_id(%d)\n", output_id); + return ret; + } + + ret = tdm_output_get_output_type(output, &type); + if (ret != TDM_ERROR_NONE) { + TDM_SNPRINTF(reply, len, "can't find the type of output_id(%d)\n", output_id); + return ret; + } + + arg = strtok_r(temp, TDM_DELIM, &end); + while (arg) { + if (!strncmp(arg, "none", 4)) + tdm_ttrace_module = 0; + else if (!strncmp(arg, "all", 3)) + tdm_ttrace_module = 0xFFFFFFFF; + else if (!strncmp(arg, "vblank", 6)) + tdm_ttrace_module |= TDM_TTRACE_VBLANK; + else if (!strncmp(arg, "client", 6)) + tdm_ttrace_module |= TDM_TTRACE_CLIENT; + else if (!strncmp(arg, "layer", 5)) + tdm_ttrace_module |= TDM_TTRACE_LAYER; + else if (!strncmp(arg, "pp", 2)) + tdm_ttrace_module |= TDM_TTRACE_PP; + else if (!strncmp(arg, "capture", 7)) + tdm_ttrace_module |= TDM_TTRACE_CAPTURE; + else { + tdm_ttrace_module = 0; + tdm_display_enable_ttrace_vblank(private_display, NULL, 0); + tdm_server_enable_ttrace_client_vblank(private_display, NULL, 0); + TDM_SNPRINTF(reply, len, "unknown option: '%s'\n", arg); + return TDM_ERROR_NONE; + } + + arg = strtok_r(NULL, TDM_DELIM, &end); + } + + TDM_SNPRINTF(reply, len, "ttrace debugging... '%s' %x\n", ttrace, tdm_ttrace_module); + + if (tdm_ttrace_module & TDM_TTRACE_VBLANK) + tdm_display_enable_ttrace_vblank(private_display, output, 1); + else + tdm_display_enable_ttrace_vblank(private_display, NULL, 0); + + if (tdm_ttrace_module & TDM_TTRACE_CLIENT) + tdm_server_enable_ttrace_client_vblank(private_display, output, 1); + else + tdm_server_enable_ttrace_client_vblank(private_display, NULL, 0); + + return TDM_ERROR_NONE; +} + +INTERN tdm_error tdm_display_enable_fps(tdm_private_display *private_display, int enable) { private_display->print_fps = enable; diff --git a/src/tdm_capture.c b/src/tdm_capture.c index bfb9e40..f0b4be6 100644 --- a/src/tdm_capture.c +++ b/src/tdm_capture.c @@ -141,6 +141,11 @@ tdm_capture_cb_done(tdm_capture *capture_backend, tbm_surface_h buffer, if (tdm_debug_module & TDM_DEBUG_BUFFER) TDM_INFO("capture(%p) done: %p", private_capture, buffer); + if (tdm_ttrace_module & TDM_TTRACE_CAPTURE) { + tbm_bo bo = tbm_surface_internal_get_bo(buffer, 0); + TDM_TRACE_ASYNC_END((int)private_capture, "[CAPTURE] %d", tbm_bo_export(bo)); + } + if (!LIST_IS_EMPTY(&private_capture->buffer_list)) { first_entry = container_of((&private_capture->buffer_list)->next, capture_buffer, link); if (first_entry->buffer != buffer) @@ -370,6 +375,12 @@ tdm_capture_destroy_internal(tdm_private_capture *private_capture) _pthread_mutex_unlock(&private_display->lock); LIST_FOR_EACH_ENTRY_SAFE(b, bb, &clone_list, link) { LIST_DEL(&b->link); + + if (tdm_ttrace_module & TDM_TTRACE_CAPTURE) { + tbm_bo bo = tbm_surface_internal_get_bo(b->buffer, 0); + TDM_TRACE_ASYNC_END((int)private_capture, "[CAPTURE] %d", tbm_bo_export(bo)); + } + tdm_buffer_unref_backend(b->buffer); free(b); } @@ -389,6 +400,12 @@ tdm_capture_destroy_internal(tdm_private_capture *private_capture) _pthread_mutex_unlock(&private_display->lock); LIST_FOR_EACH_ENTRY_SAFE(b, bb, &clone_list, link) { LIST_DEL(&b->link); + + if (tdm_ttrace_module & TDM_TTRACE_CAPTURE) { + tbm_bo bo = tbm_surface_internal_get_bo(b->buffer, 0); + TDM_TRACE_ASYNC_END((int)private_capture, "[CAPTURE] %d", tbm_bo_export(bo)); + } + tdm_buffer_unref_backend(b->buffer); free(b); } @@ -544,6 +561,11 @@ tdm_capture_attach(tdm_capture *capture, tbm_surface_h buffer) tdm_buffer_list_dump(&private_capture->buffer_list); } + if (tdm_ttrace_module & TDM_TTRACE_CAPTURE) { + tbm_bo bo = tbm_surface_internal_get_bo(buffer, 0); + TDM_TRACE_ASYNC_BEGIN((int)capture, "[CAPTURE] %d", tbm_bo_export(bo)); + } + _pthread_mutex_unlock(&private_display->lock); return ret; diff --git a/src/tdm_layer.c b/src/tdm_layer.c index 5d3d1c9..d378622 100644 --- a/src/tdm_layer.c +++ b/src/tdm_layer.c @@ -453,11 +453,17 @@ tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer) private_layer->pending_buffer_changed = 1; if (private_layer->pending_buffer) { - tbm_surface_internal_unref(private_layer->pending_buffer); if (tdm_debug_module & TDM_DEBUG_BUFFER) TDM_INFO("layer(%p) pending_buffer(%p) skipped", private_layer, private_layer->pending_buffer); + + if (tdm_ttrace_module & TDM_TTRACE_LAYER) { + tbm_bo bo = tbm_surface_internal_get_bo(private_layer->pending_buffer, 0); + TDM_TRACE_ASYNC_END((int)private_layer, "[LAYER] %d", tbm_bo_export(bo)); + } + + tbm_surface_internal_unref(private_layer->pending_buffer); } tbm_surface_internal_ref(buffer); @@ -467,6 +473,11 @@ tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer) TDM_INFO("layer(%p) pending_buffer(%p)", private_layer, private_layer->pending_buffer); + if (tdm_ttrace_module & TDM_TTRACE_LAYER) { + tbm_bo bo = tbm_surface_internal_get_bo(private_layer->pending_buffer, 0); + TDM_TRACE_ASYNC_BEGIN((int)private_layer, "[LAYER] %d", tbm_bo_export(bo)); + } + _pthread_mutex_unlock(&private_display->lock); return ret; @@ -528,8 +539,14 @@ tdm_layer_committed(tdm_private_layer *private_layer, tdm_private_layer_buffer * } /* LCOV_EXCL_STOP */ - if (private_layer->showing_buffer) + if (private_layer->showing_buffer) { + if (tdm_ttrace_module & TDM_TTRACE_LAYER) { + tbm_bo bo = tbm_surface_internal_get_bo(private_layer->showing_buffer->buffer, 0); + TDM_TRACE_ASYNC_END((int)private_layer, "[LAYER] %d", tbm_bo_export(bo)); + } + _tdm_layer_free_buffer(private_layer, private_layer->showing_buffer); + } private_layer->showing_buffer = *committed_buffer; *committed_buffer = NULL; diff --git a/src/tdm_monitor_server.c b/src/tdm_monitor_server.c index ea56a8b..7dbdc3c 100644 --- a/src/tdm_monitor_server.c +++ b/src/tdm_monitor_server.c @@ -107,57 +107,22 @@ _tdm_monitor_server_dpms(unsigned int pid, char *cwd, int argc, char *argv[], ch } static void -_tdm_monitor_server_ttrace_vblank(unsigned int pid, char *cwd, int argc, char *argv[], char *reply, int *len, tdm_display *dpy) +_tdm_monitor_server_ttrace(unsigned int pid, char *cwd, int argc, char *argv[], char *reply, int *len, tdm_display *dpy) { - int ttrace_vblank, output_id = 0; - char *arg; + int output_id = 0; char *end; + tdm_error ret; if (argc < 3) { _tdm_monitor_server_usage(argv[0], reply, len); return; } - arg = argv[2]; - ttrace_vblank = strtol(arg, &end, 10); - - if (ttrace_vblank > 0) { - tdm_output *output; - tdm_error ret; - tdm_output_type type; - char *temp; - - if (*end == '@') { - arg = end + 1; - output_id = strtol(arg, &end, 10); - } - - output = tdm_display_get_output(dpy, output_id, NULL); - if (!output) { - TDM_SNPRINTF(reply, len, "can't find the output_id(%d)\n", output_id); - return; - } - - ret = tdm_output_get_output_type(output, &type); - if (ret != TDM_ERROR_NONE) { - TDM_SNPRINTF(reply, len, "can't find the type of output_id(%d)\n", output_id); - return; - } - - temp = "server"; - tdm_display_enable_ttrace_vblank(dpy, output, 1); - - if (ttrace_vblank > 1) { - temp = "clients"; - tdm_server_enable_ttrace_vblank(dpy, output, 1); - } + if (argv[3]) + output_id = strtol(argv[3], &end, 10); - TDM_SNPRINTF(reply, len, "enable ttrace vblank for '%s': %s \n", tdm_conn_str(type), temp); - } else { - tdm_display_enable_ttrace_vblank(dpy, NULL, 0); - tdm_server_enable_ttrace_vblank(dpy, NULL, 0); - TDM_SNPRINTF(reply, len, "disable ttrace vblank\n"); - } + ret = tdm_display_enable_ttrace(dpy, argv[2], output_id, reply, len); + TDM_DBG_RETURN_IF_FAIL(ret == TDM_ERROR_NONE); } static void @@ -547,9 +512,10 @@ static struct { "set output dpms", ":", "0:3 or 0:0" }, { - "ttrace_vblank", _tdm_monitor_server_ttrace_vblank, - "enable/disable the vblank for ttrace [0:disable, 1:server, 2:clients]", - "[@]", "0 or 1 or 2 or 1@0 or 2@0 or 1@1 or 2@1" + "ttrace", _tdm_monitor_server_ttrace, + "enable/disable ttrace (module: none, vblank, client, layer, pp, capture, all", + "[@]", + NULL }, { "debug", _tdm_monitor_server_debug, diff --git a/src/tdm_pp.c b/src/tdm_pp.c index a58e4fc..53f8c73 100644 --- a/src/tdm_pp.c +++ b/src/tdm_pp.c @@ -139,9 +139,6 @@ tdm_pp_cb_done(tdm_pp *pp_backend, tbm_surface_h src, tbm_surface_h dst, /* LCOV_EXCL_STOP */ } - if (tdm_debug_module & TDM_DEBUG_BUFFER) - TDM_INFO("pp(%p) done: src(%p) dst(%p)", private_pp, src, dst); - if (!LIST_IS_EMPTY(&private_pp->buffer_list)) { first_entry = container_of((&private_pp->buffer_list)->next, pp_buffer, link); if (first_entry->src != src || first_entry->dst != dst) @@ -154,6 +151,14 @@ tdm_pp_cb_done(tdm_pp *pp_backend, tbm_surface_h src, tbm_surface_h dst, LIST_DEL(&pp_buffer->link); LIST_DELINIT(&pp_buffer->commit_link); + if (tdm_debug_module & TDM_DEBUG_BUFFER) + TDM_INFO("pp(%p) done: src(%p) dst(%p)", private_pp, src, dst); + + if (tdm_ttrace_module & TDM_TTRACE_PP) { + tbm_bo bo = tbm_surface_internal_get_bo(dst, 0); + TDM_TRACE_ASYNC_END((int)private_pp, "[PP] %d", tbm_bo_export(bo)); + } + _pthread_mutex_unlock(&private_display->lock); if (private_pp->done_func) private_pp->done_func(private_pp, src, dst, private_pp->done_user_data); @@ -285,6 +290,12 @@ tdm_pp_destroy_internal(tdm_private_pp *private_pp) _pthread_mutex_unlock(&private_display->lock); LIST_FOR_EACH_ENTRY_SAFE(b, bb, &clone_list, link) { LIST_DEL(&b->link); + + if (tdm_ttrace_module & TDM_TTRACE_PP) { + tbm_bo bo = tbm_surface_internal_get_bo(b->dst, 0); + TDM_TRACE_ASYNC_END((int)private_pp, "[PP] %d", tbm_bo_export(bo)); + } + tdm_buffer_unref_backend(b->src); tdm_buffer_unref_backend(b->dst); free(b); @@ -305,6 +316,12 @@ tdm_pp_destroy_internal(tdm_private_pp *private_pp) _pthread_mutex_unlock(&private_display->lock); LIST_FOR_EACH_ENTRY_SAFE(b, bb, &clone_list, link) { LIST_DEL(&b->link); + + if (tdm_ttrace_module & TDM_TTRACE_PP) { + tbm_bo bo = tbm_surface_internal_get_bo(b->dst, 0); + TDM_TRACE_ASYNC_END((int)private_pp, "[PP] %d", tbm_bo_export(bo)); + } + tdm_buffer_unref_backend(b->src); tdm_buffer_unref_backend(b->dst); free(b); @@ -467,6 +484,11 @@ tdm_pp_attach(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst) _tdm_pp_print_list(&private_pp->pending_buffer_list); } + if (tdm_ttrace_module & TDM_TTRACE_PP) { + tbm_bo bo = tbm_surface_internal_get_bo(dst, 0); + TDM_TRACE_ASYNC_BEGIN((int)pp, "[PP] %d", tbm_bo_export(bo)); + } + _pthread_mutex_unlock(&private_display->lock); return ret; diff --git a/src/tdm_private.h b/src/tdm_private.h index 37cceb0..8c710a8 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -86,8 +86,19 @@ enum { TDM_DEBUG_COMMIT = (1 << 5), }; +enum { + TDM_TTRACE_NONE, + TDM_TTRACE_VBLANK = (1 << 0), + TDM_TTRACE_CLIENT = (1 << 1), + TDM_TTRACE_LAYER = (1 << 2), + TDM_TTRACE_PP = (1 << 3), + TDM_TTRACE_CAPTURE = (1 << 4), +}; + extern int tdm_debug_module; extern int tdm_debug_dump; +extern int tdm_ttrace_module; +extern int tdm_ttrace_output; #ifdef HAVE_TTRACE #include @@ -238,7 +249,6 @@ struct _tdm_private_output { /* for ttrace vblank */ tdm_vblank *ttrace_vblank; - unsigned int ttrace_vblank_client; }; struct _tdm_private_layer { @@ -658,7 +668,7 @@ tdm_server_deinit(tdm_private_loop *private_loop); const char* tdm_server_get_client_name(pid_t pid); tdm_error -tdm_server_enable_ttrace_vblank(tdm_display *dpy, tdm_output *output, int enable); +tdm_server_enable_ttrace_client_vblank(tdm_display *dpy, tdm_output *output, int enable); char * tdm_helper_dump_make_directory(const char *path, char *reply, int *len); @@ -753,7 +763,7 @@ tdm_display_enable_dump(tdm_private_display *private_display, const char *dump_s tdm_error tdm_display_enable_path(const char *path); tdm_error -tdm_display_enable_ttrace_vblank(tdm_display *dpy, tdm_output *output, int enable); +tdm_display_enable_ttrace(tdm_private_display *private_display, const char *ttrace, int output_id, char *reply, int *len); tdm_error tdm_display_enable_fps(tdm_private_display *private_display, int enable); diff --git a/src/tdm_server.c b/src/tdm_server.c index 3932819..3d9daf3 100644 --- a/src/tdm_server.c +++ b/src/tdm_server.c @@ -88,7 +88,6 @@ typedef struct _tdm_server_client_info { pid_t pid; char name[TDM_NAME_LEN]; struct wl_resource *resource; - tdm_private_server *private_server; } tdm_server_client_info; static tdm_private_server *keep_private_server; @@ -169,7 +168,6 @@ _tdm_server_send_done(tdm_server_wait_info *wait_info, tdm_error error, { tdm_server_wait_info *found; tdm_server_vblank_info *vblank_info; - tdm_private_output *private_output; if (!keep_private_server) return; @@ -188,10 +186,6 @@ _tdm_server_send_done(tdm_server_wait_info *wait_info, tdm_error error, wl_tdm_vblank_send_done(vblank_info->resource, wait_info->req_id, sequence, tv_sec, tv_usec, error); - private_output = vblank_info->output_info->output; - if (private_output->ttrace_vblank_client) - TDM_TRACE_ASYNC_END((int)wait_info->req_time, "TDM_Server_Vblank:%u", vblank_info->stamp); - destroy_wait(wait_info); } /* LCOV_EXCL_STOP */ @@ -322,7 +316,6 @@ _tdm_server_vblank_cb_wait_vblank(struct wl_client *client, struct wl_resource * tdm_server_vblank_info *vblank_info = wl_resource_get_user_data(resource); tdm_server_output_info *output_info = vblank_info->output_info; tdm_private_server *private_server = output_info->private_server; - tdm_private_output *private_output = output_info->output; tdm_server_wait_info *wait_info; unsigned int enable_fake = 0; tdm_error ret; @@ -346,10 +339,6 @@ _tdm_server_vblank_cb_wait_vblank(struct wl_client *client, struct wl_resource * if (tdm_debug_module & TDM_DEBUG_VBLANK) TDM_DBG("req_id(%d) wait", req_id); - private_output = vblank_info->output_info->output; - if (private_output->ttrace_vblank_client) - TDM_TRACE_ASYNC_BEGIN((int)wait_info->req_time, "TDM_Server_Vblank:%u", vblank_info->stamp); - ret = tdm_vblank_wait(vblank_info->vblank, req_sec, req_usec, interval, _tdm_server_cb_vblank, wait_info); tdm_vblank_get_enable_fake(vblank_info->vblank, &enable_fake); @@ -376,7 +365,6 @@ _tdm_server_vblank_cb_wait_vblank_seq(struct wl_client *client, struct wl_resour tdm_server_vblank_info *vblank_info = wl_resource_get_user_data(resource); tdm_server_output_info *output_info = vblank_info->output_info; tdm_private_server *private_server = output_info->private_server; - tdm_private_output *private_output = output_info->output; tdm_server_wait_info *wait_info; unsigned int enable_fake = 0; tdm_error ret; @@ -400,10 +388,6 @@ _tdm_server_vblank_cb_wait_vblank_seq(struct wl_client *client, struct wl_resour if (tdm_debug_module & TDM_DEBUG_VBLANK) TDM_DBG("req_id(%d) wait", req_id); - private_output = vblank_info->output_info->output; - if (private_output->ttrace_vblank_client) - TDM_TRACE_ASYNC_BEGIN((int)wait_info->req_time, "TDM_Server_Vblank:%u", vblank_info->stamp); - ret = tdm_vblank_wait_seq(vblank_info->vblank, req_sec, req_usec, sequence, _tdm_server_cb_vblank, wait_info); tdm_vblank_get_enable_fake(vblank_info->vblank, &enable_fake); @@ -502,6 +486,12 @@ _tdm_server_output_cb_create_vblank(struct wl_client *client, struct wl_resource wl_tdm_vblank_send_stamp(vblank_info->resource, vblank_info->stamp); + if (tdm_ttrace_module & TDM_TTRACE_CLIENT) { + tdm_output *output = tdm_display_get_output(private_loop->dpy, tdm_ttrace_output, NULL); + if (output == output_info->output) + wl_tdm_vblank_send_ttrace(vblank_info->resource, 1); + } + return; } @@ -815,7 +805,6 @@ _tdm_server_bind(struct wl_client *client, void *data, } cinfo->resource = resource; - cinfo->private_server = data; LIST_ADDTAIL(&cinfo->link, &client_list); wl_client_get_credentials(client, &cinfo->pid, NULL, NULL); @@ -1046,26 +1035,22 @@ tdm_server_get_client_name(pid_t pid) /* LCOV_EXCL_START */ INTERN tdm_error -tdm_server_enable_ttrace_vblank(tdm_display *dpy, tdm_output *output, int enable) +tdm_server_enable_ttrace_client_vblank(tdm_display *dpy, tdm_output *output, int enable) { - tdm_server_client_info *cinfo = NULL; - - LIST_FOR_EACH_ENTRY(cinfo, &client_list, link) { - tdm_private_server *private_server = cinfo->private_server; - tdm_server_output_info *output_info = NULL; + tdm_private_server *private_server = keep_private_server; + tdm_server_output_info *output_info = NULL; - LIST_FOR_EACH_ENTRY(output_info, &private_server->output_list, link) { - tdm_server_vblank_info *vblank_info = NULL; - tdm_private_output *private_output = output_info->output; + if (!keep_private_server) + return TDM_ERROR_NONE; - if (output && output_info->output != output) - continue; + LIST_FOR_EACH_ENTRY(output_info, &private_server->output_list, link) { + tdm_server_vblank_info *vblank_info = NULL; - private_output->ttrace_vblank_client = enable; + if (output && output_info->output != output) + continue; - LIST_FOR_EACH_ENTRY(vblank_info, &output_info->vblank_list, link) { - wl_tdm_vblank_send_ttrace(vblank_info->resource, enable); - } + LIST_FOR_EACH_ENTRY(vblank_info, &output_info->vblank_list, link) { + wl_tdm_vblank_send_ttrace(vblank_info->resource, enable); } } diff --git a/src/tdm_vblank.c b/src/tdm_vblank.c index 19c12dd..72b2525 100644 --- a/src/tdm_vblank.c +++ b/src/tdm_vblank.c @@ -971,8 +971,6 @@ tdm_vblank_cb_vblank_SW(tdm_vblank *vblank, double vblank_stamp) if (w->target_time != first_wait_info->target_time) break; - TDM_TRACE_ASYNC_END((int)w->req_time, "TDM_SW_Vblank:%u", (unsigned int)private_vblank->stamp); - LIST_DEL(&w->link); _tdm_vblank_valid_list_del(&w->valid_link); @@ -1044,8 +1042,6 @@ _tdm_vblank_wait_SW(tdm_vblank_wait_info *wait_info) _tdm_vblank_insert_wait(wait_info, &private_vblank->SW_wait_list); - TDM_TRACE_ASYNC_BEGIN((int)wait_info->req_time, "TDM_SW_Vblank:%u", (unsigned int)private_vblank->stamp); - ret = _tdm_vblank_sw_timer_update(private_vblank); if (ret != TDM_ERROR_NONE) { /* LCOV_EXCL_START */ -- 2.7.4 From 0ed66904ff4ea807afe44e74f9006e090208aa3b Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 12 Dec 2017 18:07:04 +0900 Subject: [PATCH 13/16] package version up to 1.9.2 Change-Id: I35b97e2b930648a98bb1768fbd08abf9f379794f --- packaging/libtdm.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index b747070..d5916a3 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -1,7 +1,7 @@ %define UTEST_PACKAGE 1 Name: libtdm -Version: 1.9.1 +Version: 1.9.2 Release: 0 Summary: User Library of Tizen Display Manager Group: Development/Libraries -- 2.7.4 From 3452e634e527f8dc29d107979787cf9a868a38cc Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 12 Dec 2017 18:42:06 +0900 Subject: [PATCH 14/16] fix build-break for aarch64 Change-Id: I1ea0c302e37f3fd44ddce44fae8045b8041d166b --- src/tdm_capture.c | 8 ++++---- src/tdm_layer.c | 6 +++--- src/tdm_pp.c | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/tdm_capture.c b/src/tdm_capture.c index f0b4be6..9d924c2 100644 --- a/src/tdm_capture.c +++ b/src/tdm_capture.c @@ -143,7 +143,7 @@ tdm_capture_cb_done(tdm_capture *capture_backend, tbm_surface_h buffer, if (tdm_ttrace_module & TDM_TTRACE_CAPTURE) { tbm_bo bo = tbm_surface_internal_get_bo(buffer, 0); - TDM_TRACE_ASYNC_END((int)private_capture, "[CAPTURE] %d", tbm_bo_export(bo)); + TDM_TRACE_ASYNC_END((intptr_t)private_capture, "[CAPTURE] %d", tbm_bo_export(bo)); } if (!LIST_IS_EMPTY(&private_capture->buffer_list)) { @@ -378,7 +378,7 @@ tdm_capture_destroy_internal(tdm_private_capture *private_capture) if (tdm_ttrace_module & TDM_TTRACE_CAPTURE) { tbm_bo bo = tbm_surface_internal_get_bo(b->buffer, 0); - TDM_TRACE_ASYNC_END((int)private_capture, "[CAPTURE] %d", tbm_bo_export(bo)); + TDM_TRACE_ASYNC_END((intptr_t)private_capture, "[CAPTURE] %d", tbm_bo_export(bo)); } tdm_buffer_unref_backend(b->buffer); @@ -403,7 +403,7 @@ tdm_capture_destroy_internal(tdm_private_capture *private_capture) if (tdm_ttrace_module & TDM_TTRACE_CAPTURE) { tbm_bo bo = tbm_surface_internal_get_bo(b->buffer, 0); - TDM_TRACE_ASYNC_END((int)private_capture, "[CAPTURE] %d", tbm_bo_export(bo)); + TDM_TRACE_ASYNC_END((intptr_t)private_capture, "[CAPTURE] %d", tbm_bo_export(bo)); } tdm_buffer_unref_backend(b->buffer); @@ -563,7 +563,7 @@ tdm_capture_attach(tdm_capture *capture, tbm_surface_h buffer) if (tdm_ttrace_module & TDM_TTRACE_CAPTURE) { tbm_bo bo = tbm_surface_internal_get_bo(buffer, 0); - TDM_TRACE_ASYNC_BEGIN((int)capture, "[CAPTURE] %d", tbm_bo_export(bo)); + TDM_TRACE_ASYNC_BEGIN((intptr_t)capture, "[CAPTURE] %d", tbm_bo_export(bo)); } _pthread_mutex_unlock(&private_display->lock); diff --git a/src/tdm_layer.c b/src/tdm_layer.c index d378622..2a7f3b1 100644 --- a/src/tdm_layer.c +++ b/src/tdm_layer.c @@ -460,7 +460,7 @@ tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer) if (tdm_ttrace_module & TDM_TTRACE_LAYER) { tbm_bo bo = tbm_surface_internal_get_bo(private_layer->pending_buffer, 0); - TDM_TRACE_ASYNC_END((int)private_layer, "[LAYER] %d", tbm_bo_export(bo)); + TDM_TRACE_ASYNC_END((intptr_t)private_layer, "[LAYER] %d", tbm_bo_export(bo)); } tbm_surface_internal_unref(private_layer->pending_buffer); @@ -475,7 +475,7 @@ tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer) if (tdm_ttrace_module & TDM_TTRACE_LAYER) { tbm_bo bo = tbm_surface_internal_get_bo(private_layer->pending_buffer, 0); - TDM_TRACE_ASYNC_BEGIN((int)private_layer, "[LAYER] %d", tbm_bo_export(bo)); + TDM_TRACE_ASYNC_BEGIN((intptr_t)private_layer, "[LAYER] %d", tbm_bo_export(bo)); } _pthread_mutex_unlock(&private_display->lock); @@ -542,7 +542,7 @@ tdm_layer_committed(tdm_private_layer *private_layer, tdm_private_layer_buffer * if (private_layer->showing_buffer) { if (tdm_ttrace_module & TDM_TTRACE_LAYER) { tbm_bo bo = tbm_surface_internal_get_bo(private_layer->showing_buffer->buffer, 0); - TDM_TRACE_ASYNC_END((int)private_layer, "[LAYER] %d", tbm_bo_export(bo)); + TDM_TRACE_ASYNC_END((intptr_t)private_layer, "[LAYER] %d", tbm_bo_export(bo)); } _tdm_layer_free_buffer(private_layer, private_layer->showing_buffer); diff --git a/src/tdm_pp.c b/src/tdm_pp.c index 53f8c73..80eb330 100644 --- a/src/tdm_pp.c +++ b/src/tdm_pp.c @@ -156,7 +156,7 @@ tdm_pp_cb_done(tdm_pp *pp_backend, tbm_surface_h src, tbm_surface_h dst, if (tdm_ttrace_module & TDM_TTRACE_PP) { tbm_bo bo = tbm_surface_internal_get_bo(dst, 0); - TDM_TRACE_ASYNC_END((int)private_pp, "[PP] %d", tbm_bo_export(bo)); + TDM_TRACE_ASYNC_END((intptr_t)private_pp, "[PP] %d", tbm_bo_export(bo)); } _pthread_mutex_unlock(&private_display->lock); @@ -293,7 +293,7 @@ tdm_pp_destroy_internal(tdm_private_pp *private_pp) if (tdm_ttrace_module & TDM_TTRACE_PP) { tbm_bo bo = tbm_surface_internal_get_bo(b->dst, 0); - TDM_TRACE_ASYNC_END((int)private_pp, "[PP] %d", tbm_bo_export(bo)); + TDM_TRACE_ASYNC_END((intptr_t)private_pp, "[PP] %d", tbm_bo_export(bo)); } tdm_buffer_unref_backend(b->src); @@ -319,7 +319,7 @@ tdm_pp_destroy_internal(tdm_private_pp *private_pp) if (tdm_ttrace_module & TDM_TTRACE_PP) { tbm_bo bo = tbm_surface_internal_get_bo(b->dst, 0); - TDM_TRACE_ASYNC_END((int)private_pp, "[PP] %d", tbm_bo_export(bo)); + TDM_TRACE_ASYNC_END((intptr_t)private_pp, "[PP] %d", tbm_bo_export(bo)); } tdm_buffer_unref_backend(b->src); @@ -486,7 +486,7 @@ tdm_pp_attach(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst) if (tdm_ttrace_module & TDM_TTRACE_PP) { tbm_bo bo = tbm_surface_internal_get_bo(dst, 0); - TDM_TRACE_ASYNC_BEGIN((int)pp, "[PP] %d", tbm_bo_export(bo)); + TDM_TRACE_ASYNC_BEGIN((intptr_t)pp, "[PP] %d", tbm_bo_export(bo)); } _pthread_mutex_unlock(&private_display->lock); -- 2.7.4 From 6e3b71431f66086254c00bb339711e6ef8e93486 Mon Sep 17 00:00:00 2001 From: Roman Marchenko Date: Mon, 11 Dec 2017 14:11:48 +0200 Subject: [PATCH 15/16] utest: fix wrong tests for tdm_vblank.c - VblankDestroyWrongVblankPtr: use exit(0) in a ASSERT_EXIT block - VblankGetOffsetFailWrongOffsetPtr: was deleted as libtdm can't check an offset pointer - VblankGetOffsetSucces: error has to be equel TDM_ERROR_NONE Change-Id: If346f47e01de9fe884563f9ddaa12dcd26142884 Signed-off-by: Roman Marchenko --- utests/src/ut_tdm_vblank.cpp | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/utests/src/ut_tdm_vblank.cpp b/utests/src/ut_tdm_vblank.cpp index 8f61790..fe4368d 100644 --- a/utests/src/ut_tdm_vblank.cpp +++ b/utests/src/ut_tdm_vblank.cpp @@ -460,7 +460,7 @@ TEST_F(TDMVblank, VblankDestroyWrongVblankPtr) { SKIP_FLAG(has_output); - ASSERT_EXIT({tdm_vblank_destroy((tdm_vblank *)0xFFFFFFFF);}, + ASSERT_EXIT({tdm_vblank_destroy((tdm_vblank *)0xFFFFFFFF); exit(0);}, ::testing::ExitedWithCode(0), ""); } @@ -872,19 +872,6 @@ TEST_F(TDMVblank, VblankGetOffsetFailWrongVblankPtr) ::testing::ExitedWithCode(0), ""); } -TEST_F(TDMVblank, VblankGetOffsetFailWrongOffsetPtr) -{ - tdm_error error = TDM_ERROR_BAD_MODULE; - SKIP_FLAG(has_output); - - ASSERT_EXIT({error = tdm_vblank_get_offset(default_vblank, (int *)0xFFFFFFFF); - if (error == TDM_ERROR_NONE) - exit(1); - else - exit(0);}, - ::testing::ExitedWithCode(0), ""); -} - TEST_F(TDMVblank, VblankGetOffsetSuccesWithoutSet) { tdm_error error; @@ -905,10 +892,10 @@ TEST_F(TDMVblank, VblankGetOffsetSucces) SKIP_FLAG(has_output); error = tdm_vblank_set_offset(default_vblank, set_offset); - ASSERT_TRUE(error != TDM_ERROR_NONE); + ASSERT_TRUE(error == TDM_ERROR_NONE); error = tdm_vblank_get_offset(default_vblank, &ret_offset); - ASSERT_TRUE(error != TDM_ERROR_NONE); + ASSERT_TRUE(error == TDM_ERROR_NONE); ASSERT_TRUE(set_offset == ret_offset); } -- 2.7.4 From 2950e1e558bec772cd75282ffd4dfa17042d65b5 Mon Sep 17 00:00:00 2001 From: Roman Marchenko Date: Mon, 11 Dec 2017 14:14:14 +0200 Subject: [PATCH 16/16] utest: fix wrong tests for tdm_hwc_window.c - check incorrect composition types Change-Id: I22f93ab4c609afe805abdbaca9b3cf62c484828b Signed-off-by: Roman Marchenko --- src/tdm_hwc_window.c | 3 +++ utests/src/ut_tdm_hwc_window.cpp | 4 +--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/tdm_hwc_window.c b/src/tdm_hwc_window.c index 24b6207..f9b735c 100644 --- a/src/tdm_hwc_window.c +++ b/src/tdm_hwc_window.c @@ -138,6 +138,9 @@ tdm_hwc_window_set_composition_type(tdm_hwc_window *hwc_window, tdm_func_hwc_window *func_hwc_window = NULL; HWC_WINDOW_FUNC_ENTRY(); + TDM_RETURN_VAL_IF_FAIL(composition_type >= TDM_COMPOSITION_NONE, TDM_ERROR_INVALID_PARAMETER); + TDM_RETURN_VAL_IF_FAIL(composition_type <= TDM_COMPOSITION_CURSOR, TDM_ERROR_INVALID_PARAMETER); + TDM_RETURN_VAL_IF_FAIL(composition_type != TDM_COMPOSITION_DEVICE_CANDIDATE, TDM_ERROR_INVALID_PARAMETER); _pthread_mutex_lock(&private_display->lock); diff --git a/utests/src/ut_tdm_hwc_window.cpp b/utests/src/ut_tdm_hwc_window.cpp index ed12a59..043d4c8 100644 --- a/utests/src/ut_tdm_hwc_window.cpp +++ b/utests/src/ut_tdm_hwc_window.cpp @@ -469,9 +469,7 @@ TEST_F(TDMHwcWindow, SetCompositionTypeFailInvalieCompositionType) for (int i = 0; i < hwc_count; i++) { error = tdm_hwc_window_set_composition_type(hwc_wins[i], TDM_COMPOSITION_DEVICE_CANDIDATE); ASSERT_NE(TDM_ERROR_NONE, error); - error = tdm_hwc_window_set_composition_type(hwc_wins[i], TDM_COMPOSITION_CLIENT_CANDIDATE); - ASSERT_NE(TDM_ERROR_NONE, error); - error = tdm_hwc_window_set_composition_type(hwc_wins[i], tdm_hwc_window_composition(TDM_COMPOSITION_CLIENT+1)); + error = tdm_hwc_window_set_composition_type(hwc_wins[i], tdm_hwc_window_composition(TDM_COMPOSITION_NONE-1)); ASSERT_NE(TDM_ERROR_NONE, error); } } -- 2.7.4