From 1c4a0db2c6bf0320cb630b84ab87bcfd3801a53d Mon Sep 17 00:00:00 2001 From: James Jones Date: Mon, 28 Jun 2010 16:10:13 -0700 Subject: Add fence sync driver interface -Add fence sync objects -Add fence sync devPrivates -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 Reviewed-by: Keith Packard --- miext/sync/misync.c | 176 +++++++++++++++++++++++++++++++++++++++++++++++++ miext/sync/misync.h | 46 +++++++++++++ miext/sync/misyncstr.h | 13 +++- 3 files changed, 233 insertions(+), 2 deletions(-) (limited to 'miext') diff --git a/miext/sync/misync.c b/miext/sync/misync.c index 344810f56..bcc68a2bb 100644 --- a/miext/sync/misync.c +++ b/miext/sync/misync.c @@ -21,5 +21,181 @@ * DEALINGS IN THE SOFTWARE. */ +#ifdef HAVE_DIX_CONFIG_H +#include +#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); + SyncTriggerList *ptl, *pNext; + + pFence->sync.beingDestroyed = TRUE; + /* tell all the fence's triggers that the counter has been destroyed */ + for (ptl = pFence->sync.pTriglist; ptl; ptl = pNext) + { + (*ptl->pTrigger->CounterDestroyed)(ptl->pTrigger); + pNext = ptl->next; + free(ptl); /* destroy the trigger list as we go */ + } + + pScreenPriv->funcs.DestroyFence(pScreen, pFence); + + dixFreeObjectWithPrivates(pFence, PRIVATE_SYNC_FENCE); +} + +void +miSyncTriggerFence(SyncFence* pFence) +{ + SyncTriggerList *ptl, *pNext; + CARD64 unused; + + pFence->funcs.SetTriggered(pFence); + + XSyncIntToValue(&unused, 0L); + + /* run through triggers to see if any fired */ + for (ptl = pFence->sync.pTriglist; ptl; ptl = pNext) + { + pNext = ptl->next; + if ((*ptl->pTrigger->CheckTrigger)(ptl->pTrigger, unused)) + (*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 c66be8d82..1c82ea516 100644 --- a/miext/sync/misync.h +++ b/miext/sync/misync.h @@ -28,4 +28,50 @@ #ifndef _MISYNC_H_ #define _MISYNC_H_ +typedef struct _SyncFence SyncFence; +typedef struct _SyncTrigger SyncTrigger; + +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 eecf04f00..40a865c9c 100644 --- a/miext/sync/misyncstr.h +++ b/miext/sync/misyncstr.h @@ -35,6 +35,7 @@ /* Sync object types */ #define SYNC_COUNTER 0 +#define SYNC_FENCE 1 typedef struct _SyncObject { ClientPtr client; /* Owning client. 0 for system counters */ @@ -50,7 +51,15 @@ typedef struct _SyncCounter { struct _SysCounterInfo *pSysCounterInfo; /* NULL if not a system counter */ } SyncCounter; -typedef struct _SyncTrigger { +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 */ +}; + +struct _SyncTrigger { SyncObject *pSync; CARD64 wait_value; /* wait value */ unsigned int value_type; /* Absolute or Relative */ @@ -66,7 +75,7 @@ typedef struct _SyncTrigger { void (*CounterDestroyed)( struct _SyncTrigger * /*pTrigger*/ ); -} SyncTrigger; +}; typedef struct _SyncTriggerList { SyncTrigger *pTrigger; -- cgit v1.2.3