From 6e4f45f875ccc0f29b93b0b36ef34dfdc8f8394a Mon Sep 17 00:00:00 2001
From: Richard Grenville <pyxlcy@gmail.com>
Date: Wed, 26 Mar 2014 22:27:25 +0800
Subject: Misc: Add --xrender-sync{,-fence} as configuration file option

- Add --xrender-sync{,-fence} as configuration file option.

- Quit on encountering invalid opacity rule.

- Other small changes.
---
 common.h  |  4 +++-
 compton.c | 22 ++++++++++++++++++++--
 opengl.c  |  4 ++--
 3 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/common.h b/common.h
index d243dc077..525b9a96b 100644
--- a/common.h
+++ b/common.h
@@ -2230,6 +2230,7 @@ xr_sync_(session_t *ps, Drawable d
   if (!ps->o.xrender_sync)
     return;
 
+  XSync(ps->dpy, False);
 #ifdef CONFIG_XSYNC
   if (ps->o.xrender_sync_fence && ps->xsync_exists) {
     // TODO: If everybody just follows the rules stated in X Sync prototype,
@@ -2243,6 +2244,8 @@ xr_sync_(session_t *ps, Drawable d
       *pfence = XSyncCreateFence(ps->dpy, d, False);
     if (*pfence) {
       Bool triggered = False;
+      /* if (XSyncQueryFence(ps->dpy, *pfence, &triggered) && triggered)
+        XSyncResetFence(ps->dpy, *pfence); */
       // The fence may fail to be created (e.g. because of died drawable)
       assert(!XSyncQueryFence(ps->dpy, *pfence, &triggered) || !triggered);
       XSyncTriggerFence(ps->dpy, *pfence);
@@ -2257,7 +2260,6 @@ xr_sync_(session_t *ps, Drawable d
       XSyncResetFence(ps->dpy, *pfence);
   }
 #endif
-  XSync(ps->dpy, False);
 #ifdef CONFIG_GLX_SYNC
   xr_glx_sync(ps, d, pfence);
 #endif
diff --git a/compton.c b/compton.c
index 1efb05d62..1da926b5d 100644
--- a/compton.c
+++ b/compton.c
@@ -4596,6 +4596,18 @@ usage(int ret) {
     "--glx-use-gpushader4\n"
     "  GLX backend: Use GL_EXT_gpu_shader4 for some optimization on blur\n"
     "  GLSL code. My tests on GTX 670 show no noticeable effect.\n"
+    "--xrender-sync\n"
+    "  Attempt to synchronize client applications' draw calls with XSync(),\n"
+    "  used on GLX backend to ensure up-to-date window content is painted.\n"
+#undef WARNING
+#ifndef CONFIG_XSYNC
+#define WARNING WARNING_DISABLED
+#else
+#define WARNING
+#endif
+    "--xrender-sync-fence\n"
+    "  Additionally use X Sync fence to sync clients' draw calls. Needed\n"
+    "  on nvidia-drivers with GLX backend for some users." WARNING "\n"
 #undef WARNING
 #ifndef CONFIG_DBUS
 #define WARNING WARNING_DISABLED
@@ -5186,7 +5198,9 @@ parse_cfg_condlst_opct(session_t *ps, const config_t *pcfg, const char *name) {
     if (config_setting_is_array(setting)) {
       int i = config_setting_length(setting);
       while (i--)
-        parse_rule_opacity(ps, config_setting_get_string_elem(setting, i));
+        if (!parse_rule_opacity(ps, config_setting_get_string_elem(setting,
+                i)))
+          exit(1);
     }
     // Treat it as a single pattern if it's a string
     else if (CONFIG_TYPE_STRING == config_setting_type(setting)) {
@@ -5399,6 +5413,10 @@ parse_config(session_t *ps, struct options_tmp *pcfgtmp) {
     exit(1);
   // --glx-use-gpushader4
   lcfg_lookup_bool(&cfg, "glx-use-gpushader4", &ps->o.glx_use_gpushader4);
+  // --xrender-sync
+  lcfg_lookup_bool(&cfg, "xrender-sync", &ps->o.xrender_sync);
+  // --xrender-sync-fence
+  lcfg_lookup_bool(&cfg, "xrender-sync-fence", &ps->o.xrender_sync_fence);
   // Wintype settings
   {
     wintype_t i;
@@ -6996,7 +7014,7 @@ session_init(session_t *ps_old, int argc, char **argv) {
       exit(1);
     }
 #else
-    printf_errf("(): X Sync support not compiled in. --xrender-sync-fence"
+    printf_errf("(): X Sync support not compiled in. --xrender-sync-fence "
         "can't work.");
     exit(1);
 #endif
diff --git a/opengl.c b/opengl.c
index 39aac33c2..951d8e50a 100644
--- a/opengl.c
+++ b/opengl.c
@@ -16,11 +16,11 @@ xr_glx_sync(session_t *ps, Drawable d, XSyncFence *pfence) {
   if (*pfence) {
     // GLsync sync = ps->glFenceSyncProc(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
     GLsync sync = ps->glImportSyncEXT(GL_SYNC_X11_FENCE_EXT, *pfence, 0);
-    XSync(ps->dpy, False);
-    glx_check_err(ps);
     /* GLenum ret = ps->glClientWaitSyncProc(sync, GL_SYNC_FLUSH_COMMANDS_BIT,
         1000);
     assert(GL_CONDITION_SATISFIED == ret); */
+    XSyncTriggerFence(ps->dpy, *pfence);
+    XFlush(ps->dpy);
     ps->glWaitSyncProc(sync, 0, GL_TIMEOUT_IGNORED);
     // ps->glDeleteSyncProc(sync);
     // XSyncResetFence(ps->dpy, *pfence);
-- 
cgit v1.2.3

