[PATCH xserver 16/25] ephyr: Use screen block handler for flushing changes

Keith Packard keithp at keithp.com
Wed May 25 05:38:53 UTC 2016


ephyr needs to make sure it calls glXSwapBuffers after glamor finishes
its rendering. As the screen block handler is now called last, we have
to use that instead of a registered block/wakeup handler to make sure
the GL rendering is done before we copy it to the front buffer.

Signed-off-by: Keith Packard <keithp at keithp.com>
---
 hw/kdrive/ephyr/ephyr.c | 43 +++++++++++++++++++++++++++----------------
 hw/kdrive/ephyr/ephyr.h |  2 ++
 2 files changed, 29 insertions(+), 16 deletions(-)

diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index 6066b5d..a9e700e 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -337,17 +337,29 @@ ephyrInternalDamageRedisplay(ScreenPtr pScreen)
 }
 
 static void
-ephyrInternalDamageBlockHandler(void *data, void *timeout)
+ephyrScreenBlockHandler(ScreenPtr pScreen, void *timeout)
 {
-    ScreenPtr pScreen = (ScreenPtr) data;
+    KdScreenPriv(pScreen);
+    KdScreenInfo *screen = pScreenPriv->screen;
+    EphyrScrPriv *scrpriv = screen->driver;
 
-    ephyrInternalDamageRedisplay(pScreen);
-}
+    pScreen->BlockHandler = scrpriv->BlockHandler;
+    (*pScreen->BlockHandler)(pScreen, timeout);
 
-static void
-ephyrInternalDamageWakeupHandler(void *data, int i)
-{
-    /* FIXME: Not needed ? */
+    if (scrpriv->pDamage) {
+
+        /* Re-wrap if we're still tracking damage
+         */
+        scrpriv->BlockHandler = pScreen->BlockHandler;
+        pScreen->BlockHandler = ephyrScreenBlockHandler;
+        ephyrInternalDamageRedisplay(pScreen);
+    } else {
+
+        /* Done tracking damage, note that we've left
+         * the block handler unwrapped
+         */
+        scrpriv->BlockHandler = NULL;
+    }
 }
 
 Bool
@@ -362,10 +374,11 @@ ephyrSetInternalDamage(ScreenPtr pScreen)
                                     (DamageDestroyFunc) 0,
                                     DamageReportNone, TRUE, pScreen, pScreen);
 
-    if (!RegisterBlockAndWakeupHandlers(ephyrInternalDamageBlockHandler,
-                                        ephyrInternalDamageWakeupHandler,
-                                        (void *) pScreen))
-        return FALSE;
+    /* Wrap only once */
+    if (scrpriv->BlockHandler == NULL) {
+        scrpriv->BlockHandler = pScreen->BlockHandler;
+        pScreen->BlockHandler = ephyrScreenBlockHandler;
+    }
 
     pPixmap = (*pScreen->GetScreenPixmap) (pScreen);
 
@@ -382,10 +395,7 @@ ephyrUnsetInternalDamage(ScreenPtr pScreen)
     EphyrScrPriv *scrpriv = screen->driver;
 
     DamageDestroy(scrpriv->pDamage);
-
-    RemoveBlockAndWakeupHandlers(ephyrInternalDamageBlockHandler,
-                                 ephyrInternalDamageWakeupHandler,
-                                 (void *) pScreen);
+    scrpriv->pDamage = NULL;
 }
 
 #ifdef RANDR
@@ -736,6 +746,7 @@ ephyrScreenFini(KdScreenInfo * screen)
     if (scrpriv->shadow) {
         KdShadowFbFree(screen);
     }
+    scrpriv->BlockHandler = NULL;
 }
 
 void
diff --git a/hw/kdrive/ephyr/ephyr.h b/hw/kdrive/ephyr/ephyr.h
index ef5736e..1ec2c69 100644
--- a/hw/kdrive/ephyr/ephyr.h
+++ b/hw/kdrive/ephyr/ephyr.h
@@ -85,6 +85,8 @@ typedef struct _ephyrScrPriv {
     int mynum;                  /* Screen number */
     unsigned long cmap[256];
 
+    ScreenBlockHandlerProcPtr   BlockHandler;
+
     /**
      * Per-screen Xlib-using state for glamor (private to
      * ephyr_glamor_glx.c)
-- 
2.8.0.rc3



More information about the xorg-devel mailing list