[PATCH 09/10] presentation-shm: Allow setting of delay before surface.commit

Pekka Paalanen ppaalanen at gmail.com
Fri Jul 3 03:03:45 PDT 2015


On Sun, 21 Jun 2015 21:25:16 +0200
Mario Kleiner <mario.kleiner.de at gmail.com> wrote:

> 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 <mario.kleiner.de at gmail.com>
> ---
>  clients/presentation-shm.c | 24 ++++++++++++++++++++----
>  1 file changed, 20 insertions(+), 4 deletions(-)
> 
> diff --git a/clients/presentation-shm.c b/clients/presentation-shm.c
> index cf4517c..cafea40 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);
> @@ -490,6 +493,13 @@ window_create_feedback(struct window *window, uint32_t frame_stamp)
>  					   &feedback_listener, feedback);
>  
>  	feedback->frame_no = seq;
> +
> +	/* Delay by given msecs to test effects of compositor scheduling */
> +	if (window->commit_delay_msecs > 0) {
> +		struct timespec delay = { 0, window->commit_delay_msecs * 1e6 };
> +		clock_nanosleep(window->display->clk_id, 0, &delay, NULL);
> +	}
> +
>  	clock_gettime(window->display->clk_id, &feedback->commit);
>  	feedback->frame_stamp = frame_stamp;
>  	feedback->target = feedback->commit;
> @@ -810,7 +820,8 @@ usage(const char *prog, int exit_code)
>  		"  -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",
> +		"and 'options' may include\n"
> +		"  -d msecs\tdelay by given milliseconds before commit\n\n",
>  		prog);
>  
>  	fprintf(stderr, "Printed timing statistics, depending on mode:\n"
> @@ -835,6 +846,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 +855,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;
>  

Hi Mario,

yeah, this patch does what I meant, though I'd like to include the
following minor improvements:


From 389b6d3c1c31700c8bef0a0328444f7b5bd4c1a1 Mon Sep 17 00:00:00 2001
From: Pekka Paalanen <pekka.paalanen at collabora.co.uk>
Date: Fri, 3 Jul 2015 12:40:55 +0300
Subject: [PATCH weston 1/2] presentation-shm: make rendering emulation more
 obvious

This patch make no essential changes, the delay still happens in the
same places in the same cases.

This is more explicit on what the intent is. Doing a delay in the middle
of window_create_feedback() is a bit surprising.

In addition, check that the nanosleep actually works, and complain if it
refuses.

Signed-off-by: Pekka Paalanen <pekka.paalanen at collabora.co.uk>
---
 clients/presentation-shm.c | 38 ++++++++++++++++++++++++++++----------
 1 file changed, 28 insertions(+), 10 deletions(-)

diff --git a/clients/presentation-shm.c b/clients/presentation-shm.c
index cafea40..87794ca 100644
--- a/clients/presentation-shm.c
+++ b/clients/presentation-shm.c
@@ -472,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 = clock_nanosleep(window->display->clk_id, 0, &delay, NULL);
+	if (ret)
+		printf("nanosleep failed: %s (%d)\n", strerror(ret), ret);
+}
+
+static void
 window_create_feedback(struct window *window, uint32_t frame_stamp)
 {
 	static unsigned seq;
@@ -494,12 +511,6 @@ window_create_feedback(struct window *window, uint32_t frame_stamp)
 
 	feedback->frame_no = seq;
 
-	/* Delay by given msecs to test effects of compositor scheduling */
-	if (window->commit_delay_msecs > 0) {
-		struct timespec delay = { 0, window->commit_delay_msecs * 1e6 };
-		clock_nanosleep(window->display->clk_id, 0, &delay, NULL);
-	}
-
 	clock_gettime(window->display->clk_id, &feedback->commit);
 	feedback->frame_stamp = frame_stamp;
 	feedback->target = feedback->commit;
@@ -534,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);
@@ -576,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);
@@ -596,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);
@@ -615,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);
@@ -817,11 +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"
+		"  -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\tdelay by given milliseconds before commit\n\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"
-- 
2.3.6


From 194314e681e73e01d5fa6f4c169cb4a2e34b4047 Mon Sep 17 00:00:00 2001
From: Pekka Paalanen <pekka.paalanen at collabora.co.uk>
Date: Fri, 3 Jul 2015 12:53:01 +0300
Subject: [PATCH weston 2/2] presentation-shm: use nanosleep instead of
 clock_nanosleep

Using clock_nanosleep() with the compositor's presentation clock runs
the risk of not working. For instance, if the compositor chooses
CLOCK_MONOTONIC_RAW (Weston on x11-backend), clock_nanosleep will fail
with EOPNOTSUPP.

I does not matter too much which clock we use as long as it's
sufficiently accurate, so just use nanosleep.

Signed-off-by: Pekka Paalanen <pekka.paalanen at collabora.co.uk>
---
 clients/presentation-shm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clients/presentation-shm.c b/clients/presentation-shm.c
index 87794ca..120c40c 100644
--- a/clients/presentation-shm.c
+++ b/clients/presentation-shm.c
@@ -483,9 +483,9 @@ window_emulate_rendering(struct window *window)
 	delay.tv_sec = window->commit_delay_msecs / 1000;
 	delay.tv_nsec = (window->commit_delay_msecs % 1000) * 1000000;
 
-	ret = clock_nanosleep(window->display->clk_id, 0, &delay, NULL);
+	ret = nanosleep(&delay, NULL);
 	if (ret)
-		printf("nanosleep failed: %s (%d)\n", strerror(ret), ret);
+		printf("nanosleep failed: %m\n");
 }
 
 static void
-- 
2.3.6


Does this look fine to you?
Do you want these three patches pushed as is or squashed?


Thanks,
pq


More information about the wayland-devel mailing list