[PATCH weston 03/12] libweston: Use struct timespec for animations

Alexandros Frantzis alexandros.frantzis at collabora.com
Thu Nov 16 16:20:52 UTC 2017


Change code related to animations to use struct timespec to represent
time.

This commit is part of a larger effort to transition the Weston codebase
to struct timespec.

Signed-off-by: Alexandros Frantzis <alexandros.frantzis at collabora.com>
---
 desktop-shell/shell.c   | 26 ++++++++++++++------------
 desktop-shell/shell.h   |  2 +-
 libweston/animation.c   | 29 ++++++++++++++++++-----------
 libweston/compositor.c  |  5 ++++-
 libweston/compositor.h  |  7 ++++---
 libweston/spring-tool.c | 13 ++++++++-----
 libweston/zoom.c        |  7 ++++---
 7 files changed, 53 insertions(+), 36 deletions(-)

diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c
index 1f99efe3..55380417 100644
--- a/desktop-shell/shell.c
+++ b/desktop-shell/shell.c
@@ -41,6 +41,7 @@
 #include "weston-desktop-shell-server-protocol.h"
 #include "shared/config-parser.h"
 #include "shared/helpers.h"
+#include "shared/timespec-util.h"
 #include "libweston-desktop/libweston-desktop.h"
 
 #define DEFAULT_NUM_WORKSPACES 1
