diff --git a/src/wayland/meta-wayland-cursor-surface.c b/src/wayland/meta-wayland-cursor-surface.c index a24f3a3be..bece48b04 100644 --- a/src/wayland/meta-wayland-cursor-surface.c +++ b/src/wayland/meta-wayland-cursor-surface.c @@ -30,6 +30,7 @@ #include "core/boxes-private.h" #include "wayland/meta-cursor-sprite-wayland.h" #include "wayland/meta-wayland-buffer.h" +#include "wayland/meta-wayland-presentation-time-private.h" #include "wayland/meta-wayland-private.h" #include "wayland/meta-xwayland.h" @@ -340,6 +341,9 @@ on_cursor_painted (MetaCursorRenderer *renderer, MetaWaylandCursorSurfacePrivate *priv = meta_wayland_cursor_surface_get_instance_private (cursor_surface); guint32 time = (guint32) (g_get_monotonic_time () / 1000); + MetaBackend *backend = meta_get_backend (); + MetaWaylandCompositor *compositor = + meta_backend_get_wayland_compositor (backend); if (displayed_sprite != META_CURSOR_SPRITE (priv->cursor_sprite)) return; @@ -352,6 +356,10 @@ on_cursor_painted (MetaCursorRenderer *renderer, wl_callback_send_done (callback->resource, time); wl_resource_destroy (callback->resource); } + + meta_wayland_presentation_time_cursor_painted (&compositor->presentation_time, + stage_view, + cursor_surface); } void diff --git a/src/wayland/meta-wayland-presentation-time-private.h b/src/wayland/meta-wayland-presentation-time-private.h index 0a1298bbf..bc3dc6a40 100644 --- a/src/wayland/meta-wayland-presentation-time-private.h +++ b/src/wayland/meta-wayland-presentation-time-private.h @@ -26,6 +26,7 @@ #include #include "clutter/clutter.h" +#include "wayland/meta-wayland-cursor-surface.h" #include "wayland/meta-wayland-types.h" typedef struct _MetaWaylandPresentationFeedback @@ -59,4 +60,8 @@ void meta_wayland_presentation_feedback_present (MetaWaylandPresentationFeedback struct wl_list * meta_wayland_presentation_time_ensure_feedbacks (MetaWaylandPresentationTime *presentation_time, ClutterStageView *stage_view); +void meta_wayland_presentation_time_cursor_painted (MetaWaylandPresentationTime *presentation_time, + ClutterStageView *stage_view, + MetaWaylandCursorSurface *cursor_surface); + #endif /* META_WAYLAND_PRESENTATION_TIME_PRIVATE_H */ diff --git a/src/wayland/meta-wayland-presentation-time.c b/src/wayland/meta-wayland-presentation-time.c index be1319fd9..29650698c 100644 --- a/src/wayland/meta-wayland-presentation-time.c +++ b/src/wayland/meta-wayland-presentation-time.c @@ -27,6 +27,7 @@ #include #include "compositor/meta-surface-actor-wayland.h" +#include "wayland/meta-wayland-cursor-surface.h" #include "wayland/meta-wayland-private.h" #include "wayland/meta-wayland-surface.h" #include "wayland/meta-wayland-outputs.h" @@ -113,12 +114,14 @@ wp_presentation_bind (struct wl_client *client, } static void -discard_feedbacks (struct wl_list *feedbacks) +discard_non_cursor_feedbacks (struct wl_list *feedbacks) { - while (!wl_list_empty (feedbacks)) + MetaWaylandPresentationFeedback *feedback, *next; + + wl_list_for_each_safe (feedback, next, feedbacks, link) { - MetaWaylandPresentationFeedback *feedback = - wl_container_of (feedbacks->next, feedback, link); + if (META_IS_WAYLAND_CURSOR_SURFACE (feedback->surface->role)) + continue; meta_wayland_presentation_feedback_discard (feedback); } @@ -133,14 +136,19 @@ on_after_paint (ClutterStage *stage, GList *l; /* - * We just painted this stage view, which means that all feedbacks that didn't - * fire (e.g. due to page flip failing) are now obsolete and should be - * discarded. + * We just painted this stage view, which means that all non-cursor feedbacks + * that didn't fire (e.g. due to page flip failing) are now obsolete and + * should be discarded. + * + * Cursor feedbacks have a similar mechanism done separately, mainly because + * they are painted earlier, in prepare_frame(). This means that the feedbacks + * list currently contains stale non-cursor feedbacks and up-to-date cursor + * feedbacks. */ feedbacks = meta_wayland_presentation_time_ensure_feedbacks (&compositor->presentation_time, stage_view); - discard_feedbacks (feedbacks); + discard_non_cursor_feedbacks (feedbacks); l = compositor->presentation_time.feedback_surfaces; while (l) @@ -182,7 +190,14 @@ destroy_feedback_list (gpointer data) { struct wl_list *feedbacks = data; - discard_feedbacks (feedbacks); + while (!wl_list_empty (feedbacks)) + { + MetaWaylandPresentationFeedback *feedback = + wl_container_of (feedbacks->next, feedback, link); + + meta_wayland_presentation_feedback_discard (feedback); + } + g_free (feedbacks); } @@ -367,3 +382,35 @@ meta_wayland_presentation_time_ensure_feedbacks (MetaWaylandPresentationTime *pr return g_hash_table_lookup (presentation_time->feedbacks, stage_view); } + +void +meta_wayland_presentation_time_cursor_painted (MetaWaylandPresentationTime *presentation_time, + ClutterStageView *stage_view, + MetaWaylandCursorSurface *cursor_surface) +{ + struct wl_list *feedbacks; + MetaWaylandPresentationFeedback *feedback, *next; + MetaWaylandSurfaceRole *role = META_WAYLAND_SURFACE_ROLE (cursor_surface); + MetaWaylandSurface *surface = meta_wayland_surface_role_get_surface (role); + + feedbacks = + meta_wayland_presentation_time_ensure_feedbacks (presentation_time, + stage_view); + + /* Discard previous feedbacks for this cursor as now it has gone stale. */ + wl_list_for_each_safe (feedback, next, feedbacks, link) + { + if (feedback->surface->role == role) + meta_wayland_presentation_feedback_discard (feedback); + } + + /* Add new feedbacks. */ + if (!wl_list_empty (&surface->presentation_time.feedback_list)) + { + wl_list_insert_list (feedbacks, + &surface->presentation_time.feedback_list); + wl_list_init (&surface->presentation_time.feedback_list); + + surface->presentation_time.needs_sequence_update = TRUE; + } +}