wayland: Wire up presentation-time machinery
- add surfaces to the presentation list, - move their feedbacks to the map in on-after-update, - fire the feedbacks in on_presented(). Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1484>
This commit is contained in:
parent
f0c2200466
commit
2ce3a050f0
@ -26,6 +26,7 @@
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "compositor/meta-surface-actor-wayland.h"
|
||||
#include "wayland/meta-wayland-private.h"
|
||||
#include "wayland/meta-wayland-surface.h"
|
||||
#include "wayland/meta-wayland-outputs.h"
|
||||
@ -112,10 +113,8 @@ wp_presentation_bind (struct wl_client *client,
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_feedback_list (gpointer data)
|
||||
discard_feedbacks (struct wl_list *feedbacks)
|
||||
{
|
||||
struct wl_list *feedbacks = data;
|
||||
|
||||
while (!wl_list_empty (feedbacks))
|
||||
{
|
||||
MetaWaylandPresentationFeedback *feedback =
|
||||
@ -123,7 +122,67 @@ destroy_feedback_list (gpointer data)
|
||||
|
||||
meta_wayland_presentation_feedback_discard (feedback);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_after_paint (ClutterStage *stage,
|
||||
ClutterStageView *stage_view,
|
||||
MetaWaylandCompositor *compositor)
|
||||
{
|
||||
struct wl_list *feedbacks;
|
||||
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.
|
||||
*/
|
||||
feedbacks =
|
||||
meta_wayland_presentation_time_ensure_feedbacks (&compositor->presentation_time,
|
||||
stage_view);
|
||||
discard_feedbacks (feedbacks);
|
||||
|
||||
l = compositor->presentation_time.feedback_surfaces;
|
||||
while (l)
|
||||
{
|
||||
GList *l_cur = l;
|
||||
MetaWaylandSurface *surface = l->data;
|
||||
MetaSurfaceActor *actor;
|
||||
ClutterStageView *surface_primary_view;
|
||||
|
||||
l = l->next;
|
||||
|
||||
actor = meta_wayland_surface_get_actor (surface);
|
||||
if (!actor)
|
||||
continue;
|
||||
|
||||
surface_primary_view =
|
||||
meta_surface_actor_wayland_get_current_primary_view (actor, stage);
|
||||
if (stage_view != surface_primary_view)
|
||||
continue;
|
||||
|
||||
if (!wl_list_empty (&surface->presentation_time.feedback_list))
|
||||
{
|
||||
/* Add feedbacks to the list to be fired on presentation. */
|
||||
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;
|
||||
}
|
||||
|
||||
compositor->presentation_time.feedback_surfaces =
|
||||
g_list_delete_link (compositor->presentation_time.feedback_surfaces,
|
||||
l_cur);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_feedback_list (gpointer data)
|
||||
{
|
||||
struct wl_list *feedbacks = data;
|
||||
|
||||
discard_feedbacks (feedbacks);
|
||||
g_free (feedbacks);
|
||||
}
|
||||
|
||||
@ -141,6 +200,7 @@ meta_wayland_init_presentation_time (MetaWaylandCompositor *compositor)
|
||||
MetaBackend *backend = compositor->backend;
|
||||
MetaMonitorManager *monitor_manager =
|
||||
meta_backend_get_monitor_manager (backend);
|
||||
ClutterActor *stage = meta_backend_get_stage (backend);
|
||||
|
||||
compositor->presentation_time.feedbacks =
|
||||
g_hash_table_new_full (NULL, NULL, NULL, destroy_feedback_list);
|
||||
@ -148,6 +208,9 @@ meta_wayland_init_presentation_time (MetaWaylandCompositor *compositor)
|
||||
g_signal_connect (monitor_manager, "monitors-changed-internal",
|
||||
G_CALLBACK (on_monitors_changed), compositor);
|
||||
|
||||
g_signal_connect (stage, "after-paint",
|
||||
G_CALLBACK (on_after_paint), compositor);
|
||||
|
||||
if (wl_global_create (compositor->wayland_display,
|
||||
&wp_presentation_interface,
|
||||
META_WP_PRESENTATION_VERSION,
|
||||
|
@ -799,6 +799,10 @@ meta_wayland_surface_apply_state (MetaWaylandSurface *surface,
|
||||
&state->presentation_feedback_list);
|
||||
wl_list_init (&state->presentation_feedback_list);
|
||||
|
||||
if (!wl_list_empty (&surface->presentation_time.feedback_list))
|
||||
meta_wayland_compositor_add_presentation_feedback_surface (surface->compositor,
|
||||
surface);
|
||||
|
||||
if (surface->role)
|
||||
{
|
||||
meta_wayland_surface_role_apply_state (surface->role, state);
|
||||
@ -1390,6 +1394,8 @@ wl_surface_destructor (struct wl_resource *resource)
|
||||
cairo_region_destroy (surface->input_region);
|
||||
|
||||
meta_wayland_compositor_remove_frame_callback_surface (compositor, surface);
|
||||
meta_wayland_compositor_remove_presentation_feedback_surface (compositor,
|
||||
surface);
|
||||
|
||||
g_hash_table_foreach (surface->outputs,
|
||||
surface_output_disconnect_signals,
|
||||
|
@ -230,6 +230,52 @@ on_after_update (ClutterStage *stage,
|
||||
}
|
||||
}
|
||||
|
||||
static MetaWaylandOutput *
|
||||
get_output_for_stage_view (MetaWaylandCompositor *compositor,
|
||||
ClutterStageView *stage_view)
|
||||
{
|
||||
MetaCrtc *crtc;
|
||||
MetaOutput *output;
|
||||
MetaMonitor *monitor;
|
||||
MetaLogicalMonitor *logical_monitor;
|
||||
|
||||
crtc = meta_renderer_view_get_crtc (META_RENDERER_VIEW (stage_view));
|
||||
|
||||
/*
|
||||
* All outputs occupy the same region of the screen, as their contents are
|
||||
* the same, so pick the first one.
|
||||
*/
|
||||
output = meta_crtc_get_outputs (crtc)->data;
|
||||
|
||||
monitor = meta_output_get_monitor (output);
|
||||
logical_monitor = meta_monitor_get_logical_monitor (monitor);
|
||||
return g_hash_table_lookup (compositor->outputs, &logical_monitor->winsys_id);
|
||||
}
|
||||
|
||||
static void
|
||||
on_presented (ClutterStage *stage,
|
||||
ClutterStageView *stage_view,
|
||||
ClutterFrameInfo *frame_info,
|
||||
MetaWaylandCompositor *compositor)
|
||||
{
|
||||
MetaWaylandPresentationFeedback *feedback, *next;
|
||||
struct wl_list *feedbacks;
|
||||
MetaWaylandOutput *output;
|
||||
|
||||
feedbacks =
|
||||
meta_wayland_presentation_time_ensure_feedbacks (&compositor->presentation_time,
|
||||
stage_view);
|
||||
|
||||
output = get_output_for_stage_view (compositor, stage_view);
|
||||
|
||||
wl_list_for_each_safe (feedback, next, feedbacks, link)
|
||||
{
|
||||
meta_wayland_presentation_feedback_present (feedback,
|
||||
frame_info,
|
||||
output);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_wayland_compositor_handle_event:
|
||||
* @compositor: the #MetaWaylandCompositor instance
|
||||
@ -438,6 +484,8 @@ meta_wayland_compositor_setup (MetaWaylandCompositor *compositor)
|
||||
|
||||
g_signal_connect (stage, "after-update",
|
||||
G_CALLBACK (on_after_update), compositor);
|
||||
g_signal_connect (stage, "presented",
|
||||
G_CALLBACK (on_presented), compositor);
|
||||
|
||||
if (!wl_global_create (compositor->wayland_display,
|
||||
&wl_compositor_interface,
|
||||
|
Loading…
Reference in New Issue
Block a user