diff options
author | Keith Packard <keithp@keithp.com> | 2013-04-09 19:59:39 -0700 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2013-10-31 16:58:30 -0700 |
commit | 563138298868f62501875d3016f03469dcffaad0 (patch) | |
tree | a63491ea60c8a0360351b0e163a8195ce22f697d /miext | |
parent | fdec793cdc2ef9a6ea66b311cb1068a7bd4a3be3 (diff) |
dri3: Add DRI3 extension
Adds DRM compatible fences using futexes.
Uses FD passing to get pixmaps from DRM applications.
Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
Diffstat (limited to 'miext')
-rw-r--r-- | miext/sync/Makefile.am | 3 | ||||
-rw-r--r-- | miext/sync/misync.c | 29 | ||||
-rw-r--r-- | miext/sync/misync.h | 21 | ||||
-rw-r--r-- | miext/sync/misyncshm.c | 176 | ||||
-rw-r--r-- | miext/sync/misyncshm.h | 28 | ||||
-rw-r--r-- | miext/sync/misyncstr.h | 15 |
6 files changed, 250 insertions, 22 deletions
diff --git a/miext/sync/Makefile.am b/miext/sync/Makefile.am index 9aa1ba5d5..e25ceacb0 100644 --- a/miext/sync/Makefile.am +++ b/miext/sync/Makefile.am @@ -5,10 +5,11 @@ AM_CFLAGS = $(DIX_CFLAGS) AM_CPPFLAGS = if XORG -sdk_HEADERS = misync.h misyncstr.h +sdk_HEADERS = misync.h misyncstr.h misyncshm.h endif libsync_la_SOURCES = \ misync.c \ misync.h \ + misyncshm.c \ misyncstr.h diff --git a/miext/sync/misync.c b/miext/sync/misync.c index f38054754..3d03d1b59 100644 --- a/miext/sync/misync.c +++ b/miext/sync/misync.c @@ -29,20 +29,7 @@ #include "misync.h" #include "misyncstr.h" -static DevPrivateKeyRec syncScreenPrivateKeyRec; -static DevPrivateKey syncScreenPrivateKey = &syncScreenPrivateKeyRec; - -#define SYNC_SCREEN_PRIV(pScreen) \ - (SyncScreenPrivPtr) dixLookupPrivate(&pScreen->devPrivates, \ - syncScreenPrivateKey) - -typedef struct _syncScreenPriv { - /* Wrappable sync-specific screen functions */ - SyncScreenFuncsRec funcs; - - /* Wrapped screen functions */ - CloseScreenProcPtr CloseScreen; -} SyncScreenPrivRec, *SyncScreenPrivPtr; +DevPrivateKeyRec miSyncScreenPrivateKey; /* Default implementations of the sync screen functions */ void @@ -62,25 +49,25 @@ miSyncScreenDestroyFence(ScreenPtr pScreen, SyncFence * pFence) } /* Default implementations of the per-object functions */ -static void +void miSyncFenceSetTriggered(SyncFence * pFence) { pFence->triggered = TRUE; } -static void +void miSyncFenceReset(SyncFence * pFence) { pFence->triggered = FALSE; } -static Bool +Bool miSyncFenceCheckTriggered(SyncFence * pFence) { return pFence->triggered; } -static void +void miSyncFenceAddTrigger(SyncTrigger * pTrigger) { (void) pTrigger; @@ -88,7 +75,7 @@ miSyncFenceAddTrigger(SyncTrigger * pTrigger) return; } -static void +void miSyncFenceDeleteTrigger(SyncTrigger * pTrigger) { (void) pTrigger; @@ -182,8 +169,8 @@ miSyncSetup(ScreenPtr pScreen) &miSyncScreenDestroyFence }; - if (!dixPrivateKeyRegistered(syncScreenPrivateKey)) { - if (!dixRegisterPrivateKey(syncScreenPrivateKey, PRIVATE_SCREEN, + if (!dixPrivateKeyRegistered(&miSyncScreenPrivateKey)) { + if (!dixRegisterPrivateKey(&miSyncScreenPrivateKey, PRIVATE_SCREEN, sizeof(SyncScreenPrivRec))) return FALSE; } diff --git a/miext/sync/misync.h b/miext/sync/misync.h index deebb82bc..f63ec2b82 100644 --- a/miext/sync/misync.h +++ b/miext/sync/misync.h @@ -76,4 +76,25 @@ extern _X_EXPORT SyncScreenFuncsPtr miSyncGetScreenFuncs(ScreenPtr pScreen); extern _X_EXPORT Bool miSyncSetup(ScreenPtr pScreen); +Bool +miSyncFenceCheckTriggered(SyncFence * pFence); + +void +miSyncFenceSetTriggered(SyncFence * pFence); + +void +miSyncFenceReset(SyncFence * pFence); + +void +miSyncFenceAddTrigger(SyncTrigger * pTrigger); + +void +miSyncFenceDeleteTrigger(SyncTrigger * pTrigger); + +int +miSyncInitFenceFromFD(DrawablePtr pDraw, SyncFence *pFence, int fd, BOOL initially_triggered); + +int +miSyncFDFromFence(DrawablePtr pDraw, SyncFence *pFence); + #endif /* _MISYNC_H_ */ diff --git a/miext/sync/misyncshm.c b/miext/sync/misyncshm.c new file mode 100644 index 000000000..ddd15ae49 --- /dev/null +++ b/miext/sync/misyncshm.c @@ -0,0 +1,176 @@ +/* + * Copyright © 2013 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "scrnintstr.h" +#include "misync.h" +#include "misyncstr.h" +#include "misyncshm.h" +#include "pixmapstr.h" +#include <sys/mman.h> +#include <unistd.h> +#include <X11/xshmfence.h> + +static DevPrivateKeyRec syncShmFencePrivateKey; + +typedef struct _SyncShmFencePrivate { + int32_t *fence; + int fd; +} SyncShmFencePrivateRec, *SyncShmFencePrivatePtr; + +#define SYNC_FENCE_PRIV(pFence) \ + (SyncShmFencePrivatePtr) dixLookupPrivate(&pFence->devPrivates, &syncShmFencePrivateKey) + +static void +miSyncShmFenceSetTriggered(SyncFence * pFence) +{ + SyncShmFencePrivatePtr pPriv = SYNC_FENCE_PRIV(pFence); + + if (pPriv->fence) + xshmfence_trigger(pPriv->fence); + miSyncFenceSetTriggered(pFence); +} + +static void +miSyncShmFenceReset(SyncFence * pFence) +{ + SyncShmFencePrivatePtr pPriv = SYNC_FENCE_PRIV(pFence); + + if (pPriv->fence) + xshmfence_reset(pPriv->fence); + miSyncFenceReset(pFence); +} + +static Bool +miSyncShmFenceCheckTriggered(SyncFence * pFence) +{ + SyncShmFencePrivatePtr pPriv = SYNC_FENCE_PRIV(pFence); + + if (pPriv->fence) + return xshmfence_query(pPriv->fence); + else + return miSyncFenceCheckTriggered(pFence); +} + +static void +miSyncShmFenceAddTrigger(SyncTrigger * pTrigger) +{ + miSyncFenceAddTrigger(pTrigger); +} + +static void +miSyncShmFenceDeleteTrigger(SyncTrigger * pTrigger) +{ + miSyncFenceDeleteTrigger(pTrigger); +} + +static const SyncFenceFuncsRec miSyncShmFenceFuncs = { + &miSyncShmFenceSetTriggered, + &miSyncShmFenceReset, + &miSyncShmFenceCheckTriggered, + &miSyncShmFenceAddTrigger, + &miSyncShmFenceDeleteTrigger +}; + +static void +miSyncShmScreenCreateFence(ScreenPtr pScreen, SyncFence * pFence, + Bool initially_triggered) +{ + SyncShmFencePrivatePtr pPriv = SYNC_FENCE_PRIV(pFence); + + pPriv->fence = NULL; + miSyncScreenCreateFence(pScreen, pFence, initially_triggered); + pFence->funcs = miSyncShmFenceFuncs; +} + +static void +miSyncShmScreenDestroyFence(ScreenPtr pScreen, SyncFence * pFence) +{ + SyncShmFencePrivatePtr pPriv = SYNC_FENCE_PRIV(pFence); + + if (pPriv->fence) { + xshmfence_trigger(pPriv->fence); + xshmfence_unmap_shm(pPriv->fence); + close(pPriv->fd); + } + miSyncScreenDestroyFence(pScreen, pFence); +} + +int +miSyncInitFenceFromFD(DrawablePtr pDraw, SyncFence *pFence, int fd, BOOL initially_triggered) + +{ + SyncShmFencePrivatePtr pPriv = SYNC_FENCE_PRIV(pFence); + + miSyncInitFence(pDraw->pScreen, pFence, initially_triggered); + + pPriv->fence = xshmfence_map_shm(fd); + if (pPriv->fence) { + pPriv->fd = fd; + return Success; + } + else + close(fd); + return BadValue; +} + +int +miSyncFDFromFence(DrawablePtr pDraw, SyncFence *pFence) +{ + SyncShmFencePrivatePtr pPriv = SYNC_FENCE_PRIV(pFence); + + if (!pPriv->fence) { + pPriv->fd = xshmfence_alloc_shm(); + if (pPriv->fd < 0) + return -1; + pPriv->fence = xshmfence_map_shm(pPriv->fd); + if (!pPriv->fence) { + close (pPriv->fd); + return -1; + } + } + return pPriv->fd; +} + +_X_EXPORT Bool miSyncShmScreenInit(ScreenPtr pScreen) +{ + SyncScreenFuncsPtr funcs; + + if (!miSyncSetup(pScreen)) + return FALSE; + + if (!dixPrivateKeyRegistered(&syncShmFencePrivateKey)) { + if (!dixRegisterPrivateKey(&syncShmFencePrivateKey, PRIVATE_SYNC_FENCE, + sizeof(SyncShmFencePrivateRec))) + return FALSE; + } + + funcs = miSyncGetScreenFuncs(pScreen); + + funcs->CreateFence = miSyncShmScreenCreateFence; + funcs->DestroyFence = miSyncShmScreenDestroyFence; + return TRUE; +} + diff --git a/miext/sync/misyncshm.h b/miext/sync/misyncshm.h new file mode 100644 index 000000000..4edbb50c3 --- /dev/null +++ b/miext/sync/misyncshm.h @@ -0,0 +1,28 @@ +/* + * Copyright © 2013 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef _MISYNCSHM_H_ +#define _MISYNCSYM_H_ + +extern _X_EXPORT Bool miSyncShmScreenInit(ScreenPtr pScreen); + +#endif /* _MISYNCSHM_H_ */ diff --git a/miext/sync/misyncstr.h b/miext/sync/misyncstr.h index e19256fee..b5bf6fd91 100644 --- a/miext/sync/misyncstr.h +++ b/miext/sync/misyncstr.h @@ -29,6 +29,7 @@ #define _MISYNCSTR_H_ #include "dix.h" +#include "scrnintstr.h" #include <X11/extensions/syncconst.h> #define CARD64 XSyncValue /* XXX temporary! need real 64 bit values for Alpha */ @@ -79,4 +80,18 @@ typedef struct _SyncTriggerList { struct _SyncTriggerList *next; } SyncTriggerList; +extern DevPrivateKeyRec miSyncScreenPrivateKey; + +#define SYNC_SCREEN_PRIV(pScreen) \ + (SyncScreenPrivPtr) dixLookupPrivate(&pScreen->devPrivates, \ + &miSyncScreenPrivateKey) + +typedef struct _syncScreenPriv { + /* Wrappable sync-specific screen functions */ + SyncScreenFuncsRec funcs; + + /* Wrapped screen functions */ + CloseScreenProcPtr CloseScreen; +} SyncScreenPrivRec, *SyncScreenPrivPtr; + #endif /* _MISYNCSTR_H_ */ |