From 19d10ef925494dac7da1806c03d6f59584bc0517 Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Thu, 21 Feb 2013 18:35:20 +0200 Subject: [PATCH] compositor: Move fade animation out of core Weston into shell 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 9872bfef..dab9db73 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -1052,40 +1052,6 @@ weston_output_damage(struct weston_output *output) weston_output_schedule_repaint(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 7cd6a6b6..ef3d2cdf 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 da17cfbd..0a5c4f0f 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; @@ -2814,6 +2820,91 @@ unlock(struct wl_listener *listener, void *data) shell->prepare_event_sent = true; } +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) { @@ -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; }