[PATCH xserver] FlushAllOutput: Only call FlushCallbacks when actually flushing data

Michel Dänzer michel at daenzer.net
Fri Jul 8 10:01:06 UTC 2016


From: Michel Dänzer <michel.daenzer at amd.com>

The unnecessary FlushCallback calls could cause significant performance
degradation with compositing.

As an example, with the radeon driver using glamor, a gtkperf run using
default parameters (100 iterations of every test) takes:
(numbers without => with this patch)

* About 1.9 => 1.9 seconds with xfwm4 without compositing
* About 2.6 => 2.2 seconds with compton compositing added
* About 4.1 => 2.2 seconds with kwin compositing
* About 10.2 => 2.4 seconds with xfwm4 compositing

Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
---
 os/io.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/os/io.c b/os/io.c
index d04ebd8..82e22cc 100644
--- a/os/io.c
+++ b/os/io.c
@@ -633,14 +633,12 @@ FlushAllOutput(void)
     OsCommPtr oc;
     register ClientPtr client;
     Bool newoutput = NewOutputPending;
+    Bool callbacks_called = FALSE;
 
 #if defined(WIN32)
     fd_set newOutputPending;
 #endif
 
-    if (FlushCallback)
-        CallCallbacks(&FlushCallback, NULL);
-
     if (!newoutput)
         return;
 
@@ -671,8 +669,14 @@ FlushAllOutput(void)
                 FD_SET(oc->fd, &OutputPending); /* set the bit again */
                 NewOutputPending = TRUE;
             }
-            else
+            else {
+                if (FlushCallback && !callbacks_called) {
+                    CallCallbacks(&FlushCallback, NULL);
+                    callbacks_called = TRUE;
+                }
+
                 (void) FlushClient(client, oc, (char *) NULL, 0);
+            }
         }
     }
 #else                           /* WIN32 */
@@ -689,8 +693,14 @@ FlushAllOutput(void)
             FD_SET(oc->fd, &newOutputPending);  /* set the bit again */
             NewOutputPending = TRUE;
         }
-        else
+        else {
+            if (FlushCallback && !callbacks_called) {
+                CallCallbacks(&FlushCallback, NULL);
+                callbacks_called = TRUE;
+            }
+
             (void) FlushClient(client, oc, (char *) NULL, 0);
+        }
     }
     XFD_COPYSET(&newOutputPending, &OutputPending);
 #endif                          /* WIN32 */
-- 
2.8.1



More information about the xorg-devel mailing list