@@ -1027,7 +1028,7 @@ reverse_workspace_change_animation(struct desktop_shell *shell,
 	shell->workspaces.anim_to = to;
 	shell->workspaces.anim_from = from;
 	shell->workspaces.anim_dir = -1 * shell->workspaces.anim_dir;
-	shell->workspaces.anim_timestamp = 0;
+	shell->workspaces.anim_timestamp = (struct timespec) { 0 };
 
 	weston_layer_set_position(&to->layer, WESTON_LAYER_POSITION_NORMAL);
 	weston_layer_set_position(&from->layer, WESTON_LAYER_POSITION_NORMAL - 1);
@@ -1084,14 +1085,15 @@ finish_workspace_change_animation(struct desktop_shell *shell,
 
 static void
 animate_workspace_change_frame(struct weston_animation *animation,
-			       struct weston_output *output, uint32_t msecs)
+			       struct weston_output *output,
+			       const struct timespec *time)
 {
 	struct desktop_shell *shell =
 		container_of(animation, struct desktop_shell,
 			     workspaces.animation);
 	struct workspace *from = shell->workspaces.anim_from;
 	struct workspace *to = shell->workspaces.anim_to;
-	uint32_t t;
+	int64_t t;
 	double x, y;
 
 	if (workspace_is_empty(from) && workspace_is_empty(to)) {
@@ -1099,19 +1101,19 @@ animate_workspace_change_frame(struct weston_animation *animation,
 		return;
 	}
 
-	if (shell->workspaces.anim_timestamp == 0) {
+	if (timespec_is_zero(&shell->workspaces.anim_timestamp)) {
 		if (shell->workspaces.anim_current == 0.0)
-			shell->workspaces.anim_timestamp = msecs;
+			shell->workspaces.anim_timestamp = *time;
 		else
-			shell->workspaces.anim_timestamp =
-				msecs -
+			timespec_add_msec(&shell->workspaces.anim_timestamp,
+				time,
 				/* Invers of movement function 'y' below. */
-				(asin(1.0 - shell->workspaces.anim_current) *
-				 DEFAULT_WORKSPACE_CHANGE_ANIMATION_LENGTH *
-				 M_2_PI);
+				-(asin(1.0 - shell->workspaces.anim_current) *
+				  DEFAULT_WORKSPACE_CHANGE_ANIMATION_LENGTH *
+				  M_2_PI));
 	}
 
-	t = msecs - shell->workspaces.anim_timestamp;
+	t = timespec_sub_to_msec(time, &shell->workspaces.anim_timestamp);
 
 	/*
 	 * x = [0, π/2]
@@ -1154,7 +1156,7 @@ animate_workspace_change(struct desktop_shell *shell,
 	shell->workspaces.anim_from = from;
 	shell->workspaces.anim_to = to;
 	shell->workspaces.anim_current = 0.0;
-	shell->workspaces.anim_timestamp = 0;
+	shell->workspaces.anim_timestamp = (struct timespec) { 0 };
 
 	output = container_of(shell->compositor->output_list.next,
 			      struct weston_output, link);
diff --git a/desktop-shell/shell.h b/desktop-shell/shell.h
index 063641d2..0ff737bb 100644
--- a/desktop-shell/shell.h
+++ b/desktop-shell/shell.h
@@ -188,7 +188,7 @@ struct desktop_shell {
 		struct weston_animation animation;
 		struct wl_list anim_sticky_list;
 		int anim_dir;
-		uint32_t anim_timestamp;
+		struct timespec anim_timestamp;
 		double anim_current;
 		struct workspace *anim_from;
 		struct workspace *anim_to;
diff --git a/libweston/animation.c b/libweston/animation.c
index 914135a2..c2f8b9ba 100644
--- a/libweston/animation.c
+++ b/libweston/animation.c
@@ -30,12 +30,14 @@
 #include <stdint.h>
 #include <stdio.h>
 #include <math.h>
+#include <inttypes.h>
 
 #include <unistd.h>
 #include <fcntl.h>
 
 #include "compositor.h"
 #include "shared/helpers.h"
+#include "shared/timespec-util.h"
 
 WL_EXPORT void
 weston_spring_init(struct weston_spring *spring,
@@ -52,7 +54,7 @@ weston_spring_init(struct weston_spring *spring,
 }
 
 WL_EXPORT void
-weston_spring_update(struct weston_spring *spring, uint32_t msec)
+weston_spring_update(struct weston_spring *spring, const struct timespec *time)
 {
 	double force, v, current, step;
 
@@ -61,14 +63,16 @@ weston_spring_update(struct weston_spring *spring, uint32_t msec)
 	 * This handles the case where time moves backwards or forwards in
 	 * large jumps.
 	 */
-	if (msec - spring->timestamp > 1000) {
-		weston_log("unexpectedly large timestamp jump (from %u to %u)\n",
-			   spring->timestamp, msec);
-		spring->timestamp = msec - 1000;
+	if (timespec_sub_to_msec(time, &spring->timestamp) > 1000) {
+		weston_log("unexpectedly large timestamp jump "
+			   "(from %" PRId64 " to %" PRId64 ")\n",
+			   timespec_to_msec(&spring->timestamp),
+			   timespec_to_msec(time));
+		timespec_add_msec(&spring->timestamp, time, -1000);
 	}
 
 	step = 0.01;
-	while (4 < msec - spring->timestamp) {
+	while (4 < timespec_sub_to_msec(time, &spring->timestamp)) {
 		current = spring->current;
 		v = current - spring->previous;
 		force = spring->k * (spring->target - current) / 10.0 +
@@ -108,7 +112,7 @@ weston_spring_update(struct weston_spring *spring, uint32_t msec)
 			break;
 		}
 
-		spring->timestamp += 4;
+		timespec_add_msec(&spring->timestamp, &spring->timestamp, 4);
 	}
 }
 
@@ -161,7 +165,8 @@ handle_animation_view_destroy(struct wl_listener *listener, void *data)
 
 static void
 weston_view_animation_frame(struct weston_animation *base,
-			    struct weston_output *output, uint32_t msecs)
+			    struct weston_output *output,
+			    const struct timespec *time)
 {
 	struct weston_view_animation *animation =
 		container_of(base,
@@ -170,9 +175,9 @@ weston_view_animation_frame(struct weston_animation *base,
 		animation->view->surface->compositor;
 
 	if (base->frame_counter <= 1)
-		animation->spring.timestamp = msecs;
+		animation->spring.timestamp = *time;
 
-	weston_spring_update(&animation->spring, msecs);
+	weston_spring_update(&animation->spring, time);
 
 	if (weston_spring_done(&animation->spring)) {
 		weston_view_schedule_repaint(animation->view);
@@ -254,8 +259,10 @@ weston_view_animation_create(struct weston_view *view,
 static void
 weston_view_animation_run(struct weston_view_animation *animation)
 {
+	struct timespec zero_time = { 0 };
+
 	animation->animation.frame_counter = 0;
-	weston_view_animation_frame(&animation->animation, NULL, 0);
+	weston_view_animation_frame(&animation->animation, NULL, &zero_time);
 }
 
 static void
diff --git a/libweston/compositor.c b/libweston/compositor.c
index 71a9b38c..037b4b5f 100644
--- a/libweston/compositor.c
+++ b/libweston/compositor.c
@@ -2292,12 +2292,15 @@ weston_output_repaint(struct weston_output *output, void *repaint_data)
 	struct wl_list frame_callback_list;
 	pixman_region32_t output_damage;
 	int r;
+	struct timespec frame_time;
 
 	if (output->destroying)
 		return 0;
 
 	TL_POINT("core_repaint_begin", TLP_OUTPUT(output), TLP_END);
 
+	timespec_from_msec(&frame_time, output->frame_time);
+
 	/* Rebuild the surface list and update surface transforms up front. */
 	weston_compositor_build_view_list(ec);
 
@@ -2352,7 +2355,7 @@ weston_output_repaint(struct weston_output *output, void *repaint_data)
 
 	wl_list_for_each_safe(animation, next, &output->animation_list, link) {
 		animation->frame_counter++;
-		animation->frame(animation, output, output->frame_time);
+		animation->frame(animation, output, &frame_time);
 	}
 
 	TL_POINT("core_repaint_posted", TLP_OUTPUT(output), TLP_END);
diff --git a/libweston/compositor.h b/libweston/compositor.h
index 8b2d2b06..23d709ce 100644
--- a/libweston/compositor.h
+++ b/libweston/compositor.h
@@ -101,7 +101,8 @@ struct weston_mode {
 
 struct weston_animation {
 	void (*frame)(struct weston_animation *animation,
-		      struct weston_output *output, uint32_t msecs);
+		      struct weston_output *output,
+		      const struct timespec *time);
 	int frame_counter;
 	struct wl_list link;
 };
@@ -119,7 +120,7 @@ struct weston_spring {
 	double target;
 	double previous;
 	double min, max;
-	uint32_t timestamp;
+	struct timespec timestamp;
 	uint32_t clip;
 };
 
@@ -1352,7 +1353,7 @@ void
 weston_spring_init(struct weston_spring *spring,
 		   double k, double current, double target);
 void
-weston_spring_update(struct weston_spring *spring, uint32_t msec);
+weston_spring_update(struct weston_spring *spring, const struct timespec *time);
 int
 weston_spring_done(struct weston_spring *spring);
 
diff --git a/libweston/spring-tool.c b/libweston/spring-tool.c
index 9e7c344e..a6ce055d 100644
--- a/libweston/spring-tool.c
+++ b/libweston/spring-tool.c
@@ -24,10 +24,12 @@
  */
 
 #include <stdint.h>
+#include <inttypes.h>
 
 #include "config.h"
 
 #include "compositor.h"
+#include "shared/timespec-util.h"
 
 WL_EXPORT void
 weston_view_geometry_dirty(struct weston_view *view)
@@ -59,17 +61,18 @@ main(int argc, char *argv[])
 	const double friction = 1400;
 
 	struct weston_spring spring;
-	uint32_t time = 0;
+	struct timespec time = { 0 };
 
 	weston_spring_init(&spring, k, current, target);
 	spring.friction = friction;
 	spring.previous = 0.48;
-	spring.timestamp = 0;
+	spring.timestamp = (struct timespec) { 0 };
 
 	while (!weston_spring_done(&spring)) {
-		printf("\t%d\t%f\n", time, spring.current);
-		weston_spring_update(&spring, time);
-		time += 16;
+		printf("\t%" PRId64 "\t%f\n",
+		       timespec_to_msec(&time), spring.current);
+		weston_spring_update(&spring, &time);
+		timespec_add_msec(&time, &time, 16);
 	}
 
 	return 0;
diff --git a/libweston/zoom.c b/libweston/zoom.c
index a1a1ab21..84f1a320 100644
--- a/libweston/zoom.c
+++ b/libweston/zoom.c
@@ -36,12 +36,13 @@
 
 static void
 weston_zoom_frame_z(struct weston_animation *animation,
-		struct weston_output *output, uint32_t msecs)
+		    struct weston_output *output,
+		    const struct timespec *time)
 {
 	if (animation->frame_counter <= 1)
-		output->zoom.spring_z.timestamp = msecs;
+		output->zoom.spring_z.timestamp = *time;
 
-	weston_spring_update(&output->zoom.spring_z, msecs);
+	weston_spring_update(&output->zoom.spring_z, time);
 
 	if (output->zoom.spring_z.current > output->zoom.max_level)
 		output->zoom.spring_z.current = output->zoom.max_level;
-- 
2.14.1



More information about the wayland-devel mailing list