* Taeheon Kim <th908.kim@samsung.com>,
* YoungJun Cho <yj44.cho@samsung.com>,
* SooChan Lim <sc1.lim@samsung.com>,
- * Boram Park <sc1.lim@samsung.com>
+ * Boram Park <boram1288.park@samsung.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
#include <time.h>
#include <stdint.h>
-#include <tdm_client.h>
+#include "tdm_client.h"
#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 {
struct typestrings {
int type;
- char string[512];
+ const char *string;
};
struct optstrings {
int type;
- char opt[512];
- char desc[512];
- char arg[512];
- char ex[512];
+ const char *opt;
+ const char *desc;
+ const char *arg;
+ const char *ex;
};
enum {
static struct optstrings optstrs[] = {
{OPT_QRY, "qo", "output objects info", "<output_name>", "primary"},
- {OPT_TST, "v", "vblank test", "<output_name>[,<sync>][@<fps>][#<interval>][+<offset>][*fake]", "primary,0@60#1+0*1"},
+ {OPT_TST, "v", "vblank test", "<output_name>[,<sync>][@<fps>][~<interval>][+<offset>][*fake][^vblank_name]", "primary,0@60~1+0*1^test"},
};
-#define DELIM "!@#^&*+-|,"
-
-static 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;
-}
-
static void
usage(char *app_name)
{
if (f == 1)
printf(" %s options:\n\n", typestrs[t].string);
printf("\t-%s\t%s\n", optstrs[o].opt, optstrs[o].desc);
- printf("\t\t%s\n", optstrs[o].arg);
- printf("\t\tex) %s\n", optstrs[o].ex);
+ if (optstrs[o].arg)
+ printf("\t\t %s\n", optstrs[o].arg);
+ if (optstrs[o].ex)
+ printf("\t\t ex) %s\n", optstrs[o].ex);
f = 0;
}
+ printf("\n");
}
exit(0);
//"<output_name>"
static void
-parse_arg_qo(tdm_test_client *data, char *p)
+parse_arg_qo(tdm_test_client *data, char *arg)
{
- strtostr(data->args.output_name, 512, p, DELIM);
+ char name[TDM_NAME_LEN];
+ strtostr(name, TDM_NAME_LEN, arg, TDM_DELIM);
+ data->args.output_name = strndup(name, TDM_NAME_LEN);
}
-//"<output_name>[,<sync>][@<fps>][#<interval>][+<offset>][*fake]"
+//"<output_name>[,<sync>][@<fps>][~<interval>][+<offset>][*fake]"
static void
-parse_arg_v(tdm_test_client *data, char *p)
+parse_arg_v(tdm_test_client *data, char *arg)
{
- char *end = p;
+ char *end = arg;
+ char name[TDM_NAME_LEN];
- end = strtostr(data->args.output_name, 512, p, DELIM);
+ end = strtostr(name, TDM_NAME_LEN, arg, TDM_DELIM);
+ data->args.output_name = strndup(name, TDM_NAME_LEN);
if (*end == ',') {
- p = end + 1;
- data->args.sync = strtol(p, &end, 10);
+ arg = end + 1;
+ data->args.sync = strtol(arg, &end, 10);
}
if (*end == '@') {
- p = end + 1;
- data->args.fps = strtol(p, &end, 10);
+ arg = end + 1;
+ data->args.fps = strtol(arg, &end, 10);
}
- if (*end == '#') {
- p = end + 1;
- data->args.interval = strtol(p, &end, 10);
+ if (*end == '~') {
+ arg = end + 1;
+ data->args.interval = strtol(arg, &end, 10);
}
if (*end == '+' || *end == '-') {
- p = end;
- data->args.offset = strtol(p, &end, 10);
+ arg = end;
+ data->args.offset = strtol(arg, &end, 10);
}
if (*end == '*') {
- p = end + 1;
- data->args.enable_fake= strtol(p, &end, 10);
+ 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_args(tdm_test_client *data, int argc, char *argv[])
{
- int size = sizeof(optstrs) / sizeof(struct optstrings);
- int i, j = 0;
+ int i;
- if (argc < 2) {
+ if (argc < 3) {
usage(argv[0]);
- exit(1);
+ exit(0);
}
memset(data, 0, sizeof *data);
data->args.interval = 1;
for (i = 1; i < argc; i++) {
- for (j = 0; j < size; j++) {
- if (!strncmp(argv[i]+1, "qo", 512)) {
- data->do_query = 1;
- parse_arg_qo(data, argv[++i]);
- break;
- } else if (!strncmp(argv[i]+1, "v", 512)) {
- data->do_vblank = 1;
- parse_arg_v(data, argv[++i]);
- break;
- } else {
- usage(argv[0]);
- exit(1);
- }
+ if (!strncmp(argv[i] + 1, "qo", 2)) {
+ data->do_query = 1;
+ parse_arg_qo(data, argv[++i]);
+ } else if (!strncmp(argv[i] + 1, "v", 1)) {
+ data->do_vblank = 1;
+ parse_arg_v(data, argv[++i]);
+ } else {
+ usage(argv[0]);
+ exit(0);
}
}
}
-static unsigned long
-get_time_in_micros(void)
+static double
+get_time(void)
{
struct timespec tp;
if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0)
- return (unsigned long)(tp.tv_sec * 1000000) + (tp.tv_nsec / 1000L);
+ return (double)tp.tv_sec + ((double)tp.tv_nsec) / 1000000000.0;
return 0;
}
unsigned int tv_sec, unsigned int tv_usec, void *user_data)
{
tdm_test_client *data = user_data;
- unsigned long cur, vbl;
- static unsigned long p_vbl = 0;
+ double cur, vbl;
+ static double p_vbl = 0;
data->waiting = 0;
if (error == TDM_ERROR_DPMS_OFF) {
printf("exit: dpms off\n");
- exit(1);
+ exit(0);
}
if (error != TDM_ERROR_NONE) {
printf("exit: error(%d)\n", error);
- exit(1);
+ exit(0);
}
- cur = get_time_in_micros();
- vbl = (unsigned long)tv_sec * (unsigned long)1000000 + (unsigned long)tv_usec;
+ cur = get_time();
+ vbl = (double)tv_sec + ((double)tv_usec) / 1000000.0;
- printf("vblank : %ld us vbl(%lu)\n", vbl - p_vbl, vbl);
+ printf("vblank : %.6f us vbl(%.6f)\n", vbl - p_vbl, vbl);
- if (cur - vbl > 2000) /* 2ms */
- printf("kernel -> tdm-client: %ld us\n", cur - vbl);
+ if (cur - vbl > 0.002) /* 2ms */
+ printf("kernel -> tdm-client: %.0f us\n", (cur - vbl) * 1000000.0);
p_vbl = vbl;
}
return;
}
- tdm_client_output_get_conn_status(output, &status);
- tdm_client_output_get_dpms(output, &dpms);
- tdm_client_output_get_refresh_rate(output, &refresh);
+ error = tdm_client_output_get_conn_status(output, &status);
+ TDM_WARNING_IF_FAIL(error == TDM_ERROR_NONE);
+ error = tdm_client_output_get_dpms(output, &dpms);
+ TDM_WARNING_IF_FAIL(error == TDM_ERROR_NONE);
+ error = tdm_client_output_get_refresh_rate(output, &refresh);
+ TDM_WARNING_IF_FAIL(error == TDM_ERROR_NONE);
printf("tdm_output \"%s\"\n", data->args.output_name);
printf("\tstatus : %s\n", conn_str[status]);
return;
}
- tdm_client_output_add_change_handler(output, _client_output_handler, NULL);
+ error = tdm_client_output_add_change_handler(output, _client_output_handler, NULL);
+ TDM_WARNING_IF_FAIL(error == TDM_ERROR_NONE);
vblank = tdm_client_output_create_vblank(output, &error);
if (error != TDM_ERROR_NONE) {
return;
}
- 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)
- tdm_client_vblank_set_fps(vblank, data->args.fps);
- tdm_client_vblank_set_offset(vblank, data->args.offset);
+ error = tdm_client_vblank_set_name(vblank, data->args.vblank_name);
+ TDM_WARNING_IF_FAIL(error == TDM_ERROR_NONE);
+ error = tdm_client_vblank_set_enable_fake(vblank, data->args.enable_fake);
+ TDM_WARNING_IF_FAIL(error == TDM_ERROR_NONE);
+ error = tdm_client_vblank_set_sync(vblank, data->args.sync);
+ TDM_WARNING_IF_FAIL(error == TDM_ERROR_NONE);
+ if (data->args.fps > 0) {
+ error = tdm_client_vblank_set_fps(vblank, data->args.fps);
+ TDM_WARNING_IF_FAIL(error == TDM_ERROR_NONE);
+ }
+ error = tdm_client_vblank_set_offset(vblank, data->args.offset);
+ TDM_WARNING_IF_FAIL(error == TDM_ERROR_NONE);
error = tdm_client_get_fd(data->client, &fd);
if (error != TDM_ERROR_NONE || fd < 0) {
tdm_test_client *data = &ttc_data;
tdm_error error;
+#if 1 /* for testing */
+ const char *xdg = (const char*)getenv("XDG_RUNTIME_DIR");
+ if (!xdg) {
+ char buf[32];
+ snprintf(buf, sizeof(buf), "/run");
+ int ret = setenv("XDG_RUNTIME_DIR", (const char*)buf, 1);
+ if (ret != 0)
+ exit(0);
+ }
+#endif
+
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) {
do_vblank(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);