[PATCH 2/2] pixmap: add wait shared pixmap

Dave Airlie airlied at gmail.com
Tue Feb 9 06:54:23 UTC 2016


With modesetting/glamor/reverse prime setups, we don't have
a decent sync mechanism between master and slave drivers. The
drivers each have their own driver pixmap/bo for their side
of the shared pixmap so nothing is available to synchronise
these. Ideally we'd have cross driver sync objects, but those
particular pigs can't fly yet.

In lieu of this glFinish is pretty close to the best thing
we have, it might be possible to use a glSyncObject to make
this a bit lighter, but for now lets try this.

This just causes glFinish to be called so the first driver
has written all its changes to the shared pixmap before the
second driver does things to its side of the shared pixmap.

This fixes a wierd lag, if you run X across two GPUs, and
then run xsetroot -solid and various values, the slave screens
end up a slot behind.

Signed-off-by: Dave Airlie <airlied at redhat.com>
---
 dix/pixmap.c                            | 13 +++++++++++++
 glamor/glamor.c                         |  9 +++++++++
 glamor/glamor.h                         |  1 +
 hw/xfree86/drivers/modesetting/driver.c | 11 +++++++++++
 include/pixmap.h                        |  3 +++
 include/scrnintstr.h                    |  4 ++++
 6 files changed, 41 insertions(+)

diff --git a/dix/pixmap.c b/dix/pixmap.c
index 11d83fe..a696c92 100644
--- a/dix/pixmap.c
+++ b/dix/pixmap.c
@@ -392,3 +392,16 @@ Bool PixmapSyncDirtyHelper(PixmapDirtyUpdatePtr dirty)
     pScreen->SourceValidate = SourceValidate;
     return TRUE;
 }
+
+void WaitSharedPixmap(PixmapPtr pSharedPix)
+{
+    ScreenPtr mscreen;
+    if (!pSharedPix->master_pixmap)
+        return;
+
+    mscreen = pSharedPix->master_pixmap->drawable.pScreen;
+    if (!mscreen->WaitSharedPixmap)
+        return;
+
+    mscreen->WaitSharedPixmap(pSharedPix->master_pixmap);
+}
diff --git a/glamor/glamor.c b/glamor/glamor.c
index e9c1d9e..f356ab1 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -808,3 +808,12 @@ glamor_name_from_pixmap(PixmapPtr pixmap, CARD16 *stride, CARD32 *size)
     }
     return -1;
 }
+
+void
+glamor_finish(ScreenPtr screen)
+{
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+
+    glamor_make_current(glamor_priv);
+    glFinish();
+}
diff --git a/glamor/glamor.h b/glamor/glamor.h
index a73e9ef..e27033a 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -336,6 +336,7 @@ extern _X_EXPORT void glamor_destroy_gc(GCPtr gc);
 extern Bool _X_EXPORT glamor_change_window_attributes(WindowPtr pWin, unsigned long mask);
 extern void _X_EXPORT glamor_copy_window(WindowPtr window, DDXPointRec old_origin, RegionPtr src_region);
 
+extern _X_EXPORT void glamor_finish(ScreenPtr screen);
 #define HAS_GLAMOR_TEXT 1
 
 #ifdef GLAMOR_FOR_XORG
diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
index 8f60eae..f5ef173 100644
--- a/hw/xfree86/drivers/modesetting/driver.c
+++ b/hw/xfree86/drivers/modesetting/driver.c
@@ -570,6 +570,7 @@ redisplay_dirty(ScreenPtr screen, PixmapDirtyUpdatePtr dirty)
 
         RegionRec pixregion;
 
+        WaitSharedPixmap(dirty->slave_dst);
         PixmapRegionInit(&pixregion, dirty->slave_dst);
         DamageRegionAppend(&dirty->slave_dst->drawable, &pixregion);
         PixmapSyncDirtyHelper(dirty);
@@ -1098,6 +1099,15 @@ SetMaster(ScrnInfoPtr pScrn)
     return ret == 0;
 }
 
+static void
+msWaitSharedPixmap(PixmapPtr pPixmap)
+{
+    ScreenPtr pScreen = pPixmap->drawable.pScreen;
+#ifdef GLAMOR_HAS_GBM
+    glamor_finish(pScreen);
+#endif
+}
+
 static Bool
 ScreenInit(ScreenPtr pScreen, int argc, char **argv)
 {
@@ -1217,6 +1227,7 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv)
     pScreen->SetSharedPixmapBacking = msSetSharedPixmapBacking;
     pScreen->StartPixmapTracking = PixmapStartDirtyTracking;
     pScreen->StopPixmapTracking = PixmapStopDirtyTracking;
+    pScreen->WaitSharedPixmap = msWaitSharedPixmap;
 
     if (!xf86CrtcScreenInit(pScreen))
         return FALSE;
diff --git a/include/pixmap.h b/include/pixmap.h
index c6a7736..c1fc033 100644
--- a/include/pixmap.h
+++ b/include/pixmap.h
@@ -130,4 +130,7 @@ PixmapStopDirtyTracking(PixmapPtr src, PixmapPtr slave_dst);
 extern _X_EXPORT Bool
 PixmapSyncDirtyHelper(PixmapDirtyUpdatePtr dirty);
 
+extern _X_EXPORT void
+WaitSharedPixmap(PixmapPtr pSharedPix);
+
 #endif                          /* PIXMAP_H */
diff --git a/include/scrnintstr.h b/include/scrnintstr.h
index 2e617c4..e808735 100644
--- a/include/scrnintstr.h
+++ b/include/scrnintstr.h
@@ -358,6 +358,8 @@ typedef WindowPtr (*XYToWindowProcPtr)(ScreenPtr pScreen,
 
 typedef int (*NameWindowPixmapProcPtr)(WindowPtr, PixmapPtr, CARD32);
 
+typedef void (*WaitSharedPixmapProcPtr)(PixmapPtr);
+
 /* Wrapping Screen procedures
 
    There are a few modules in the X server which dynamically add and
@@ -610,6 +612,8 @@ typedef struct _Screen {
 
     ReplaceScanoutPixmapProcPtr ReplaceScanoutPixmap;
     XYToWindowProcPtr XYToWindow;
+
+    WaitSharedPixmapProcPtr WaitSharedPixmap;
 } ScreenRec;
 
 static inline RegionPtr
-- 
2.5.0



More information about the xorg-devel mailing list