[PATCH xserver 8/9] Add fence sync driver interface
James Jones
jajones at nvidia.com
Tue Sep 21 16:32:18 PDT 2010
-Add devPrivates to fence sync objects.
-Add a X sync module screen private
-Add wrappable functions to create and destroy
fence sync objects
-Give fence sync objects wrappable functions to
trigger, test, and reset their 'triggered' value.
-Give fence sync objects wrappable functions to
notify driver when adding/removing triggers to/
from the sync object.
Signed-off-by: James Jones <jajones at nvidia.com>
Reviewed-by: Aaron Plattner <aplattner at nvidia.com>
Reviewed-by: Robert Morell <rmorell at nvidia.com>
---
Xext/sync.c | 38 +++++++----
dix/privates.c | 1 +
hw/xfree86/loader/sdksyms.sh | 3 +
include/privates.h | 1 +
miext/X/misync.c | 147 +++++++++++++++++++++++++++++++++++++++++-
miext/X/misync.h | 43 ++++++++++++-
miext/X/misyncstr.h | 6 +-
7 files changed, 222 insertions(+), 17 deletions(-)
diff --git a/Xext/sync.c b/Xext/sync.c
index 644bdd7..f9fe339 100644
--- a/Xext/sync.c
+++ b/Xext/sync.c
@@ -59,7 +59,7 @@ PERFORMANCE OF THIS SOFTWARE.
#include <X11/X.h>
#include <X11/Xproto.h>
#include <X11/Xmd.h>
-#include "misc.h"
+#include "scrnintstr.h"
#include "os.h"
#include "extnsionst.h"
#include "dixstruct.h"
@@ -187,6 +187,9 @@ SyncDeleteTriggerFromSyncObject(SyncTrigger *pTrigger)
if (IsSystemCounter(pCounter))
SyncComputeBracketValues(pCounter);
+ } else if (SYNC_FENCE == pTrigger->pSync->type) {
+ SyncFence* pFence = (SyncFence*) pTrigger->pSync;
+ pFence->funcs.DeleteTrigger(pTrigger);
}
}
@@ -220,6 +223,9 @@ SyncAddTriggerToSyncObject(SyncTrigger *pTrigger)
if (IsSystemCounter(pCounter))
SyncComputeBracketValues(pCounter);
+ } else if (SYNC_FENCE == pTrigger->pSync->type) {
+ SyncFence* pFence = (SyncFence*) pTrigger->pSync;
+ pFence->funcs.AddTrigger(pTrigger);
}
return Success;
@@ -294,10 +300,11 @@ SyncCheckTriggerNegativeTransition(SyncTrigger *pTrigger, CARD64 oldval)
static Bool
SyncCheckTriggerFence(SyncTrigger *pTrigger, CARD64 unused)
{
+ SyncFence* pFence = (SyncFence*) pTrigger->pSync;
(void)unused;
- return (pTrigger->pSync == NULL ||
- ((SyncFence *)pTrigger->pSync)->triggered);
+ return (pFence == NULL ||
+ pFence->funcs.CheckTriggered(pFence));
}
static int
@@ -910,22 +917,22 @@ SyncCreate(ClientPtr client, XID id, unsigned char type)
{
SyncObject *pSync;
RESTYPE resType;
- unsigned long syncSize;
switch (type) {
case SYNC_COUNTER:
resType = RTCounter;
- syncSize = sizeof(SyncCounter);
+ pSync = malloc(sizeof(SyncCounter));
break;
case SYNC_FENCE:
resType = RTFence;
- syncSize = sizeof(SyncFence);
+ pSync = (SyncObject *)dixAllocateObjectWithPrivates(SyncFence,
+ PRIVATE_SYNC_FENCE);
break;
default:
return NULL;
}
- if (!(pSync = (SyncObject *)malloc(syncSize)))
+ if (!pSync)
return NULL;
if (!AddResource(id, resType, (pointer) pSync))
@@ -1951,8 +1958,7 @@ ProcSyncCreateFence(ClientPtr client)
SYNC_FENCE)))
return BadAlloc;
- pFence->pScreen = pDraw->pScreen;
- pFence->triggered = stuff->initially_triggered;
+ miSyncInitFence(pDraw->pScreen, pFence, stuff->initially_triggered);
return client->noClientException;
}
@@ -1972,7 +1978,9 @@ FreeFence(void *obj, XID id)
free(ptl); /* destroy the trigger list as we go */
}
- free(pFence);
+ miSyncDestroyFence(pFence);
+
+ dixFreeObjectWithPrivates(pFence, PRIVATE_SYNC_FENCE);
return Success;
}
@@ -2022,10 +2030,10 @@ ProcSyncResetFence(ClientPtr client)
if (rc != Success)
return rc;
- if (pFence->triggered != TRUE)
+ if (pFence->funcs.CheckTriggered(pFence) != TRUE)
return BadMatch;
- pFence->triggered = FALSE;
+ pFence->funcs.Reset(pFence);
return client->noClientException;
}
@@ -2067,7 +2075,7 @@ ProcSyncQueryFence(ClientPtr client)
rep.length = 0;
rep.sequenceNumber = client->sequence;
- rep.triggered = pFence->triggered;
+ rep.triggered = pFence->funcs.CheckTriggered(pFence);
if (client->swapped)
{
@@ -2597,6 +2605,10 @@ void
SyncExtensionInit(void)
{
ExtensionEntry *extEntry;
+ int s;
+
+ for (s = 0; s < screenInfo.numScreens; s++)
+ miSyncSetup(screenInfo.screens[s]);
if (RTCounter == 0)
{
diff --git a/dix/privates.c b/dix/privates.c
index 17e1050..9b55508 100644
--- a/dix/privates.c
+++ b/dix/privates.c
@@ -440,6 +440,7 @@ static const char *key_names[PRIVATE_LAST] = {
[PRIVATE_GLYPH] = "GLYPH",
[PRIVATE_GLYPHSET] = "GLYPHSET",
[PRIVATE_PICTURE] = "PICTURE",
+ [PRIVATE_SYNC_FENCE] = "SYNC_FENCE",
};
void
diff --git a/hw/xfree86/loader/sdksyms.sh b/hw/xfree86/loader/sdksyms.sh
index 6ca368e..060663c 100755
--- a/hw/xfree86/loader/sdksyms.sh
+++ b/hw/xfree86/loader/sdksyms.sh
@@ -42,6 +42,9 @@ cat > sdksyms.c << EOF
#include "damage.h"
#include "damagestr.h"
+/* miext/X/Makefile.am */
+#include "misync.h"
+#include "misyncstr.h"
/* Xext/Makefile.am -- half is module, half is builtin */
/*
diff --git a/include/privates.h b/include/privates.h
index d3c0e13..e750b6d 100644
--- a/include/privates.h
+++ b/include/privates.h
@@ -51,6 +51,7 @@ typedef enum {
PRIVATE_GLYPH,
PRIVATE_GLYPHSET,
PRIVATE_PICTURE,
+ PRIVATE_SYNC_FENCE,
/* last private type */
PRIVATE_LAST,
diff --git a/miext/X/misync.c b/miext/X/misync.c
index c0ee13d..03665ac 100644
--- a/miext/X/misync.c
+++ b/miext/X/misync.c
@@ -21,16 +21,115 @@
* DEALINGS IN THE SOFTWARE.
*/
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "scrnintstr.h"
#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;
+
+/* Default implementations of the sync screen functions */
+void
+miSyncScreenCreateFence(ScreenPtr pScreen, SyncFence* pFence,
+ Bool initially_triggered)
+{
+ (void)pScreen;
+
+ pFence->triggered = initially_triggered;
+}
+
+void miSyncScreenDestroyFence(ScreenPtr pScreen, SyncFence* pFence)
+{
+ (void)pScreen;
+ (void)pFence;
+}
+
+/* Default implementations of the per-object functions */
+static void
+miSyncFenceSetTriggered(SyncFence* pFence)
+{
+ pFence->triggered = TRUE;
+}
+
+static void
+miSyncFenceReset(SyncFence* pFence)
+{
+ pFence->triggered = FALSE;
+}
+
+static Bool
+miSyncFenceCheckTriggered(SyncFence* pFence)
+{
+ return pFence->triggered;
+}
+
+static void
+miSyncFenceAddTrigger(SyncTrigger* pTrigger)
+{
+ (void)pTrigger;
+
+ return;
+}
+
+static void
+miSyncFenceDeleteTrigger(SyncTrigger* pTrigger)
+{
+ (void)pTrigger;
+
+ return;
+}
+
+/* Machine independent portion of the fence sync object implementation */
+void
+miSyncInitFence(ScreenPtr pScreen, SyncFence* pFence, Bool initially_triggered)
+{
+ SyncScreenPrivPtr pScreenPriv = SYNC_SCREEN_PRIV(pScreen);
+ static const SyncFenceFuncsRec miSyncFenceFuncs = {
+ &miSyncFenceSetTriggered,
+ &miSyncFenceReset,
+ &miSyncFenceCheckTriggered,
+ &miSyncFenceAddTrigger,
+ &miSyncFenceDeleteTrigger
+ };
+
+ pFence->pScreen = pScreen;
+ pFence->funcs = miSyncFenceFuncs;
+
+ pScreenPriv->funcs.CreateFence(pScreen, pFence, initially_triggered);
+}
+
+void
+miSyncDestroyFence(SyncFence* pFence)
+{
+ ScreenPtr pScreen = pFence->pScreen;
+ SyncScreenPrivPtr pScreenPriv = SYNC_SCREEN_PRIV(pScreen);
+
+ pScreenPriv->funcs.DestroyFence(pScreen, pFence);
+}
+
void
miSyncTriggerFence(SyncFence* pFence)
{
SyncTriggerList *ptl, *pNext;
CARD64 unused;
- pFence->triggered = TRUE;
+ pFence->funcs.SetTriggered(pFence);
XSyncIntToValue(&unused, 0L);
@@ -42,3 +141,49 @@ miSyncTriggerFence(SyncFence* pFence)
(*ptl->pTrigger->TriggerFired)(ptl->pTrigger);
}
}
+
+SyncScreenFuncsPtr miSyncGetScreenFuncs(ScreenPtr pScreen)
+{
+ SyncScreenPrivPtr pScreenPriv = SYNC_SCREEN_PRIV(pScreen);
+
+ return &pScreenPriv->funcs;
+}
+
+static Bool
+SyncCloseScreen (int i, ScreenPtr pScreen)
+{
+ SyncScreenPrivPtr pScreenPriv = SYNC_SCREEN_PRIV(pScreen);
+
+ pScreen->CloseScreen = pScreenPriv->CloseScreen;
+ free(pScreenPriv);
+
+ return (*pScreen->CloseScreen) (i, pScreen);
+}
+
+Bool
+miSyncSetup(ScreenPtr pScreen)
+{
+ SyncScreenPrivPtr pScreenPriv;
+
+ static const SyncScreenFuncsRec miSyncScreenFuncs = {
+ &miSyncScreenCreateFence,
+ &miSyncScreenDestroyFence
+ };
+
+ if (dixPrivateKeyRegistered(syncScreenPrivateKey))
+ return TRUE;
+
+ if (!dixRegisterPrivateKey(syncScreenPrivateKey, PRIVATE_SCREEN,
+ sizeof(SyncScreenPrivRec)))
+ return FALSE;
+
+ pScreenPriv = SYNC_SCREEN_PRIV(pScreen);
+
+ pScreenPriv->funcs = miSyncScreenFuncs;
+
+ /* Wrap CloseScreen to clean up */
+ pScreenPriv->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = SyncCloseScreen;
+
+ return TRUE;
+}
diff --git a/miext/X/misync.h b/miext/X/misync.h
index d3e52f5..1c82ea5 100644
--- a/miext/X/misync.h
+++ b/miext/X/misync.h
@@ -29,8 +29,49 @@
#define _MISYNC_H_
typedef struct _SyncFence SyncFence;
+typedef struct _SyncTrigger SyncTrigger;
-extern void
+typedef void (*SyncScreenCreateFenceFunc) (ScreenPtr pScreen,
+ SyncFence* pFence,
+ Bool initially_triggered);
+typedef void (*SyncScreenDestroyFenceFunc) (ScreenPtr pScreen,
+ SyncFence* pFence);
+
+typedef struct _syncScreenFuncs {
+ SyncScreenCreateFenceFunc CreateFence;
+ SyncScreenDestroyFenceFunc DestroyFence;
+} SyncScreenFuncsRec, *SyncScreenFuncsPtr;
+
+extern _X_EXPORT void
+miSyncScreenCreateFence(ScreenPtr pScreen, SyncFence* pFence,
+ Bool initially_triggered);
+extern _X_EXPORT void
+miSyncScreenDestroyFence(ScreenPtr pScreen, SyncFence* pFence);
+
+typedef void (*SyncFenceSetTriggeredFunc) (SyncFence* pFence);
+typedef void (*SyncFenceResetFunc) (SyncFence* pFence);
+typedef Bool (*SyncFenceCheckTriggeredFunc) (SyncFence* pFence);
+typedef void (*SyncFenceAddTriggerFunc) (SyncTrigger* pTrigger);
+typedef void (*SyncFenceDeleteTriggerFunc) (SyncTrigger* pTrigger);
+
+typedef struct _syncFenceFuncs {
+ SyncFenceSetTriggeredFunc SetTriggered;
+ SyncFenceResetFunc Reset;
+ SyncFenceCheckTriggeredFunc CheckTriggered;
+ SyncFenceAddTriggerFunc AddTrigger;
+ SyncFenceDeleteTriggerFunc DeleteTrigger;
+} SyncFenceFuncsRec, *SyncFenceFuncsPtr;
+
+extern _X_EXPORT void
+miSyncInitFence(ScreenPtr pScreen, SyncFence* pFence, Bool initially_triggered);
+extern _X_EXPORT void
+miSyncDestroyFence(SyncFence* pFence);
+extern _X_EXPORT void
miSyncTriggerFence(SyncFence* pFence);
+extern _X_EXPORT SyncScreenFuncsPtr
+miSyncGetScreenFuncs(ScreenPtr pScreen);
+extern _X_EXPORT Bool
+miSyncSetup(ScreenPtr pScreen);
+
#endif /* _MISYNC_H_ */
diff --git a/miext/X/misyncstr.h b/miext/X/misyncstr.h
index 90a17ac..da09964 100644
--- a/miext/X/misyncstr.h
+++ b/miext/X/misyncstr.h
@@ -54,10 +54,12 @@ typedef struct _SyncCounter {
struct _SyncFence {
SyncObject sync; /* Common sync object data */
ScreenPtr pScreen; /* Screen of this fence object */
+ SyncFenceFuncsRec funcs; /* Funcs for performing ops on fence */
Bool triggered; /* fence state */
+ PrivateRec *devPrivates; /* driver-specific per-fence data */
};
-typedef struct _SyncTrigger {
+struct _SyncTrigger {
SyncObject *pSync;
CARD64 wait_value; /* wait value */
unsigned int value_type; /* Absolute or Relative */
@@ -73,7 +75,7 @@ typedef struct _SyncTrigger {
void (*CounterDestroyed)(
struct _SyncTrigger * /*pTrigger*/
);
-} SyncTrigger;
+};
typedef struct _SyncTriggerList {
SyncTrigger *pTrigger;
--
1.7.1
More information about the xorg-devel
mailing list