[PATCH xserver (v3) 09/10] Add fence sync driver interface

James Jones jajones at nvidia.com
Sun Dec 5 19:25:34 PST 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>
Reviewed-by: Adam Jackson <ajax at redhat.com>
---
 Xext/sync.c                  |   38 +++++++----
 dix/privates.c               |    1 +
 hw/xfree86/loader/sdksyms.sh |    3 +
 include/privates.h           |    1 +
 miext/sync/misync.c          |  147 +++++++++++++++++++++++++++++++++++++++++-
 miext/sync/misync.h          |   43 ++++++++++++-
 miext/sync/misyncstr.h       |    6 +-
 7 files changed, 222 insertions(+), 17 deletions(-)

diff --git a/Xext/sync.c b/Xext/sync.c
index 9b087f6..3ca4d68 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"
@@ -145,6 +145,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);
     }
 }
 
@@ -178,6 +181,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;
@@ -252,10 +258,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
@@ -868,22 +875,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))
@@ -1909,8 +1916,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;
 }
@@ -1930,7 +1936,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;
 }
@@ -1980,10 +1988,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;
 }
@@ -2025,7 +2033,7 @@ ProcSyncQueryFence(ClientPtr client)
     rep.length = 0;
     rep.sequenceNumber = client->sequence;
 
-    rep.triggered = pFence->triggered;
+    rep.triggered = pFence->funcs.CheckTriggered(pFence);
 
     if (client->swapped)
     {
@@ -2555,6 +2563,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 687fa7a..d651258 100644
--- a/dix/privates.c
+++ b/dix/privates.c
@@ -447,6 +447,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 4b3ed86..2135430 100755
--- a/hw/xfree86/loader/sdksyms.sh
+++ b/hw/xfree86/loader/sdksyms.sh
@@ -41,6 +41,9 @@ cat > sdksyms.c << EOF
 #include "damage.h"
 #include "damagestr.h"
 
+/* miext/sync/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 9fb6ae8..7ef2cb7 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/sync/misync.c b/miext/sync/misync.c
index c0ee13d..03665ac 100644
--- a/miext/sync/misync.c
+++ b/miext/sync/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/sync/misync.h b/miext/sync/misync.h
index d3e52f5..1c82ea5 100644
--- a/miext/sync/misync.h
+++ b/miext/sync/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/sync/misyncstr.h b/miext/sync/misyncstr.h
index 050040b..40a865c 100644
--- a/miext/sync/misyncstr.h
+++ b/miext/sync/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