[mutter] compositor/x11: Notify the sync ring about frames on updates



commit 44a4e616658edb2a21a9612cfd3a41742a1ca427
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Thu Mar 4 19:11:12 2021 +0100

    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>

 src/compositor/meta-compositor-x11.c | 35 ++++++++++++++++++-----------------
 1 file changed, 18 insertions(+), 17 deletions(-)
---
diff --git a/src/compositor/meta-compositor-x11.c b/src/compositor/meta-compositor-x11.c
index 27999fbaec..1d0ba4c8d8 100644
--- a/src/compositor/meta-compositor-x11.c
+++ b/src/compositor/meta-compositor-x11.c
@@ -40,6 +40,7 @@ struct _MetaCompositorX11
   Window output;
 
   gulong before_update_handler_id;
+  gulong after_update_handler_id;
 
   gboolean frame_has_updated_xsurfaces;
   gboolean have_x11_sync_object;
@@ -363,35 +364,32 @@ on_before_update (ClutterStage     *stage,
 }
 
 static void
-meta_compositor_x11_before_paint (MetaCompositor   *compositor,
-                                  ClutterStageView *stage_view)
+on_after_update (ClutterStage     *stage,
+                 ClutterStageView *stage_view,
+                 MetaCompositor   *compositor)
 {
   MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (compositor);
-  MetaCompositorClass *parent_class;
 
-  maybe_unredirect_top_window (compositor_x11);
+  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 ();
 
-  parent_class = META_COMPOSITOR_CLASS (meta_compositor_x11_parent_class);
-  parent_class->before_paint (compositor, stage_view);
+      compositor_x11->frame_has_updated_xsurfaces = FALSE;
+    }
 }
 
 static void
-meta_compositor_x11_after_paint (MetaCompositor   *compositor,
-                                 ClutterStageView *stage_view)
+meta_compositor_x11_before_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;
-    }
+  maybe_unredirect_top_window (compositor_x11);
 
   parent_class = META_COMPOSITOR_CLASS (meta_compositor_x11_parent_class);
-  parent_class->after_paint (compositor, stage_view);
+  parent_class->before_paint (compositor, stage_view);
 }
 
 static void
@@ -481,6 +479,9 @@ meta_compositor_x11_constructed (GObject *object)
   compositor_x11->before_update_handler_id =
     g_signal_connect (stage, "before-update",
                       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);
 }
@@ -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->after_update_handler_id, stage);
 
   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->unmanage = meta_compositor_x11_unmanage;
   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->monotonic_to_high_res_xserver_time =
    meta_compositor_x11_monotonic_to_high_res_xserver_time;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]