From 4e56dc7fe08b6582fa5041c80196879aab43646d Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Wed, 22 Mar 2017 16:13:05 +0900 Subject: [PATCH 01/16] use %license macro to copy the COPYING file. Change-Id: I66b44ad1d92bf2db69cd7215ae16d5eca309e46e --- packaging/libtdm.spec | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index 80d8ac5..7debb4c 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -79,8 +79,6 @@ make -C ut check %install rm -rf %{buildroot} -mkdir -p %{buildroot}/%{TZ_SYS_RO_SHARE}/license -cp -af COPYING %{buildroot}/%{TZ_SYS_RO_SHARE}/license/%{name} %make_install %__mkdir_p %{buildroot}%{_unitdir} @@ -109,7 +107,7 @@ rm -f %{_unitdir_user}/basic.target.wants/tdm-socket-user.path %files %manifest %{name}.manifest %defattr(-,root,root,-) -%{TZ_SYS_RO_SHARE}/license/%{name} +%license COPYING %{_libdir}/libtdm.so.* %attr(750,root,root) %{_bindir}/tdm-monitor %{_unitdir}/tdm-socket.path @@ -136,7 +134,7 @@ rm -f %{_unitdir_user}/basic.target.wants/tdm-socket-user.path %files client %manifest %{name}.manifest %defattr(-,root,root,-) -%{TZ_SYS_RO_SHARE}/license/%{name} +%license COPYING %{_libdir}/libtdm-client.so.* %files client-devel -- 2.7.4 From 6d4a432c4b9b8a7047555bf8c217bc97be3f4db4 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Thu, 23 Mar 2017 15:51:33 +0900 Subject: [PATCH 02/16] event_loop: set the user func and data before calling wayland API. The user func can be called at the line of wl api by the backend implementation Change-Id: Idfc19afa17f584531ef37834c592f59f803d2823 --- src/tdm_event_loop.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/tdm_event_loop.c b/src/tdm_event_loop.c index 29a9763..a2cac7e 100644 --- a/src/tdm_event_loop.c +++ b/src/tdm_event_loop.c @@ -324,6 +324,10 @@ tdm_event_loop_add_fd_handler(tdm_display *dpy, int fd, tdm_event_loop_mask mask if (mask & TDM_EVENT_LOOP_WRITABLE) wl_mask |= WL_EVENT_WRITABLE; + fd_source->private_display = private_display; + fd_source->func = func; + fd_source->user_data = user_data; + fd_source->base.wl_source = wl_event_loop_add_fd(private_loop->wl_loop, fd, wl_mask, _tdm_event_loop_fd_func, fd_source); @@ -334,10 +338,6 @@ tdm_event_loop_add_fd_handler(tdm_display *dpy, int fd, tdm_event_loop_mask mask return NULL; } - fd_source->private_display = private_display; - fd_source->func = func; - fd_source->user_data = user_data; - if (error) *error = TDM_ERROR_NONE; @@ -411,6 +411,10 @@ tdm_event_loop_add_timer_handler(tdm_display *dpy, tdm_event_loop_timer_handler timer_source = calloc(1, sizeof(tdm_event_loop_source_timer)); TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(timer_source, TDM_ERROR_OUT_OF_MEMORY, NULL); + timer_source->private_display = private_display; + timer_source->func = func; + timer_source->user_data = user_data; + timer_source->base.wl_source = wl_event_loop_add_timer(private_loop->wl_loop, _tdm_event_loop_timer_func, timer_source); @@ -421,10 +425,6 @@ tdm_event_loop_add_timer_handler(tdm_display *dpy, tdm_event_loop_timer_handler return NULL; } - timer_source->private_display = private_display; - timer_source->func = func; - timer_source->user_data = user_data; - if (error) *error = TDM_ERROR_NONE; -- 2.7.4 From 5ef467feec2b03979eb0d98e7768ed488f7fc81d Mon Sep 17 00:00:00 2001 From: Boram Park Date: Thu, 23 Mar 2017 16:59:32 +0900 Subject: [PATCH 03/16] test: remove sig handler to avoid deadlock Change-Id: I4db7accacebca43bca85751d18918a94dfb43d94 --- tools/tdm_test_server.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/tools/tdm_test_server.c b/tools/tdm_test_server.c index cfd6a02..0c30519 100644 --- a/tools/tdm_test_server.c +++ b/tools/tdm_test_server.c @@ -789,9 +789,8 @@ get_tts_buffer(tbm_surface_h b) } static void -exit_test(int sig) +destroy(tdm_test_server *data) { - tdm_test_server *data = &tts_data; tdm_test_server_output *o = NULL, *oo = NULL; tdm_test_server_layer *l = NULL, *ll = NULL; tdm_test_server_pp *p = NULL, *pp = NULL; @@ -799,8 +798,6 @@ exit_test(int sig) tdm_test_server_prop *w = NULL, *ww = NULL; int i; - printf("got signal: %d\n", sig); - LIST_FOR_EACH_ENTRY_SAFE(c, cc, &data->capture_list, link) { LIST_DEL(&c->link); tdm_capture_destroy(c->capture); @@ -871,9 +868,6 @@ main(int argc, char *argv[]) printf("SCREEN_PREROTATION_HINT = %d", tts_screen_prerotation_hint); } - signal(SIGINT, exit_test); /* 2 */ - signal(SIGTERM, exit_test); /* 15 */ - memset(data, 0, sizeof * data); LIST_INITHEAD(&data->output_list); LIST_INITHEAD(&data->pp_list); @@ -1434,6 +1428,8 @@ run_test(tdm_test_server *data) while (1) tdm_display_handle_events(data->display); + destroy(data); + return; no_pp: printf("no PP capability\n"); -- 2.7.4 From 87b7c9f748aa9932fd1d153575eb1ac7a8f9fc12 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Thu, 23 Mar 2017 18:18:50 +0900 Subject: [PATCH 04/16] log: add debugging logs for dump Change-Id: If8d84e12c2ece5cd46379d97c42f45ffaa80cc36 --- src/tdm_helper.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/tdm_helper.c b/src/tdm_helper.c index 4873d12..6b4178e 100644 --- a/src/tdm_helper.c +++ b/src/tdm_helper.c @@ -245,6 +245,7 @@ tdm_helper_dump_buffer(tbm_surface_h buffer, const char *file) tbm_surface_info_s info; int len, ret; const char *ext; + int bo_cnt; TDM_RETURN_IF_FAIL(buffer != NULL); TDM_RETURN_IF_FAIL(file != NULL); @@ -264,6 +265,13 @@ tdm_helper_dump_buffer(tbm_surface_h buffer, const char *file) return; } + bo_cnt = tbm_surface_internal_get_num_bos(buffer); + TDM_DBG("buffer: bo_cnt(%d) %dx%d %c%c%c%c, plane: (%p+%d, %d,%d) (%p+%d, %d,%d) (%p+%d, %d,%d)", + bo_cnt, info.width, info.height, FOURCC_STR(info.format), + info.planes[0].ptr, info.planes[0].offset, info.planes[0].stride, info.planes[0].size, + info.planes[1].ptr, info.planes[1].offset, info.planes[1].stride, info.planes[1].size, + info.planes[2].ptr, info.planes[2].offset, info.planes[2].stride, info.planes[2].size); + switch (info.format) { case TBM_FORMAT_ARGB8888: case TBM_FORMAT_XRGB8888: @@ -282,6 +290,10 @@ tdm_helper_dump_buffer(tbm_surface_h buffer, const char *file) break; case TBM_FORMAT_NV12: case TBM_FORMAT_NV21: + if (bo_cnt == 1 && + (info.planes[0].ptr + info.planes[0].stride * info.height) != info.planes[1].ptr) + TDM_WRN("%p != %p", info.planes[0].ptr + info.planes[0].stride * info.height, info.planes[1].ptr); + _tdm_helper_dump_raw(file, info.planes[0].ptr, info.planes[0].stride * info.height, -- 2.7.4 From c0d2101b557122d8e81c092dea81ae369e43da2d Mon Sep 17 00:00:00 2001 From: Boram Park Date: Thu, 23 Mar 2017 19:15:17 +0900 Subject: [PATCH 05/16] package version up to 1.6.13 Change-Id: I622f6d65a5d106d7f8ac86e6f92eb8441d8f8d55 --- packaging/libtdm.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index 7debb4c..e2ddf34 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -1,7 +1,7 @@ %bcond_with utest Name: libtdm -Version: 1.6.12 +Version: 1.6.13 Release: 0 Summary: User Library of Tizen Display Manager Group: Development/Libraries -- 2.7.4 From e213c902f1f34b9e6bfdad346ded38205c3661f7 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Fri, 7 Apr 2017 16:51:02 +0900 Subject: [PATCH 06/16] client: allow set-fps during vblank running Change-Id: I8139d220d7938b5b5001e68c066c066cf2e49f61 --- client/tdm_client.c | 1 - 1 file changed, 1 deletion(-) diff --git a/client/tdm_client.c b/client/tdm_client.c index 504c119..2062915 100644 --- a/client/tdm_client.c +++ b/client/tdm_client.c @@ -689,7 +689,6 @@ tdm_client_vblank_set_fps(tdm_client_vblank *vblank, unsigned int fps) TDM_RETURN_VAL_IF_FAIL(fps > 0, TDM_ERROR_INVALID_PARAMETER); private_vblank = vblank; - TDM_RETURN_VAL_IF_FAIL(private_vblank->started == 0, TDM_ERROR_BAD_REQUEST); if (private_vblank->fps == fps) return TDM_ERROR_NONE; -- 2.7.4 From 5bd6c8bcbb65615ce395ae444d3e93daa1217f5a Mon Sep 17 00:00:00 2001 From: Boram Park Date: Fri, 7 Apr 2017 16:51:19 +0900 Subject: [PATCH 07/16] log: enable dlog by default to debug client error Change-Id: Id3c2a1b7fc7089efb6d62fdb1832fcd48fd4f688 --- common/tdm_log.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/common/tdm_log.c b/common/tdm_log.c index fc1a8f1..593dc5e 100644 --- a/common/tdm_log.c +++ b/common/tdm_log.c @@ -61,7 +61,7 @@ #undef LOG_TAG #define LOG_TAG "TDM" -static unsigned int dlog_enable; +static unsigned int dlog_enable = 1; static unsigned int color_enable = 1; static unsigned int debug_level = TDM_LOG_LEVEL_INFO; @@ -85,8 +85,8 @@ _tdm_log_check_env(void) debug_level = TDM_LOG_LEVEL_DBG; str = getenv("TDM_DLOG"); - if (str && (strstr(str, "1"))) - dlog_enable = 1; + if (str && (strstr(str, "0"))) + dlog_enable = 0; } EXTERN void -- 2.7.4 From 147db0ae0e77b2b2764ad4d983fa31a4061addb1 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Fri, 7 Apr 2017 16:51:59 +0900 Subject: [PATCH 08/16] package version up to 1.6.14 Change-Id: Ic05b0a42b8ec8f5856afeaba3d74e05525f3e62d --- packaging/libtdm.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index e2ddf34..92dd7e7 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -1,7 +1,7 @@ %bcond_with utest Name: libtdm -Version: 1.6.13 +Version: 1.6.14 Release: 0 Summary: User Library of Tizen Display Manager Group: Development/Libraries -- 2.7.4 From a146084d611e6b2b6a60b20c712ec38f719a61e8 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Fri, 14 Apr 2017 11:46:50 +0900 Subject: [PATCH 09/16] tdm: don't send output changes if client doesn't watch them Change-Id: I0c77afab20462f01cc8d2676e868d48b32978878 --- client/tdm_client.c | 7 +++++++ protocol/tdm.xml | 4 ++++ src/tdm_server.c | 26 ++++++++++++++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/client/tdm_client.c b/client/tdm_client.c index 2062915..4d8ba30 100644 --- a/client/tdm_client.c +++ b/client/tdm_client.c @@ -499,6 +499,9 @@ tdm_client_output_add_change_handler(tdm_client_output *output, h = calloc(1, sizeof *h); TDM_RETURN_VAL_IF_FAIL(h != NULL, TDM_ERROR_OUT_OF_MEMORY); + if (LIST_IS_EMPTY(&private_output->change_handler_list)) + wl_tdm_output_watch_output_changes(private_output->output, 1); + h->private_output = private_output; h->func = func; h->user_data = user_data; @@ -526,6 +529,10 @@ tdm_client_output_remove_change_handler(tdm_client_output *output, LIST_DEL(&h->link); free(h); + + if (LIST_IS_EMPTY(&private_output->change_handler_list)) + wl_tdm_output_watch_output_changes(private_output->output, 0); + return; } } diff --git a/protocol/tdm.xml b/protocol/tdm.xml index 0a157e0..bd5ed89 100644 --- a/protocol/tdm.xml +++ b/protocol/tdm.xml @@ -55,6 +55,10 @@ + + + + diff --git a/src/tdm_server.c b/src/tdm_server.c index f803a0b..f025365 100644 --- a/src/tdm_server.c +++ b/src/tdm_server.c @@ -63,6 +63,7 @@ typedef struct _tdm_server_output_info { struct wl_resource *resource; tdm_output *output; struct list_head vblank_list; + unsigned int watch_output_changes; } tdm_server_output_info; typedef struct _tdm_server_vblank_info { @@ -163,9 +164,23 @@ _tdm_server_cb_output_change(tdm_output *output, tdm_output_change_type type, tdm_value value, void *user_data) { tdm_server_output_info *output_info = user_data; + struct wl_client *client; + pid_t pid = 0; TDM_RETURN_IF_FAIL(output_info != NULL); + client = wl_resource_get_client(output_info->resource); + TDM_RETURN_IF_FAIL(client != NULL); + + wl_client_get_credentials(client, &pid, NULL, NULL); + + if (!output_info->watch_output_changes) { + TDM_DBG("skip sending the output changes: pid(%d)", (unsigned int)pid); + return; + } + + TDM_DBG("send the output changes: %d", (unsigned int)pid); + switch (type) { case TDM_OUTPUT_CHANGE_DPMS: wl_tdm_output_send_dpms(output_info->resource, value.u32); @@ -392,9 +407,20 @@ _tdm_server_output_cb_create_vblank(struct wl_client *client, struct wl_resource return; } +static void +_tdm_server_output_cb_watch_output_changes(struct wl_client *client, struct wl_resource *resource, unsigned int enable) +{ + tdm_server_output_info *output_info = wl_resource_get_user_data(resource); + + TDM_RETURN_IF_FAIL(output_info != NULL); + + output_info->watch_output_changes = enable; +} + static const struct wl_tdm_output_interface tdm_output_implementation = { _tdm_server_output_cb_destroy, _tdm_server_output_cb_create_vblank, + _tdm_server_output_cb_watch_output_changes, }; static void -- 2.7.4 From c17aeaac0b97f6148a906e420b4828a6f367d8a9 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Fri, 14 Apr 2017 12:23:26 +0900 Subject: [PATCH 10/16] package version up to 1.6.15 Change-Id: Ied1c6d1fb9b1a09b2e495c7ee39366d7b3fd675b --- packaging/libtdm.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index 92dd7e7..c01dd65 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -1,7 +1,7 @@ %bcond_with utest Name: libtdm -Version: 1.6.14 +Version: 1.6.15 Release: 0 Summary: User Library of Tizen Display Manager Group: Development/Libraries -- 2.7.4 From bdf5ec0ef8368ad36dab2a280a4833fb88747d04 Mon Sep 17 00:00:00 2001 From: Junkyeong Kim Date: Mon, 17 Apr 2017 17:43:42 +0900 Subject: [PATCH 11/16] change sscanf to strtol for getting fd Change-Id: I7fed3efbd3fc9a9273a670b3b967707453471be2 Signed-off-by: Junkyeong Kim --- src/tdm_helper.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/tdm_helper.c b/src/tdm_helper.c index 6b4178e..4adbcb8 100644 --- a/src/tdm_helper.c +++ b/src/tdm_helper.c @@ -521,15 +521,35 @@ tdm_helper_get_fd(const char *env) { const char *value; int fd, newfd, flags, ret; + char *end; + errno = 0; value = (const char*)getenv(env); if (!value) return -1; - ret = sscanf(value, "%d", &fd); - if (ret < 0) { - TDM_ERR("sscanf failed: %m"); + const long sl = strtol(value, &end, 10); + if (end == value) { + TDM_ERR("%s: not a decimal number\n", value); return -1; + } else if (*end != '\0') { + TDM_ERR("%s: extra characters at end of input: %s\n", value, end); + return -1; + } else if ((sl == LONG_MIN || sl == LONG_MAX) && errno == ERANGE) { + TDM_ERR("%s out of range of type long\n", value); + return -1; + } else if (sl > INT_MAX) { + TDM_ERR("%ld greater than INT_MAX\n", sl); + return -1; + } else if (sl < INT_MIN) { + TDM_ERR("%ld less than INT_MIN\n", sl); + return -1; + } else { + fd = (int)sl; + if (fd < 0) { + TDM_ERR("%d out of fd range\n", fd); + return -1; + } } flags = fcntl(fd, F_GETFD); -- 2.7.4 From ffdd7c6a82afdb2dfa91ee75de944fed294ae067 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Fri, 28 Apr 2017 09:26:57 +0900 Subject: [PATCH 12/16] package version up to 1.6.16 Change-Id: I8f48e66666d0e2e664facf5a179b327c21683d7b --- packaging/libtdm.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index c01dd65..fb7df61 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -1,7 +1,7 @@ %bcond_with utest Name: libtdm -Version: 1.6.15 +Version: 1.6.16 Release: 0 Summary: User Library of Tizen Display Manager Group: Development/Libraries -- 2.7.4 From cfcdcadec411787e56844a8449376fd7d02c342d Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 2 May 2017 11:33:43 +0900 Subject: [PATCH 13/16] server: trace client information Change-Id: I3e9ae2599119240628ff276aeebdd7cb34ff1341 --- src/tdm_private.h | 2 ++ src/tdm_server.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 90 insertions(+), 1 deletion(-) diff --git a/src/tdm_private.h b/src/tdm_private.h index 2a92f24..4552a5e 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -587,6 +587,8 @@ tdm_error tdm_server_init(tdm_private_loop *private_loop); void tdm_server_deinit(tdm_private_loop *private_loop); +const char* +tdm_server_get_client_name(pid_t pid); char * tdm_helper_dump_make_directory(const char *path, char *reply, int *len); diff --git a/src/tdm_server.c b/src/tdm_server.c index f025365..5299c93 100644 --- a/src/tdm_server.c +++ b/src/tdm_server.c @@ -81,10 +81,44 @@ typedef struct _tdm_server_wait_info { unsigned int req_id; } tdm_server_wait_info; +typedef struct _tdm_server_client_info { + struct list_head link; + pid_t pid; + char name[TDM_NAME_LEN]; +} tdm_server_client_info; + static tdm_private_server *keep_private_server; +static struct list_head client_list; static void destroy_wait(tdm_server_wait_info *wait_info); +static void +_tdm_server_get_process_name(pid_t pid, char *name, unsigned int size) +{ + char proc[TDM_NAME_LEN], pname[TDM_NAME_LEN]; + FILE *h; + size_t len; + + snprintf(name, size, "Unknown"); + + snprintf(proc, TDM_NAME_LEN, "/proc/%d/cmdline", pid); + h = fopen(proc, "r"); + if (!h) + return; + + len = fread(pname, sizeof(char), TDM_NAME_LEN, h); + if (len == 0) { + char *p = strncpy(pname, "NO NAME", sizeof(pname) - 1); + len = p - pname; + } + pname[len - 1] = '\0'; + + strncpy(name, pname, size - 1); + name[size - 1] = '\0'; + + fclose(h); +} + static tdm_output* _tdm_server_find_output(tdm_private_server *private_server, const char *name) { @@ -544,10 +578,32 @@ static const struct wl_tdm_interface tdm_implementation = { }; static void +destroy_client(struct wl_resource *resource) +{ + tdm_server_client_info *c = NULL, *cc = NULL; + struct wl_client *client; + pid_t pid = -1; + + client = wl_resource_get_client(resource); + TDM_RETURN_IF_FAIL(client != NULL); + + wl_client_get_credentials(client, &pid, NULL, NULL); + + LIST_FOR_EACH_ENTRY_SAFE(c, cc, &client_list, link) { + if (c->pid == pid) { + LIST_DEL(&c->link); + free(c); + return; + } + } +} + +static void _tdm_server_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id) { struct wl_resource *resource; + tdm_server_client_info *cinfo; resource = wl_resource_create(client, &wl_tdm_interface, version, id); if (!resource) { @@ -555,7 +611,18 @@ _tdm_server_bind(struct wl_client *client, void *data, return; } - wl_resource_set_implementation(resource, &tdm_implementation, data, NULL); + cinfo = calloc(1, sizeof(tdm_server_client_info)); + if (!cinfo) { + wl_client_post_no_memory(client); + wl_resource_destroy(resource); + return; + } + + LIST_ADDTAIL(&cinfo->link, &client_list); + wl_client_get_credentials(client, &cinfo->pid, NULL, NULL); + _tdm_server_get_process_name(cinfo->pid, cinfo->name, TDM_NAME_LEN); + + wl_resource_set_implementation(resource, &tdm_implementation, data, destroy_client); } INTERN tdm_error @@ -594,6 +661,8 @@ tdm_server_init(tdm_private_loop *private_loop) private_loop->private_server = private_server; keep_private_server = private_server; + LIST_INITHEAD(&client_list); + return TDM_ERROR_NONE; } @@ -602,6 +671,7 @@ tdm_server_deinit(tdm_private_loop *private_loop) { tdm_server_output_info *o = NULL, *oo = NULL; tdm_server_wait_info *w = NULL, *ww = NULL; + tdm_server_client_info *c = NULL, *cc = NULL; tdm_private_server *private_server; if (!private_loop->private_server) @@ -620,5 +690,22 @@ tdm_server_deinit(tdm_private_loop *private_loop) free(private_server); private_loop->private_server = NULL; keep_private_server = NULL; + + LIST_FOR_EACH_ENTRY_SAFE(c, cc, &client_list, link) { + LIST_DEL(&c->link); + free(c); + } } +INTERN const char* +tdm_server_get_client_name(pid_t pid) +{ + tdm_server_client_info *c = NULL; + + LIST_FOR_EACH_ENTRY(c, &client_list, link) { + if (c->pid == pid) + return (const char*)c->name; + } + + return NULL; +} -- 2.7.4 From fd2eadc76fbca53159c630a08e9ae777bb405894 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 2 May 2017 11:35:53 +0900 Subject: [PATCH 14/16] vblank: use tdm_server_get_client_name Change-Id: I4f47cca1d1f4fa268ab330fd947cd91e5c9458b8 --- src/tdm_vblank.c | 33 ++++----------------------------- 1 file changed, 4 insertions(+), 29 deletions(-) diff --git a/src/tdm_vblank.c b/src/tdm_vblank.c index 662204f..99ce8a0 100644 --- a/src/tdm_vblank.c +++ b/src/tdm_vblank.c @@ -1109,31 +1109,6 @@ tdm_vblank_set_resource(tdm_vblank *vblank, struct wl_resource *resource) return TDM_ERROR_NONE; } -static void -_tdm_vblank_get_process_name(pid_t pid, char *name, unsigned int size) -{ - char proc[TDM_NAME_LEN], pname[TDM_NAME_LEN]; - FILE *h; - size_t len; - - snprintf(proc, TDM_NAME_LEN, "/proc/%d/cmdline", pid); - h = fopen(proc, "r"); - if (!h) - return; - - len = fread(pname, sizeof(char), TDM_NAME_LEN, h); - if (len == 0) { - char *p = strncpy(pname, "NO NAME", sizeof(pname) - 1); - len = p - pname; - } - pname[len - 1] = '\0'; - - strncpy(name, pname, size - 1); - name[size - 1] = '\0'; - - fclose(h); -} - INTERN void tdm_vblank_get_vblank_list_information(tdm_display *dpy, char *reply, int *len) { @@ -1147,17 +1122,17 @@ tdm_vblank_get_vblank_list_information(tdm_display *dpy, char *reply, int *len) pthread_mutex_lock(&valid_list_lock); LIST_FOR_EACH_ENTRY(v, &valid_vblank_list, valid_link) { struct wl_client *client = wl_resource_get_client(v->resource); - char proc_name[TDM_NAME_LEN]; + const char *proc_name = NULL; pid_t pid = 0; - snprintf(proc_name, TDM_NAME_LEN, "Unknown"); if (client) { wl_client_get_credentials(client, &pid, NULL, NULL); - _tdm_vblank_get_process_name(pid, proc_name, TDM_NAME_LEN); + proc_name = tdm_server_get_client_name(pid); } TDM_SNPRINTF(reply, len, "%-12s %u %d %u %s (pid: %u)\n", - v->name, v->fps, v->offset, v->enable_fake, proc_name, pid); + v->name, v->fps, v->offset, v->enable_fake, + (proc_name) ? proc_name : "Unknown", pid); } pthread_mutex_unlock(&valid_list_lock); -- 2.7.4 From 11599cb15fc96bc8389869e0bcd08b3146ebd9c4 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 2 May 2017 13:47:32 +0900 Subject: [PATCH 15/16] monitor: add trace option to debug server-client protocol Change-Id: Id27af997282b51db1541e2d7e59e521d95097d66 --- src/tdm_event_loop.c | 281 +++++++++++++++++++++++++++++++++++++++++++++++ src/tdm_monitor_server.c | 23 ++++ src/tdm_private.h | 29 +++++ 3 files changed, 333 insertions(+) diff --git a/src/tdm_event_loop.c b/src/tdm_event_loop.c index a2cac7e..7445ad5 100644 --- a/src/tdm_event_loop.c +++ b/src/tdm_event_loop.c @@ -461,3 +461,284 @@ tdm_event_loop_source_remove(tdm_event_loop_source *source) free(source); } + +static void +_trace_cb_client_destroy(struct wl_listener *listener, void *data) +{ + struct wl_client *client = (struct wl_client *) data; + struct timespec tp; + unsigned int time; + pid_t pid = -1; + const char *proc_name; + char temp[512] = { 0, }, *p = temp; + int len = sizeof(temp), *l = &len; + + wl_client_get_credentials(client, &pid, NULL, NULL); + proc_name = tdm_server_get_client_name(pid); + + clock_gettime(CLOCK_MONOTONIC, &tp); + time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000); + + TDM_SNPRINTF(p, l, "[%10.3f] Server [PID:%d] client destroying", time / 1000.0, pid); + TDM_SNPRINTF(p, l, ", cmd: %s", proc_name ? proc_name : "Unknown"); + + TDM_INFO("%s", temp); + + wl_list_remove(&listener->link); + free(listener); +} + +static void +_trace_reg_client_destroy_listener(struct wl_client *client) +{ + struct wl_listener *listener; + + listener = wl_client_get_destroy_listener(client, _trace_cb_client_destroy); + if (listener) + return; + + listener = calloc(1, sizeof(struct wl_listener)); + TDM_RETURN_IF_FAIL(listener != NULL); + + listener->notify = _trace_cb_client_destroy; + wl_client_add_destroy_listener(client, listener); +} + +static const char * +_trace_get_next_argument(const char *signature, + struct argument_details *details) +{ + details->nullable = 0; + for (; *signature; ++signature) { + switch (*signature) { + case 'i': + case 'u': + case 'f': + case 's': + case 'o': + case 'n': + case 'a': + case 'h': + details->type = *signature; + return signature + 1; + case '?': + details->nullable = 1; + break; + default: + return NULL; + } + } + details->type = '\0'; + return signature; +} + +#if !TDM_WAYLAND_LOGGER + +static void +_trace_protocol_cb(struct wl_closure *closure, struct wl_resource *resource, int send) +{ + int i; + struct argument_details arg; + struct wl_object *object = &resource->object; + struct wl_client *client = resource->client; + const char *signature = closure->message->signature; + struct timespec tp; + unsigned int time; + pid_t pid = -1; + const char *proc_name; + char temp[512] = { 0, }, *p = temp; + int len = sizeof(temp), *l = &len; + + if (client) { + _trace_reg_client_destroy_listener(client); + wl_client_get_credentials(client, &pid, NULL, NULL); + } + + proc_name = tdm_server_get_client_name(pid); + + clock_gettime(CLOCK_MONOTONIC, &tp); + time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000); + + TDM_SNPRINTF(p, l, "[%10.3f] %s%d%s%s@%u.%s(", + time / 1000.0, + send ? "Server -> Client [PID:" : "Server <- Client [PID:", + pid, "] ", + object->interface->name, object->id, closure->message->name); + + for (i = 0; i < closure->count; i++) { + signature = _trace_get_next_argument(signature, &arg); + TDM_RETURN_IF_FAIL(signature != NULL); + + if (i > 0) + TDM_SNPRINTF(p, l, ", "); + + switch (arg.type) { + case 'u': + TDM_SNPRINTF(p, l, "%u", closure->args[i].u); + break; + case 'i': + TDM_SNPRINTF(p, l, "%d", closure->args[i].i); + break; + case 'f': + TDM_SNPRINTF(p, l, "%f", wl_fixed_to_double(closure->args[i].f)); + break; + case 's': + TDM_SNPRINTF(p, l, "\"%s\"", closure->args[i].s); + break; + case 'o': + if (closure->args[i].o) + TDM_SNPRINTF(p, l, "%s@%u", closure->args[i].o->interface->name, closure->args[i].o->id); + else + TDM_SNPRINTF(p, l, "nil"); + break; + case 'n': + TDM_SNPRINTF(p, l, "new id %s@", + (closure->message->types[i]) ? closure->message->types[i]->name : "[unknown]"); + if (closure->args[i].n != 0) + TDM_SNPRINTF(p, l, "%u", closure->args[i].n); + else + TDM_SNPRINTF(p, l, "nil"); + break; + case 'a': + TDM_SNPRINTF(p, l, "array"); + break; + case 'h': + TDM_SNPRINTF(p, l, "fd %d", closure->args[i].h); + break; + default: + return; + } + } + + TDM_SNPRINTF(p, l, "), cmd: %s", proc_name ? proc_name : "Unknown"); + + TDM_INFO("%s", temp); +} + +#else + +static struct wl_protocol_logger *_trace_protocol_logger; + +static void +_trace_protocol_logger_cb(void *user_data, + enum wl_protocol_logger_type direction, + const struct wl_protocol_logger_message *message) +{ + int i; + struct argument_details arg; + struct wl_client *client = wl_resource_get_client(message->resource); + const char *signature = message->message->signature; + struct timespec tp; + unsigned int time; + pid_t pid = -1; + const char *proc_name; + char temp[512] = { 0, }, *p = temp; + int len = sizeof(temp), *l = &len; + int send; + + if (client) { + _trace_reg_client_destroy_listener(client); + wl_client_get_credentials(client, &pid, NULL, NULL); + } + + proc_name = tdm_server_get_client_name(pid); + + clock_gettime(CLOCK_MONOTONIC, &tp); + time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000); + + send = (direction == WL_PROTOCOL_LOGGER_EVENT) ? 1 : 0; + + TDM_SNPRINTF(p, l, "[%10.3f] %s%d%s%s@%u.%s(", + time / 1000.0, + send ? "Server -> Client [PID:" : "Server <- Client [PID:", + pid, "] ", + wl_resource_get_name(message->resource), + wl_resource_get_id(message->resource), + message->message->name); + + for (i = 0; i < message->arguments_count; i++) { + signature = _trace_get_next_argument(signature, &arg); + TDM_RETURN_IF_FAIL(signature != NULL); + + if (i > 0) + TDM_SNPRINTF(p, l, ", "); + + switch (arg.type) { + case 'u': + TDM_SNPRINTF(p, l, "%u", message->arguments[i].u); + break; + case 'i': + TDM_SNPRINTF(p, l, "%d", message->arguments[i].i); + break; + case 'f': + TDM_SNPRINTF(p, l, "%f", + wl_fixed_to_double(message->arguments[i].f)); + break; + case 's': + TDM_SNPRINTF(p, l, "\"%s\"", message->arguments[i].s); + break; + case 'o': + if (message->arguments[i].o) + TDM_SNPRINTF(p, l, "%s@%u", + wl_resource_get_name((struct wl_resource *) message->arguments[i].o), + wl_resource_get_id((struct wl_resource *) message->arguments[i].o)); + else + TDM_SNPRINTF(p, l, "nil"); + break; + case 'n': + TDM_SNPRINTF(p, l, "new id %s@", + (message->message->types[i]) ? message->message->types[i]->name : "[unknown]"); + if (message->arguments[i].n != 0) + TDM_SNPRINTF(p, l, "%u", message->arguments[i].n); + else + TDM_SNPRINTF(p, l, "nil"); + break; + case 'a': + TDM_SNPRINTF(p, l, "array"); + break; + case 'h': + TDM_SNPRINTF(p, l, "fd %d", message->arguments[i].h); + break; + default: + return; + } + } + + TDM_SNPRINTF(p, l, "), cmd: %s", proc_name ? proc_name : "Unknown"); + + TDM_INFO("%s", temp); +} +#endif + +INTERN tdm_error +tdm_event_loop_trace_enable(tdm_private_display * private_display, + unsigned int enable) +{ + tdm_private_loop *private_loop = private_display->private_loop; + + TDM_RETURN_VAL_IF_FAIL(private_loop->wl_display != NULL, TDM_ERROR_NONE); + + if (!enable) { +#if !TDM_WAYLAND_LOGGER + wl_debug_server_debug_func_set(NULL); +#else + if (_trace_protocol_logger) { + wl_protocol_logger_destroy(_trace_protocol_logger); + _trace_protocol_logger = NULL; + } +#endif + return TDM_ERROR_NONE; + } + +#if !TDM_WAYLAND_LOGGER + wl_debug_server_debug_func_set((wl_server_debug_func_ptr) _trace_protocol_cb); +#else + if (_trace_protocol_logger) + wl_protocol_logger_destroy(_trace_protocol_logger); + + _trace_protocol_logger = + wl_display_add_protocol_logger(private_loop->wl_display, _trace_protocol_logger_cb, NULL); +#endif + + return TDM_ERROR_NONE; +} diff --git a/src/tdm_monitor_server.c b/src/tdm_monitor_server.c index d12a9eb..2df4dd3 100644 --- a/src/tdm_monitor_server.c +++ b/src/tdm_monitor_server.c @@ -54,6 +54,23 @@ _tdm_monitor_server_query(unsigned int pid, char *cwd, int argc, char *argv[], c } static void +_tdm_monitor_server_protocol_trace(unsigned int pid, char *cwd, int argc, char *argv[], char *reply, int *len, tdm_display *dpy) +{ + int enable; + + if (argc < 3) { + _tdm_monitor_server_usage(argv[0], reply, len); + return; + } + + enable = atoi(argv[2]); + + tdm_event_loop_trace_enable(dpy, enable); + + TDM_SNPRINTF(reply, len, "protocol trace: '%s'\n", (enable) ? "enabled" : "disabled"); +} + +static void _tdm_monitor_server_dpms(unsigned int pid, char *cwd, int argc, char *argv[], char *reply, int *len, tdm_display *dpy) { tdm_output *output; @@ -463,6 +480,12 @@ static struct { "show tdm output, layer information", NULL, NULL }, { + "trace", _tdm_monitor_server_protocol_trace, + "enable/disable the wl protocol", + "", + "0 or 1" + }, + { "dpms", _tdm_monitor_server_dpms, "set output dpms", ":", "0:3 or 0:0" }, diff --git a/src/tdm_private.h b/src/tdm_private.h index 4552a5e..59cb1ad 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -499,6 +499,8 @@ tdm_error tdm_event_loop_dispatch(tdm_private_display *private_display); void 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, @@ -692,6 +694,33 @@ 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); + + +#define TDM_WAYLAND_LOGGER ((WAYLAND_VERSION_MAJOR == 1) && (WAYLAND_VERSION_MINOR > 11)) + +#if !TDM_WAYLAND_LOGGER +#ifndef WL_CLOSURE_MAX_ARGS +#define WL_CLOSURE_MAX_ARGS 20 +#endif + +struct wl_closure { + int count; + const struct wl_message *message; + uint32_t opcode; + uint32_t sender_id; + union wl_argument args[WL_CLOSURE_MAX_ARGS]; + struct wl_list link; + struct wl_proxy *proxy; + struct wl_array extra[0]; +}; +#endif /* TDM_WAYLAND_LOGGER */ + +struct argument_details { + char type; + int nullable; +}; + + #ifdef __cplusplus } #endif -- 2.7.4 From 24a0b46061fa6640bcc26f4ddf4c7c92d049bee6 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 2 May 2017 14:25:12 +0900 Subject: [PATCH 16/16] vblank: correct target time We should consider the vblank interval to calculate the target time. Change-Id: I7f78631d644ce5dce0e2dfb2c8d8bcefbab45205 --- src/tdm_vblank.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tdm_vblank.c b/src/tdm_vblank.c index 99ce8a0..ee8d352 100644 --- a/src/tdm_vblank.c +++ b/src/tdm_vblank.c @@ -768,9 +768,9 @@ _tdm_vblank_wait_HW(tdm_vblank_wait_info *wait_info) prev = last + private_vblank->vblank_gap * skip; curr = tdm_helper_get_time(); - target = prev; + target = last; while (target < curr) - target += private_vblank->vblank_gap; + target += (private_vblank->vblank_gap * wait_info->interval); hw_interval = (unsigned int)((target - curr) / private_vblank->HW_vblank_gap + TDM_TIME_MARGIN) + 1; -- 2.7.4