From: Boram Park Date: Wed, 8 Feb 2017 03:39:16 +0000 (+0900) Subject: vblank: add set_vblank_fps functionality for the given PID X-Git-Tag: accepted/tizen/3.0/common/20170213.160533~5 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F02%2F113502%2F2;p=platform%2Fcore%2Fuifw%2Flibtdm.git vblank: add set_vblank_fps functionality for the given PID Change-Id: I28a8b5ca1e585f68817da6f887aed13f188b64f0 --- diff --git a/client/tdm_client.c b/client/tdm_client.c index c9b312c..bdab4c0 100644 --- a/client/tdm_client.c +++ b/client/tdm_client.c @@ -86,6 +86,7 @@ struct _tdm_private_client_vblank { struct wl_tdm_vblank *vblank; struct list_head wait_list; + char name[TDM_NAME_LEN]; unsigned int sync; unsigned int fps; int offset; @@ -425,6 +426,25 @@ tdm_client_wait_vblank(tdm_client *client, char *name, return tdm_client_vblank_wait(private_client->temp_vblank, interval, _tdm_client_vblank_handler_temp, vblank_temp); } +tdm_error +tdm_client_set_client_vblank_fps(tdm_client *client, pid_t pid, const char *name, unsigned int fps) +{ + tdm_private_client *private_client = (tdm_private_client*)client; + + TDM_RETURN_VAL_IF_FAIL(private_client != NULL, TDM_ERROR_INVALID_PARAMETER); + TDM_RETURN_VAL_IF_FAIL(pid > 0, TDM_ERROR_INVALID_PARAMETER); + TDM_RETURN_VAL_IF_FAIL(fps > 0, TDM_ERROR_INVALID_PARAMETER); + + if (!name) + name = TDM_VBLANK_DEFAULT_NAME; + + wl_tdm_set_client_vblank_fps(private_client->tdm, pid, name, fps); + + wl_display_flush(private_client->display); + + return TDM_ERROR_NONE; +} + tdm_client_output* tdm_client_get_output(tdm_client *client, char *name, tdm_error *error) { @@ -647,6 +667,26 @@ tdm_client_vblank_destroy(tdm_client_vblank *vblank) } tdm_error +tdm_client_vblank_set_name(tdm_client_vblank *vblank, const char *name) +{ + tdm_private_client_vblank *private_vblank; + + TDM_RETURN_VAL_IF_FAIL(vblank != NULL, TDM_ERROR_INVALID_PARAMETER); + + private_vblank = vblank; + + if (!name) + name = TDM_VBLANK_DEFAULT_NAME; + + strncpy(private_vblank->name, name, TDM_NAME_LEN - 1); + private_vblank->name[TDM_NAME_LEN - 1] = '\0'; + + wl_tdm_vblank_set_name(private_vblank->vblank, private_vblank->name); + + return TDM_ERROR_NONE; +} + +tdm_error tdm_client_vblank_set_sync(tdm_client_vblank *vblank, unsigned int sync) { tdm_private_client_vblank *private_vblank; diff --git a/client/tdm_client.h b/client/tdm_client.h index e7df780..5cb1cce 100644 --- a/client/tdm_client.h +++ b/client/tdm_client.h @@ -138,6 +138,17 @@ tdm_client_wait_vblank(tdm_client *client, char *name, tdm_client_vblank_handler2 func, void *user_data); /** + * @brief Set the client vblank fps for the given PID and name. + * @param[in] client A TDM client object + * @param[in] pid The process ID + * @param[in] name The client vblank name + * @param[in] fps The client vblank fps + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ +tdm_error +tdm_client_set_client_vblank_fps(tdm_client *client, pid_t pid, const char *name, unsigned int fps); + +/** * @brief Get the client output object which has the given name. * @details * The client output name can be @b 'primary' or @b 'default' to get the main output. @@ -241,6 +252,15 @@ void tdm_client_vblank_destroy(tdm_client_vblank *vblank); /** + * @brief Set the name to the client vblank object + * @param[in] vblank The client vblank object + * @param[in] name The client vblank name + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ +tdm_error +tdm_client_vblank_set_name(tdm_client_vblank *vblank, const char *name); + +/** * @brief Set the sync value to the client vblank object * @details * If sync == 1, the user client vblank handler of #tdm_client_vblank_wait diff --git a/include/tdm.h b/include/tdm.h index 3a066c1..ebb8f4f 100644 --- a/include/tdm.h +++ b/include/tdm.h @@ -903,6 +903,26 @@ void tdm_vblank_destroy(tdm_vblank *vblank); /** + * @brief Set the name to a vblank object + * @details The default name is "unknown" + * @param[in] vblank A vblank object + * @param[in] name vblank name + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ +tdm_error +tdm_vblank_set_name(tdm_vblank *vblank, const char *name); + +/** + * @brief Get the name for a vblank object + * @details The default name is "unknown" + * @param[in] vblank A vblank object + * @param[out] name vblank name + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ +tdm_error +tdm_vblank_get_name(tdm_vblank *vblank, const char **name); + +/** * @brief Set the fps to a vblank object * @details Default is the @b vertical @b refresh @b rate of the given output. * @param[in] vblank A vblank object @@ -913,6 +933,15 @@ tdm_error tdm_vblank_set_fps(tdm_vblank *vblank, unsigned int fps); /** + * @brief Get the fps for a vblank object + * @param[in] vblank A vblank object + * @param[out] fps over 0 + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ +tdm_error +tdm_vblank_get_fps(tdm_vblank *vblank, unsigned int *fps); + +/** * @brief Set the offset(milli-second) to a vblank object * @details Default is @b 0. * @param[in] vblank A vblank object @@ -923,6 +952,15 @@ tdm_error tdm_vblank_set_offset(tdm_vblank *vblank, int offset); /** + * @brief Get the offset(milli-second) for a vblank object + * @param[in] vblank A vblank object + * @param[out] offset the offset(milli-second) + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ +tdm_error +tdm_vblank_get_offset(tdm_vblank *vblank, int *offset); + +/** * @brief Enable/Disable the fake vblank to a vblank object * @details * If enable_fake == 0, #tdm_vblank_wait will return TDM_ERROR_DPMS_OFF @@ -938,10 +976,11 @@ tdm_vblank_set_enable_fake(tdm_vblank *vblank, unsigned int enable_fake); /** * @brief Get the fake vblank * @param[in] vblank A vblank object - * @return 1 if enable. Otherwise, 0. + * @param[out] enable_fake 1:enable, 0:disable + * @return #TDM_ERROR_NONE if success. Otherwise, error value. */ -unsigned int -tdm_vblank_get_enable_fake(tdm_vblank *vblank); +tdm_error +tdm_vblank_get_enable_fake(tdm_vblank *vblank, unsigned int *enable_fake); /** * @brief Wait for a vblank diff --git a/include/tdm_common.h b/include/tdm_common.h index 3b9f5fa..dc33494 100644 --- a/include/tdm_common.h +++ b/include/tdm_common.h @@ -44,6 +44,7 @@ extern "C" { #define TDM_NAME_LEN 64 #define TDM_PATH_LEN 1024 +#define TDM_VBLANK_DEFAULT_NAME "Unknown" /** * @file tdm_common.h diff --git a/protocol/tdm.xml b/protocol/tdm.xml index 3f98fd1..0a157e0 100644 --- a/protocol/tdm.xml +++ b/protocol/tdm.xml @@ -12,13 +12,19 @@ + + + + - - + + + + @@ -61,8 +67,14 @@ + + + + + + diff --git a/src/tdm_monitor_server.c b/src/tdm_monitor_server.c index 0d18743..1916e4a 100644 --- a/src/tdm_monitor_server.c +++ b/src/tdm_monitor_server.c @@ -241,6 +241,56 @@ _tdm_monitor_server_fps(unsigned int pid, char *cwd, int argc, char *argv[], cha } static void +_tdm_monitor_server_vblank_list(unsigned int pid, char *cwd, int argc, char *argv[], + char *reply, int *len, tdm_display *dpy) +{ + tdm_server_get_vblank_list_information(dpy, reply, len); +} + +static void +_tdm_monitor_server_vblank_fps(unsigned int pid, char *cwd, int argc, char *argv[], + char *reply, int *len, tdm_display *dpy) +{ + unsigned int target_pid, fps; + char *arg; + char *end; + char name[TDM_NAME_LEN]; + tdm_error ret; + + if (argc < 3) { + _tdm_monitor_server_usage(argv[0], reply, len); + return; + } + + arg = argv[2]; + target_pid = strtol(arg, &end, 10); + + if (*end == ',') { + arg = end + 1; + end = strtostr(name, TDM_NAME_LEN, arg, TDM_DELIM); + } else { + strncpy(name, TDM_VBLANK_DEFAULT_NAME, TDM_NAME_LEN - 1); + name[TDM_NAME_LEN - 1] = '\0'; + } + + if (*end != '@') { + TDM_SNPRINTF(reply, len, "failed: no fps value\n"); + return; + } + + arg = end + 1; + fps = strtol(arg, &end, 10); + + ret = tdm_server_set_client_vblank_fps(target_pid, name, fps); + if (ret != TDM_ERROR_NONE) { + TDM_SNPRINTF(reply, len, "can't set '%u' fps to '%s' client vblank(PID:%u)\n", fps, name, target_pid); + return; + } + + TDM_SNPRINTF(reply, len, "success: '%u' fps for '%s' client vblank(PID:%u)\n", fps, name, target_pid); +} + +static void _tdm_monitor_server_prop(unsigned int pid, char *cwd, int argc, char *argv[], char *reply, int *len, tdm_display *dpy) { tdm_output *output; @@ -446,6 +496,18 @@ static struct { "0 or 1" }, { + "vblank_list", _tdm_monitor_server_vblank_list, + "print the client vblank list", + NULL, + NULL + }, + { + "vblank_fps", _tdm_monitor_server_vblank_fps, + "set the client vblank fps for the given process ID and client vblank name", + "[,]@", + NULL + }, + { "prop", _tdm_monitor_server_prop, "set the property of a output or a layer", "[,]:,", diff --git a/src/tdm_private.h b/src/tdm_private.h index cd7405d..c7a08d8 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -554,6 +554,10 @@ tdm_error tdm_server_init(tdm_private_loop *private_loop); void tdm_server_deinit(tdm_private_loop *private_loop); +tdm_error +tdm_server_set_client_vblank_fps(unsigned int pid, const char *name, unsigned int fps); +void +tdm_server_get_vblank_list_information(tdm_display *dpy, char *reply, int *len); 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 914b1da..bb2a7c3 100644 --- a/src/tdm_server.c +++ b/src/tdm_server.c @@ -67,6 +67,8 @@ typedef struct _tdm_server_output_info { typedef struct _tdm_server_vblank_info { struct list_head link; + struct list_head valid_link; + tdm_server_output_info *output_info; struct wl_resource *resource; @@ -81,6 +83,7 @@ typedef struct _tdm_server_wait_info { } tdm_server_wait_info; static tdm_private_server *keep_private_server; +static struct list_head valid_vblank_list; static void destroy_wait(tdm_server_wait_info *wait_info); @@ -202,6 +205,8 @@ destroy_vblank_callback(struct wl_resource *resource) } LIST_DEL(&vblank_info->link); + LIST_DEL(&vblank_info->valid_link); + free(vblank_info); } @@ -212,6 +217,14 @@ _tdm_server_vblank_cb_destroy(struct wl_client *client, struct wl_resource *reso } static void +_tdm_server_vblank_cb_set_name(struct wl_client *client, struct wl_resource *resource, const char *name) +{ + tdm_server_vblank_info *vblank_info = wl_resource_get_user_data(resource); + + tdm_vblank_set_name(vblank_info->vblank, name); +} + +static void _tdm_server_vblank_cb_set_fps(struct wl_client *client, struct wl_resource *resource, uint32_t fps) { tdm_server_vblank_info *vblank_info = wl_resource_get_user_data(resource); @@ -243,6 +256,7 @@ _tdm_server_vblank_cb_wait_vblank(struct wl_client *client, struct wl_resource * tdm_server_output_info *output_info = vblank_info->output_info; tdm_private_server *private_server = output_info->private_server; tdm_server_wait_info *wait_info; + unsigned int enable_fake = 0; tdm_error ret; TDM_TRACE_COUNT(ServerWaitVBlank, req_id); @@ -263,7 +277,8 @@ _tdm_server_vblank_cb_wait_vblank(struct wl_client *client, struct wl_resource * ret = tdm_vblank_wait(vblank_info->vblank, req_sec, req_usec, interval, _tdm_server_cb_vblank, wait_info); - if (!tdm_vblank_get_enable_fake(vblank_info->vblank) && ret == TDM_ERROR_DPMS_OFF) + tdm_vblank_get_enable_fake(vblank_info->vblank, &enable_fake); + if (!enable_fake && ret == TDM_ERROR_DPMS_OFF) goto wait_failed; TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, wait_failed); @@ -283,6 +298,7 @@ _tdm_server_vblank_cb_wait_vblank_seq(struct wl_client *client, struct wl_resour tdm_server_output_info *output_info = vblank_info->output_info; tdm_private_server *private_server = output_info->private_server; tdm_server_wait_info *wait_info; + unsigned int enable_fake = 0; tdm_error ret; TDM_TRACE_COUNT(ServerWaitVBlank, req_id); @@ -303,7 +319,8 @@ _tdm_server_vblank_cb_wait_vblank_seq(struct wl_client *client, struct wl_resour ret = tdm_vblank_wait_seq(vblank_info->vblank, req_sec, req_usec, sequence, _tdm_server_cb_vblank, wait_info); - if (!tdm_vblank_get_enable_fake(vblank_info->vblank) && ret == TDM_ERROR_DPMS_OFF) + tdm_vblank_get_enable_fake(vblank_info->vblank, &enable_fake); + if (!enable_fake && ret == TDM_ERROR_DPMS_OFF) goto wait_failed; TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, wait_failed); @@ -317,6 +334,7 @@ wait_failed: static const struct wl_tdm_vblank_interface tdm_vblank_implementation = { _tdm_server_vblank_cb_destroy, + _tdm_server_vblank_cb_set_name, _tdm_server_vblank_cb_set_fps, _tdm_server_vblank_cb_set_offset, _tdm_server_vblank_cb_set_enable_fake, @@ -367,6 +385,8 @@ _tdm_server_output_cb_create_vblank(struct wl_client *client, struct wl_resource } LIST_ADDTAIL(&vblank_info->link, &output_info->vblank_list); + LIST_ADDTAIL(&vblank_info->valid_link, &valid_vblank_list); + vblank_info->output_info = output_info; vblank_info->resource = vblank_resource; vblank_info->vblank = vblank; @@ -486,9 +506,20 @@ _tdm_server_cb_debug(struct wl_client *client, struct wl_resource *resource, con wl_tdm_send_debug_done(resource, message); } +static void +_tdm_server_cb_set_client_vblank_fps(struct wl_client *client, struct wl_resource *resource, + unsigned int pid, const char *name, unsigned int fps) +{ + tdm_error ret = tdm_server_set_client_vblank_fps(pid, name, fps); + TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE); + + TDM_INFO("'%s' vblank fps(PID: '%u'): %u", name, pid, fps); +} + static const struct wl_tdm_interface tdm_implementation = { - _tdm_server_cb_create_output, _tdm_server_cb_debug, + _tdm_server_cb_create_output, + _tdm_server_cb_set_client_vblank_fps, }; static void @@ -538,6 +569,8 @@ tdm_server_init(tdm_private_loop *private_loop) return TDM_ERROR_OUT_OF_MEMORY; } + LIST_INITHEAD(&valid_vblank_list); + private_server->private_loop = private_loop; private_loop->private_server = private_server; keep_private_server = private_server; @@ -569,3 +602,98 @@ tdm_server_deinit(tdm_private_loop *private_loop) private_loop->private_server = NULL; keep_private_server = NULL; } + +INTERN tdm_error +tdm_server_set_client_vblank_fps(unsigned int pid, const char *name, unsigned int fps) +{ + tdm_server_vblank_info *v; + + TDM_RETURN_VAL_IF_FAIL(pid > 0, TDM_ERROR_INVALID_PARAMETER); + TDM_RETURN_VAL_IF_FAIL(fps > 0, TDM_ERROR_INVALID_PARAMETER); + + LIST_FOR_EACH_ENTRY(v, &valid_vblank_list, valid_link) { + struct wl_client *client = wl_resource_get_client(v->resource); + pid_t client_pid = 0; + const char *vblank_name = NULL; + + if (!client) + continue; + + wl_client_get_credentials(client, &client_pid, NULL, NULL); + + if (client_pid != pid) + continue; + + if (name && strncmp(name, TDM_VBLANK_DEFAULT_NAME, TDM_NAME_LEN)) { + tdm_vblank_get_name(v->vblank, &vblank_name); + if (strncmp(vblank_name, name, TDM_NAME_LEN)) + continue; + } + + tdm_vblank_set_fps(v->vblank, fps); + } + + return TDM_ERROR_NONE; +} + +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(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_server_get_vblank_list_information(tdm_display *dpy, char *reply, int *len) +{ + tdm_server_vblank_info *v; + + TDM_SNPRINTF(reply, len, "[Client Vblank List]\n"); + TDM_SNPRINTF(reply, len, "---------------------------------------------------------------\n"); + TDM_SNPRINTF(reply, len, "name fps offset fake process\n"); + TDM_SNPRINTF(reply, len, "---------------------------------------------------------------\n"); + + LIST_FOR_EACH_ENTRY(v, &valid_vblank_list, valid_link) { + struct wl_client *client = wl_resource_get_client(v->resource); + const char *vbl_name = NULL; + char proc_name[TDM_NAME_LEN]; + unsigned int fps = 0, fake = 0; + int offset = 0; + pid_t pid = 0; + + tdm_vblank_get_name(v->vblank, &vbl_name); + tdm_vblank_get_fps(v->vblank, &fps); + tdm_vblank_get_offset(v->vblank, &offset); + tdm_vblank_get_enable_fake(v->vblank, &fake); + + snprintf(proc_name, TDM_NAME_LEN, "Unknown"); + if (client) { + wl_client_get_credentials(client, &pid, NULL, NULL); + _tdm_server_get_process_name(pid, proc_name, TDM_NAME_LEN); + } + + TDM_SNPRINTF(reply, len, "%-12s %u %d %u %s (pid: %u)\n", + vbl_name, fps, offset, fake, proc_name, pid); + } + + TDM_SNPRINTF(reply, len, "\n"); +} + diff --git a/src/tdm_vblank.c b/src/tdm_vblank.c index 0e3c1aa..b9ce1ab 100644 --- a/src/tdm_vblank.c +++ b/src/tdm_vblank.c @@ -91,6 +91,7 @@ typedef struct _tdm_private_vblank { unsigned int vrefresh; unsigned int check_HW_or_SW; + char name[TDM_NAME_LEN]; unsigned int fps; int offset; unsigned int enable_fake; @@ -378,6 +379,9 @@ tdm_vblank_create(tdm_display *dpy, tdm_output *output, tdm_error *error) private_vblank->check_HW_or_SW = 1; private_vblank->fps = mode->vrefresh; + strncpy(private_vblank->name, TDM_VBLANK_DEFAULT_NAME, TDM_NAME_LEN - 1); + private_vblank->name[TDM_NAME_LEN - 1] = '\0'; + LIST_INITHEAD(&private_vblank->HW_wait_list); LIST_INITHEAD(&private_vblank->SW_wait_list); @@ -425,6 +429,38 @@ tdm_vblank_destroy(tdm_vblank *vblank) } EXTERN tdm_error +tdm_vblank_set_name(tdm_vblank *vblank, const char *name) +{ + tdm_private_vblank *private_vblank = vblank; + + TDM_RETURN_VAL_IF_FAIL(private_vblank != NULL, TDM_ERROR_INVALID_PARAMETER); + + if (!name) + name = TDM_VBLANK_DEFAULT_NAME; + + strncpy(private_vblank->name, name, TDM_NAME_LEN - 1); + private_vblank->name[TDM_NAME_LEN - 1] = '\0'; + + if (tdm_debug_module & TDM_DEBUG_VBLANK) + VIN("name(%s)", name); + + return TDM_ERROR_NONE; +} + +EXTERN tdm_error +tdm_vblank_get_name(tdm_vblank *vblank, const char **name) +{ + tdm_private_vblank *private_vblank = vblank; + + TDM_RETURN_VAL_IF_FAIL(private_vblank != NULL, TDM_ERROR_INVALID_PARAMETER); + TDM_RETURN_VAL_IF_FAIL(name != NULL, TDM_ERROR_INVALID_PARAMETER); + + *name = (const char*)private_vblank->name; + + return TDM_ERROR_NONE; +} + +EXTERN tdm_error tdm_vblank_set_fps(tdm_vblank *vblank, unsigned int fps) { tdm_private_vblank *private_vblank = vblank; @@ -445,6 +481,19 @@ tdm_vblank_set_fps(tdm_vblank *vblank, unsigned int fps) } EXTERN tdm_error +tdm_vblank_get_fps(tdm_vblank *vblank, unsigned int *fps) +{ + tdm_private_vblank *private_vblank = vblank; + + TDM_RETURN_VAL_IF_FAIL(private_vblank != NULL, TDM_ERROR_INVALID_PARAMETER); + TDM_RETURN_VAL_IF_FAIL(fps != NULL, TDM_ERROR_INVALID_PARAMETER); + + *fps = private_vblank->fps; + + return TDM_ERROR_NONE; +} + +EXTERN tdm_error tdm_vblank_set_offset(tdm_vblank *vblank, int offset) { tdm_private_vblank *private_vblank = vblank; @@ -464,6 +513,19 @@ tdm_vblank_set_offset(tdm_vblank *vblank, int offset) } EXTERN tdm_error +tdm_vblank_get_offset(tdm_vblank *vblank, int *offset) +{ + tdm_private_vblank *private_vblank = vblank; + + TDM_RETURN_VAL_IF_FAIL(private_vblank != NULL, TDM_ERROR_INVALID_PARAMETER); + TDM_RETURN_VAL_IF_FAIL(offset != NULL, TDM_ERROR_INVALID_PARAMETER); + + *offset = private_vblank->offset; + + return TDM_ERROR_NONE; +} + +EXTERN tdm_error tdm_vblank_set_enable_fake(tdm_vblank *vblank, unsigned int enable_fake) { tdm_private_vblank *private_vblank = vblank; @@ -481,14 +543,17 @@ tdm_vblank_set_enable_fake(tdm_vblank *vblank, unsigned int enable_fake) return TDM_ERROR_NONE; } -EXTERN unsigned int -tdm_vblank_get_enable_fake(tdm_vblank *vblank) +EXTERN tdm_error +tdm_vblank_get_enable_fake(tdm_vblank *vblank, unsigned int *enable_fake) { tdm_private_vblank *private_vblank = vblank; - TDM_RETURN_VAL_IF_FAIL(private_vblank != NULL, 0); + TDM_RETURN_VAL_IF_FAIL(private_vblank != NULL, TDM_ERROR_INVALID_PARAMETER); + TDM_RETURN_VAL_IF_FAIL(enable_fake != NULL, TDM_ERROR_INVALID_PARAMETER); + + *enable_fake = private_vblank->enable_fake; - return private_vblank->enable_fake; + return TDM_ERROR_NONE; } static tdm_error diff --git a/tools/tdm_test_client.c b/tools/tdm_test_client.c index fb371f5..1ec8f93 100644 --- a/tools/tdm_test_client.c +++ b/tools/tdm_test_client.c @@ -45,12 +45,14 @@ #include "tdm_macro.h" typedef struct _tdm_test_client_arg { - char output_name[512]; + char *output_name; int fps; int sync; int interval; int offset; int enable_fake; + int pid; + char *vblank_name; } tdm_test_client_arg; typedef struct _tdm_test_client { @@ -58,6 +60,7 @@ typedef struct _tdm_test_client { int do_query; int do_vblank; + int do_set_fps; int waiting; tdm_client *client; @@ -90,7 +93,8 @@ static struct typestrings typestrs[] = { static struct optstrings optstrs[] = { {OPT_QRY, "qo", "output objects info", "", "primary"}, - {OPT_TST, "v", "vblank test", "[,][@][~][+][*fake]", "primary,0@60~1+0*1"}, + {OPT_TST, "v", "vblank test", "[,][@][~][+][*fake][^vblank_name]", "primary,0@60~1+0*1^test"}, + {OPT_TST, "f", "fps setting test", "[,]@", "@60"}, }; static void @@ -126,7 +130,9 @@ usage(char *app_name) static void parse_arg_qo(tdm_test_client *data, char *arg) { - strtostr(data->args.output_name, 512, arg, TDM_DELIM); + char name[TDM_NAME_LEN]; + strtostr(name, TDM_NAME_LEN, arg, TDM_DELIM); + data->args.output_name = strndup(name, TDM_NAME_LEN); } //"[,][@][~][+][*fake]" @@ -134,8 +140,10 @@ static void parse_arg_v(tdm_test_client *data, char *arg) { char *end = arg; + char name[TDM_NAME_LEN]; - end = strtostr(data->args.output_name, 512, arg, TDM_DELIM); + end = strtostr(name, TDM_NAME_LEN, arg, TDM_DELIM); + data->args.output_name = strndup(name, TDM_NAME_LEN); if (*end == ',') { arg = end + 1; @@ -161,6 +169,37 @@ parse_arg_v(tdm_test_client *data, char *arg) arg = end + 1; data->args.enable_fake = strtol(arg, &end, 10); } + + if (*end == '^') { + char name[TDM_NAME_LEN]; + arg = end + 1; + end = strtostr(name, TDM_NAME_LEN, arg, TDM_DELIM); + data->args.vblank_name = strndup(name, TDM_NAME_LEN); + } +} + +//"@" +static void +parse_arg_f(tdm_test_client *data, char *arg) +{ + char *end = arg; + + data->args.pid = strtol(arg, &end, 10); + + if (*end == ',') { + char name[TDM_NAME_LEN]; + arg = end + 1; + end = strtostr(name, TDM_NAME_LEN, arg, TDM_DELIM); + data->args.vblank_name = strndup(name, TDM_NAME_LEN); + } + + if (*end != '@') { + printf("failed: no fps value\n"); + exit(0); + } + + arg = end + 1; + data->args.fps = strtol(arg, &end, 10); } static void @@ -183,6 +222,9 @@ parse_args(tdm_test_client *data, int argc, char *argv[]) } else if (!strncmp(argv[i] + 1, "v", 1)) { data->do_vblank = 1; parse_arg_v(data, argv[++i]); + } else if (!strncmp(argv[i] + 1, "f", 1)) { + data->do_set_fps = 1; + parse_arg_f(data, argv[++i]); } else { usage(argv[0]); exit(0); @@ -293,6 +335,7 @@ do_vblank(tdm_test_client *data) return; } + tdm_client_vblank_set_name(vblank, data->args.vblank_name); tdm_client_vblank_set_enable_fake(vblank, data->args.enable_fake); tdm_client_vblank_set_sync(vblank, data->args.sync); if (data->args.fps > 0) @@ -350,6 +393,18 @@ done: tdm_client_vblank_destroy(vblank); } +static void +do_set_fps(tdm_test_client *data) +{ + tdm_error error; + + error = tdm_client_set_client_vblank_fps(data->client, data->args.pid, data->args.vblank_name, data->args.fps); + if (error != TDM_ERROR_NONE) { + printf("tdm_client_set_client_vblank_fps failed\n"); + return; + } +} + static tdm_test_client ttc_data; int @@ -371,9 +426,9 @@ main(int argc, char *argv[]) parse_args(data, argc, argv); - printf("sync(%d) fps(%d) interval(%d) offset(%d) enable_fake(%d)\n", + printf("sync(%d) fps(%d) interval(%d) offset(%d) enable_fake(%d) pid(%d)\n", data->args.sync, data->args.fps, data->args.interval, - data->args.offset, data->args.enable_fake); + data->args.offset, data->args.enable_fake, data->args.pid); data->client = tdm_client_create(&error); if (error != TDM_ERROR_NONE) { @@ -385,8 +440,14 @@ main(int argc, char *argv[]) do_query(data); if (data->do_vblank) do_vblank(data); + if (data->do_set_fps) + do_set_fps(data); done: + if (data->args.output_name) + free(data->args.output_name); + if (data->args.vblank_name) + free(data->args.vblank_name); if (data->client) tdm_client_destroy(data->client);