mirror of
https://github.com/brl/mutter.git
synced 2024-11-10 07:56:14 -05:00
wayland: Send presentation feedbacks to cursors
This commit assumes that cursor surfaces work in a "mailbox" fashion. If they are painted multiple times before a successful flip, all commits but the last get discarded, and the last commit gets presented after the flip succeeds. This is more or less how it works in the atomic backend, and also more or less how it works in other backends, with the exception that the cursor painting might fail without any way of knowing. This assumption is still better than unconditionally discarding all cursor surface feedbacks as if the cursor painting always fails. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1484>
This commit is contained in:
parent
cd9ae13465
commit
82af1fb87e
@ -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
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <wayland-server.h>
|
||||
|
||||
#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 */
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <glib.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user