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)
{
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.
unsigned int tv_sec, unsigned int tv_usec, void *user_data);
/**
+ * @brief Set the vblank fps for the given PID and name.
+ * @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_vblank_set_client_vblank_fps(unsigned int pid, const char *name, unsigned int fps);
+
+/**
* @brief Create a vblank object
* @param[in] dpy A display object
* @param[in] output A output object
_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);
+ tdm_vblank_get_vblank_list_information(dpy, reply, len);
}
static void
arg = end + 1;
fps = strtol(arg, &end, 10);
- ret = tdm_server_set_client_vblank_fps(target_pid, name, fps);
+ ret = tdm_vblank_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;
#include <sys/types.h>
#include <math.h>
+#include <wayland-server-protocol.h>
#include <tbm_bufmgr.h>
#include <tbm_surface_queue.h>
tdm_vblank_cb_vblank_SW(tdm_vblank *vblank, double vblank_stamp);
tdm_error
tdm_vblank_set_add_front(tdm_vblank *vblank, unsigned int add_front);
+tdm_error
+tdm_vblank_set_resource(tdm_vblank *vblank, struct wl_resource *resource);
+tdm_error
+tdm_vblank_set_client_vblank_fps(unsigned int pid, const char *name, unsigned int fps);
+void
+tdm_vblank_get_vblank_list_information(tdm_display *dpy, char *reply, int *len);
void
tdm_output_call_change_handler_internal(tdm_private_output *private_output,
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);
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;
} 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);
}
LIST_DEL(&vblank_info->link);
- LIST_DEL(&vblank_info->valid_link);
-
free(vblank_info);
}
}
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;
+ tdm_vblank_set_resource(vblank, vblank_resource);
+
wl_resource_set_implementation(vblank_resource, &tdm_vblank_implementation,
vblank_info, destroy_vblank_callback);
_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_error ret = tdm_vblank_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);
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;
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");
-}
-
#include "tdm_list.h"
/* CAUTION:
- * tdm vblank doesn't care about thread things.
+ * Basically tdm vblank doesn't care about thread things.
* However, to use tdm_event_loop_xxx functions, have to use the internal function.
- * So need to lock/unlock the mutex of private_display.
+ * So need to lock/unlock the mutex of private_display. And valid_vblank_list and
+ * valid_wait_list should be protected by valid_list_lock because tdm_vblank can
+ * be used in multi-thread.
*/
/* TDM vblank
double last_time;
unsigned int add_front;
+ struct wl_resource *resource;
/* for HW */
double HW_vblank_gap;
}
}
+EXTERN tdm_error
+tdm_vblank_set_client_vblank_fps(unsigned int pid, const char *name, unsigned int fps)
+{
+ tdm_private_vblank *v;
+
+ TDM_RETURN_VAL_IF_FAIL(pid > 0, TDM_ERROR_INVALID_PARAMETER);
+ TDM_RETURN_VAL_IF_FAIL(fps > 0, TDM_ERROR_INVALID_PARAMETER);
+
+ TDM_INFO("pid: %u, name: %s, fps: %d", pid, name, fps);
+
+ pthread_mutex_lock(&valid_list_lock);
+ LIST_FOR_EACH_ENTRY(v, &valid_vblank_list, valid_link) {
+ struct wl_client *client;
+ pid_t client_pid = 0;
+
+ if (!v->resource)
+ continue;
+
+ client = wl_resource_get_client(v->resource);
+ 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)) {
+ if (strncmp(v->name, name, TDM_NAME_LEN))
+ continue;
+ }
+
+ tdm_vblank_set_fps(v, fps);
+
+ TDM_INFO("(pid:%u) '%s' fps changed: %d", pid, v->name, fps);
+ }
+ pthread_mutex_unlock(&valid_list_lock);
+
+ return TDM_ERROR_NONE;
+}
+
EXTERN tdm_vblank *
tdm_vblank_create(tdm_display *dpy, tdm_output *output, tdm_error *error)
{
return TDM_ERROR_NONE;
}
+INTERN tdm_error
+tdm_vblank_set_resource(tdm_vblank *vblank, struct wl_resource *resource)
+{
+ tdm_private_vblank *private_vblank = vblank;
+
+ TDM_RETURN_VAL_IF_FAIL(private_vblank != NULL, TDM_ERROR_INVALID_PARAMETER);
+ TDM_RETURN_VAL_IF_FAIL(private_vblank->resource == NULL, TDM_ERROR_OPERATION_FAILED);
+
+ private_vblank->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)
+{
+ tdm_private_vblank *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");
+
+ 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];
+ 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);
+ }
+
+ TDM_SNPRINTF(reply, len, "%-12s %u %d %u %s (pid: %u)\n",
+ v->name, v->fps, v->offset, v->enable_fake, proc_name, pid);
+ }
+ pthread_mutex_unlock(&valid_list_lock);
+
+ TDM_SNPRINTF(reply, len, "\n");
+}
+
int do_query;
int do_vblank;
- int do_set_fps;
int waiting;
tdm_client *client;
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][^vblank_name]", "primary,0@60~1+0*1^test"},
- {OPT_TST, "f", "fps setting test", "<pid>[,<vblank_name>]@<fps>", "<pid>@60"},
};
static void
}
}
-//"<pid>@<fps>"
-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
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);
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
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)