mirror of
https://github.com/brl/mutter.git
synced 2024-11-25 09:30:45 -05:00
compositor/x11: Notify the sync ring about frames on updates
The sync ring has an API about "frames", where it is notified about the end of frames. However, its "insert wait" call is done before updates, meaning that some "insert waits" will never see the "after frame" if there was no frame drawn. This will cause mismatching in the frame counting, causing freezes in the synchronization until something else triggers an actual frame, effectively "unfreezing" the sync ring. Fix this by not only notifying the sync ring about frames when there were actual frames drawn, but also on plain updates which didn't result in a drawn frame. Related: https://gitlab.gnome.org/GNOME/mutter/-/issues/1516 Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1754>
This commit is contained in:
parent
c2968c89fe
commit
44a4e61665
@ -40,6 +40,7 @@ struct _MetaCompositorX11
|
|||||||
Window output;
|
Window output;
|
||||||
|
|
||||||
gulong before_update_handler_id;
|
gulong before_update_handler_id;
|
||||||
|
gulong after_update_handler_id;
|
||||||
|
|
||||||
gboolean frame_has_updated_xsurfaces;
|
gboolean frame_has_updated_xsurfaces;
|
||||||
gboolean have_x11_sync_object;
|
gboolean have_x11_sync_object;
|
||||||
@ -362,6 +363,22 @@ on_before_update (ClutterStage *stage,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_after_update (ClutterStage *stage,
|
||||||
|
ClutterStageView *stage_view,
|
||||||
|
MetaCompositor *compositor)
|
||||||
|
{
|
||||||
|
MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (compositor);
|
||||||
|
|
||||||
|
if (compositor_x11->frame_has_updated_xsurfaces)
|
||||||
|
{
|
||||||
|
if (compositor_x11->have_x11_sync_object)
|
||||||
|
compositor_x11->have_x11_sync_object = meta_sync_ring_after_frame ();
|
||||||
|
|
||||||
|
compositor_x11->frame_has_updated_xsurfaces = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_compositor_x11_before_paint (MetaCompositor *compositor,
|
meta_compositor_x11_before_paint (MetaCompositor *compositor,
|
||||||
ClutterStageView *stage_view)
|
ClutterStageView *stage_view)
|
||||||
@ -375,25 +392,6 @@ meta_compositor_x11_before_paint (MetaCompositor *compositor,
|
|||||||
parent_class->before_paint (compositor, stage_view);
|
parent_class->before_paint (compositor, stage_view);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
meta_compositor_x11_after_paint (MetaCompositor *compositor,
|
|
||||||
ClutterStageView *stage_view)
|
|
||||||
{
|
|
||||||
MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (compositor);
|
|
||||||
MetaCompositorClass *parent_class;
|
|
||||||
|
|
||||||
if (compositor_x11->frame_has_updated_xsurfaces)
|
|
||||||
{
|
|
||||||
if (compositor_x11->have_x11_sync_object)
|
|
||||||
compositor_x11->have_x11_sync_object = meta_sync_ring_after_frame ();
|
|
||||||
|
|
||||||
compositor_x11->frame_has_updated_xsurfaces = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
parent_class = META_COMPOSITOR_CLASS (meta_compositor_x11_parent_class);
|
|
||||||
parent_class->after_paint (compositor, stage_view);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_compositor_x11_remove_window (MetaCompositor *compositor,
|
meta_compositor_x11_remove_window (MetaCompositor *compositor,
|
||||||
MetaWindow *window)
|
MetaWindow *window)
|
||||||
@ -481,6 +479,9 @@ meta_compositor_x11_constructed (GObject *object)
|
|||||||
compositor_x11->before_update_handler_id =
|
compositor_x11->before_update_handler_id =
|
||||||
g_signal_connect (stage, "before-update",
|
g_signal_connect (stage, "before-update",
|
||||||
G_CALLBACK (on_before_update), compositor);
|
G_CALLBACK (on_before_update), compositor);
|
||||||
|
compositor_x11->after_update_handler_id =
|
||||||
|
g_signal_connect (stage, "after-update",
|
||||||
|
G_CALLBACK (on_after_update), compositor);
|
||||||
|
|
||||||
G_OBJECT_CLASS (meta_compositor_x11_parent_class)->constructed (object);
|
G_OBJECT_CLASS (meta_compositor_x11_parent_class)->constructed (object);
|
||||||
}
|
}
|
||||||
@ -499,6 +500,7 @@ meta_compositor_x11_dispose (GObject *object)
|
|||||||
}
|
}
|
||||||
|
|
||||||
g_clear_signal_handler (&compositor_x11->before_update_handler_id, stage);
|
g_clear_signal_handler (&compositor_x11->before_update_handler_id, stage);
|
||||||
|
g_clear_signal_handler (&compositor_x11->after_update_handler_id, stage);
|
||||||
|
|
||||||
G_OBJECT_CLASS (meta_compositor_x11_parent_class)->dispose (object);
|
G_OBJECT_CLASS (meta_compositor_x11_parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
@ -520,7 +522,6 @@ meta_compositor_x11_class_init (MetaCompositorX11Class *klass)
|
|||||||
compositor_class->manage = meta_compositor_x11_manage;
|
compositor_class->manage = meta_compositor_x11_manage;
|
||||||
compositor_class->unmanage = meta_compositor_x11_unmanage;
|
compositor_class->unmanage = meta_compositor_x11_unmanage;
|
||||||
compositor_class->before_paint = meta_compositor_x11_before_paint;
|
compositor_class->before_paint = meta_compositor_x11_before_paint;
|
||||||
compositor_class->after_paint = meta_compositor_x11_after_paint;
|
|
||||||
compositor_class->remove_window = meta_compositor_x11_remove_window;
|
compositor_class->remove_window = meta_compositor_x11_remove_window;
|
||||||
compositor_class->monotonic_to_high_res_xserver_time =
|
compositor_class->monotonic_to_high_res_xserver_time =
|
||||||
meta_compositor_x11_monotonic_to_high_res_xserver_time;
|
meta_compositor_x11_monotonic_to_high_res_xserver_time;
|
||||||
|
Loading…
Reference in New Issue
Block a user