[PATCH weston 5/8] compositor: Move fade animation out of core Weston into shell

Ander Conselvan de Oliveira ander.conselvan.de.oliveira at intel.com
Thu Feb 21 08:35:20 PST 2013


Previously, it was impossible to override the fade in/out behavior of
Weston using a different shell, since this was implemented in core
Weston. This also led to complicated interaction between the shell and
the core when displaying lock surfaces and screensavers.

This patch starts to solve this issue by moving the fade animation out
of the core. On compositor.c, besides deleting the fade code, the idle
handler had to be changed to emit the lock signal, since it was called
from the fade_frame() function before. This causes a slight change of
behavior, since before the fade would happen with the compositor being
active, while now it is already in the idle state. That leads to the
dpms state being set when cancelling the fade with mouse movement, and
in turn, to a slight freeze with drm compositor. This problem will be
fixed in a follow up patch.

On the shell side, the fade was re-implemented in a slightly different
manner. Instead of using a custom frame function, the fade animation
from animation.c is used. The interface for starting the fade was also
changed to take the value of an enum instead of a float alpha value,
in order to improve readability.
---
 src/compositor.c |   77 +------------------------------------
 src/compositor.h |    5 ---
 src/shell.c      |  112 +++++++++++++++++++++++++++++++++++++++++++++++++-----
 3 files changed, 105 insertions(+), 89 deletions(-)

diff --git a/src/compositor.c b/src/compositor.c
index 36525de..2d4095b 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -1053,40 +1053,6 @@ weston_output_damage(struct weston_output *output)
 }
 
 static void
-fade_frame(struct weston_animation *animation,
-	   struct weston_output *output, uint32_t msecs)
-{
-	struct weston_compositor *compositor =
-		container_of(animation,
-			     struct weston_compositor, fade.animation);
-	struct weston_surface *surface;
-
-	if (animation->frame_counter <= 1)
-		compositor->fade.spring.timestamp = msecs;
-
-	surface = compositor->fade.surface;
-	weston_spring_update(&compositor->fade.spring, msecs);
-	weston_surface_set_color(surface, 0.0, 0.0, 0.0,
-				 compositor->fade.spring.current);
-	weston_surface_damage(surface);
-
-	if (weston_spring_done(&compositor->fade.spring)) {
-		compositor->fade.spring.current =
-			compositor->fade.spring.target;
-		wl_list_remove(&animation->link);
-		wl_list_init(&animation->link);
-
-		if (compositor->fade.spring.current < 0.001) {
-			destroy_surface(&surface->surface.resource);
-			compositor->fade.surface = NULL;
-		} else if (compositor->fade.spring.current > 0.999) {
-			compositor->state = WESTON_COMPOSITOR_SLEEPING;
-			wl_signal_emit(&compositor->lock_signal, compositor);
-		}
-	}
-}
-
-static void
 surface_accumulate_damage(struct weston_surface *surface,
 			  pixman_region32_t *opaque)
 {
@@ -1288,41 +1254,6 @@ weston_compositor_schedule_repaint(struct weston_compositor *compositor)
 		weston_output_schedule_repaint(output);
 }
 
