[mutter] compositor: Sync X drawing only once per frame



commit f55737ec06611cf5cdacf32809cffe2332e7894a
Author: Rui Matos <tiagomatos gmail com>
Date:   Mon May 12 15:11:53 2014 +0200

    compositor: Sync X drawing only once per frame
    
    We only need to call XSync() once per frame to synchronize X with GL
    drawing.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=728464

 src/compositor/compositor-private.h     |    2 ++
 src/compositor/compositor.c             |   29 +++++++++++++++++++++++++++++
 src/compositor/meta-surface-actor-x11.c |   20 --------------------
 3 files changed, 31 insertions(+), 20 deletions(-)
---
diff --git a/src/compositor/compositor-private.h b/src/compositor/compositor-private.h
index ef0a534..a41f563 100644
--- a/src/compositor/compositor-private.h
+++ b/src/compositor/compositor-private.h
@@ -38,6 +38,8 @@ struct _MetaCompositor
   gint                   switch_workspace_in_progress;
 
   MetaPluginManager *plugin_mgr;
+
+  gboolean frame_has_updated_xsurfaces;
 };
 
 /* Wait 2ms after vblank before starting to draw next frame */
diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
index 318e07a..3e5a205 100644
--- a/src/compositor/compositor.c
+++ b/src/compositor/compositor.c
@@ -146,6 +146,8 @@ process_damage (MetaCompositor     *compositor,
 {
   MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
   meta_window_actor_process_x11_damage (window_actor, event);
+
+  compositor->frame_has_updated_xsurfaces = TRUE;
 }
 
 /* compat helper */
@@ -1135,6 +1137,33 @@ pre_paint_windows (MetaCompositor *compositor)
 
   for (l = compositor->windows; l; l = l->next)
     meta_window_actor_pre_paint (l->data);
+
+  if (compositor->frame_has_updated_xsurfaces)
+    {
+      /* We need to make sure that any X drawing that happens before
+       * the XDamageSubtract() for each window above is visible to
+       * subsequent GL rendering; the only standardized way to do this
+       * is EXT_x11_sync_object, which isn't yet widely available. For
+       * now, we count on details of Xorg and the open source drivers,
+       * and hope for the best otherwise.
+       *
+       * Xorg and open source driver specifics:
+       *
+       * The X server makes sure to flush drawing to the kernel before
+       * sending out damage events, but since we use
+       * DamageReportBoundingBox there may be drawing between the last
+       * damage event and the XDamageSubtract() that needs to be
+       * flushed as well.
+       *
+       * Xorg always makes sure that drawing is flushed to the kernel
+       * before writing events or responses to the client, so any
+       * round trip request at this point is sufficient to flush the
+       * GLX buffers.
+       */
+      XSync (compositor->display->xdisplay, False);
+
+      compositor->frame_has_updated_xsurfaces = FALSE;
+    }
 }
 
 static gboolean
diff --git a/src/compositor/meta-surface-actor-x11.c b/src/compositor/meta-surface-actor-x11.c
index 78004f5..9322081 100644
--- a/src/compositor/meta-surface-actor-x11.c
+++ b/src/compositor/meta-surface-actor-x11.c
@@ -239,26 +239,6 @@ meta_surface_actor_x11_pre_paint (MetaSurfaceActor *actor)
       XDamageSubtract (xdisplay, priv->damage, None, None);
       meta_error_trap_pop (display);
 
-      /* We need to make sure that any X drawing that happens before the
-       * XDamageSubtract() above is visible to subsequent GL rendering;
-       * the only standardized way to do this is EXT_x11_sync_object,
-       * which isn't yet widely available. For now, we count on details
-       * of Xorg and the open source drivers, and hope for the best
-       * otherwise.
-       *
-       * Xorg and open source driver specifics:
-       *
-       * The X server makes sure to flush drawing to the kernel before
-       * sending out damage events, but since we use DamageReportBoundingBox
-       * there may be drawing between the last damage event and the
-       * XDamageSubtract() that needs to be flushed as well.
-       *
-       * Xorg always makes sure that drawing is flushed to the kernel
-       * before writing events or responses to the client, so any round trip
-       * request at this point is sufficient to flush the GLX buffers.
-       */
-      XSync (xdisplay, False);
-
       priv->received_damage = FALSE;
     }
 


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