[mutter/gnome-3-38] compositor/x11: Notify the sync ring about frames on updates



commit b4192c4550fef7c6b259fec1ada82c4aa3a00df2
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>
    (cherry picked from commit 44a4e616658edb2a21a9612cfd3a41742a1ca427)

 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 e7da103e3a..339ef03849 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
@@ -465,6 +463,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);
 }
@@ -483,6 +484,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);
 }
@@ -504,7 +506,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]