From e87df648c248d1d78fb7b6268bbf3ff2d8f93743 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 9 Jan 2018 14:55:27 +0900 Subject: [PATCH 01/16] Revert "vblank: return TDM_ERROR_TIMEOUT when timeout occurs" This reverts commit dc1e81c0f4f0c6e6c4c0d4d553cf8ba730dfb4f5. Change-Id: I2e1b765e34bf406dcb40a44f0658246e7e43d52a --- include/tdm_common.h | 1 - src/tdm_vblank.c | 148 ++++----------------------------------------------- 2 files changed, 9 insertions(+), 140 deletions(-) diff --git a/include/tdm_common.h b/include/tdm_common.h index cfc031c..b170c48 100644 --- a/include/tdm_common.h +++ b/include/tdm_common.h @@ -68,7 +68,6 @@ typedef enum { TDM_ERROR_NO_CAPABILITY = -9, /**< no capability */ TDM_ERROR_DPMS_OFF = -10, /**< dpms off */ TDM_ERROR_OUTPUT_DISCONNECTED = -11, /**< output disconnected */ - TDM_ERROR_TIMEOUT = -12, /**< timeout */ } tdm_error; /** diff --git a/src/tdm_vblank.c b/src/tdm_vblank.c index 99cb744..e0ca079 100644 --- a/src/tdm_vblank.c +++ b/src/tdm_vblank.c @@ -128,9 +128,6 @@ typedef struct _tdm_private_vblank { /* for SW */ tdm_event_loop_source *SW_timer; struct list_head SW_wait_list; - - /* for timeout */ - tdm_event_loop_source *timeout_timer; } tdm_private_vblank; struct _tdm_vblank_wait_info { @@ -175,9 +172,6 @@ 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); -static void _tdm_vblank_timeout_timer_update(tdm_private_vblank *private_vblank, int ms_delay); -static void _tdm_vblank_get_client_information(tdm_private_vblank *private_vblank, - pid_t *pid, const char **name); #if 0 static void @@ -338,13 +332,6 @@ _tdm_vblank_free_HW_wait(tdm_private_vblank *private_vblank, tdm_error error, un { tdm_vblank_wait_info *w = NULL, *ww = NULL; - if (!LIST_IS_EMPTY(&private_vblank->SW_wait_list)) - TDM_NEVER_GET_HERE(); - - tdm_display_lock(private_vblank->dpy); - _tdm_vblank_timeout_timer_update(private_vblank, 0); - tdm_display_unlock(private_vblank->dpy); - 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); @@ -715,20 +702,14 @@ tdm_vblank_destroy(tdm_vblank *vblank) tdm_output_remove_change_handler(private_vblank->output, _tdm_vblank_cb_output_change, private_vblank); + _tdm_vblank_free_HW_wait(private_vblank, 0, 0); + LIST_FOR_EACH_ENTRY_SAFE(w, ww, &private_vblank->SW_wait_list, link) { LIST_DEL(&w->link); _tdm_vblank_valid_list_del(&w->valid_link); free(w); } - _tdm_vblank_free_HW_wait(private_vblank, 0, 0); - - if (private_vblank->timeout_timer) { - tdm_display_lock(private_vblank->dpy); - tdm_event_loop_source_remove(private_vblank->timeout_timer); - tdm_display_unlock(private_vblank->dpy); - } - VIN("destroyed"); free(private_vblank); @@ -931,84 +912,6 @@ tdm_vblank_get_enable_fake(tdm_vblank *vblank, unsigned int *enable_fake) } static tdm_error -_tdm_vblank_timeout_timer_cb(void *user_data) -{ - tdm_private_vblank *private_vblank = user_data; - tdm_vblank_wait_info *w = NULL, *ww = NULL; - tdm_error error = TDM_ERROR_TIMEOUT; - pid_t pid; - const char *proc_name; - - TDM_RETURN_VAL_IF_FAIL(tdm_vblank_is_valid(private_vblank), TDM_ERROR_OPERATION_FAILED); - - _tdm_vblank_get_client_information(private_vblank, &pid, &proc_name); - - if (!LIST_IS_EMPTY(&private_vblank->HW_wait_list)) { - - VER("HW vblank TIMEOUT!! (pid: %u, name: %s)", pid, proc_name); - - 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 (w->func) - w->func(private_vblank, error, 0, 0, 0, w->user_data); - - free(w); - } - } - - if (!LIST_IS_EMPTY(&private_vblank->SW_wait_list)) { - - VER("SW vblank TIMEOUT!! (pid: %u, name: %s)", pid, proc_name); - - LIST_FOR_EACH_ENTRY_SAFE(w, ww, &private_vblank->SW_wait_list, link) { - LIST_DEL(&w->link); - _tdm_vblank_valid_list_del(&w->valid_link); - - if (w->func) - w->func(private_vblank, error, 0, 0, 0, w->user_data); - - free(w); - } - } - - return TDM_ERROR_NONE; -} - -static void -_tdm_vblank_timeout_timer_update(tdm_private_vblank *private_vblank, int ms_delay) -{ - tdm_error ret; - - if (!private_vblank->timeout_timer) { - private_vblank->timeout_timer = - tdm_event_loop_add_timer_handler(private_vblank->dpy, - _tdm_vblank_timeout_timer_cb, - private_vblank, - &ret); - if (!private_vblank->timeout_timer) { - VER("couldn't add timer"); - return; - } - VIN("Create Timeout timer"); - } - - ret = tdm_event_loop_source_timer_update(private_vblank->timeout_timer, ms_delay); - if (ret != TDM_ERROR_NONE) { - VER("couldn't update timer"); - return; - } - - if (ms_delay != 0) - VDB("timeout timer updated"); - else - VDB("timeout timer disabled"); -} - -static tdm_error _tdm_vblank_sw_timer_update(tdm_private_vblank *private_vblank) { tdm_vblank_wait_info *first_wait_info = NULL; @@ -1114,13 +1017,6 @@ _tdm_vblank_cb_vblank_HW(tdm_output *output, unsigned int sequence, VWR("couldn't update sw timer"); } - if (!LIST_IS_EMPTY(&private_vblank->SW_wait_list)) - TDM_NEVER_GET_HERE(); - - tdm_display_lock(private_vblank->dpy); - _tdm_vblank_timeout_timer_update(private_vblank, 0); - tdm_display_unlock(private_vblank->dpy); - LIST_DEL(&wait_info->link); _tdm_vblank_valid_list_del(&wait_info->valid_link); @@ -1272,11 +1168,6 @@ tdm_vblank_cb_vblank_SW(tdm_vblank *vblank, double vblank_stamp) return TDM_ERROR_OPERATION_FAILED; } - if (!LIST_IS_EMPTY(&private_vblank->HW_wait_list)) - TDM_NEVER_GET_HERE(); - - _tdm_vblank_timeout_timer_update(private_vblank, 0); - first_wait_info = container_of(private_vblank->SW_wait_list.next, first_wait_info, link); TDM_RETURN_VAL_IF_FAIL(first_wait_info != NULL, TDM_ERROR_OPERATION_FAILED); @@ -1496,10 +1387,6 @@ tdm_vblank_wait(tdm_vblank *vblank, unsigned int req_sec, unsigned int req_usec, /* LCOV_EXCL_STOP */ } - tdm_display_lock(private_vblank->dpy); - _tdm_vblank_timeout_timer_update(private_vblank, 2000); - tdm_display_unlock(private_vblank->dpy); - return TDM_ERROR_NONE; } @@ -1596,29 +1483,6 @@ tdm_vblank_get_stamp(tdm_vblank *vblank) return private_vblank->stamp; } -static void -_tdm_vblank_get_client_information(tdm_private_vblank *private_vblank, pid_t *pid, const char **name) -{ - struct wl_client *client; - - if (!private_vblank->resource) - goto no_client; - - client = wl_resource_get_client(private_vblank->resource); - if (!client) - goto no_client; - - wl_client_get_credentials(client, pid, NULL, NULL); - *name = tdm_server_get_client_name(*pid); - - return; - -no_client: - *pid = 0; - *name = NULL; - return; -} - /* LCOV_EXCL_START */ INTERN void tdm_vblank_get_vblank_list_information(tdm_display *dpy, char *reply, int *len) @@ -1636,7 +1500,13 @@ tdm_vblank_get_vblank_list_information(tdm_display *dpy, char *reply, int *len) const char *proc_name = NULL; pid_t pid = 0; - _tdm_vblank_get_client_information(v, &pid, &proc_name); + if (v->resource) { + struct wl_client *client = wl_resource_get_client(v->resource); + if (client) { + wl_client_get_credentials(client, &pid, NULL, NULL); + proc_name = tdm_server_get_client_name(pid); + } + } TDM_SNPRINTF(reply, len, "%-12s %u %u %d %u %s (pid: %u)\n", v->name, v->fps, v->ignore_global_fps, v->offset, v->enable_fake, -- 2.7.4 From 13276f714fa4faf1485df81d2db169bb300e9bc4 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 9 Jan 2018 14:55:54 +0900 Subject: [PATCH 02/16] package version up to 1.11.3 Change-Id: I202d8808f01f842fdab3999224455514cc31c4d0 --- packaging/libtdm.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index 0a99efd..7efa83f 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -1,7 +1,7 @@ %define UTEST_PACKAGE 1 Name: libtdm -Version: 1.11.2 +Version: 1.11.3 Release: 0 Summary: User Library of Tizen Display Manager Group: Development/Libraries -- 2.7.4 From 7fe9c76c28843a1b88057ced0e99cf33146feaad Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 9 Jan 2018 16:30:00 +0900 Subject: [PATCH 03/16] monitor: enhance vblank_list information Change-Id: I0624e291be53f0abbf8d991969de3e6a6b353759 --- src/tdm_vblank.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 6 deletions(-) diff --git a/src/tdm_vblank.c b/src/tdm_vblank.c index e0ca079..abba414 100644 --- a/src/tdm_vblank.c +++ b/src/tdm_vblank.c @@ -115,6 +115,7 @@ typedef struct _tdm_private_vblank { double vblank_gap; unsigned int quotient; + int last_interval; unsigned int last_seq; double last_time; @@ -340,6 +341,9 @@ _tdm_vblank_free_HW_wait(tdm_private_vblank *private_vblank, tdm_error error, un tdm_output_remove_vblank_handler_internal(private_vblank->output, _tdm_vblank_cb_vblank_HW, w); tdm_display_unlock(private_vblank->dpy); + VDB("wait(%p) last(%.6f) sequence(%u) done (error:%d, call_cb:%u)", + w, 0, w->target_seq, error, call_cb); + if (call_cb && w->func) w->func(private_vblank, error, 0, 0, 0, w->user_data); @@ -657,6 +661,7 @@ tdm_vblank_create(tdm_display *dpy, tdm_output *output, tdm_error *error) private_vblank->output = output; private_vblank->check_HW_or_SW = 1; private_vblank->fps_changeable = 1; + private_vblank->last_interval = -1; _tdm_vblank_update_output_info(private_vblank); @@ -958,6 +963,8 @@ _tdm_vblank_sw_timer_update(tdm_private_vblank *private_vblank) VIN("Create SW timer"); } + private_vblank->last_interval = ms_delay; + ret = tdm_event_loop_source_timer_update(private_vblank->SW_timer, ms_delay); if (ret != TDM_ERROR_NONE) { /* LCOV_EXCL_START */ @@ -1103,6 +1110,8 @@ _tdm_vblank_wait_HW(tdm_vblank_wait_info *wait_info) skip, hw_interval, wait_info->target_seq); } + private_vblank->last_interval = hw_interval; + if (private_vblank->add_front) ret = tdm_output_wait_vblank_add_front(private_vblank->output, hw_interval, 0, _tdm_vblank_cb_vblank_HW, wait_info); @@ -1483,22 +1492,46 @@ tdm_vblank_get_stamp(tdm_vblank *vblank) return private_vblank->stamp; } +static unsigned int +_tdm_vblank_get_waiting_count(tdm_private_vblank *private_vblank) +{ + tdm_vblank_wait_info *wait_info = NULL; + unsigned int count = 0; + + LIST_FOR_EACH_ENTRY(wait_info, &private_vblank->HW_wait_list, link) { + count++; + } + + LIST_FOR_EACH_ENTRY(wait_info, &private_vblank->SW_wait_list, link) { + count++; + } + + return count; +} + /* LCOV_EXCL_START */ INTERN void tdm_vblank_get_vblank_list_information(tdm_display *dpy, char *reply, int *len) { tdm_private_vblank *v = NULL; + tdm_output_dpms dpms = TDM_OUTPUT_DPMS_OFF; + tdm_output *output = tdm_display_get_output(dpy, 0, NULL); + + if (output) + tdm_output_get_dpms(output, &dpms); TDM_SNPRINTF(reply, len, "[Client Vblank List]\n"); + TDM_SNPRINTF(reply, len, "* DPMS: %s\n", tdm_dpms_str(dpms)); TDM_SNPRINTF(reply, len, "* global fps: %u\n", vblank_global_fps); - TDM_SNPRINTF(reply, len, "---------------------------------------------------------------\n"); - TDM_SNPRINTF(reply, len, "name fps ignore offset fake process\n"); - TDM_SNPRINTF(reply, len, "---------------------------------------------------------------\n"); + TDM_SNPRINTF(reply, len, "----------------------------------------------------------------------------------\n"); + TDM_SNPRINTF(reply, len, "Name Type Wait Interval Sequence Fps Ignore Offset Fake Process\n"); + TDM_SNPRINTF(reply, len, "----------------------------------------------------------------------------------\n"); pthread_mutex_lock(&valid_list_lock); LIST_FOR_EACH_ENTRY(v, &valid_vblank_list, valid_link) { const char *proc_name = NULL; pid_t pid = 0; + unsigned int count; if (v->resource) { struct wl_client *client = wl_resource_get_client(v->resource); @@ -1508,9 +1541,18 @@ tdm_vblank_get_vblank_list_information(tdm_display *dpy, char *reply, int *len) } } - TDM_SNPRINTF(reply, len, "%-12s %u %u %d %u %s (pid: %u)\n", - v->name, v->fps, v->ignore_global_fps, v->offset, v->enable_fake, - (proc_name) ? proc_name : "Unknown", pid); + count = _tdm_vblank_get_waiting_count(v); + + TDM_SNPRINTF(reply, len, "%-8s(%p) ", v->name, v); + TDM_SNPRINTF(reply, len, "%-4s ", (v->last_type == VBLANK_EVENT_TYPE_HW) ? "HW" : "SW"); + TDM_SNPRINTF(reply, len, "%-4s ", (count > 0) ? "O" : " "); + TDM_SNPRINTF(reply, len, "%-8d ", v->last_interval); + TDM_SNPRINTF(reply, len, "%-8u ", v->last_seq); + TDM_SNPRINTF(reply, len, "%-3u ", v->fps); + TDM_SNPRINTF(reply, len, "%-6u ", v->ignore_global_fps); + TDM_SNPRINTF(reply, len, "%-6d ", v->offset); + TDM_SNPRINTF(reply, len, "%-4u ", v->enable_fake); + TDM_SNPRINTF(reply, len, "%s(pid:%d)\n", (proc_name) ? proc_name : "Unknown", pid); } pthread_mutex_unlock(&valid_list_lock); -- 2.7.4 From b2ac517c738abad46508a44b2435cee98f5f83ab Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 9 Jan 2018 18:07:55 +0900 Subject: [PATCH 04/16] package version up to 1.11.4 Change-Id: Iae258ccfd542896d4e5f91842c450b307242465d --- packaging/libtdm.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index 7efa83f..a551839 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -1,7 +1,7 @@ %define UTEST_PACKAGE 1 Name: libtdm -Version: 1.11.3 +Version: 1.11.4 Release: 0 Summary: User Library of Tizen Display Manager Group: Development/Libraries -- 2.7.4 From b90ed508ff9d10217e32a09a4d8fe6a129328d3b Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 10 Jan 2018 14:19:07 +0900 Subject: [PATCH 05/16] correct printf formats Change-Id: I8b414e1f2016298699a7f1c1dadc85b0414d910f --- src/tdm_capture.c | 2 +- src/tdm_layer.c | 2 +- src/tdm_pp.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tdm_capture.c b/src/tdm_capture.c index 9d924c2..add764a 100644 --- a/src/tdm_capture.c +++ b/src/tdm_capture.c @@ -457,7 +457,7 @@ tdm_capture_set_info(tdm_capture *capture, tdm_info_capture *info) info->frequency = private_output->current_mode->vrefresh; } - TDM_INFO("capture(%p) info: dst(%dx%d %d,%d %dx%d %c%c%c%c) trans(%d) type(%d) freq(%d) flags(%x)", + TDM_INFO("capture(%p) info: dst(%ux%u %u,%u %ux%u %c%c%c%c) trans(%d) type(%d) freq(%d) flags(%x)", private_capture, info->dst_config.size.h, info->dst_config.size.v, info->dst_config.pos.x, info->dst_config.pos.y, diff --git a/src/tdm_layer.c b/src/tdm_layer.c index b906f74..0e66228 100644 --- a/src/tdm_layer.c +++ b/src/tdm_layer.c @@ -240,7 +240,7 @@ tdm_layer_set_info(tdm_layer *layer, tdm_info_layer *info) else snprintf(fmtstr, 128, "NONE"); - TDM_INFO("layer(%p) info: src(%dx%d %d,%d %dx%d %s) dst(%d,%d %dx%d) trans(%d)", + TDM_INFO("layer(%p) info: src(%ux%u %u,%u %ux%u %s) dst(%u,%u %ux%u) trans(%d)", private_layer, info->src_config.size.h, info->src_config.size.v, info->src_config.pos.x, info->src_config.pos.y, info->src_config.pos.w, info->src_config.pos.h, diff --git a/src/tdm_pp.c b/src/tdm_pp.c index 80eb330..ccec73f 100644 --- a/src/tdm_pp.c +++ b/src/tdm_pp.c @@ -366,7 +366,7 @@ tdm_pp_set_info(tdm_pp *pp, tdm_info_pp *info) /* LCOV_EXCL_STOP */ } - TDM_INFO("pp(%p) info: src(%dx%d %d,%d %dx%d %c%c%c%c) dst(%dx%d %d,%d %dx%d %c%c%c%c) trans(%d) sync(%d) flags(%x)", + TDM_INFO("pp(%p) info: src(%ux%u %u,%u %ux%u %c%c%c%c) dst(%ux%u %u,%u %ux%u %c%c%c%c) trans(%d) sync(%d) flags(%x)", private_pp, info->src_config.size.h, info->src_config.size.v, info->src_config.pos.x, info->src_config.pos.y, info->src_config.pos.w, info->src_config.pos.h, -- 2.7.4 From 142120b6f9cb4f48d10fcaba19a6b6702654cc1a Mon Sep 17 00:00:00 2001 From: Junkyeong Kim Date: Thu, 11 Jan 2018 10:32:28 +0900 Subject: [PATCH 06/16] add pp scanout capability can be executed converting only scanout buffer. Change-Id: I9c1143ebf16f7be394709789b71da149e5356d79 Signed-off-by: Junkyeong Kim --- include/tdm_common.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/tdm_common.h b/include/tdm_common.h index b170c48..d706e19 100644 --- a/include/tdm_common.h +++ b/include/tdm_common.h @@ -152,6 +152,7 @@ typedef enum { TDM_PP_CAPABILITY_ASYNC = (1 << 1), /**< The pp device supports asynchronous operation */ TDM_PP_CAPABILITY_SCALE = (1 << 4), /**< The pp device supports scale operation */ TDM_PP_CAPABILITY_TRANSFORM = (1 << 5), /**< The pp device supports transform operation */ + TDM_PP_CAPABILITY_SCANOUT = (1 << 6), /**< The pp device supports only scanout buffer */ } tdm_pp_capability; /** -- 2.7.4 From 020864ee8e611fc504576a7af5c485e05342210c Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Thu, 11 Jan 2018 19:21:09 +0900 Subject: [PATCH 07/16] hwc: change the type of the zpos Change-Id: Ibc014c34f2414cf7b186b7c740a085b21d8cfed7 --- include/tdm.h | 2 +- include/tdm_backend.h | 2 +- src/tdm_hwc_window.c | 2 +- utests/src/ut_tdm_hwc_window.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/tdm.h b/include/tdm.h index 3812842..18ef948 100644 --- a/include/tdm.h +++ b/include/tdm.h @@ -983,7 +983,7 @@ tdm_hwc_window_get_tbm_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error * @since 2.0.0 */ tdm_error -tdm_hwc_window_set_zpos(tdm_hwc_window *hwc_window, uint32_t zpos); +tdm_hwc_window_set_zpos(tdm_hwc_window *hwc_window, int32_t zpos); /** * @brief Sets the desired composition type of the given window. diff --git a/include/tdm_backend.h b/include/tdm_backend.h index 99eff29..fa36479 100644 --- a/include/tdm_backend.h +++ b/include/tdm_backend.h @@ -842,7 +842,7 @@ typedef struct _tdm_func_window { * @param[in] z the new Z order * @return #TDM_ERROR_NONE if success. Otherwise, error value. */ - tdm_error (*hwc_window_set_zpos)(tdm_hwc_window *hwc_window, uint32_t zpos); + tdm_error (*hwc_window_set_zpos)(tdm_hwc_window *hwc_window, int32_t zpos); /** * @brief Sets the desired composition type of the given window. diff --git a/src/tdm_hwc_window.c b/src/tdm_hwc_window.c index 88a8e9d..9fb69b6 100644 --- a/src/tdm_hwc_window.c +++ b/src/tdm_hwc_window.c @@ -104,7 +104,7 @@ tdm_hwc_window_get_tbm_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error } EXTERN tdm_error -tdm_hwc_window_set_zpos(tdm_hwc_window *hwc_window, uint32_t zpos) +tdm_hwc_window_set_zpos(tdm_hwc_window *hwc_window, int32_t zpos) { tdm_func_hwc_window *func_hwc_window = NULL; diff --git a/utests/src/ut_tdm_hwc_window.cpp b/utests/src/ut_tdm_hwc_window.cpp index ffea35f..48472d3 100644 --- a/utests/src/ut_tdm_hwc_window.cpp +++ b/utests/src/ut_tdm_hwc_window.cpp @@ -446,7 +446,7 @@ TEST_F(TDMHwcWindow, GetBufferQueueSuccessful) } } -/* tdm_error tdm_hwc_window_set_zpos(tdm_hwc_window *hwc_window, uint32_t zpos); */ +/* tdm_error tdm_hwc_window_set_zpos(tdm_hwc_window *hwc_window, int32_t zpos); */ TEST_F(TDMHwcWindow, SetZposFailNull) { error = tdm_hwc_window_set_zpos(NULL, 1); -- 2.7.4 From 726c06f3a555bed0c3dc1d0e1488faf7d5b1ef8f Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Fri, 12 Jan 2018 13:00:38 +0900 Subject: [PATCH 08/16] hwc: add TDM_COMPOSITION_VIDEO Change-Id: Ib1ed904c821ab83cad4d79f8dc794649067b6228 --- include/tdm_types.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/tdm_types.h b/include/tdm_types.h index ebb8291..6813c72 100644 --- a/include/tdm_types.h +++ b/include/tdm_types.h @@ -187,6 +187,11 @@ typedef enum { * still permit the device to composite the layer. */ TDM_COMPOSITION_CURSOR = 4, + /** This type is for the VIDEO window which can be set to the reserved hw overlay + * which is assigned by the device. + * + * Normally, this VIDEO window displays under the primary hw overlayer of the output. */ + TDM_COMPOSITION_VIDEO = 5, } tdm_hwc_window_composition; /** -- 2.7.4 From ee8de55b67792c568eb4fbea8630a299d8138963 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Fri, 12 Jan 2018 13:18:05 +0900 Subject: [PATCH 09/16] package version up to 1.11.4 Change-Id: Ibbdc2481446d2f5e9bb6d5556ce57e0103af83d2 --- packaging/libtdm.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index a551839..8abd7e0 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -1,7 +1,7 @@ %define UTEST_PACKAGE 1 Name: libtdm -Version: 1.11.4 +Version: 1.11.5 Release: 0 Summary: User Library of Tizen Display Manager Group: Development/Libraries -- 2.7.4 From 1c3c5d57f8f8ede726c40e3116254c93b43e1906 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Wed, 17 Jan 2018 14:04:32 +0900 Subject: [PATCH 10/16] hwc: change the condition at set_composition_type Change-Id: Ie5ac8b7fe49bf3c65f12368f3bfdb612c13a099e --- src/tdm_hwc_window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tdm_hwc_window.c b/src/tdm_hwc_window.c index 9fb69b6..47ea149 100644 --- a/src/tdm_hwc_window.c +++ b/src/tdm_hwc_window.c @@ -139,7 +139,7 @@ tdm_hwc_window_set_composition_type(tdm_hwc_window *hwc_window, 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_VIDEO, TDM_ERROR_INVALID_PARAMETER); _pthread_mutex_lock(&private_display->lock); -- 2.7.4 From e77e3b05eea42d515618712dfc8cdc1d8569fc3f Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 17 Jan 2018 12:42:14 +0900 Subject: [PATCH 11/16] correct the header file dependency Change-Id: Icf6348180240bf23ae54f0c6a74e7ee193047b81 --- client/tdm_client.c | 3 +- client/tdm_client.h | 4 +- client/tdm_client_types.h | 4 +- client/tdm_monitor.c | 8 +- include/tdm_common.h | 13 -- include/tdm_helper.h | 3 +- include/tdm_types.h | 17 +- src/tdm.c | 6 +- src/tdm_backend.c | 2 - src/tdm_buffer.c | 2 - src/tdm_capture.c | 3 - src/tdm_display.c | 3 - src/tdm_event_loop.c | 4 - src/tdm_helper.c | 9 - src/tdm_hwc_window.c | 5 +- src/tdm_layer.c | 7 +- src/tdm_macro.h | 74 +++++- src/tdm_monitor_server.c | 8 - src/tdm_output.c | 5 +- src/tdm_pp.c | 3 - src/tdm_private.h | 564 +--------------------------------------------- src/tdm_private_types.h | 497 ++++++++++++++++++++++++++++++++++++++++ src/tdm_server.c | 5 +- src/tdm_thread.c | 4 - src/tdm_thread.h | 65 ++++++ src/tdm_vblank.c | 3 - tools/buffers.c | 2 +- tools/tdm_test_client.c | 2 +- tools/tdm_test_server.c | 10 +- 29 files changed, 687 insertions(+), 648 deletions(-) create mode 100644 src/tdm_private_types.h create mode 100644 src/tdm_thread.h diff --git a/client/tdm_client.c b/client/tdm_client.c index a855e8f..349c454 100644 --- a/client/tdm_client.c +++ b/client/tdm_client.c @@ -43,13 +43,14 @@ #include #include +#include + #include "tdm_client.h" #include "tdm_log.h" #include "tdm_macro.h" #include "tdm_list.h" #include "tdm.h" #include "tdm_private.h" -#include "tdm-client-protocol.h" typedef struct _tdm_private_client_vblank tdm_private_client_vblank; diff --git a/client/tdm_client.h b/client/tdm_client.h index 175bb45..a96e4d4 100644 --- a/client/tdm_client.h +++ b/client/tdm_client.h @@ -36,6 +36,8 @@ #ifndef _TDM_CLIENT_H_ #define _TDM_CLIENT_H_ +#include "tdm_client_types.h" + #ifdef __cplusplus extern "C" { #endif @@ -49,8 +51,6 @@ extern "C" { * @endcode */ -#include - /** * @brief Create a TDM client object. * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. diff --git a/client/tdm_client_types.h b/client/tdm_client_types.h index 94807ec..f799c0b 100644 --- a/client/tdm_client_types.h +++ b/client/tdm_client_types.h @@ -36,6 +36,8 @@ #ifndef _TDM_CLIENT_TYPES_H_ #define _TDM_CLIENT_TYPES_H_ +#include "tdm_common.h" + #ifdef __cplusplus extern "C" { #endif @@ -45,8 +47,6 @@ extern "C" { * @brief The header file which defines Enumerations and Structures for client. */ -#include - /** * @deprecated */ diff --git a/client/tdm_monitor.c b/client/tdm_monitor.c index 60ce16d..30a1a12 100644 --- a/client/tdm_monitor.c +++ b/client/tdm_monitor.c @@ -37,10 +37,10 @@ #include "config.h" #endif -#include -#include -#include -#include +#include "tdm_log.h" +#include "tdm_macro.h" +#include "tdm_list.h" +#include "tdm-client-protocol.h" #undef exit_if_fail #define exit_if_fail(cond) { \ diff --git a/include/tdm_common.h b/include/tdm_common.h index d706e19..dd01247 100644 --- a/include/tdm_common.h +++ b/include/tdm_common.h @@ -279,11 +279,6 @@ typedef struct _tdm_pos { unsigned int h; } tdm_pos; -typedef struct _tdm_hwc_region { - unsigned int num_rects; - tdm_pos const *rects; -} tdm_hwc_region; - /** * @brief The tdm value type enumeration */ @@ -307,14 +302,6 @@ typedef union { uint64_t u64; } tdm_value; -/** - * @brief The hwc window flag enumeration - * @since 2.0.0 - */ -typedef enum { - TDM_HWC_WINDOW_FLAG_NONE = 0, -} tdm_hwc_window_flag; - #ifdef __cplusplus } #endif diff --git a/include/tdm_helper.h b/include/tdm_helper.h index 8bae8fa..4c501e3 100644 --- a/include/tdm_helper.h +++ b/include/tdm_helper.h @@ -36,9 +36,10 @@ #ifndef _TDM_HELPER_H_ #define _TDM_HELPER_H_ -#include "tdm_types.h" #include +#include "tdm_types.h" + #ifdef __cplusplus extern "C" { #endif diff --git a/include/tdm_types.h b/include/tdm_types.h index 6813c72..a20049f 100644 --- a/include/tdm_types.h +++ b/include/tdm_types.h @@ -38,6 +38,8 @@ #include +#include "tdm_common.h" + #ifdef __cplusplus extern "C" { #endif @@ -57,8 +59,6 @@ extern "C" { * @endcode */ -#include - typedef enum { TDM_EVENT_LOOP_READABLE = (1 << 0), TDM_EVENT_LOOP_WRITABLE = (1 << 1), @@ -116,6 +116,11 @@ typedef struct _tdm_hwc_window_info { tdm_transform transform; } tdm_hwc_window_info; +typedef struct _tdm_hwc_region { + unsigned int num_rects; + tdm_pos const *rects; +} tdm_hwc_region; + /** * @brief The pp info structre */ @@ -195,6 +200,14 @@ typedef enum { } tdm_hwc_window_composition; /** + * @brief The hwc window flag enumeration + * @since 2.0.0 + */ +typedef enum { + TDM_HWC_WINDOW_FLAG_NONE = 0, +} tdm_hwc_window_flag; + +/** * @brief The tdm display object */ typedef void tdm_display; diff --git a/src/tdm.c b/src/tdm.c index 9492336..30b4a91 100644 --- a/src/tdm.c +++ b/src/tdm.c @@ -37,11 +37,7 @@ #include "config.h" #endif -#include "tdm.h" -#include "tdm_backend.h" #include "tdm_private.h" -#include "tdm_helper.h" -#include pthread_mutex_t tdm_mutex_check_lock = PTHREAD_MUTEX_INITIALIZER; int tdm_mutex_locked; @@ -790,7 +786,7 @@ static tdm_error _tdm_display_load_module_with_file(tdm_private_display *private_display, const char *file) { - char path[PATH_MAX] = {0,}; + char path[TDM_PATH_LEN] = {0,}; tdm_backend_module *module_data; void *module; tdm_error ret; diff --git a/src/tdm_backend.c b/src/tdm_backend.c index f8d36d3..e6463bc 100644 --- a/src/tdm_backend.c +++ b/src/tdm_backend.c @@ -37,8 +37,6 @@ #include "config.h" #endif -#include "tdm.h" -#include "tdm_backend.h" #include "tdm_private.h" #define BACKEND_FUNC_ENTRY() \ diff --git a/src/tdm_buffer.c b/src/tdm_buffer.c index 6037dc2..3c9fb48 100644 --- a/src/tdm_buffer.c +++ b/src/tdm_buffer.c @@ -37,9 +37,7 @@ #include "config.h" #endif -#include "tdm.h" #include "tdm_private.h" -#include "tdm_list.h" static int tdm_buffer_key; #define TDM_BUFFER_KEY ((unsigned long)&tdm_buffer_key) diff --git a/src/tdm_capture.c b/src/tdm_capture.c index add764a..de7439c 100644 --- a/src/tdm_capture.c +++ b/src/tdm_capture.c @@ -37,10 +37,7 @@ #include "config.h" #endif -#include "tdm.h" -#include "tdm_backend.h" #include "tdm_private.h" -#include "tdm_helper.h" #define CAPTURE_FUNC_ENTRY() \ tdm_func_capture *func_capture; \ diff --git a/src/tdm_display.c b/src/tdm_display.c index a009756..83fbec3 100644 --- a/src/tdm_display.c +++ b/src/tdm_display.c @@ -37,10 +37,7 @@ #include "config.h" #endif -#include "tdm.h" -#include "tdm_backend.h" #include "tdm_private.h" -#include "tdm_helper.h" #define COUNT_MAX 10 diff --git a/src/tdm_event_loop.c b/src/tdm_event_loop.c index bb0ed57..4be20ce 100644 --- a/src/tdm_event_loop.c +++ b/src/tdm_event_loop.c @@ -37,11 +37,7 @@ #include "config.h" #endif -#include "tdm.h" #include "tdm_private.h" -#include "tdm_list.h" - -#include typedef struct _tdm_event_loop_source_base { struct wl_event_source *wl_source; diff --git a/src/tdm_helper.c b/src/tdm_helper.c index 74d8bb5..c8bcb1c 100644 --- a/src/tdm_helper.c +++ b/src/tdm_helper.c @@ -38,18 +38,9 @@ #endif #include -#include -#include -#include -#include -#include -#include #include -#include -#include "tdm.h" #include "tdm_private.h" -#include "tdm_helper.h" #define PNG_DEPTH 8 diff --git a/src/tdm_hwc_window.c b/src/tdm_hwc_window.c index 47ea149..40820ce 100644 --- a/src/tdm_hwc_window.c +++ b/src/tdm_hwc_window.c @@ -37,10 +37,7 @@ #include "config.h" #endif -#include "tdm.h" -#include "tdm_backend.h" #include "tdm_private.h" -#include "tdm_helper.h" #define COUNT_MAX 10 @@ -240,7 +237,7 @@ _tdm_window_dump_buffer(tdm_hwc_window *hwc_window, tbm_surface_h buffer) tdm_private_output *private_output = private_window->private_output; unsigned int pipe; uint32_t zpos; - char fname[PATH_MAX]; + char fname[TDM_PATH_LEN]; pipe = private_output->pipe; zpos = private_window->zpos; diff --git a/src/tdm_layer.c b/src/tdm_layer.c index 0e66228..8ef46a6 100644 --- a/src/tdm_layer.c +++ b/src/tdm_layer.c @@ -37,10 +37,7 @@ #include "config.h" #endif -#include "tdm.h" -#include "tdm_backend.h" #include "tdm_private.h" -#include "tdm_helper.h" #define COUNT_MAX 10 @@ -291,8 +288,8 @@ _tdm_layer_dump_buffer(tdm_layer *layer, tbm_surface_h buffer) tdm_private_layer *private_layer = (tdm_private_layer*)layer; tdm_private_output *private_output = private_layer->private_output; unsigned int pipe; - char fname[PATH_MAX], bufs[PATH_MAX]; - int zpos, len = PATH_MAX; + char fname[TDM_PATH_LEN], bufs[TDM_PATH_LEN]; + int zpos, len = TDM_PATH_LEN; tdm_private_layer *l = NULL; char *p = bufs; int *remain = &len; diff --git a/src/tdm_macro.h b/src/tdm_macro.h index a55251e..78e2643 100644 --- a/src/tdm_macro.h +++ b/src/tdm_macro.h @@ -41,13 +41,17 @@ #include #include -#include #include +#include "tdm_private_types.h" +#include "tdm_thread.h" + #ifdef __cplusplus extern "C" { #endif +#define TDM_DUMP_DIR "/tmp" + #define TDM_SERVER_REPLY_MSG_LEN 8192 #define TDM_DEBUG_REPLY_MSG_LEN 2048 @@ -336,6 +340,74 @@ strtostr(char *buf, int len, char *str, char *delim) return str + len - 1; } +#ifdef HAVE_TTRACE +#include +#define TDM_TRACE_BEGIN(fmt, ...) traceBegin(TTRACE_TAG_GRAPHICS, fmt, ##__VA_ARGS__) +#define TDM_TRACE_END() traceEnd(TTRACE_TAG_GRAPHICS) +#define TDM_TRACE_ASYNC_BEGIN(key, name,...) traceAsyncBegin(TTRACE_TAG_GRAPHICS, key, name, ##__VA_ARGS__) +#define TDM_TRACE_ASYNC_END(key, name,...) traceAsyncEnd(TTRACE_TAG_GRAPHICS, key, name, ##__VA_ARGS__) +#define TDM_TRACE_COUNT(count, fmt, ...) traceCounter(TTRACE_TAG_GRAPHICS, count, fmt, ##__VA_ARGS__) +#define TDM_TRACE_MARK(fmt, ...) traceMark(TTRACE_TAG_GRAPHICS, fmt, ##__VA_ARGS__) +#else +#define TDM_TRACE_BEGIN(fmt, ...) +#define TDM_TRACE_END() +#define TDM_TRACE_ASYNC_BEGIN(key, name,...) +#define TDM_TRACE_ASYNC_END(key, name,...) +#define TDM_TRACE_COUNT(count, fmt, ...) +#define TDM_TRACE_MARK(fmt, ...) +#endif + + +extern pthread_mutex_t tdm_mutex_check_lock; +extern int tdm_mutex_locked; +extern const char *tdm_mutex_lock_func; +extern int tdm_mutex_lock_line; +extern const char *tdm_mutex_unlock_func; +extern int tdm_mutex_unlock_line; + +#define _pthread_mutex_lock(l) \ + do { \ + if (tdm_debug_module & TDM_DEBUG_MUTEX) \ + TDM_INFO("mutex lock"); \ + pthread_mutex_lock(l); \ + pthread_mutex_lock(&tdm_mutex_check_lock); \ + tdm_mutex_locked = 1; \ + tdm_mutex_lock_func = __FUNCTION__; \ + tdm_mutex_lock_line = __LINE__; \ + tdm_mutex_unlock_func = NULL; \ + tdm_mutex_unlock_line = 0; \ + pthread_mutex_unlock(&tdm_mutex_check_lock); \ + } while (0) + +#define _pthread_mutex_unlock(l) \ + do { \ + if (tdm_debug_module & TDM_DEBUG_MUTEX) \ + TDM_INFO("mutex unlock"); \ + pthread_mutex_lock(&tdm_mutex_check_lock); \ + tdm_mutex_locked = 0; \ + tdm_mutex_lock_func = NULL; \ + tdm_mutex_lock_line = 0; \ + tdm_mutex_unlock_func = __FUNCTION__; \ + tdm_mutex_unlock_line = __LINE__; \ + pthread_mutex_unlock(&tdm_mutex_check_lock); \ + pthread_mutex_unlock(l); \ + } while (0) + +static inline int TDM_MUTEX_IS_LOCKED(void) +{ + int ret; + /* if thread is not running, we don't need to consider mutex things. */ + if (!tdm_thread_is_running()) + return 1; + pthread_mutex_lock(&tdm_mutex_check_lock); + ret = (tdm_mutex_locked == 1); + pthread_mutex_unlock(&tdm_mutex_check_lock); + return ret; +} + +#define tdm_display_lock(dpy) _pthread_mutex_lock(&((tdm_private_display *)dpy)->lock) +#define tdm_display_unlock(dpy) _pthread_mutex_unlock(&((tdm_private_display *)dpy)->lock) + #ifdef __cplusplus } #endif diff --git a/src/tdm_monitor_server.c b/src/tdm_monitor_server.c index 7dbdc3c..8b28fa8 100644 --- a/src/tdm_monitor_server.c +++ b/src/tdm_monitor_server.c @@ -33,15 +33,7 @@ * **************************************************************************/ -#include -#include -#include -#include - -#include "tdm.h" #include "tdm_private.h" -#include "tdm_helper.h" -#include "tdm_log.h" #define TDM_DBG_SERVER_ARGS_MAX 32 diff --git a/src/tdm_output.c b/src/tdm_output.c index 76192a2..c58c272 100644 --- a/src/tdm_output.c +++ b/src/tdm_output.c @@ -37,10 +37,7 @@ #include "config.h" #endif -#include "tdm.h" -#include "tdm_backend.h" #include "tdm_private.h" -#include "tdm_helper.h" #define COUNT_MAX 10 @@ -1692,7 +1689,7 @@ static void _tdm_target_window_dump_buffer(tdm_private_output *private_output, tbm_surface_h buffer) { unsigned int pipe; - char fname[PATH_MAX]; + char fname[TDM_PATH_LEN]; pipe = private_output->pipe; diff --git a/src/tdm_pp.c b/src/tdm_pp.c index ccec73f..6e1dafd 100644 --- a/src/tdm_pp.c +++ b/src/tdm_pp.c @@ -37,10 +37,7 @@ #include "config.h" #endif -#include "tdm.h" -#include "tdm_backend.h" #include "tdm_private.h" -#include "tdm_helper.h" #define PP_FUNC_ENTRY() \ tdm_func_pp *func_pp; \ diff --git a/src/tdm_private.h b/src/tdm_private.h index 6d9c95f..058c228 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -43,7 +43,6 @@ #include #include #include -#include #include #include #include @@ -51,7 +50,6 @@ #include #include #include -#include #include #include #include @@ -59,11 +57,13 @@ #include #include #include +#include +#include -#include "tdm_backend.h" -#include "tdm_log.h" -#include "tdm_list.h" +#include "tdm_private_types.h" #include "tdm_macro.h" +#include "tdm_helper.h" +#include "tdm_thread.h" #ifdef __cplusplus extern "C" { @@ -71,383 +71,17 @@ extern "C" { //#define INIT_BUFMGR -/** - * @file tdm_private.h - * @brief The private header file for a frontend library - */ - -enum { - TDM_DEBUG_NONE, - TDM_DEBUG_BUFFER = (1 << 0), - TDM_DEBUG_MUTEX = (1 << 1), - TDM_DEBUG_THREAD = (1 << 2), - TDM_DEBUG_SERVER = (1 << 3), - TDM_DEBUG_VBLANK = (1 << 4), - 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), -}; +/***************************************************************************** + * This file includes + * - other private headers + * - function prototypes + *****************************************************************************/ extern int tdm_debug_module; extern int tdm_debug_dump; extern int tdm_ttrace_module; extern int tdm_ttrace_output; -#ifdef HAVE_TTRACE -#include -#define TDM_TRACE_BEGIN(fmt, ...) traceBegin(TTRACE_TAG_GRAPHICS, fmt, ##__VA_ARGS__) -#define TDM_TRACE_END() traceEnd(TTRACE_TAG_GRAPHICS) -#define TDM_TRACE_ASYNC_BEGIN(key, name,...) traceAsyncBegin(TTRACE_TAG_GRAPHICS, key, name, ##__VA_ARGS__) -#define TDM_TRACE_ASYNC_END(key, name,...) traceAsyncEnd(TTRACE_TAG_GRAPHICS, key, name, ##__VA_ARGS__) -#define TDM_TRACE_COUNT(count, fmt, ...) traceCounter(TTRACE_TAG_GRAPHICS, count, fmt, ##__VA_ARGS__) -#define TDM_TRACE_MARK(fmt, ...) traceMark(TTRACE_TAG_GRAPHICS, fmt, ##__VA_ARGS__) -#else -#define TDM_TRACE_BEGIN(fmt, ...) -#define TDM_TRACE_END() -#define TDM_TRACE_ASYNC_BEGIN(key, name,...) -#define TDM_TRACE_ASYNC_END(key, name,...) -#define TDM_TRACE_COUNT(count, fmt, ...) -#define TDM_TRACE_MARK(fmt, ...) -#endif - -typedef enum { - TDM_CAPTURE_TARGET_OUTPUT, - TDM_CAPTURE_TARGET_LAYER, -} tdm_capture_target; - -enum { - TDM_DUMP_FLAG_LAYER = (1 << 0), - TDM_DUMP_FLAG_PP = (1 << 1), - TDM_DUMP_FLAG_CAPTURE = (1 << 2), - TDM_DUMP_FLAG_WINDOW = (1 << 3), -}; - -#define TDM_DUMP_DIR "/tmp" - -typedef enum { - TDM_COMMIT_TYPE_NONE, - TDM_COMMIT_TYPE_OUTPUT, - TDM_COMMIT_TYPE_LAYER, -} tdm_commit_type; - -typedef struct _tdm_private_display tdm_private_display; -typedef struct _tdm_private_output tdm_private_output; -typedef struct _tdm_private_layer tdm_private_layer; -typedef struct _tdm_private_hwc_window tdm_private_hwc_window; -typedef struct _tdm_private_pp tdm_private_pp; -typedef struct _tdm_private_capture tdm_private_capture; -typedef struct _tdm_private_loop tdm_private_loop; -typedef struct _tdm_private_server tdm_private_server; -typedef struct _tdm_private_thread tdm_private_thread; -typedef struct _tdm_private_vblank_handler tdm_private_vblank_handler; -typedef struct _tdm_private_output_commit_handler tdm_private_output_commit_handler; -typedef struct _tdm_private_layer_commit_handler tdm_private_layer_commit_handler; -typedef struct _tdm_private_change_handler tdm_private_change_handler; -typedef struct _tdm_private_layer_buffer tdm_private_layer_buffer; - -struct _tdm_private_display { - pthread_mutex_t lock; - unsigned int init_count; - - /* backend module info */ - void *module; - tdm_backend_module *module_data; - tdm_backend_data *bdata; - -#ifdef INIT_BUFMGR - tbm_bufmgr bufmgr; -#endif - - /* backend function */ - tdm_display_capability capabilities; - tdm_func_display func_display; - tdm_func_output func_output; - tdm_func_layer func_layer; - tdm_func_hwc_window func_hwc_window; - tdm_func_pp func_pp; - tdm_func_capture func_capture; - - /* backend capability */ - tdm_caps_display caps_display; - tdm_caps_pp caps_pp; - tdm_caps_capture caps_capture; - - /* output, pp list */ - struct list_head output_list; - struct list_head pp_list; - struct list_head capture_list; - - void **outputs_ptr; - - /* for event handling */ - tdm_private_loop *private_loop; - - /* output order */ - tdm_output **outputs; - - int print_fps; -}; - -struct _tdm_private_output { - struct list_head link; - - int index; - double stamp; - - tdm_private_display *private_display; - - tdm_caps_output caps; - tdm_output *output_backend; - - unsigned int pipe; - tdm_output_dpms current_dpms_value; - unsigned int waiting_dpms_change; - const tdm_output_mode *current_mode; - - int regist_vblank_cb; - int regist_commit_cb; - int regist_change_cb; - int regist_dpms_cb; - - struct list_head layer_list; - struct list_head hwc_window_list; - struct list_head capture_list; - struct list_head vblank_handler_list; - struct list_head output_commit_handler_list; - - /* for layer commit */ - struct list_head layer_commit_handler_list; - struct list_head pending_commit_handler_list; - tdm_vblank *vblank; - int layer_waiting_vblank; - - /* seperate list for multi-thread*/ - struct list_head change_handler_list_main; - struct list_head change_handler_list_sub; - - void **layers_ptr; - - /* TODO: temp solution for handling DPMS things in sub-htread */ - tdm_event_loop_source *dpms_changed_timer; - - struct { - /* look at the tdm_output_set_need_revalidate_handler() declaration for the details */ - tdm_output_need_validate_handler hndl; - int event_fd; - tdm_event_loop_source *event_source; - } need_validate; - - /* calling a output commit per a vblank */ - int commit_per_vblank; - tdm_commit_type commit_type; - - /* for ttrace vblank */ - tdm_vblank *ttrace_vblank; -}; - -struct _tdm_private_layer { - struct list_head link; - - int index; - - tdm_private_display *private_display; - tdm_private_output *private_output; - - tdm_caps_layer caps; - tdm_layer *layer_backend; - - /* pending data until committed */ - unsigned int pending_info_changed; - tdm_info_layer pending_info; - unsigned int pending_buffer_changed; - tbm_surface_h pending_buffer; - - /* When a buffer is set to a layer, it will be stored to waiting_buffer. - * And when a layer is committed, it will be moved to committed_buffer. - * Finally when a commit handler is called, it will be moved to showing_buffer. - */ - tdm_private_layer_buffer *waiting_buffer; - tdm_private_layer_buffer *committed_buffer; /* for output_commit */ - tdm_private_layer_buffer *showing_buffer; - tbm_surface_queue_h buffer_queue; - - struct list_head capture_list; - - unsigned int usable; - unsigned int committing; - - double fps_stamp; - unsigned int fps_count; -}; - -struct _tdm_private_hwc_window { - struct list_head link; - - int index; - uint32_t zpos; - - tdm_private_display *private_display; - tdm_private_output *private_output; - - tdm_hwc_window *hwc_window_backend; -}; - - -struct _tdm_private_pp { - struct list_head link; - - double stamp; - - tdm_private_display *private_display; - - tdm_pp *pp_backend; - - struct list_head pending_buffer_list; - struct list_head buffer_list; - - tdm_info_pp info; - pid_t owner_tid; - - tdm_pp_done_handler done_func; - void *done_user_data; -}; - -struct _tdm_private_capture { - struct list_head link; - struct list_head display_link; - - double stamp; - - tdm_capture_target target; - - tdm_private_display *private_display; - tdm_private_output *private_output; - tdm_private_layer *private_layer; - - tdm_capture *capture_backend; - - struct list_head pending_buffer_list; - struct list_head buffer_list; - - tdm_info_capture info; - pid_t owner_tid; - - tdm_capture_done_handler done_func; - void *done_user_data; -}; - -/* CAUTION: - * Note that we don't need to (un)lock mutex to use this structure. If there is - * no TDM thread, all TDM resources are protected by private_display's mutex. - * If there is a TDM thread, this struct will be used only in a TDM thread. - * So, we don't need to protect this structure by mutex. Not thread-safe. - */ -struct _tdm_private_loop { - /* TDM uses wl_event_loop to handle various event sources including the TDM - * backend's fd. - */ - struct wl_display *wl_display; - struct wl_event_loop *wl_loop; - - int backend_fd; - tdm_event_loop_source *backend_source; - - /* In event loop, all resources are accessed by this dpy. - * CAUTION: - * - DO NOT include other private structure in this structure because this - * struct is not protected by mutex. - */ - tdm_display *dpy; - - /* for handling TDM client requests */ - tdm_private_server *private_server; - - /* To have a TDM event thread. If TDM_THREAD enviroment variable is not set - * private_thread is NULL. - */ - tdm_private_thread *private_thread; -}; - -struct _tdm_private_vblank_handler { - struct list_head link; - - tdm_private_output *private_output; - int interval; - int sync; - tdm_output_vblank_handler func; - void *user_data; - - pid_t owner_tid; -}; - -struct _tdm_private_output_commit_handler { - struct list_head link; - - tdm_private_output *private_output; - tdm_output_commit_handler func; - void *user_data; - - pid_t owner_tid; -}; - -struct _tdm_private_layer_commit_handler { - struct list_head link; - - tdm_private_layer *private_layer; - tdm_layer_commit_handler func; - void *user_data; - - tdm_private_layer_buffer *committed_buffer; /* for layer_commit */ -}; - -struct _tdm_private_change_handler { - struct list_head link; - - tdm_private_output *private_output; - tdm_output_change_handler func; - void *user_data; - - pid_t owner_tid; -}; - -struct _tdm_private_layer_buffer { - tbm_surface_h buffer; - struct list_head link; -}; - -typedef struct _tdm_buffer_info { - tbm_surface_h buffer; - - /* ref_count for backend */ - int backend_ref_count; - - struct list_head release_funcs; - struct list_head destroy_funcs; - - struct list_head *list; - struct list_head link; -} tdm_buffer_info; - -typedef struct _tdm_pp_private_buffer { - tbm_surface_h src; - tbm_surface_h dst; - struct list_head link; - struct list_head commit_link; -} tdm_pp_private_buffer; - -typedef struct _tdm_capture_private_buffer { - tbm_surface_h buffer; - struct list_head link; - struct list_head commit_link; -} tdm_capture_private_buffer; - int tdm_display_is_valid(tdm_display *display); @@ -476,7 +110,7 @@ tdm_output_cb_status(tdm_output *output_backend, tdm_output_conn_status status, void tdm_output_cb_dpms(tdm_output *output_backend, tdm_output_dpms dpms, void *user_data); -INTERN tdm_error +tdm_error tdm_output_cb_need_validate(tdm_private_output *private_output); tdm_error @@ -584,103 +218,6 @@ tdm_event_loop_flush(tdm_private_display *private_display); tdm_error tdm_event_loop_trace_enable(tdm_private_display *private_display, unsigned int enable); -typedef enum { - TDM_THREAD_CB_NONE, - TDM_THREAD_CB_OUTPUT_COMMIT, - TDM_THREAD_CB_OUTPUT_VBLANK, - TDM_THREAD_CB_OUTPUT_STATUS, - TDM_THREAD_CB_OUTPUT_DPMS, - TDM_THREAD_CB_PP_DONE, - TDM_THREAD_CB_CAPTURE_DONE, - TDM_THREAD_CB_VBLANK_SW, - TDM_THREAD_CB_VBLANK_CREATE, - TDM_THREAD_CB_NEED_VALIDATE, -} tdm_thread_cb_type; - -typedef struct _tdm_thread_cb_base tdm_thread_cb_base; -typedef struct _tdm_thread_cb_output_vblank tdm_thread_cb_output_commit; -typedef struct _tdm_thread_cb_output_vblank tdm_thread_cb_output_vblank; -typedef struct _tdm_thread_cb_output_status tdm_thread_cb_output_status; -typedef struct _tdm_thread_cb_output_dpms tdm_thread_cb_output_dpms; -typedef struct _tdm_thread_cb_pp_done tdm_thread_cb_pp_done; -typedef struct _tdm_thread_cb_capture_done tdm_thread_cb_capture_done; -typedef struct _tdm_thread_cb_vblank_sw tdm_thread_cb_vblank_sw; -typedef struct _tdm_thread_cb_vblank_create tdm_thread_cb_vblank_create; -typedef struct _tdm_thread_cb_need_validate tdm_thread_cb_need_validate; - -struct _tdm_thread_cb_base { - tdm_thread_cb_type type; - unsigned int length; -}; - -struct _tdm_thread_cb_output_vblank { - tdm_thread_cb_base base; - double output_stamp; - unsigned int sequence; - unsigned int tv_sec; - unsigned int tv_usec; - void *user_data; -}; - -struct _tdm_thread_cb_output_status { - tdm_thread_cb_base base; - double output_stamp; - tdm_output_conn_status status; - void *user_data; -}; - -struct _tdm_thread_cb_output_dpms { - tdm_thread_cb_base base; - double output_stamp; - tdm_output_dpms dpms; - void *user_data; -}; - -struct _tdm_thread_cb_pp_done { - tdm_thread_cb_base base; - double pp_stamp; - tbm_surface_h src; - tbm_surface_h dst; - void *user_data; -}; - -struct _tdm_thread_cb_capture_done { - tdm_thread_cb_base base; - double capture_stamp; - tbm_surface_h buffer; - void *user_data; -}; - -struct _tdm_thread_cb_vblank_sw { - tdm_thread_cb_base base; - double vblank_stamp; -}; - -struct _tdm_thread_cb_vblank_create { - tdm_thread_cb_base base; - double vblank_stamp; -}; - -struct _tdm_thread_cb_need_validate { - tdm_thread_cb_base base; - tdm_private_output *o; -}; - -tdm_error -tdm_thread_init(tdm_private_loop *private_loop); -void -tdm_thread_deinit(tdm_private_loop *private_loop); -int -tdm_thread_get_fd(tdm_private_loop *private_loop); -tdm_error -tdm_thread_send_cb(tdm_private_loop *private_loop, tdm_thread_cb_base *base); -tdm_error -tdm_thread_handle_cb(tdm_private_loop *private_loop); -int -tdm_thread_in_display_thread(pid_t tid); -int -tdm_thread_is_running(void); - tdm_error tdm_server_init(tdm_private_loop *private_loop); void @@ -697,82 +234,9 @@ tdm_helper_dump_buffer_str(tbm_surface_h buffer, char *dir, char *str); double tdm_helper_get_time(void); -extern pthread_mutex_t tdm_mutex_check_lock; -extern int tdm_mutex_locked; -extern const char *tdm_mutex_lock_func; -extern int tdm_mutex_lock_line; -extern const char *tdm_mutex_unlock_func; -extern int tdm_mutex_unlock_line; extern int tdm_dump_enable; extern char *tdm_debug_dump_dir; -#define _pthread_mutex_unlock(l) \ - do { \ - if (tdm_debug_module & TDM_DEBUG_MUTEX) \ - TDM_INFO("mutex unlock"); \ - pthread_mutex_lock(&tdm_mutex_check_lock); \ - tdm_mutex_locked = 0; \ - tdm_mutex_lock_func = NULL; \ - tdm_mutex_lock_line = 0; \ - tdm_mutex_unlock_func = __FUNCTION__; \ - tdm_mutex_unlock_line = __LINE__; \ - pthread_mutex_unlock(&tdm_mutex_check_lock); \ - pthread_mutex_unlock(l); \ - } while (0) -#ifdef TDM_CONFIG_MUTEX_TIMEOUT -#define MUTEX_TIMEOUT_SEC 5 -#define _pthread_mutex_lock(l) \ - do { \ - if (tdm_debug_module & TDM_DEBUG_MUTEX) \ - TDM_INFO("mutex lock"); \ - struct timespec rtime; \ - clock_gettime(CLOCK_REALTIME, &rtime); \ - rtime.tv_sec += MUTEX_TIMEOUT_SEC; \ - if (pthread_mutex_timedlock(l, &rtime)) { \ - TDM_ERR("Mutex lock failed PID %d", getpid()); \ - _pthread_mutex_unlock(l); \ - } \ - else { \ - pthread_mutex_lock(&tdm_mutex_check_lock); \ - tdm_mutex_locked = 1; \ - tdm_mutex_lock_func = __FUNCTION__; \ - tdm_mutex_lock_line = __LINE__; \ - tdm_mutex_unlock_func = NULL; \ - tdm_mutex_unlock_line = 0; \ - pthread_mutex_unlock(&tdm_mutex_check_lock); \ - } \ - } while (0) -#else //TDM_CONFIG_MUTEX_TIMEOUT -#define _pthread_mutex_lock(l) \ - do { \ - if (tdm_debug_module & TDM_DEBUG_MUTEX) \ - TDM_INFO("mutex lock"); \ - pthread_mutex_lock(l); \ - pthread_mutex_lock(&tdm_mutex_check_lock); \ - tdm_mutex_locked = 1; \ - tdm_mutex_lock_func = __FUNCTION__; \ - tdm_mutex_lock_line = __LINE__; \ - tdm_mutex_unlock_func = NULL; \ - tdm_mutex_unlock_line = 0; \ - pthread_mutex_unlock(&tdm_mutex_check_lock); \ - } while (0) -#endif //TDM_CONFIG_MUTEX_TIMEOUT -//#define TDM_MUTEX_IS_LOCKED() (tdm_mutex_locked == 1) -static inline int TDM_MUTEX_IS_LOCKED(void) -{ - int ret; - /* if thread is not running, we don't need to consider mutex things. */ - if (!tdm_thread_is_running()) - return 1; - pthread_mutex_lock(&tdm_mutex_check_lock); - ret = (tdm_mutex_locked == 1); - pthread_mutex_unlock(&tdm_mutex_check_lock); - return ret; -} - -#define tdm_display_lock(dpy) _pthread_mutex_lock(&((tdm_private_display *)dpy)->lock) -#define tdm_display_unlock(dpy) _pthread_mutex_unlock(&((tdm_private_display *)dpy)->lock) - tdm_error tdm_display_update_output(tdm_private_display *private_display, tdm_output *output_backend, int pipe); @@ -790,12 +254,6 @@ tdm_display_enable_fps(tdm_private_display *private_display, int enable); void tdm_monitor_server_command(tdm_display *dpy, const char *options, char *reply, int *len); -struct argument_details { - char type; - int nullable; -}; - - #ifdef __cplusplus } #endif diff --git a/src/tdm_private_types.h b/src/tdm_private_types.h new file mode 100644 index 0000000..fd641c1 --- /dev/null +++ b/src/tdm_private_types.h @@ -0,0 +1,497 @@ +/************************************************************************** + * + * libtdm + * + * Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved. + * + * Contact: Eunchul Kim , + * JinYoung Jeon , + * Taeheon Kim , + * YoungJun Cho , + * SooChan Lim , + * Boram Park + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * +**************************************************************************/ + +#ifndef _TDM_PRIVATE_TYPES_H_ +#define _TDM_PRIVATE_TYPES_H_ + +#include +#include +#include + +#include "tdm_types.h" +#include "tdm_list.h" +#include "tdm_log.h" +#include "tdm.h" +#include "tdm_backend.h" + +#ifdef __cplusplus +extern "C" { +#endif + +//#define INIT_BUFMGR + +/***************************************************************************** + * This file defines private Enumerations and Structures for frontend + *****************************************************************************/ + +enum { + TDM_DEBUG_NONE, + TDM_DEBUG_BUFFER = (1 << 0), + TDM_DEBUG_MUTEX = (1 << 1), + TDM_DEBUG_THREAD = (1 << 2), + TDM_DEBUG_SERVER = (1 << 3), + TDM_DEBUG_VBLANK = (1 << 4), + 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), +}; + +typedef enum { + TDM_CAPTURE_TARGET_OUTPUT, + TDM_CAPTURE_TARGET_LAYER, +} tdm_capture_target; + +enum { + TDM_DUMP_FLAG_LAYER = (1 << 0), + TDM_DUMP_FLAG_PP = (1 << 1), + TDM_DUMP_FLAG_CAPTURE = (1 << 2), + TDM_DUMP_FLAG_WINDOW = (1 << 3), +}; + +typedef enum { + TDM_COMMIT_TYPE_NONE, + TDM_COMMIT_TYPE_OUTPUT, + TDM_COMMIT_TYPE_LAYER, +} tdm_commit_type; + +typedef struct _tdm_private_display tdm_private_display; +typedef struct _tdm_private_output tdm_private_output; +typedef struct _tdm_private_layer tdm_private_layer; +typedef struct _tdm_private_hwc_window tdm_private_hwc_window; +typedef struct _tdm_private_pp tdm_private_pp; +typedef struct _tdm_private_capture tdm_private_capture; +typedef struct _tdm_private_loop tdm_private_loop; +typedef struct _tdm_private_server tdm_private_server; +typedef struct _tdm_private_thread tdm_private_thread; +typedef struct _tdm_private_vblank_handler tdm_private_vblank_handler; +typedef struct _tdm_private_output_commit_handler tdm_private_output_commit_handler; +typedef struct _tdm_private_layer_commit_handler tdm_private_layer_commit_handler; +typedef struct _tdm_private_change_handler tdm_private_change_handler; +typedef struct _tdm_private_layer_buffer tdm_private_layer_buffer; + +struct _tdm_private_display { + pthread_mutex_t lock; + unsigned int init_count; + + /* backend module info */ + void *module; + tdm_backend_module *module_data; + tdm_backend_data *bdata; + +#ifdef INIT_BUFMGR + tbm_bufmgr bufmgr; +#endif + + /* backend function */ + tdm_display_capability capabilities; + tdm_func_display func_display; + tdm_func_output func_output; + tdm_func_layer func_layer; + tdm_func_hwc_window func_hwc_window; + tdm_func_pp func_pp; + tdm_func_capture func_capture; + + /* backend capability */ + tdm_caps_display caps_display; + tdm_caps_pp caps_pp; + tdm_caps_capture caps_capture; + + /* output, pp list */ + struct list_head output_list; + struct list_head pp_list; + struct list_head capture_list; + + void **outputs_ptr; + + /* for event handling */ + tdm_private_loop *private_loop; + + /* output order */ + tdm_output **outputs; + + int print_fps; +}; + +struct _tdm_private_output { + struct list_head link; + + int index; + double stamp; + + tdm_private_display *private_display; + + tdm_caps_output caps; + tdm_output *output_backend; + + unsigned int pipe; + tdm_output_dpms current_dpms_value; + unsigned int waiting_dpms_change; + const tdm_output_mode *current_mode; + + int regist_vblank_cb; + int regist_commit_cb; + int regist_change_cb; + int regist_dpms_cb; + + struct list_head layer_list; + struct list_head hwc_window_list; + struct list_head capture_list; + struct list_head vblank_handler_list; + struct list_head output_commit_handler_list; + + /* for layer commit */ + struct list_head layer_commit_handler_list; + struct list_head pending_commit_handler_list; + tdm_vblank *vblank; + int layer_waiting_vblank; + + /* seperate list for multi-thread*/ + struct list_head change_handler_list_main; + struct list_head change_handler_list_sub; + + void **layers_ptr; + + /* TODO: temp solution for handling DPMS things in sub-htread */ + tdm_event_loop_source *dpms_changed_timer; + + struct { + /* look at the tdm_output_set_need_revalidate_handler() declaration for the details */ + tdm_output_need_validate_handler hndl; + int event_fd; + tdm_event_loop_source *event_source; + } need_validate; + + /* calling a output commit per a vblank */ + int commit_per_vblank; + tdm_commit_type commit_type; + + /* for ttrace vblank */ + tdm_vblank *ttrace_vblank; +}; + +struct _tdm_private_layer { + struct list_head link; + + int index; + + tdm_private_display *private_display; + tdm_private_output *private_output; + + tdm_caps_layer caps; + tdm_layer *layer_backend; + + /* pending data until committed */ + unsigned int pending_info_changed; + tdm_info_layer pending_info; + unsigned int pending_buffer_changed; + tbm_surface_h pending_buffer; + + /* When a buffer is set to a layer, it will be stored to waiting_buffer. + * And when a layer is committed, it will be moved to committed_buffer. + * Finally when a commit handler is called, it will be moved to showing_buffer. + */ + tdm_private_layer_buffer *waiting_buffer; + tdm_private_layer_buffer *committed_buffer; /* for output_commit */ + tdm_private_layer_buffer *showing_buffer; + tbm_surface_queue_h buffer_queue; + + struct list_head capture_list; + + unsigned int usable; + unsigned int committing; + + double fps_stamp; + unsigned int fps_count; +}; + +struct _tdm_private_hwc_window { + struct list_head link; + + int index; + uint32_t zpos; + + tdm_private_display *private_display; + tdm_private_output *private_output; + + tdm_hwc_window *hwc_window_backend; +}; + +struct _tdm_private_pp { + struct list_head link; + + double stamp; + + tdm_private_display *private_display; + + tdm_pp *pp_backend; + + struct list_head pending_buffer_list; + struct list_head buffer_list; + + tdm_info_pp info; + pid_t owner_tid; + + tdm_pp_done_handler done_func; + void *done_user_data; +}; + +struct _tdm_private_capture { + struct list_head link; + struct list_head display_link; + + double stamp; + + tdm_capture_target target; + + tdm_private_display *private_display; + tdm_private_output *private_output; + tdm_private_layer *private_layer; + + tdm_capture *capture_backend; + + struct list_head pending_buffer_list; + struct list_head buffer_list; + + tdm_info_capture info; + pid_t owner_tid; + + tdm_capture_done_handler done_func; + void *done_user_data; +}; + +/* CAUTION: + * Note that we don't need to (un)lock mutex to use this structure. If there is + * no TDM thread, all TDM resources are protected by private_display's mutex. + * If there is a TDM thread, this struct will be used only in a TDM thread. + * So, we don't need to protect this structure by mutex. Not thread-safe. + */ +struct _tdm_private_loop { + /* TDM uses wl_event_loop to handle various event sources including the TDM + * backend's fd. + */ + struct wl_display *wl_display; + struct wl_event_loop *wl_loop; + + int backend_fd; + tdm_event_loop_source *backend_source; + + /* In event loop, all resources are accessed by this dpy. + * CAUTION: + * - DO NOT include other private structure in this structure because this + * struct is not protected by mutex. + */ + tdm_display *dpy; + + /* for handling TDM client requests */ + tdm_private_server *private_server; + + /* To have a TDM event thread. If TDM_THREAD enviroment variable is not set + * private_thread is NULL. + */ + tdm_private_thread *private_thread; +}; + +struct _tdm_private_vblank_handler { + struct list_head link; + + tdm_private_output *private_output; + int interval; + int sync; + tdm_output_vblank_handler func; + void *user_data; + + pid_t owner_tid; +}; + +struct _tdm_private_output_commit_handler { + struct list_head link; + + tdm_private_output *private_output; + tdm_output_commit_handler func; + void *user_data; + + pid_t owner_tid; +}; + +struct _tdm_private_layer_commit_handler { + struct list_head link; + + tdm_private_layer *private_layer; + tdm_layer_commit_handler func; + void *user_data; + + tdm_private_layer_buffer *committed_buffer; /* for layer_commit */ +}; + +struct _tdm_private_change_handler { + struct list_head link; + + tdm_private_output *private_output; + tdm_output_change_handler func; + void *user_data; + + pid_t owner_tid; +}; + +struct _tdm_private_layer_buffer { + tbm_surface_h buffer; + struct list_head link; +}; + +typedef struct _tdm_buffer_info { + tbm_surface_h buffer; + + /* ref_count for backend */ + int backend_ref_count; + + struct list_head release_funcs; + struct list_head destroy_funcs; + + struct list_head *list; + struct list_head link; +} tdm_buffer_info; + +typedef struct _tdm_pp_private_buffer { + tbm_surface_h src; + tbm_surface_h dst; + struct list_head link; + struct list_head commit_link; +} tdm_pp_private_buffer; + +typedef struct _tdm_capture_private_buffer { + tbm_surface_h buffer; + struct list_head link; + struct list_head commit_link; +} tdm_capture_private_buffer; + +typedef enum { + TDM_THREAD_CB_NONE, + TDM_THREAD_CB_OUTPUT_COMMIT, + TDM_THREAD_CB_OUTPUT_VBLANK, + TDM_THREAD_CB_OUTPUT_STATUS, + TDM_THREAD_CB_OUTPUT_DPMS, + TDM_THREAD_CB_PP_DONE, + TDM_THREAD_CB_CAPTURE_DONE, + TDM_THREAD_CB_VBLANK_SW, + TDM_THREAD_CB_VBLANK_CREATE, + TDM_THREAD_CB_NEED_VALIDATE, +} tdm_thread_cb_type; + +typedef struct _tdm_thread_cb_base tdm_thread_cb_base; +typedef struct _tdm_thread_cb_output_vblank tdm_thread_cb_output_commit; +typedef struct _tdm_thread_cb_output_vblank tdm_thread_cb_output_vblank; +typedef struct _tdm_thread_cb_output_status tdm_thread_cb_output_status; +typedef struct _tdm_thread_cb_output_dpms tdm_thread_cb_output_dpms; +typedef struct _tdm_thread_cb_pp_done tdm_thread_cb_pp_done; +typedef struct _tdm_thread_cb_capture_done tdm_thread_cb_capture_done; +typedef struct _tdm_thread_cb_vblank_sw tdm_thread_cb_vblank_sw; +typedef struct _tdm_thread_cb_vblank_create tdm_thread_cb_vblank_create; +typedef struct _tdm_thread_cb_need_validate tdm_thread_cb_need_validate; + +struct _tdm_thread_cb_base { + tdm_thread_cb_type type; + unsigned int length; +}; + +struct _tdm_thread_cb_output_vblank { + tdm_thread_cb_base base; + double output_stamp; + unsigned int sequence; + unsigned int tv_sec; + unsigned int tv_usec; + void *user_data; +}; + +struct _tdm_thread_cb_output_status { + tdm_thread_cb_base base; + double output_stamp; + tdm_output_conn_status status; + void *user_data; +}; + +struct _tdm_thread_cb_output_dpms { + tdm_thread_cb_base base; + double output_stamp; + tdm_output_dpms dpms; + void *user_data; +}; + +struct _tdm_thread_cb_pp_done { + tdm_thread_cb_base base; + double pp_stamp; + tbm_surface_h src; + tbm_surface_h dst; + void *user_data; +}; + +struct _tdm_thread_cb_capture_done { + tdm_thread_cb_base base; + double capture_stamp; + tbm_surface_h buffer; + void *user_data; +}; + +struct _tdm_thread_cb_vblank_sw { + tdm_thread_cb_base base; + double vblank_stamp; +}; + +struct _tdm_thread_cb_vblank_create { + tdm_thread_cb_base base; + double vblank_stamp; +}; + +struct _tdm_thread_cb_need_validate { + tdm_thread_cb_base base; + tdm_private_output *o; +}; + +struct argument_details { + char type; + int nullable; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* _TDM_PRIVATE_TYPES_H_ */ diff --git a/src/tdm_server.c b/src/tdm_server.c index e4a3e75..0a359f4 100644 --- a/src/tdm_server.c +++ b/src/tdm_server.c @@ -37,10 +37,9 @@ #include "config.h" #endif -#include "tdm.h" +#include + #include "tdm_private.h" -#include "tdm_list.h" -#include "tdm-server-protocol.h" /* CAUTION: * - tdm server doesn't care about thread things. diff --git a/src/tdm_thread.c b/src/tdm_thread.c index a775690..22d67af 100644 --- a/src/tdm_thread.c +++ b/src/tdm_thread.c @@ -37,11 +37,7 @@ #include "config.h" #endif -#include - -#include "tdm.h" #include "tdm_private.h" -#include "tdm_list.h" static tdm_private_thread *keep_private_thread; diff --git a/src/tdm_thread.h b/src/tdm_thread.h new file mode 100644 index 0000000..c9ef06d --- /dev/null +++ b/src/tdm_thread.h @@ -0,0 +1,65 @@ +/************************************************************************** + * + * libtdm + * + * Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved. + * + * Contact: Eunchul Kim , + * JinYoung Jeon , + * Taeheon Kim , + * YoungJun Cho , + * SooChan Lim , + * Boram Park + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * +**************************************************************************/ + +#ifndef _TDM_THREAD_H_ +#define _TDM_THREAD_H_ + +#include "tdm_private_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +tdm_error +tdm_thread_init(tdm_private_loop *private_loop); +void +tdm_thread_deinit(tdm_private_loop *private_loop); +int +tdm_thread_get_fd(tdm_private_loop *private_loop); +tdm_error +tdm_thread_send_cb(tdm_private_loop *private_loop, tdm_thread_cb_base *base); +tdm_error +tdm_thread_handle_cb(tdm_private_loop *private_loop); +int +tdm_thread_in_display_thread(pid_t tid); +int +tdm_thread_is_running(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _TDM_THREAD_H_ */ + diff --git a/src/tdm_vblank.c b/src/tdm_vblank.c index abba414..4a0d03f 100644 --- a/src/tdm_vblank.c +++ b/src/tdm_vblank.c @@ -37,10 +37,7 @@ #include "config.h" #endif -#include "tdm.h" #include "tdm_private.h" -#include "tdm_list.h" -#include "tdm_macro.h" /* CAUTION: * Basically tdm vblank doesn't care about thread things. diff --git a/tools/buffers.c b/tools/buffers.c index 907e6f8..318dcde 100644 --- a/tools/buffers.c +++ b/tools/buffers.c @@ -37,7 +37,7 @@ #include #include -#include +#include "tdm_log.h" #include "tdm_macro.h" #include "buffers.h" diff --git a/tools/tdm_test_client.c b/tools/tdm_test_client.c index 879668e..a8e7c62 100644 --- a/tools/tdm_test_client.c +++ b/tools/tdm_test_client.c @@ -41,7 +41,7 @@ #include #include -#include +#include "tdm_client.h" #include "tdm_macro.h" typedef struct _tdm_test_client_arg { diff --git a/tools/tdm_test_server.c b/tools/tdm_test_server.c index 76a437d..7dff9eb 100644 --- a/tools/tdm_test_server.c +++ b/tools/tdm_test_server.c @@ -45,11 +45,11 @@ #include #include -#include -#include -#include -#include -#include +#include "tdm.h" +#include "tdm_log.h" +#include "tdm_list.h" +#include "tdm_helper.h" +#include "tdm_backend.h" #include "tdm_macro.h" #include "tdm_private.h" -- 2.7.4 From 8f6880f3201d181533298cabf83a9e6f1006529c Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 17 Jan 2018 09:55:00 +0900 Subject: [PATCH 12/16] fix typo Change-Id: I37f372b390417910997ec3f059afc52aa1e23a3c --- configure.ac | 2 +- src/tdm_output.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 739c1b7..26ba06d 100644 --- a/configure.ac +++ b/configure.ac @@ -64,7 +64,7 @@ AC_SUBST(TDM_LIBS) AC_SUBST(TDM_CLIENT_CFLAGS) AC_SUBST(TDM_CLIENT_LIBS) -# set the dir for the tbm module +# set the dir for the tdm module DEFAULT_TDM_MODULE_PATH="${libdir}/tdm" AC_ARG_WITH(tdm-module-path, AS_HELP_STRING([--with-tdm-module-path=PATH], [tdm module dir]), [ TDM_MODULE_PATH="$withval" ], diff --git a/src/tdm_output.c b/src/tdm_output.c index c58c272..c9fba68 100644 --- a/src/tdm_output.c +++ b/src/tdm_output.c @@ -202,7 +202,7 @@ tdm_output_add_change_handler(tdm_output *output, TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER); - pthread_mutex_lock(&private_display->lock); + _pthread_mutex_lock(&private_display->lock); change_handler = calloc(1, sizeof(tdm_private_change_handler)); if (!change_handler) { -- 2.7.4 From 3839085bf20014f21172bdd5dbcd2d6d76b03053 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 17 Jan 2018 10:30:28 +0900 Subject: [PATCH 13/16] add debugging log Change-Id: I7c758cba21e6398890e7441071b63d6354425f65 --- src/tdm_thread.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/tdm_thread.c b/src/tdm_thread.c index 22d67af..f71f3a1 100644 --- a/src/tdm_thread.c +++ b/src/tdm_thread.c @@ -245,7 +245,8 @@ tdm_thread_handle_cb(tdm_private_loop *private_loop) tdm_private_thread *private_thread; tdm_thread_cb_base *base; char buffer[1024]; - unsigned int len, i; + unsigned int i; + int len; /* DON'T check TDM_MUTEX_IS_LOCKED here */ @@ -255,16 +256,23 @@ tdm_thread_handle_cb(tdm_private_loop *private_loop) private_thread = private_loop->private_thread; private_display = private_loop->dpy; - len = read(private_thread->pipe[0], buffer, sizeof buffer); + do { + len = read(private_thread->pipe[0], buffer, sizeof buffer); + } while (len < 0 && errno == EINTR); if (tdm_debug_module & TDM_DEBUG_THREAD) TDM_INFO("fd(%d) read length(%d)", private_thread->pipe[0], len); + if (len < 0) { + TDM_ERR("read failed: errno(%d), len(%d) %m", errno, len); + return TDM_ERROR_OPERATION_FAILED; + } + if (len == 0) return TDM_ERROR_NONE; if (len < sizeof * base) { - TDM_NEVER_GET_HERE(); + TDM_ERR("read failed: len(%d)", len); return TDM_ERROR_OPERATION_FAILED; } -- 2.7.4 From 7d1e761e8277ef3cb5d07593cbdd592ace8e6c99 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Thu, 18 Jan 2018 07:59:17 +0900 Subject: [PATCH 14/16] macro: re-ordered Change-Id: I91dbc2259a1bc08ecf43d28e3bfb4e863e557a41 --- src/tdm_macro.h | 215 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 111 insertions(+), 104 deletions(-) diff --git a/src/tdm_macro.h b/src/tdm_macro.h index 78e2643..428b38f 100644 --- a/src/tdm_macro.h +++ b/src/tdm_macro.h @@ -50,96 +50,7 @@ extern "C" { #endif -#define TDM_DUMP_DIR "/tmp" - -#define TDM_SERVER_REPLY_MSG_LEN 8192 -#define TDM_DEBUG_REPLY_MSG_LEN 2048 - -#undef EXTERN -#undef DEPRECATED -#undef INTERN - -#if defined(__GNUC__) && __GNUC__ >= 4 -#define EXTERN __attribute__ ((visibility("default"))) -#else -#define EXTERN -#endif - -#if defined(__GNUC__) && __GNUC__ >= 4 -#define INTERN __attribute__ ((visibility("hidden"))) -#else -#define INTERN -#endif - -#if defined(__GNUC__) && __GNUC__ >= 4 -#define DEPRECATED __attribute__ ((deprecated)) -#else -#define DEPRECATED -#endif - -/* check condition */ -#define TDM_RETURN_IF_FAIL(cond) { \ - if (!(cond)) { \ - TDM_ERR("'%s' failed", #cond); \ - return; \ - } \ -} -#define TDM_RETURN_VAL_IF_FAIL(cond, val) { \ - if (!(cond)) { \ - TDM_ERR("'%s' failed", #cond); \ - return val; \ - } \ -} -#define TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(cond, error_v, val) { \ - if (!(cond)) { \ - TDM_ERR("'%s' failed", #cond); \ - ret = error_v; \ - if (error) *error = ret; \ - return val; \ - } \ -} - -#define TDM_WARNING_IF_FAIL(cond) { \ - if (!(cond)) \ - TDM_WRN("'%s' failed", #cond); \ -} -#define TDM_GOTO_IF_FAIL(cond, dst) { \ - if (!(cond)) { \ - TDM_ERR("'%s' failed", #cond); \ - goto dst; \ - } \ -} -#define TDM_EXIT_IF_FAIL(cond) { \ - if (!(cond)) { \ - TDM_ERR("'%s' failed", #cond); \ - exit(0); \ - } \ -} - -#define TDM_NEVER_GET_HERE() TDM_WRN("** NEVER GET HERE **") - -#define TDM_SNPRINTF(p, len, fmt, ARG...) \ - do { \ - if (p && len && *len > 0) { \ - int s = snprintf(p, *len, fmt, ##ARG); \ - p += s; \ - *len -= s; \ - } \ - } while (0) - -#define TDM_DBG_RETURN_IF_FAIL(cond) { \ - if (!(cond)) { \ - TDM_SNPRINTF(reply, len, "[%s %d] '%s' failed\n", __func__, __LINE__, #cond); \ - return; \ - } \ -} -#define TDM_DBG_GOTO_IF_FAIL(cond, dst) { \ - if (!(cond)) { \ - TDM_SNPRINTF(reply, len, "[%s %d] '%s' failed\n", __func__, __LINE__, #cond); \ - goto dst; \ - } \ -} - +/* not-categorized **********************************************************/ #define TDM_NOT_DEFINED_VALUE (-1) #define TDM_FRONT_VALUE(n) (((n) > 0) ? (n) : TDM_NOT_DEFINED_VALUE) @@ -163,6 +74,25 @@ 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])) +#define TDM_NEVER_GET_HERE() TDM_WRN("** NEVER GET HERE **") + +#define TDM_SNPRINTF(p, len, fmt, ARG...) \ + do { \ + if (p && len && *len > 0) { \ + int s = snprintf(p, *len, fmt, ##ARG); \ + p += s; \ + *len -= s; \ + } \ + } while (0) + +/* dump directory ***********************************************************/ +#define TDM_DUMP_DIR "/tmp" + +/* message length ***********************************************************/ +#define TDM_SERVER_REPLY_MSG_LEN 8192 +#define TDM_DEBUG_REPLY_MSG_LEN 2048 + +/* DPMS *********************************************************************/ /* 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? */ @@ -170,6 +100,46 @@ extern "C" { #define TDM_OUTPUT_DPMS_VSYNC_OFF_MASK 0x2 #define TDM_OUTPUT_DPMS_VSYNC_IS_OFF(dpms) ((dpms) & TDM_OUTPUT_DPMS_VSYNC_OFF_MASK) +/* strtostr *****************************************************************/ +static inline char* +strtostr(char *buf, int len, char *str, char *delim) +{ + char *end; + end = strpbrk(str, delim); + if (end) + len = ((end - str + 1) < len) ? (end - str + 1) : len; + else { + int l = strlen(str); + len = ((l + 1) < len) ? (l + 1) : len; + } + snprintf(buf, len, "%s", str); + return str + len - 1; +} + +/* EXTERN, INTERN, DEPRECATED ***********************************************/ +#undef EXTERN +#undef DEPRECATED +#undef INTERN + +#if defined(__GNUC__) && __GNUC__ >= 4 +#define EXTERN __attribute__ ((visibility("default"))) +#else +#define EXTERN +#endif + +#if defined(__GNUC__) && __GNUC__ >= 4 +#define INTERN __attribute__ ((visibility("hidden"))) +#else +#define INTERN +#endif + +#if defined(__GNUC__) && __GNUC__ >= 4 +#define DEPRECATED __attribute__ ((deprecated)) +#else +#define DEPRECATED +#endif + +/* type to string ***********************************************************/ struct tdm_type_name { int type; const char *name; @@ -325,21 +295,57 @@ static const char *tdm_capture_caps_names[] = { }; TDM_BIT_NAME_FB(capture_caps) -static inline char* -strtostr(char *buf, int len, char *str, char *delim) -{ - char *end; - end = strpbrk(str, delim); - if (end) - len = ((end - str + 1) < len) ? (end - str + 1) : len; - else { - int l = strlen(str); - len = ((l + 1) < len) ? (l + 1) : len; - } - snprintf(buf, len, "%s", str); - return str + len - 1; +/* check condition **********************************************************/ +#define TDM_RETURN_IF_FAIL(cond) { \ + if (!(cond)) { \ + TDM_ERR("'%s' failed", #cond); \ + return; \ + } \ +} +#define TDM_RETURN_VAL_IF_FAIL(cond, val) { \ + if (!(cond)) { \ + TDM_ERR("'%s' failed", #cond); \ + return val; \ + } \ +} +#define TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(cond, error_v, val) { \ + if (!(cond)) { \ + TDM_ERR("'%s' failed", #cond); \ + ret = error_v; \ + if (error) *error = ret; \ + return val; \ + } \ +} +#define TDM_WARNING_IF_FAIL(cond) { \ + if (!(cond)) \ + TDM_WRN("'%s' failed", #cond); \ +} +#define TDM_GOTO_IF_FAIL(cond, dst) { \ + if (!(cond)) { \ + TDM_ERR("'%s' failed", #cond); \ + goto dst; \ + } \ +} +#define TDM_EXIT_IF_FAIL(cond) { \ + if (!(cond)) { \ + TDM_ERR("'%s' failed", #cond); \ + exit(0); \ + } \ +} +#define TDM_DBG_RETURN_IF_FAIL(cond) { \ + if (!(cond)) { \ + TDM_SNPRINTF(reply, len, "[%s %d] '%s' failed\n", __func__, __LINE__, #cond); \ + return; \ + } \ +} +#define TDM_DBG_GOTO_IF_FAIL(cond, dst) { \ + if (!(cond)) { \ + TDM_SNPRINTF(reply, len, "[%s %d] '%s' failed\n", __func__, __LINE__, #cond); \ + goto dst; \ + } \ } +/* trace ********************************************************************/ #ifdef HAVE_TTRACE #include #define TDM_TRACE_BEGIN(fmt, ...) traceBegin(TTRACE_TAG_GRAPHICS, fmt, ##__VA_ARGS__) @@ -357,7 +363,7 @@ strtostr(char *buf, int len, char *str, char *delim) #define TDM_TRACE_MARK(fmt, ...) #endif - +/* display mutex ************************************************************/ extern pthread_mutex_t tdm_mutex_check_lock; extern int tdm_mutex_locked; extern const char *tdm_mutex_lock_func; @@ -408,6 +414,7 @@ static inline int TDM_MUTEX_IS_LOCKED(void) #define tdm_display_lock(dpy) _pthread_mutex_lock(&((tdm_private_display *)dpy)->lock) #define tdm_display_unlock(dpy) _pthread_mutex_unlock(&((tdm_private_display *)dpy)->lock) + #ifdef __cplusplus } #endif -- 2.7.4 From 15c12bf72c24f1ad4a1b98c29d36b1e2beecd465 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Thu, 18 Jan 2018 08:38:17 +0900 Subject: [PATCH 15/16] macro: add error string to make debugging easier Change-Id: I08b618f77afb06e4986f71a22b75af23dd87c54a --- src/tdm_macro.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/tdm_macro.h b/src/tdm_macro.h index 428b38f..4ac6a4f 100644 --- a/src/tdm_macro.h +++ b/src/tdm_macro.h @@ -156,6 +156,22 @@ static inline const char * tdm_##res##_str(int type) \ return "(invalid)"; \ } +static struct tdm_type_name tdm_error_names[] = { + { TDM_ERROR_NONE, "Success" }, + { TDM_ERROR_BAD_REQUEST, "bad request" }, + { TDM_ERROR_OPERATION_FAILED, "operaion failed" }, + { TDM_ERROR_INVALID_PARAMETER, "wrong input parameter" }, + { TDM_ERROR_PERMISSION_DENIED, "access denied" }, + { TDM_ERROR_BUSY, "hardware resource busy" }, + { TDM_ERROR_OUT_OF_MEMORY, "no free memory" }, + { TDM_ERROR_BAD_MODULE, "bad backend module" }, + { TDM_ERROR_NOT_IMPLEMENTED, "not implemented" }, + { TDM_ERROR_NO_CAPABILITY, "no capability" }, + { TDM_ERROR_DPMS_OFF, "dpms off" }, + { TDM_ERROR_OUTPUT_DISCONNECTED, "output disconnected" }, +}; +TDM_TYPE_NAME_FN(error) + static struct tdm_type_name tdm_dpms_names[] = { { TDM_OUTPUT_DPMS_ON, "on" }, { TDM_OUTPUT_DPMS_STANDBY, "standby" }, -- 2.7.4 From ae652c71b3b123682832bd4d5b60b24de8628cb9 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Fri, 19 Jan 2018 10:47:54 +0900 Subject: [PATCH 16/16] vblank: add server ttrace information Change-Id: I4ab060b514b04be0bd48606b8c56a5308b6bbe20 --- client/tdm_client.c | 21 +++++++++++++++++++++ src/tdm.c | 12 ++++++++---- src/tdm_monitor_server.c | 2 +- src/tdm_private_types.h | 12 +++++++----- src/tdm_server.c | 12 +++++++++++- src/tdm_vblank.c | 6 ++++++ 6 files changed, 54 insertions(+), 11 deletions(-) diff --git a/client/tdm_client.c b/client/tdm_client.c index 349c454..f126490 100644 --- a/client/tdm_client.c +++ b/client/tdm_client.c @@ -60,6 +60,9 @@ typedef struct _tdm_private_client { struct wl_tdm *tdm; struct list_head output_list; + unsigned int enable_ttrace; + unsigned int stamp; + tdm_private_client_vblank *temp_vblank; } tdm_private_client; @@ -130,10 +133,16 @@ static void _tdm_client_vblank_cb_stamp(void *data, struct wl_tdm_vblank *wl_tdm_vblank, uint32_t stamp) { tdm_private_client_vblank *private_vblank = data; + tdm_private_client *private_client; TDM_RETURN_IF_FAIL(private_vblank != NULL); private_vblank->stamp = stamp; + + TDM_RETURN_IF_FAIL(private_vblank->private_output != NULL); + private_client = private_vblank->private_output->private_client; + + private_client->stamp = stamp; } /* LCOV_EXCL_START */ @@ -180,10 +189,16 @@ static void _tdm_client_vblank_cb_ttrace(void *data, struct wl_tdm_vblank *wl_tdm_vblank, uint32_t enable) { tdm_private_client_vblank *private_vblank = data; + tdm_private_client *private_client; TDM_RETURN_IF_FAIL(private_vblank != NULL); private_vblank->enable_ttrace = enable; + + TDM_RETURN_IF_FAIL(private_vblank->private_output != NULL); + private_client = private_vblank->private_output->private_client; + + private_client->enable_ttrace = enable; } /* LCOV_EXCL_STOP */ @@ -432,8 +447,14 @@ tdm_client_handle_events(tdm_client *client) /* LCOV_EXCL_START */ private_client = (tdm_private_client*)client; + if (private_client->enable_ttrace) + TDM_TRACE_ASYNC_BEGIN((int)private_client->stamp, "TDM_Client_Events:%u", (unsigned int)private_client->stamp); + wl_display_dispatch(private_client->display); + if (private_client->enable_ttrace) + TDM_TRACE_ASYNC_END((int)private_client->stamp, "TDM_Client_Events:%u", (unsigned int)private_client->stamp); + return TDM_ERROR_NONE; /* LCOV_EXCL_STOP */ } diff --git a/src/tdm.c b/src/tdm.c index 30b4a91..e20e7dd 100644 --- a/src/tdm.c +++ b/src/tdm.c @@ -1425,10 +1425,14 @@ tdm_display_enable_ttrace(tdm_private_display *private_display, const char *ttra tdm_ttrace_module = 0; else if (!strncmp(arg, "all", 3)) tdm_ttrace_module = 0xFFFFFFFF; + else if (!strncmp(arg, "vsync", 5)) + tdm_ttrace_module |= TDM_TTRACE_VSYNC; + else if (!strncmp(arg, "client_vblank", 13)) + tdm_ttrace_module |= TDM_TTRACE_CLIENT_VBLANK; + else if (!strncmp(arg, "server_vblank", 13)) + tdm_ttrace_module |= TDM_TTRACE_SERVER_VBLANK; 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)) @@ -1448,12 +1452,12 @@ tdm_display_enable_ttrace(tdm_private_display *private_display, const char *ttra TDM_SNPRINTF(reply, len, "ttrace debugging... '%s' %x\n", ttrace, tdm_ttrace_module); - if (tdm_ttrace_module & TDM_TTRACE_VBLANK) + if (tdm_ttrace_module & TDM_TTRACE_VSYNC) 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) + if (tdm_ttrace_module & TDM_TTRACE_CLIENT_VBLANK) tdm_server_enable_ttrace_client_vblank(private_display, output, 1); else tdm_server_enable_ttrace_client_vblank(private_display, NULL, 0); diff --git a/src/tdm_monitor_server.c b/src/tdm_monitor_server.c index 8b28fa8..6fdb190 100644 --- a/src/tdm_monitor_server.c +++ b/src/tdm_monitor_server.c @@ -505,7 +505,7 @@ static struct { }, { "ttrace", _tdm_monitor_server_ttrace, - "enable/disable ttrace (module: none, vblank, client, layer, pp, capture, all", + "enable/disable ttrace (module: none,vsync,client_vblank,server_vblank,vblank,layer,pp,capture,all", "[@]", NULL }, diff --git a/src/tdm_private_types.h b/src/tdm_private_types.h index fd641c1..a406ecd 100644 --- a/src/tdm_private_types.h +++ b/src/tdm_private_types.h @@ -68,11 +68,13 @@ enum { 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), + TDM_TTRACE_VSYNC = (1 << 0), + TDM_TTRACE_CLIENT_VBLANK = (1 << 1), + TDM_TTRACE_SERVER_VBLANK = (1 << 2), + TDM_TTRACE_VBLANK = (1 << 3), + TDM_TTRACE_LAYER = (1 << 4), + TDM_TTRACE_PP = (1 << 5), + TDM_TTRACE_CAPTURE = (1 << 6), }; typedef enum { diff --git a/src/tdm_server.c b/src/tdm_server.c index 0a359f4..c1b1359 100644 --- a/src/tdm_server.c +++ b/src/tdm_server.c @@ -182,6 +182,10 @@ _tdm_server_send_done(tdm_server_wait_info *wait_info, tdm_error error, TDM_DBG("req_id(%d) done", wait_info->req_id); vblank_info = wait_info->vblank_info; + + if (tdm_ttrace_module & TDM_TTRACE_SERVER_VBLANK) + TDM_TRACE_ASYNC_END((int)wait_info->req_time, "TDM_Server_Vblank:%u", vblank_info->stamp); + wl_tdm_vblank_send_done(vblank_info->resource, wait_info->req_id, sequence, tv_sec, tv_usec, error); @@ -338,6 +342,9 @@ _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); + if (tdm_ttrace_module & TDM_TTRACE_SERVER_VBLANK) + 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); @@ -387,6 +394,9 @@ _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); + if (tdm_ttrace_module & TDM_TTRACE_SERVER_VBLANK) + 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); @@ -485,7 +495,7 @@ _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) { + if (tdm_ttrace_module & TDM_TTRACE_CLIENT_VBLANK) { 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); diff --git a/src/tdm_vblank.c b/src/tdm_vblank.c index 4a0d03f..16c1838 100644 --- a/src/tdm_vblank.c +++ b/src/tdm_vblank.c @@ -1040,6 +1040,9 @@ _tdm_vblank_cb_vblank_HW(tdm_output *output, unsigned int sequence, VDB("wait(%p) last(%.6f) sequence(%u) done", wait_info, private_vblank->last_time, wait_info->target_seq); + if (tdm_ttrace_module & TDM_TTRACE_VBLANK) + TDM_TRACE_ASYNC_END((int)wait_info->req_time, "TDM_Vblank:%u", (unsigned int)private_vblank->stamp); + if (wait_info->func) wait_info->func(private_vblank, TDM_ERROR_NONE, wait_info->target_seq, tv_sec, tv_usec, wait_info->user_data); @@ -1109,6 +1112,9 @@ _tdm_vblank_wait_HW(tdm_vblank_wait_info *wait_info) private_vblank->last_interval = hw_interval; + if (tdm_ttrace_module & TDM_TTRACE_VBLANK) + TDM_TRACE_ASYNC_BEGIN((int)wait_info->req_time, "TDM_Vblank:%u", (unsigned int)private_vblank->stamp); + if (private_vblank->add_front) ret = tdm_output_wait_vblank_add_front(private_vblank->output, hw_interval, 0, _tdm_vblank_cb_vblank_HW, wait_info); -- 2.7.4