wayland: Store map of ready presentation feedbacks

These are feedbacks for updates that were drawn or otherwise displayed
on screen, and need to be fired as soon as their presentation happens.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1484>
This commit is contained in:
Ivan Molodetskikh 2020-10-12 14:10:43 +03:00 committed by Marge Bot
parent 0c3490223e
commit f0c2200466
2 changed files with 62 additions and 0 deletions

View File

@ -39,6 +39,13 @@ typedef struct _MetaWaylandPresentationFeedback
typedef struct _MetaWaylandPresentationTime
{
GList *feedback_surfaces;
/*
* A mapping from (ClutterStageView *) to a
* (MetaWaylandPresentationFeedback *) wl_list of presentation-time feedbacks
* that are scheduled to be presented.
*/
GHashTable *feedbacks;
} MetaWaylandPresentationTime;
void meta_wayland_init_presentation_time (MetaWaylandCompositor *compositor);
@ -49,4 +56,7 @@ void meta_wayland_presentation_feedback_present (MetaWaylandPresentationFeedback
ClutterFrameInfo *frame_info,
MetaWaylandOutput *output);
struct wl_list * meta_wayland_presentation_time_ensure_feedbacks (MetaWaylandPresentationTime *presentation_time,
ClutterStageView *stage_view);
#endif /* META_WAYLAND_PRESENTATION_TIME_PRIVATE_H */

View File

@ -111,9 +111,43 @@ wp_presentation_bind (struct wl_client *client,
wp_presentation_send_clock_id (resource, CLOCK_MONOTONIC);
}
static void
destroy_feedback_list (gpointer data)
{
struct wl_list *feedbacks = data;
while (!wl_list_empty (feedbacks))
{
MetaWaylandPresentationFeedback *feedback =
wl_container_of (feedbacks->next, feedback, link);
meta_wayland_presentation_feedback_discard (feedback);
}
g_free (feedbacks);
}
static void
on_monitors_changed (MetaMonitorManager *manager,
MetaWaylandCompositor *compositor)
{
/* All ClutterStageViews were re-created, so clear our map. */
g_hash_table_remove_all (compositor->presentation_time.feedbacks);
}
void
meta_wayland_init_presentation_time (MetaWaylandCompositor *compositor)
{
MetaBackend *backend = compositor->backend;
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
compositor->presentation_time.feedbacks =
g_hash_table_new_full (NULL, NULL, NULL, destroy_feedback_list);
g_signal_connect (monitor_manager, "monitors-changed-internal",
G_CALLBACK (on_monitors_changed), compositor);
if (wl_global_create (compositor->wayland_display,
&wp_presentation_interface,
META_WP_PRESENTATION_VERSION,
@ -252,3 +286,21 @@ meta_wayland_presentation_feedback_present (MetaWaylandPresentationFeedback *fee
wl_resource_destroy (feedback->resource);
}
struct wl_list *
meta_wayland_presentation_time_ensure_feedbacks (MetaWaylandPresentationTime *presentation_time,
ClutterStageView *stage_view)
{
if (!g_hash_table_contains (presentation_time->feedbacks, stage_view))
{
struct wl_list *list;
list = g_new0 (struct wl_list, 1);
wl_list_init (list);
g_hash_table_insert (presentation_time->feedbacks, stage_view, list);
return list;
}
return g_hash_table_lookup (presentation_time->feedbacks, stage_view);
}