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 <glib.h>
|
||||||
|
|
||||||
|
#include "compositor/meta-surface-actor-wayland.h"
|
||||||
#include "wayland/meta-wayland-private.h"
|
#include "wayland/meta-wayland-private.h"
|
||||||
#include "wayland/meta-wayland-surface.h"
|
#include "wayland/meta-wayland-surface.h"
|
||||||
#include "wayland/meta-wayland-outputs.h"
|
#include "wayland/meta-wayland-outputs.h"
|
||||||
@ -112,10 +113,8 @@ wp_presentation_bind (struct wl_client *client,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
destroy_feedback_list (gpointer data)
|
discard_feedbacks (struct wl_list *feedbacks)
|
||||||
{
|
{
|
||||||
struct wl_list *feedbacks = data;
|
|
||||||
|
|
||||||
while (!wl_list_empty (feedbacks))
|
while (!wl_list_empty (feedbacks))
|
||||||
{
|
{
|
||||||
MetaWaylandPresentationFeedback *feedback =
|
MetaWaylandPresentationFeedback *feedback =
|
||||||
@ -123,7 +122,67 @@ destroy_feedback_list (gpointer data)
|
|||||||
|
|
||||||
meta_wayland_presentation_feedback_discard (feedback);
|
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);
|
g_free (feedbacks);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,6 +200,7 @@ meta_wayland_init_presentation_time (MetaWaylandCompositor *compositor)
|
|||||||
MetaBackend *backend = compositor->backend;
|
MetaBackend *backend = compositor->backend;
|
||||||
MetaMonitorManager *monitor_manager =
|
MetaMonitorManager *monitor_manager =
|
||||||
meta_backend_get_monitor_manager (backend);
|
meta_backend_get_monitor_manager (backend);
|
||||||
|
ClutterActor *stage = meta_backend_get_stage (backend);
|
||||||
|
|
||||||
compositor->presentation_time.feedbacks =
|
compositor->presentation_time.feedbacks =
|
||||||
g_hash_table_new_full (NULL, NULL, NULL, destroy_feedback_list);
|
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_signal_connect (monitor_manager, "monitors-changed-internal",
|
||||||
G_CALLBACK (on_monitors_changed), compositor);
|
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,
|
if (wl_global_create (compositor->wayland_display,
|
||||||
&wp_presentation_interface,
|
&wp_presentation_interface,
|
||||||
META_WP_PRESENTATION_VERSION,
|
META_WP_PRESENTATION_VERSION,
|
||||||
|
@ -799,6 +799,10 @@ meta_wayland_surface_apply_state (MetaWaylandSurface *surface,
|
|||||||
&state->presentation_feedback_list);
|
&state->presentation_feedback_list);
|
||||||
wl_list_init (&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)
|
if (surface->role)
|
||||||
{
|
{
|
||||||
meta_wayland_surface_role_apply_state (surface->role, state);
|
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);
|
cairo_region_destroy (surface->input_region);
|
||||||
|
|
||||||
meta_wayland_compositor_remove_frame_callback_surface (compositor, surface);
|
meta_wayland_compositor_remove_frame_callback_surface (compositor, surface);
|
||||||
|
meta_wayland_compositor_remove_presentation_feedback_surface (compositor,
|
||||||
|
surface);
|
||||||
|
|
||||||
g_hash_table_foreach (surface->outputs,
|
g_hash_table_foreach (surface->outputs,
|
||||||
surface_output_disconnect_signals,
|
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:
|
* meta_wayland_compositor_handle_event:
|
||||||
* @compositor: the #MetaWaylandCompositor instance
|
* @compositor: the #MetaWaylandCompositor instance
|
||||||
@ -438,6 +484,8 @@ meta_wayland_compositor_setup (MetaWaylandCompositor *compositor)
|
|||||||
|
|
||||||
g_signal_connect (stage, "after-update",
|
g_signal_connect (stage, "after-update",
|
||||||
G_CALLBACK (on_after_update), compositor);
|
G_CALLBACK (on_after_update), compositor);
|
||||||
|
g_signal_connect (stage, "presented",
|
||||||
|
G_CALLBACK (on_presented), compositor);
|
||||||
|
|
||||||
if (!wl_global_create (compositor->wayland_display,
|
if (!wl_global_create (compositor->wayland_display,
|
||||||
&wl_compositor_interface,
|
&wl_compositor_interface,
|
||||||
|
Loading…
Reference in New Issue
Block a user