From: Mario Kleiner <[email protected]>

A new optional parameter "-d msecs" allows to specify a
delay before the surface attach/damage/commit to shift
the point in time when a surface update is committed.

This allows to test how different client timings interact
with the compositors repaint timing.

Suggested by Pekka Paalanen.

Signed-off-by: Mario Kleiner <[email protected]>
Acked-by: Pekka Paalanen <[email protected]>

v2: Clarify the intent, doing a delay in window_create_feedback()
    is a bit surprising. Use nanosleep() instead of clock_nanosleep(),
    which may not support the chosen presentation clock.

Signed-off-by: Pekka Paalanen <[email protected]>
---
 clients/presentation-shm.c | 48 +++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 41 insertions(+), 7 deletions(-)

diff --git a/clients/presentation-shm.c b/clients/presentation-shm.c
index cf4517c..120c40c 100644
--- a/clients/presentation-shm.c
+++ b/clients/presentation-shm.c
@@ -101,6 +101,7 @@ struct window {
        int num_buffers;
        int next;
        int refresh_nsec;
+       int commit_delay_msecs;
 
        struct wl_callback *callback;
        struct wl_list feedback_list;
@@ -201,19 +202,21 @@ static const struct wl_shell_surface_listener 
shell_surface_listener = {
 
 static struct window *
 create_window(struct display *display, int width, int height,
-             enum run_mode mode)
+             enum run_mode mode, int commit_delay_msecs)
 {
        struct window *window;
        char title[128];
        int ret;
 
        snprintf(title, sizeof(title),
-                "presentation-shm: %s", run_mode_name[mode]);
+                "presentation-shm: %s [Delay %i msecs]", run_mode_name[mode],
+                commit_delay_msecs);
 
        window = calloc(1, sizeof *window);
        if (!window)
                return NULL;
 
+       window->commit_delay_msecs = commit_delay_msecs;
        window->mode = mode;
        window->callback = NULL;
        wl_list_init(&window->feedback_list);
@@ -469,6 +472,23 @@ static const struct presentation_feedback_listener 
feedback_listener = {
 };
 
 static void
+window_emulate_rendering(struct window *window)
+{
+       struct timespec delay;
+       int ret;
+
+       if (window->commit_delay_msecs <= 0)
+               return;
+
+       delay.tv_sec = window->commit_delay_msecs / 1000;
+       delay.tv_nsec = (window->commit_delay_msecs % 1000) * 1000000;
+
+       ret = nanosleep(&delay, NULL);
+       if (ret)
+               printf("nanosleep failed: %m\n");
+}
+
+static void
 window_create_feedback(struct window *window, uint32_t frame_stamp)
 {
        static unsigned seq;
@@ -490,6 +510,7 @@ window_create_feedback(struct window *window, uint32_t 
frame_stamp)
                                           &feedback_listener, feedback);
 
        feedback->frame_no = seq;
+
        clock_gettime(window->display->clk_id, &feedback->commit);
        feedback->frame_stamp = frame_stamp;
        feedback->target = feedback->commit;
@@ -524,6 +545,8 @@ redraw_mode_feedback(void *data, struct wl_callback 
*callback, uint32_t time)
        if (callback)
                wl_callback_destroy(callback);
 
+       window_emulate_rendering(window);
+
        window->callback = wl_surface_frame(window->surface);
        wl_callback_add_listener(window->callback,
                                 &frame_listener_mode_feedback, window);
@@ -566,6 +589,7 @@ feedkick_presented(void *data,
 
        switch (window->mode) {
        case RUN_MODE_PRESENT:
+               window_emulate_rendering(window);
                window_create_feedback(window, 0);
                window_feedkick(window);
                window_commit_next(window);
@@ -586,6 +610,7 @@ feedkick_discarded(void *data,
 
        switch (window->mode) {
        case RUN_MODE_PRESENT:
+               window_emulate_rendering(window);
                window_create_feedback(window, 0);
                window_feedkick(window);
                window_commit_next(window);
@@ -605,6 +630,8 @@ static const struct presentation_feedback_listener 
feedkick_listener = {
 static void
 firstdraw_mode_burst(struct window *window)
 {
+       window_emulate_rendering(window);
+
        switch (window->mode) {
        case RUN_MODE_PRESENT:
                window_create_feedback(window, 0);
@@ -807,10 +834,12 @@ usage(const char *prog, int exit_code)
 {
        fprintf(stderr, "Usage: %s [mode] [options]\n"
                "where 'mode' is one of\n"
-               "  -f\trun in feedback mode (default)\n"
-               "  -i\trun in feedback-idle mode; sleep 1s between frames\n"
-               "  -p\trun in low-latency presentation mode\n"
-               "and 'options' may include\n",
+               "  -f\t\trun in feedback mode (default)\n"
+               "  -i\t\trun in feedback-idle mode; sleep 1s between frames\n"
+               "  -p\t\trun in low-latency presentation mode\n"
+               "and 'options' may include\n"
+               "  -d msecs\temulate the time used for rendering by a delay \n"
+               "\t\tof the given milliseconds before commit\n\n",
                prog);
 
        fprintf(stderr, "Printed timing statistics, depending on mode:\n"
@@ -835,6 +864,7 @@ main(int argc, char **argv)
        int ret = 0;
        enum run_mode mode = RUN_MODE_FEEDBACK;
        int i;
+       int commit_delay_msecs = 0;
 
        for (i = 1; i < argc; i++) {
                if (strcmp("-f", argv[i]) == 0)
@@ -843,12 +873,16 @@ main(int argc, char **argv)
                        mode = RUN_MODE_FEEDBACK_IDLE;
                else if (strcmp("-p", argv[i]) == 0)
                        mode = RUN_MODE_PRESENT;
+               else if ((strcmp("-d", argv[i]) == 0) && (i + 1 < argc)) {
+                       i++;
+                       commit_delay_msecs = atoi(argv[i]);
+               }
                else
                        usage(argv[0], EXIT_FAILURE);
        }
 
        display = create_display();
-       window = create_window(display, 250, 250, mode);
+       window = create_window(display, 250, 250, mode, commit_delay_msecs);
        if (!window)
                return 1;
 
-- 
2.3.6

_______________________________________________
wayland-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to