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 <kei...@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

_______________________________________________
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: https://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to