diff options
author | Keith Packard <keithp@keithp.com> | 2013-11-18 22:36:17 -0800 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2013-11-23 22:06:19 -0800 |
commit | f1604002a32b7f098c2a16b4a8649c694af570c8 (patch) | |
tree | 99c8cb3c402dacfe839ded18943e7ca68a0f59d0 | |
parent | 037566c57caff93fd7717f385d4b532b81f19c77 (diff) |
miext: Ensure xshmfence is only called when driver supports it
This provides a place for drivers to insert their own FD-based
SyncFence implementations, and prevents applications from using DRI3
SyncFence creation functions unless the driver has some support for
them.
Signed-off-by: Keith Packard <keithp@keithp.com>
Tested-by: Fredrik Höglund <fredrik@kde.org>
-rw-r--r-- | miext/sync/Makefile.am | 3 | ||||
-rw-r--r-- | miext/sync/misync.h | 2 | ||||
-rw-r--r-- | miext/sync/misyncfd.c | 99 | ||||
-rw-r--r-- | miext/sync/misyncfd.h | 45 | ||||
-rw-r--r-- | miext/sync/misyncshm.c | 21 | ||||
-rw-r--r-- | miext/sync/misyncshm.h | 2 |
6 files changed, 162 insertions, 10 deletions
diff --git a/miext/sync/Makefile.am b/miext/sync/Makefile.am index ac13c52e2..34961d5ff 100644 --- a/miext/sync/Makefile.am +++ b/miext/sync/Makefile.am @@ -5,7 +5,7 @@ AM_CFLAGS = $(DIX_CFLAGS) AM_CPPFLAGS = if XORG -sdk_HEADERS = misync.h misyncstr.h misyncshm.h +sdk_HEADERS = misync.h misyncstr.h misyncshm.h misyncfd.h endif XSHMFENCE_SRCS = misyncshm.c @@ -13,6 +13,7 @@ XSHMFENCE_SRCS = misyncshm.c libsync_la_SOURCES = \ misync.c \ misync.h \ + misyncfd.c \ misyncstr.h if XSHMFENCE diff --git a/miext/sync/misync.h b/miext/sync/misync.h index f63ec2b82..dc78c5fdb 100644 --- a/miext/sync/misync.h +++ b/miext/sync/misync.h @@ -42,8 +42,8 @@ typedef struct _syncScreenFuncs { SyncScreenDestroyFenceFunc DestroyFence; } SyncScreenFuncsRec, *SyncScreenFuncsPtr; -extern _X_EXPORT void +extern _X_EXPORT void miSyncScreenCreateFence(ScreenPtr pScreen, SyncFence * pFence, Bool initially_triggered); extern _X_EXPORT void diff --git a/miext/sync/misyncfd.c b/miext/sync/misyncfd.c new file mode 100644 index 000000000..93ff85fa8 --- /dev/null +++ b/miext/sync/misyncfd.c @@ -0,0 +1,99 @@ +/* + * 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 "misyncfd.h" +#include "pixmapstr.h" + +static DevPrivateKeyRec syncFdScreenPrivateKey; + +typedef struct _SyncFdScreenPrivate { + SyncFdScreenFuncsRec funcs; +} SyncFdScreenPrivateRec, *SyncFdScreenPrivatePtr; + +static inline SyncFdScreenPrivatePtr sync_fd_screen_priv(ScreenPtr pScreen) +{ + if (!dixPrivateKeyRegistered(&syncFdScreenPrivateKey)) + return NULL; + return dixLookupPrivate(&pScreen->devPrivates, &syncFdScreenPrivateKey); +} + +int +miSyncInitFenceFromFD(DrawablePtr pDraw, SyncFence *pFence, int fd, BOOL initially_triggered) + +{ + SyncFdScreenPrivatePtr priv = sync_fd_screen_priv(pDraw->pScreen); + + if (!priv) + return BadMatch; + + return (*priv->funcs.CreateFenceFromFd)(pDraw->pScreen, pFence, fd, initially_triggered); +} + +int +miSyncFDFromFence(DrawablePtr pDraw, SyncFence *pFence) +{ + SyncFdScreenPrivatePtr priv = sync_fd_screen_priv(pDraw->pScreen); + + if (!priv) + return -1; + + return (*priv->funcs.GetFenceFd)(pDraw->pScreen, pFence); +} + +_X_EXPORT Bool miSyncFdScreenInit(ScreenPtr pScreen, + const SyncFdScreenFuncsRec *funcs) +{ + SyncFdScreenPrivatePtr priv; + + /* Check to see if we've already been initialized */ + if (sync_fd_screen_priv(pScreen) != NULL) + return FALSE; + + if (!miSyncSetup(pScreen)) + return FALSE; + + if (!dixPrivateKeyRegistered(&syncFdScreenPrivateKey)) { + if (!dixRegisterPrivateKey(&syncFdScreenPrivateKey, PRIVATE_SCREEN, 0)) + return FALSE; + } + + priv = calloc(1, sizeof (SyncFdScreenPrivateRec)); + if (!priv) + return FALSE; + + /* Will require version checks when there are multiple versions + * of the funcs structure + */ + + priv->funcs = *funcs; + + dixSetPrivate(&pScreen->devPrivates, &syncFdScreenPrivateKey, priv); + + return TRUE; +} diff --git a/miext/sync/misyncfd.h b/miext/sync/misyncfd.h new file mode 100644 index 000000000..c1d05f948 --- /dev/null +++ b/miext/sync/misyncfd.h @@ -0,0 +1,45 @@ +/* + * 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 _MISYNCFD_H_ +#define _MISYNCFD_H_ + +typedef int (*SyncScreenCreateFenceFromFdFunc) (ScreenPtr screen, + SyncFence *fence, + int fd, + Bool initially_triggered); + +typedef int (*SyncScreenGetFenceFdFunc) (ScreenPtr screen, + SyncFence *fence); + +#define SYNC_FD_SCREEN_FUNCS_VERSION 1 + +typedef struct _syncFdScreenFuncs { + int version; + SyncScreenCreateFenceFromFdFunc CreateFenceFromFd; + SyncScreenGetFenceFdFunc GetFenceFd; +} SyncFdScreenFuncsRec, *SyncFdScreenFuncsPtr; + +extern _X_EXPORT Bool miSyncFdScreenInit(ScreenPtr pScreen, + const SyncFdScreenFuncsRec *funcs); + +#endif /* _MISYNCFD_H_ */ diff --git a/miext/sync/misyncshm.c b/miext/sync/misyncshm.c index ddd15ae49..3f9350af5 100644 --- a/miext/sync/misyncshm.c +++ b/miext/sync/misyncshm.c @@ -28,6 +28,7 @@ #include "misync.h" #include "misyncstr.h" #include "misyncshm.h" +#include "misyncfd.h" #include "pixmapstr.h" #include <sys/mman.h> #include <unistd.h> @@ -118,13 +119,12 @@ miSyncShmScreenDestroyFence(ScreenPtr pScreen, SyncFence * pFence) miSyncScreenDestroyFence(pScreen, pFence); } -int -miSyncInitFenceFromFD(DrawablePtr pDraw, SyncFence *pFence, int fd, BOOL initially_triggered) - +static int +miSyncShmCreateFenceFromFd(ScreenPtr pScreen, SyncFence *pFence, int fd, Bool initially_triggered) { SyncShmFencePrivatePtr pPriv = SYNC_FENCE_PRIV(pFence); - miSyncInitFence(pDraw->pScreen, pFence, initially_triggered); + miSyncInitFence(pScreen, pFence, initially_triggered); pPriv->fence = xshmfence_map_shm(fd); if (pPriv->fence) { @@ -136,8 +136,8 @@ miSyncInitFenceFromFD(DrawablePtr pDraw, SyncFence *pFence, int fd, BOOL initial return BadValue; } -int -miSyncFDFromFence(DrawablePtr pDraw, SyncFence *pFence) +static int +miSyncShmGetFenceFd(ScreenPtr pScreen, SyncFence *pFence) { SyncShmFencePrivatePtr pPriv = SYNC_FENCE_PRIV(pFence); @@ -154,11 +154,17 @@ miSyncFDFromFence(DrawablePtr pDraw, SyncFence *pFence) return pPriv->fd; } +static const SyncFdScreenFuncsRec miSyncShmScreenFuncs = { + .version = SYNC_FD_SCREEN_FUNCS_VERSION, + .CreateFenceFromFd = miSyncShmCreateFenceFromFd, + .GetFenceFd = miSyncShmGetFenceFd +}; + _X_EXPORT Bool miSyncShmScreenInit(ScreenPtr pScreen) { SyncScreenFuncsPtr funcs; - if (!miSyncSetup(pScreen)) + if (!miSyncFdScreenInit(pScreen, &miSyncShmScreenFuncs)) return FALSE; if (!dixPrivateKeyRegistered(&syncShmFencePrivateKey)) { @@ -171,6 +177,7 @@ _X_EXPORT Bool miSyncShmScreenInit(ScreenPtr pScreen) funcs->CreateFence = miSyncShmScreenCreateFence; funcs->DestroyFence = miSyncShmScreenDestroyFence; + return TRUE; } diff --git a/miext/sync/misyncshm.h b/miext/sync/misyncshm.h index 4edbb50c3..23c001ab1 100644 --- a/miext/sync/misyncshm.h +++ b/miext/sync/misyncshm.h @@ -21,7 +21,7 @@ */ #ifndef _MISYNCSHM_H_ -#define _MISYNCSYM_H_ +#define _MISYNCSHM_H_ extern _X_EXPORT Bool miSyncShmScreenInit(ScreenPtr pScreen); |