-WL_EXPORT void
-weston_compositor_fade(struct weston_compositor *compositor, float tint)
-{
-	struct weston_output *output;
-	struct weston_surface *surface;
-
-	output = container_of(compositor->output_list.next,
-                             struct weston_output, link);
-
-	compositor->fade.spring.target = tint;
-	if (weston_spring_done(&compositor->fade.spring))
-		return;
-
-	if (compositor->fade.surface == NULL) {
-		surface = weston_surface_create(compositor);
-		if (!surface)
-			return;
-
-		weston_surface_configure(surface, 0, 0, 8192, 8192);
-		weston_surface_set_color(surface, 0.0, 0.0, 0.0, 1.0 - tint);
-		wl_list_insert(&compositor->fade_layer.surface_list,
-			       &surface->layer_link);
-		weston_surface_update_transform(surface);
-		compositor->fade.surface = surface;
-		pixman_region32_init(&surface->input);
-	}
-
-	weston_surface_damage(compositor->fade.surface);
-	if (wl_list_empty(&compositor->fade.animation.link)) {
-		compositor->fade.animation.frame_counter = 0;
-		wl_list_insert(output->animation_list.prev,
-			       &compositor->fade.animation.link);
-	}
-}
-
 static void
 surface_destroy(struct wl_client *client, struct wl_resource *resource)
 {
@@ -1646,7 +1577,6 @@ WL_EXPORT void
 weston_compositor_wake(struct weston_compositor *compositor)
 {
 	compositor->state = WESTON_COMPOSITOR_ACTIVE;
-	weston_compositor_fade(compositor, 0.0);
 
 	wl_event_source_timer_update(compositor->idle_source,
 				     compositor->idle_time * 1000);
@@ -1695,7 +1625,8 @@ idle_handler(void *data)
 	if (compositor->idle_inhibit)
 		return 1;
 
-	weston_compositor_fade(compositor, 1.0);
+	compositor->state = WESTON_COMPOSITOR_IDLE;
+	wl_signal_emit(&compositor->lock_signal, compositor);
 
 	return 1;
 }
@@ -3094,7 +3025,6 @@ weston_compositor_init(struct weston_compositor *ec,
 	wl_list_init(&ec->button_binding_list);
 	wl_list_init(&ec->axis_binding_list);
 	wl_list_init(&ec->debug_binding_list);
-	wl_list_init(&ec->fade.animation.link);
 
 	weston_plane_init(&ec->primary_plane, 0, 0);
 
@@ -3117,9 +3047,6 @@ weston_compositor_init(struct weston_compositor *ec,
 
 	ec->input_loop = wl_event_loop_create();
 
-	weston_spring_init(&ec->fade.spring, 30.0, 1.0, 1.0);
-	ec->fade.animation.frame = fade_frame;
-
 	weston_layer_init(&ec->fade_layer, &ec->layer_list);
 	weston_layer_init(&ec->cursor_layer, &ec->fade_layer.link);
 
diff --git a/src/compositor.h b/src/compositor.h
index 7cd6a6b..ef3d2cd 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -318,11 +318,6 @@ struct weston_compositor {
 	struct wl_list button_binding_list;
 	struct wl_list axis_binding_list;
 	struct wl_list debug_binding_list;
-	struct {
-		struct weston_spring spring;
-		struct weston_animation animation;
-		struct weston_surface *surface;
-	} fade;
 
 	uint32_t state;
 	struct wl_event_source *idle_source;
diff --git a/src/shell.c b/src/shell.c
index da17cfb..0a5c4f0 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -49,6 +49,11 @@ enum animation_type {
 	ANIMATION_FADE
 };
 
+enum fade_type {
+	FADE_IN,
+	FADE_OUT
+};
+
 struct focus_state {
 	struct weston_seat *seat;
 	struct workspace *ws;
@@ -137,6 +142,12 @@ struct desktop_shell {
 		struct wl_list surfaces;
 	} input_panel;
 
+	struct {
+		struct weston_surface *surface;
+		struct weston_surface_animation *animation;
+		enum fade_type type;
+	} fade;
+
 	uint32_t binding_modifier;
 	enum animation_type win_animation_type;
 };
@@ -2754,10 +2765,8 @@ click_to_activate_binding(struct wl_seat *seat, uint32_t time, uint32_t button,
 }
 
 static void
-lock(struct wl_listener *listener, void *data)
+lock(struct desktop_shell *shell)
 {
-	struct desktop_shell *shell =
-		container_of(listener, struct desktop_shell, lock_listener);
 	struct weston_output *output;
 	struct workspace *ws = get_current_workspace(shell);
 
@@ -2791,11 +2800,8 @@ lock(struct wl_listener *listener, void *data)
 }
 
 static void
-unlock(struct wl_listener *listener, void *data)
+unlock(struct desktop_shell *shell)
 {
-	struct desktop_shell *shell =
-		container_of(listener, struct desktop_shell, unlock_listener);
-
 	if (!shell->locked || shell->lock_surface) {
 		weston_compositor_wake(shell->compositor);
 		return;
@@ -2815,6 +2821,91 @@ unlock(struct wl_listener *listener, void *data)
 }
 
 static void
+shell_fade_done(struct weston_surface_animation *animation, void *data)
+{
+	struct desktop_shell *shell = data;
+
+	shell->fade.animation = NULL;
+
+	switch (shell->fade.type) {
+	case FADE_IN:
+		weston_surface_destroy(shell->fade.surface);
+		shell->fade.surface = NULL;
+		break;
+	case FADE_OUT:
+		shell->compositor->state = WESTON_COMPOSITOR_SLEEPING;
+		lock(shell);
+		break;
+	}
+}
+
+static void
+shell_fade(struct desktop_shell *shell, enum fade_type type)
+{
+	struct weston_compositor *compositor = shell->compositor;
+	struct weston_surface *surface;
+	float tint;
+
+	switch (type) {
+	case FADE_IN:
+		tint = 0.0;
+		break;
+	case FADE_OUT:
+		tint = 1.0;
+		break;
+	default:
+		weston_log("shell: invalid fade type\n");
+		return;
+	}
+
+	shell->fade.type = type;
+
+	if (shell->fade.surface == NULL) {
+		surface = weston_surface_create(compositor);
+		if (!surface)
+			return;
+
+		weston_surface_configure(surface, 0, 0, 8192, 8192);
+		weston_surface_set_color(surface, 0.0, 0.0, 0.0, 1.0);
+		surface->alpha = 1.0 - tint;
+		wl_list_insert(&compositor->fade_layer.surface_list,
+			       &surface->layer_link);
+		weston_surface_update_transform(surface);
+		shell->fade.surface = surface;
+		pixman_region32_init(&surface->input);
+	}
+
+	if (shell->fade.animation)
+		weston_fade_update(shell->fade.animation,
+				   shell->fade.surface->alpha, tint, 30.0);
+	else
+		shell->fade.animation =
+			weston_fade_run(shell->fade.surface,
+					1.0 - tint, tint, 30.0,
+					shell_fade_done, shell);
+}
+
+static void
+lock_handler(struct wl_listener *listener, void *data)
+{
+	struct desktop_shell *shell =
+		container_of(listener, struct desktop_shell, lock_listener);
+
+	shell_fade(shell, FADE_OUT);
+	/* lock() is called from shell_fade_done() */
+}
+
+static void
+unlock_handler(struct wl_listener *listener, void *data)
+{
+	struct desktop_shell *shell =
+		container_of(listener, struct desktop_shell, unlock_listener);
+
+	shell_fade(shell, FADE_IN);
+	unlock(shell);
+}
+
+static void
 show_input_panels(struct wl_listener *listener, void *data)
 {
 	struct desktop_shell *shell =
@@ -3216,6 +3307,7 @@ screensaver_configure(struct weston_surface *surface, int32_t sx, int32_t sy)
 			       &surface->layer_link);
 		weston_surface_update_transform(surface);
 		shell->compositor->idle_time = shell->screensaver.duration;
+		shell_fade(shell, FADE_IN);
 		weston_compositor_wake(shell->compositor);
 		shell->compositor->state = WESTON_COMPOSITOR_IDLE;
 	}
@@ -3972,9 +4064,9 @@ module_init(struct weston_compositor *ec,
 
 	shell->destroy_listener.notify = shell_destroy;
 	wl_signal_add(&ec->destroy_signal, &shell->destroy_listener);
-	shell->lock_listener.notify = lock;
+	shell->lock_listener.notify = lock_handler;
 	wl_signal_add(&ec->lock_signal, &shell->lock_listener);
-	shell->unlock_listener.notify = unlock;
+	shell->unlock_listener.notify = unlock_handler;
 	wl_signal_add(&ec->unlock_signal, &shell->unlock_listener);
 	shell->show_input_panel_listener.notify = show_input_panels;
 	wl_signal_add(&ec->show_input_panel_signal, &shell->show_input_panel_listener);
@@ -4048,5 +4140,7 @@ module_init(struct weston_compositor *ec,
 
 	shell_add_bindings(ec, shell);
 
+	shell_fade(shell, FADE_IN);
+
 	return 0;
 }
-- 
1.7.10.4



More information about the wayland-devel mailing list