diff options
author | Dave Airlie <airlied@gmail.com> | 2016-02-09 16:42:33 +1000 |
---|---|---|
committer | Dave Airlie <airlied@gmail.com> | 2016-02-09 16:49:36 +1000 |
commit | bbc826578f17eb6bbf404162892483972de8cbfb (patch) | |
tree | 895ca64b90c2486559ded1709489094489e710e4 | |
parent | b0c7318ecc3e3817f8cf3519d229640a1ff73712 (diff) |
pixmap: add wait shared pixmapprime-fixes
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@redhat.com>
-rw-r--r-- | dix/pixmap.c | 13 | ||||
-rw-r--r-- | glamor/glamor.c | 9 | ||||
-rw-r--r-- | glamor/glamor.h | 1 | ||||
-rw-r--r-- | hw/xfree86/drivers/modesetting/driver.c | 11 | ||||
-rw-r--r-- | include/pixmap.h | 3 | ||||
-rw-r--r-- | include/scrnintstr.h | 4 |
6 files changed, 41 insertions, 0 deletions
diff --git a/dix/pixmap.c b/dix/pixmap.c index 11d83fe00..a696c92e4 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 e9c1d9ed3..f356ab1d2 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 a73e9eff0..e27033a84 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 8f60eae57..f5ef17387 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 c6a773649..c1fc033c0 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 2e617c466..e8087357f 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 |