diff --git a/COPYING b/COPYING index 3fb06b8df..3aad5faf6 100644 --- a/COPYING +++ b/COPYING @@ -14,7 +14,7 @@ Copyright © 2006-2007 Intel Corporation Copyright © 2006 Nokia Corporation Copyright © 2006-2008 Peter Hutterer Copyright © 2006 Adam Jackson -Copyright © 2009 NVIDIA Corporation +Copyright © 2009-2010 NVIDIA Corporation Copyright © 1999 Keith Packard Copyright © 2007-2009 Red Hat, Inc. Copyright © 2005-2008 Daniel Stone diff --git a/Xext/Makefile.am b/Xext/Makefile.am index e444fd08f..b6c95cb17 100644 --- a/Xext/Makefile.am +++ b/Xext/Makefile.am @@ -15,7 +15,7 @@ INCLUDES = -I$(top_srcdir)/hw/xfree86/dixmods/extmod AM_CFLAGS = $(DIX_CFLAGS) if XORG -sdk_HEADERS = xvdix.h xvmcext.h geext.h geint.h shmint.h +sdk_HEADERS = xvdix.h xvmcext.h geext.h geint.h shmint.h syncsdk.h endif # Sources always included in libXextbuiltin.la & libXext.la @@ -26,6 +26,7 @@ BUILTIN_SRCS = \ sleepuntil.c \ sleepuntil.h \ sync.c \ + syncsdk.h \ syncsrv.h \ xcmisc.c \ xtest.c diff --git a/Xext/sync.c b/Xext/sync.c index f23df6cb9..ce00755b4 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -59,14 +59,17 @@ PERFORMANCE OF THIS SOFTWARE. #include #include #include -#include "misc.h" +#include "scrnintstr.h" #include "os.h" #include "extnsionst.h" #include "dixstruct.h" +#include "pixmapstr.h" #include "resource.h" #include "opaque.h" #include #include "syncsrv.h" +#include "syncsdk.h" +#include "protocol-versions.h" #include #if !defined(WIN32) @@ -84,11 +87,12 @@ static RESTYPE RTCounter = 0; static RESTYPE RTAwait; static RESTYPE RTAlarm; static RESTYPE RTAlarmClient; +static RESTYPE RTFence; static int SyncNumSystemCounters = 0; static SyncCounter **SysCounterList = NULL; #define IsSystemCounter(pCounter) \ - (pCounter && (pCounter->client == NULL)) + (pCounter && (pCounter->sync.client == NULL)) /* these are all the alarm attributes that pertain to the alarm's trigger */ #define XSyncCAAllTrigger \ @@ -106,18 +110,19 @@ static void SyncInitIdleTime(void); * delete and add triggers on this list. */ static void -SyncDeleteTriggerFromCounter(SyncTrigger *pTrigger) +SyncDeleteTriggerFromSyncObject(SyncTrigger *pTrigger) { SyncTriggerList *pCur; SyncTriggerList *pPrev; + SyncCounter *pCounter; - /* pCounter needs to be stored in pTrigger before calling here. */ + /* pSync needs to be stored in pTrigger before calling here. */ - if (!pTrigger->pCounter) + if (!pTrigger->pSync) return; pPrev = NULL; - pCur = pTrigger->pCounter->pTriglist; + pCur = pTrigger->pSync->pTriglist; while (pCur) { @@ -126,7 +131,7 @@ SyncDeleteTriggerFromCounter(SyncTrigger *pTrigger) if (pPrev) pPrev->next = pCur->next; else - pTrigger->pCounter->pTriglist = pCur->next; + pTrigger->pSync->pTriglist = pCur->next; free(pCur); break; @@ -136,21 +141,30 @@ SyncDeleteTriggerFromCounter(SyncTrigger *pTrigger) pCur = pCur->next; } - if (IsSystemCounter(pTrigger->pCounter)) - SyncComputeBracketValues(pTrigger->pCounter); + if (SYNC_COUNTER == pTrigger->pSync->type) + { + pCounter = (SyncCounter *)pTrigger->pSync; + + if (IsSystemCounter(pCounter)) + SyncComputeBracketValues(pCounter); + } else if (SYNC_FENCE == pTrigger->pSync->type) { + SyncFence* pFence = (SyncFence*) pTrigger->pSync; + pFence->funcs.DeleteTrigger(pTrigger); + } } static int -SyncAddTriggerToCounter(SyncTrigger *pTrigger) +SyncAddTriggerToSyncObject(SyncTrigger *pTrigger) { SyncTriggerList *pCur; + SyncCounter *pCounter; - if (!pTrigger->pCounter) + if (!pTrigger->pSync) return Success; /* don't do anything if it's already there */ - for (pCur = pTrigger->pCounter->pTriglist; pCur; pCur = pCur->next) + for (pCur = pTrigger->pSync->pTriglist; pCur; pCur = pCur->next) { if (pCur->pTrigger == pTrigger) return Success; @@ -160,96 +174,137 @@ SyncAddTriggerToCounter(SyncTrigger *pTrigger) return BadAlloc; pCur->pTrigger = pTrigger; - pCur->next = pTrigger->pCounter->pTriglist; - pTrigger->pCounter->pTriglist = pCur; + pCur->next = pTrigger->pSync->pTriglist; + pTrigger->pSync->pTriglist = pCur; - if (IsSystemCounter(pTrigger->pCounter)) - SyncComputeBracketValues(pTrigger->pCounter); + if (SYNC_COUNTER == pTrigger->pSync->type) + { + pCounter = (SyncCounter *)pTrigger->pSync; + + if (IsSystemCounter(pCounter)) + SyncComputeBracketValues(pCounter); + } else if (SYNC_FENCE == pTrigger->pSync->type) { + SyncFence* pFence = (SyncFence*) pTrigger->pSync; + pFence->funcs.AddTrigger(pTrigger); + } return Success; } -/* Below are four possible functions that can be plugged into - * pTrigger->CheckTrigger, corresponding to the four possible - * test-types. These functions are called after the counter's - * value changes but are also passed the old counter value - * so they can inspect both the old and new values. - * (PositiveTransition and NegativeTransition need to see both - * pieces of information.) These functions return the truth value - * of the trigger. +/* Below are five possible functions that can be plugged into + * pTrigger->CheckTrigger for counter sync objects, corresponding to + * the four possible test-types, and the one possible function that + * can be plugged into pTrigger->CheckTrigger for fence sync objects. + * These functions are called after the sync object's state changes + * but are also passed the old state so they can inspect both the old + * and new values. (PositiveTransition and NegativeTransition need to + * see both pieces of information.) These functions return the truth + * value of the trigger. * - * All of them include the condition pTrigger->pCounter == NULL. - * This is because the spec says that a trigger with a counter value + * All of them include the condition pTrigger->pSync == NULL. + * This is because the spec says that a trigger with a sync value * of None is always TRUE. */ static Bool SyncCheckTriggerPositiveComparison(SyncTrigger *pTrigger, CARD64 oldval) { - return (pTrigger->pCounter == NULL || - XSyncValueGreaterOrEqual(pTrigger->pCounter->value, - pTrigger->test_value)); + SyncCounter *pCounter; + + assert(!pTrigger->pSync || (SYNC_COUNTER == pTrigger->pSync->type)); + pCounter = (SyncCounter *)pTrigger->pSync; + + return (pCounter == NULL || + XSyncValueGreaterOrEqual(pCounter->value, pTrigger->test_value)); } static Bool SyncCheckTriggerNegativeComparison(SyncTrigger *pTrigger, CARD64 oldval) { - return (pTrigger->pCounter == NULL || - XSyncValueLessOrEqual(pTrigger->pCounter->value, - pTrigger->test_value)); + SyncCounter *pCounter; + + assert(!pTrigger->pSync || (SYNC_COUNTER == pTrigger->pSync->type)); + pCounter = (SyncCounter *)pTrigger->pSync; + + return (pCounter == NULL || + XSyncValueLessOrEqual(pCounter->value, pTrigger->test_value)); } static Bool SyncCheckTriggerPositiveTransition(SyncTrigger *pTrigger, CARD64 oldval) { - return (pTrigger->pCounter == NULL || + SyncCounter *pCounter; + + assert(!pTrigger->pSync || (SYNC_COUNTER == pTrigger->pSync->type)); + pCounter = (SyncCounter *)pTrigger->pSync; + + return (pCounter == NULL || (XSyncValueLessThan(oldval, pTrigger->test_value) && - XSyncValueGreaterOrEqual(pTrigger->pCounter->value, - pTrigger->test_value))); + XSyncValueGreaterOrEqual(pCounter->value, pTrigger->test_value))); } static Bool SyncCheckTriggerNegativeTransition(SyncTrigger *pTrigger, CARD64 oldval) { - return (pTrigger->pCounter == NULL || + SyncCounter *pCounter; + + assert(!pTrigger->pSync || (SYNC_COUNTER == pTrigger->pSync->type)); + pCounter = (SyncCounter *)pTrigger->pSync; + + return (pCounter == NULL || (XSyncValueGreaterThan(oldval, pTrigger->test_value) && - XSyncValueLessOrEqual(pTrigger->pCounter->value, - pTrigger->test_value))); + XSyncValueLessOrEqual(pCounter->value, pTrigger->test_value))); +} + +static Bool +SyncCheckTriggerFence(SyncTrigger *pTrigger, CARD64 unused) +{ + SyncFence* pFence = (SyncFence*) pTrigger->pSync; + (void)unused; + + return (pFence == NULL || + pFence->funcs.CheckTriggered(pFence)); } static int -SyncInitTrigger(ClientPtr client, SyncTrigger *pTrigger, XSyncCounter counter, - Mask changes) +SyncInitTrigger(ClientPtr client, SyncTrigger *pTrigger, XID syncObject, + RESTYPE resType, Mask changes) { - SyncCounter *pCounter = pTrigger->pCounter; + SyncObject *pSync = pTrigger->pSync; + SyncCounter *pCounter = NULL; int rc; - Bool newcounter = FALSE; + Bool newSyncObject = FALSE; if (changes & XSyncCACounter) { - if (counter == None) - pCounter = NULL; - else if (Success != (rc = dixLookupResourceByType ((pointer *)&pCounter, - counter, RTCounter, client, DixReadAccess))) + if (syncObject == None) + pSync = NULL; + else if (Success != (rc = dixLookupResourceByType ((pointer *)&pSync, + syncObject, resType, client, DixReadAccess))) { - client->errorValue = counter; + client->errorValue = syncObject; return rc; } - if (pCounter != pTrigger->pCounter) + if (pSync != pTrigger->pSync) { /* new counter for trigger */ - SyncDeleteTriggerFromCounter(pTrigger); - pTrigger->pCounter = pCounter; - newcounter = TRUE; + SyncDeleteTriggerFromSyncObject(pTrigger); + pTrigger->pSync = pSync; + newSyncObject = TRUE; } } /* if system counter, ask it what the current value is */ - if (IsSystemCounter(pCounter)) + if (SYNC_COUNTER == pSync->type) { - (*pCounter->pSysCounterInfo->QueryValue) ((pointer) pCounter, - &pCounter->value); + pCounter = (SyncCounter *)pSync; + + if (IsSystemCounter(pCounter)) + { + (*pCounter->pSysCounterInfo->QueryValue) ((pointer) pCounter, + &pCounter->value); + } } if (changes & XSyncCAValueType) @@ -264,30 +319,38 @@ SyncInitTrigger(ClientPtr client, SyncTrigger *pTrigger, XSyncCounter counter, if (changes & XSyncCATestType) { - if (pTrigger->test_type != XSyncPositiveTransition && - pTrigger->test_type != XSyncNegativeTransition && - pTrigger->test_type != XSyncPositiveComparison && - pTrigger->test_type != XSyncNegativeComparison) - { - client->errorValue = pTrigger->test_type; - return BadValue; - } - /* select appropriate CheckTrigger function */ - switch (pTrigger->test_type) + if (SYNC_FENCE == pSync->type) { - case XSyncPositiveTransition: - pTrigger->CheckTrigger = SyncCheckTriggerPositiveTransition; - break; - case XSyncNegativeTransition: - pTrigger->CheckTrigger = SyncCheckTriggerNegativeTransition; - break; - case XSyncPositiveComparison: - pTrigger->CheckTrigger = SyncCheckTriggerPositiveComparison; - break; - case XSyncNegativeComparison: - pTrigger->CheckTrigger = SyncCheckTriggerNegativeComparison; - break; + pTrigger->CheckTrigger = SyncCheckTriggerFence; + } + else + { + if (pTrigger->test_type != XSyncPositiveTransition && + pTrigger->test_type != XSyncNegativeTransition && + pTrigger->test_type != XSyncPositiveComparison && + pTrigger->test_type != XSyncNegativeComparison) + { + client->errorValue = pTrigger->test_type; + return BadValue; + } + /* select appropriate CheckTrigger function */ + + switch (pTrigger->test_type) + { + case XSyncPositiveTransition: + pTrigger->CheckTrigger = SyncCheckTriggerPositiveTransition; + break; + case XSyncNegativeTransition: + pTrigger->CheckTrigger = SyncCheckTriggerNegativeTransition; + break; + case XSyncPositiveComparison: + pTrigger->CheckTrigger = SyncCheckTriggerPositiveComparison; + break; + case XSyncNegativeComparison: + pTrigger->CheckTrigger = SyncCheckTriggerNegativeComparison; + break; + } } } @@ -314,12 +377,12 @@ SyncInitTrigger(ClientPtr client, SyncTrigger *pTrigger, XSyncCounter counter, /* we wait until we're sure there are no errors before registering * a new counter on a trigger */ - if (newcounter) + if (newSyncObject) { - if ((rc = SyncAddTriggerToCounter(pTrigger)) != Success) + if ((rc = SyncAddTriggerToSyncObject(pTrigger)) != Success) return rc; } - else if (IsSystemCounter(pCounter)) + else if (pCounter && IsSystemCounter(pCounter)) { SyncComputeBracketValues(pCounter); } @@ -337,16 +400,21 @@ SyncSendAlarmNotifyEvents(SyncAlarm *pAlarm) SyncAlarmClientList *pcl; xSyncAlarmNotifyEvent ane; SyncTrigger *pTrigger = &pAlarm->trigger; + SyncCounter *pCounter; + + assert(!pTrigger->pSync || (SYNC_COUNTER == pTrigger->pSync->type)); + + pCounter = (SyncCounter *)pTrigger->pSync; UpdateCurrentTime(); ane.type = SyncEventBase + XSyncAlarmNotify; ane.kind = XSyncAlarmNotify; ane.alarm = pAlarm->alarm_id; - if (pTrigger->pCounter) + if (pTrigger->pSync && SYNC_COUNTER == pTrigger->pSync->type) { - ane.counter_value_hi = XSyncValueHigh32(pTrigger->pCounter->value); - ane.counter_value_lo = XSyncValueLow32(pTrigger->pCounter->value); + ane.counter_value_hi = XSyncValueHigh32(pCounter->value); + ane.counter_value_lo = XSyncValueLow32(pCounter->value); } else { /* XXX what else can we do if there's no counter? */ @@ -389,14 +457,25 @@ SyncSendCounterNotifyEvents(ClientPtr client, SyncAwait **ppAwait, SyncTrigger *pTrigger = &(*ppAwait)->trigger; pev->type = SyncEventBase + XSyncCounterNotify; pev->kind = XSyncCounterNotify; - pev->counter = pTrigger->pCounter->id; + pev->counter = pTrigger->pSync->id; pev->wait_value_lo = XSyncValueLow32(pTrigger->test_value); pev->wait_value_hi = XSyncValueHigh32(pTrigger->test_value); - pev->counter_value_lo = XSyncValueLow32(pTrigger->pCounter->value); - pev->counter_value_hi = XSyncValueHigh32(pTrigger->pCounter->value); + if (SYNC_COUNTER == pTrigger->pSync->type) + { + SyncCounter *pCounter = (SyncCounter *)pTrigger->pSync; + + pev->counter_value_lo = XSyncValueLow32(pCounter->value); + pev->counter_value_hi = XSyncValueHigh32(pCounter->value); + } + else + { + pev->counter_value_lo = 0; + pev->counter_value_hi = 0; + } + pev->time = currentTime.milliseconds; pev->count = num_events - i - 1; /* events remaining */ - pev->destroyed = pTrigger->pCounter->beingDestroyed; + pev->destroyed = pTrigger->pSync->beingDestroyed; } /* swapping will be taken care of by this */ WriteEventsToClient(client, num_events, (xEvent *)pEvents); @@ -414,7 +493,7 @@ SyncAlarmCounterDestroyed(SyncTrigger *pTrigger) pAlarm->state = XSyncAlarmInactive; SyncSendAlarmNotifyEvents(pAlarm); - pTrigger->pCounter = NULL; + pTrigger->pSync = NULL; } @@ -425,8 +504,12 @@ static void SyncAlarmTriggerFired(SyncTrigger *pTrigger) { SyncAlarm *pAlarm = (SyncAlarm *)pTrigger; + SyncCounter *pCounter; CARD64 new_test_value; + assert(!pTrigger->pSync || (SYNC_COUNTER == pTrigger->pSync->type)); + pCounter = (SyncCounter *)pTrigger->pSync; + /* no need to check alarm unless it's active */ if (pAlarm->state != XSyncAlarmActive) return; @@ -436,7 +519,7 @@ SyncAlarmTriggerFired(SyncTrigger *pTrigger) * no change is made to value (test-value) and the alarm * state is changed to Inactive before the event is generated." */ - if (pAlarm->trigger.pCounter == NULL + if (pCounter == NULL || (XSyncValueIsZero(pAlarm->delta) && (pAlarm->trigger.test_type == XSyncPositiveComparison || pAlarm->trigger.test_type == XSyncNegativeComparison))) @@ -449,6 +532,10 @@ SyncAlarmTriggerFired(SyncTrigger *pTrigger) Bool overflow; CARD64 oldvalue; SyncTrigger *paTrigger = &pAlarm->trigger; + SyncCounter *paCounter; + + assert(!paTrigger->pSync || (SYNC_COUNTER == paTrigger->pSync->type)); + paCounter = (SyncCounter *)pTrigger->pSync; /* "The alarm is updated by repeatedly adding delta to the * value of the trigger and re-initializing it until it @@ -464,7 +551,7 @@ SyncAlarmTriggerFired(SyncTrigger *pTrigger) pAlarm->delta, &overflow); } while (!overflow && (*paTrigger->CheckTrigger)(paTrigger, - paTrigger->pCounter->value)); + paCounter->value)); new_test_value = paTrigger->test_value; paTrigger->test_value = oldvalue; @@ -531,46 +618,51 @@ SyncAwaitTriggerFired(SyncTrigger *pTrigger) * always generated if the counter for one of the triggers is * destroyed." */ - if (pAwait->trigger.pCounter->beingDestroyed) + if (pAwait->trigger.pSync->beingDestroyed) { ppAwait[num_events++] = pAwait; continue; } - - /* "The difference between the counter and the test value is - * calculated by subtracting the test value from the value of - * the counter." - */ - XSyncValueSubtract(&diff, pAwait->trigger.pCounter->value, - pAwait->trigger.test_value, &overflow); - - /* "If the difference lies outside the range for an INT64, an - * event is not generated." - */ - if (overflow) - continue; - diffgreater = XSyncValueGreaterThan(diff, pAwait->event_threshold); - diffequal = XSyncValueEqual(diff, pAwait->event_threshold); - - /* "If the test-type is PositiveTransition or - * PositiveComparison, a CounterNotify event is generated if - * the difference is at least event-threshold. If the test-type - * is NegativeTransition or NegativeComparison, a CounterNotify - * event is generated if the difference is at most - * event-threshold." - */ - - if ( ((pAwait->trigger.test_type == XSyncPositiveComparison || - pAwait->trigger.test_type == XSyncPositiveTransition) - && (diffgreater || diffequal)) - || - ((pAwait->trigger.test_type == XSyncNegativeComparison || - pAwait->trigger.test_type == XSyncNegativeTransition) - && (!diffgreater) /* less or equal */ - ) - ) + + if (SYNC_COUNTER == pAwait->trigger.pSync->type) { - ppAwait[num_events++] = pAwait; + SyncCounter *pCounter = (SyncCounter *) pAwait->trigger.pSync; + + /* "The difference between the counter and the test value is + * calculated by subtracting the test value from the value of + * the counter." + */ + XSyncValueSubtract(&diff, pCounter->value, + pAwait->trigger.test_value, &overflow); + + /* "If the difference lies outside the range for an INT64, an + * event is not generated." + */ + if (overflow) + continue; + diffgreater = XSyncValueGreaterThan(diff, pAwait->event_threshold); + diffequal = XSyncValueEqual(diff, pAwait->event_threshold); + + /* "If the test-type is PositiveTransition or + * PositiveComparison, a CounterNotify event is generated if + * the difference is at least event-threshold. If the test-type + * is NegativeTransition or NegativeComparison, a CounterNotify + * event is generated if the difference is at most + * event-threshold." + */ + + if ( ((pAwait->trigger.test_type == XSyncPositiveComparison || + pAwait->trigger.test_type == XSyncPositiveTransition) + && (diffgreater || diffequal)) + || + ((pAwait->trigger.test_type == XSyncNegativeComparison || + pAwait->trigger.test_type == XSyncNegativeTransition) + && (!diffgreater) /* less or equal */ + ) + ) + { + ppAwait[num_events++] = pAwait; + } } } if (num_events) @@ -599,7 +691,7 @@ SyncChangeCounter(SyncCounter *pCounter, CARD64 newval) pCounter->value = newval; /* run through triggers to see if any become true */ - for (ptl = pCounter->pTriglist; ptl; ptl = pnext) + for (ptl = pCounter->sync.pTriglist; ptl; ptl = pnext) { pnext = ptl->next; if ((*ptl->pTrigger->CheckTrigger)(ptl->pTrigger, oldval)) @@ -691,7 +783,8 @@ SyncChangeAlarmAttributes(ClientPtr client, SyncAlarm *pAlarm, Mask mask, XSyncCounter counter; Mask origmask = mask; - counter = pAlarm->trigger.pCounter ? pAlarm->trigger.pCounter->id : None; + counter = + pAlarm->trigger.pSync ? pAlarm->trigger.pSync->id : None; while (mask) { @@ -771,7 +864,7 @@ SyncChangeAlarmAttributes(ClientPtr client, SyncAlarm *pAlarm, Mask mask, } /* postpone this until now, when we're sure nothing else can go wrong */ - if ((status = SyncInitTrigger(client, &pAlarm->trigger, counter, + if ((status = SyncInitTrigger(client, &pAlarm->trigger, counter, RTCounter, origmask & XSyncCAAllTrigger)) != Success) return status; @@ -780,26 +873,63 @@ SyncChangeAlarmAttributes(ClientPtr client, SyncAlarm *pAlarm, Mask mask, return Success; } +static SyncObject * +SyncCreate(ClientPtr client, XID id, unsigned char type) +{ + SyncObject *pSync; + RESTYPE resType; + + switch (type) { + case SYNC_COUNTER: + resType = RTCounter; + pSync = malloc(sizeof(SyncCounter)); + break; + case SYNC_FENCE: + resType = RTFence; + pSync = dixAllocateObjectWithPrivates(SyncFence, + PRIVATE_SYNC_FENCE); + break; + default: + return NULL; + } + + if (!pSync) + return NULL; + + if (!AddResource(id, resType, (pointer) pSync)) + { + switch (type) { + case SYNC_FENCE: + dixFreeObjectWithPrivates((SyncFence *)pSync, PRIVATE_SYNC_FENCE); + break; + default: + free(pSync); + } + + return NULL; + } + + pSync->client = client; + pSync->id = id; + pSync->pTriglist = NULL; + pSync->beingDestroyed = FALSE; + pSync->type = type; + + return pSync; +} + static SyncCounter * SyncCreateCounter(ClientPtr client, XSyncCounter id, CARD64 initialvalue) { SyncCounter *pCounter; - if (!(pCounter = malloc(sizeof(SyncCounter)))) + if (!(pCounter = (SyncCounter *)SyncCreate(client, + id, + SYNC_COUNTER))) return NULL; - if (!AddResource(id, RTCounter, (pointer) pCounter)) - { - free(pCounter); - return NULL; - } - - pCounter->client = client; - pCounter->id = id; pCounter->value = initialvalue; - pCounter->pTriglist = NULL; - pCounter->beingDestroyed = FALSE; pCounter->pSysCounterInfo = NULL; return pCounter; } @@ -851,7 +981,7 @@ SyncCreateSystemCounter( psci = malloc(sizeof(SysCounterInfo)); if (!psci) { - FreeResource(pCounter->id, RT_NONE); + FreeResource(pCounter->sync.id, RT_NONE); return pCounter; } pCounter->pSysCounterInfo = psci; @@ -871,7 +1001,7 @@ void SyncDestroySystemCounter(pointer pSysCounter) { SyncCounter *pCounter = (SyncCounter *)pSysCounter; - FreeResource(pCounter->id, RT_NONE); + FreeResource(pCounter->sync.id, RT_NONE); } static void @@ -895,7 +1025,7 @@ SyncComputeBracketValues(SyncCounter *pCounter) XSyncMaxValue(&psci->bracket_greater); XSyncMinValue(&psci->bracket_less); - for (pCur = pCounter->pTriglist; pCur; pCur = pCur->next) + for (pCur = pCounter->sync.pTriglist; pCur; pCur = pCur->next) { pTrigger = pCur->pTrigger; @@ -968,7 +1098,7 @@ FreeAlarm(void *addr, XID id) while (pAlarm->pEventClients) FreeResource(pAlarm->pEventClients->delete_id, RT_NONE); - SyncDeleteTriggerFromCounter(&pAlarm->trigger); + SyncDeleteTriggerFromSyncObject(&pAlarm->trigger); free(pAlarm); return Success; @@ -985,9 +1115,9 @@ FreeCounter(void *env, XID id) SyncCounter *pCounter = (SyncCounter *) env; SyncTriggerList *ptl, *pnext; - pCounter->beingDestroyed = TRUE; + pCounter->sync.beingDestroyed = TRUE; /* tell all the counter's triggers that the counter has been destroyed */ - for (ptl = pCounter->pTriglist; ptl; ptl = pnext) + for (ptl = pCounter->sync.pTriglist; ptl; ptl = pnext) { (*ptl->pTrigger->CounterDestroyed)(ptl->pTrigger); pnext = ptl->next; @@ -1046,9 +1176,9 @@ FreeAwait(void *addr, XID id) /* If the counter is being destroyed, FreeCounter will delete * the trigger list itself, so don't do it here. */ - SyncCounter *pCounter = pAwait->trigger.pCounter; - if (pCounter && !pCounter->beingDestroyed) - SyncDeleteTriggerFromCounter(&pAwait->trigger); + SyncObject *pSync = pAwait->trigger.pSync; + if (pSync && !pSync->beingDestroyed) + SyncDeleteTriggerFromSyncObject(&pAwait->trigger); } free(pAwaitUnion); return Success; @@ -1099,8 +1229,8 @@ ProcSyncInitialize(ClientPtr client) memset(&rep, 0, sizeof(xSyncInitializeReply)); rep.type = X_Reply; rep.sequenceNumber = client->sequence; - rep.majorVersion = SYNC_MAJOR_VERSION; - rep.minorVersion = SYNC_MINOR_VERSION; + rep.majorVersion = SERVER_SYNC_MAJOR_VERSION; + rep.minorVersion = SERVER_SYNC_MINOR_VERSION; rep.length = 0; if (client->swapped) @@ -1157,7 +1287,7 @@ ProcSyncListSystemCounters(ClientPtr client) char *pname_in_reply; SysCounterInfo *psci = SysCounterList[i]->pSysCounterInfo; - walklist->counter = SysCounterList[i]->id; + walklist->counter = SysCounterList[i]->sync.id; walklist->resolution_hi = XSyncValueHigh32(psci->resolution); walklist->resolution_lo = XSyncValueLow32(psci->resolution); namelen = strlen(psci->name); @@ -1370,10 +1500,70 @@ ProcSyncDestroyCounter(ClientPtr client) client->errorValue = stuff->counter; return BadAccess; } - FreeResource(pCounter->id, RT_NONE); + FreeResource(pCounter->sync.id, RT_NONE); return Success; } +static SyncAwaitUnion* +SyncAwaitPrologue(ClientPtr client, int items) +{ + SyncAwaitUnion *pAwaitUnion; + + /* all the memory for the entire await list is allocated + * here in one chunk + */ + pAwaitUnion = malloc((items+1) * sizeof(SyncAwaitUnion)); + if (!pAwaitUnion) + return NULL; + + /* first item is the header, remainder are real wait conditions */ + + pAwaitUnion->header.delete_id = FakeClientID(client->index); + if (!AddResource(pAwaitUnion->header.delete_id, RTAwait, pAwaitUnion)) + { + free(pAwaitUnion); + return NULL; + } + + pAwaitUnion->header.client = client; + pAwaitUnion->header.num_waitconditions = 0; + + return pAwaitUnion; +} + +static void +SyncAwaitEpilogue(ClientPtr client, int items, SyncAwaitUnion *pAwaitUnion) +{ + SyncAwait *pAwait; + int i; + + IgnoreClient(client); + + /* see if any of the triggers are already true */ + + pAwait = &(pAwaitUnion+1)->await; /* skip over header */ + for (i = 0; i < items; i++, pAwait++) + { + CARD64 value; + + /* don't have to worry about NULL counters because the request + * errors before we get here out if they occur + */ + switch (pAwait->trigger.pSync->type) { + case SYNC_COUNTER: + value = ((SyncCounter *)pAwait->trigger.pSync)->value; + break; + default: + XSyncIntToValue(&value, 0); + } + + if ((*pAwait->trigger.CheckTrigger)(&pAwait->trigger, value)) + { + (*pAwait->trigger.TriggerFired)(&pAwait->trigger); + break; /* once is enough */ + } + } +} /* * ** Await @@ -1405,28 +1595,12 @@ ProcSyncAwait(ClientPtr client) return BadValue; } - pProtocolWaitConds = (xSyncWaitCondition *) & stuff[1]; - - /* all the memory for the entire await list is allocated - * here in one chunk - */ - pAwaitUnion = malloc((items+1) * sizeof(SyncAwaitUnion)); - if (!pAwaitUnion) + if (!(pAwaitUnion = SyncAwaitPrologue(client, items))) return BadAlloc; - /* first item is the header, remainder are real wait conditions */ - - pAwaitUnion->header.delete_id = FakeClientID(client->index); - if (!AddResource(pAwaitUnion->header.delete_id, RTAwait, pAwaitUnion)) - { - free(pAwaitUnion); - return BadAlloc; - } - /* don't need to do any more memory allocation for this request! */ - pAwaitUnion->header.client = client; - pAwaitUnion->header.num_waitconditions = 0; + pProtocolWaitConds = (xSyncWaitCondition *) & stuff[1]; pAwait = &(pAwaitUnion+1)->await; /* skip over header */ for (i = 0; i < items; i++, pProtocolWaitConds++, pAwait++) @@ -1434,7 +1608,7 @@ ProcSyncAwait(ClientPtr client) if (pProtocolWaitConds->counter == None) /* XXX protocol change */ { /* this should take care of removing any triggers created by - * this request that have already been registered on counters + * this request that have already been registered on sync objects */ FreeResource(pAwaitUnion->header.delete_id, RT_NONE); client->errorValue = pProtocolWaitConds->counter; @@ -1442,7 +1616,7 @@ ProcSyncAwait(ClientPtr client) } /* sanity checks are in SyncInitTrigger */ - pAwait->trigger.pCounter = NULL; + pAwait->trigger.pSync = NULL; pAwait->trigger.value_type = pProtocolWaitConds->value_type; XSyncIntsToValue(&pAwait->trigger.wait_value, pProtocolWaitConds->wait_value_lo, @@ -1450,11 +1624,12 @@ ProcSyncAwait(ClientPtr client) pAwait->trigger.test_type = pProtocolWaitConds->test_type; status = SyncInitTrigger(client, &pAwait->trigger, - pProtocolWaitConds->counter, XSyncCAAllTrigger); + pProtocolWaitConds->counter, RTCounter, + XSyncCAAllTrigger); if (status != Success) { /* this should take care of removing any triggers created by - * this request that have already been registered on counters + * this request that have already been registered on sync objects */ FreeResource(pAwaitUnion->header.delete_id, RT_NONE); return status; @@ -1469,23 +1644,8 @@ ProcSyncAwait(ClientPtr client) pAwaitUnion->header.num_waitconditions++; } - IgnoreClient(client); + SyncAwaitEpilogue(client, items, pAwaitUnion); - /* see if any of the triggers are already true */ - - pAwait = &(pAwaitUnion+1)->await; /* skip over header */ - for (i = 0; i < items; i++, pAwait++) - { - /* don't have to worry about NULL counters because the request - * errors before we get here out if they occur - */ - if ((*pAwait->trigger.CheckTrigger)(&pAwait->trigger, - pAwait->trigger.pCounter->value)) - { - (*pAwait->trigger.TriggerFired)(&pAwait->trigger); - break; /* once is enough */ - } - } return Success; } @@ -1565,13 +1725,14 @@ ProcSyncCreateAlarm(ClientPtr client) /* set up defaults */ pTrigger = &pAlarm->trigger; - pTrigger->pCounter = NULL; + pTrigger->pSync = NULL; pTrigger->value_type = XSyncAbsolute; XSyncIntToValue(&pTrigger->wait_value, 0L); pTrigger->test_type = XSyncPositiveComparison; pTrigger->TriggerFired = SyncAlarmTriggerFired; pTrigger->CounterDestroyed = SyncAlarmCounterDestroyed; - status = SyncInitTrigger(client, pTrigger, None, XSyncCAAllTrigger); + status = SyncInitTrigger(client, pTrigger, None, RTCounter, + XSyncCAAllTrigger); if (status != Success) { free(pAlarm); @@ -1602,13 +1763,19 @@ ProcSyncCreateAlarm(ClientPtr client) * in CreateAlarm and sets alarm state to Inactive. */ - if (!pTrigger->pCounter) + if (!pTrigger->pSync) { pAlarm->state = XSyncAlarmInactive; /* XXX protocol change */ } - else if ((*pTrigger->CheckTrigger)(pTrigger, pTrigger->pCounter->value)) + else { - (*pTrigger->TriggerFired)(pTrigger); + SyncCounter *pCounter; + + assert(SYNC_COUNTER == pTrigger->pSync->type); + pCounter = (SyncCounter *)pTrigger->pSync; + + if ((*pTrigger->CheckTrigger)(pTrigger, pCounter->value)) + (*pTrigger->TriggerFired)(pTrigger); } return Success; @@ -1622,6 +1789,7 @@ ProcSyncChangeAlarm(ClientPtr client) { REQUEST(xSyncChangeAlarmReq); SyncAlarm *pAlarm; + SyncCounter *pCounter = NULL; long vmask; int len, status; @@ -1642,13 +1810,18 @@ ProcSyncChangeAlarm(ClientPtr client) (CARD32 *)&stuff[1])) != Success) return status; + if (pAlarm->trigger.pSync) + { + assert(SYNC_COUNTER == pAlarm->trigger.pSync->type); + pCounter = (SyncCounter *)pAlarm->trigger.pSync; + } + /* see if alarm already triggered. NULL counter WILL trigger * in ChangeAlarm. */ - if (!pAlarm->trigger.pCounter || - (*pAlarm->trigger.CheckTrigger)(&pAlarm->trigger, - pAlarm->trigger.pCounter->value)) + if (!pCounter || + (*pAlarm->trigger.CheckTrigger)(&pAlarm->trigger, pCounter->value)) { (*pAlarm->trigger.TriggerFired)(&pAlarm->trigger); } @@ -1676,7 +1849,7 @@ ProcSyncQueryAlarm(ClientPtr client) rep.sequenceNumber = client->sequence; pTrigger = &pAlarm->trigger; - rep.counter = (pTrigger->pCounter) ? pTrigger->pCounter->id : None; + rep.counter = (pTrigger->pSync) ? pTrigger->pSync->id : None; #if 0 /* XXX unclear what to do, depends on whether relative value-types * are "consumed" immediately and are considered absolute from then @@ -1732,6 +1905,228 @@ ProcSyncDestroyAlarm(ClientPtr client) return Success; } +static int +ProcSyncCreateFence(ClientPtr client) +{ + REQUEST(xSyncCreateFenceReq); + DrawablePtr pDraw; + SyncFence *pFence; + int rc; + + REQUEST_SIZE_MATCH(xSyncCreateFenceReq); + + rc = dixLookupDrawable(&pDraw, stuff->d, client, M_ANY, DixGetAttrAccess); + if (rc != Success) + return rc; + + LEGAL_NEW_RESOURCE(stuff->fid, client); + + if (!(pFence = (SyncFence *)SyncCreate(client, + stuff->fid, + SYNC_FENCE))) + return BadAlloc; + + miSyncInitFence(pDraw->pScreen, pFence, stuff->initially_triggered); + + return client->noClientException; +} + +static int +FreeFence(void *obj, XID id) +{ + SyncFence *pFence = (SyncFence *) obj; + + miSyncDestroyFence(pFence); + + return Success; +} + +int SyncVerifyFence(SyncFence **ppSyncFence, XID fid, + ClientPtr client, Mask mode) +{ + int rc = dixLookupResourceByType((pointer *)ppSyncFence, fid, RTFence, + client, mode); + + if (rc != Success) + client->errorValue = fid; + + return rc; +} + +static int +ProcSyncTriggerFence(ClientPtr client) +{ + REQUEST(xSyncTriggerFenceReq); + SyncFence *pFence; + int rc; + + REQUEST_SIZE_MATCH(xSyncTriggerFenceReq); + + rc = dixLookupResourceByType((pointer *)&pFence, stuff->fid, RTFence, + client, DixWriteAccess); + if (rc != Success) + return rc; + + miSyncTriggerFence(pFence); + + return client->noClientException; +} + +static int +ProcSyncResetFence(ClientPtr client) +{ + REQUEST(xSyncResetFenceReq); + SyncFence *pFence; + int rc; + + REQUEST_SIZE_MATCH(xSyncResetFenceReq); + + rc = dixLookupResourceByType((pointer *)&pFence, stuff->fid, RTFence, + client, DixWriteAccess); + if (rc != Success) + return rc; + + if (pFence->funcs.CheckTriggered(pFence) != TRUE) + return BadMatch; + + pFence->funcs.Reset(pFence); + + return client->noClientException; +} + +static int +ProcSyncDestroyFence(ClientPtr client) +{ + REQUEST(xSyncDestroyFenceReq); + SyncFence *pFence; + int rc; + + REQUEST_SIZE_MATCH(xSyncDestroyFenceReq); + + rc = dixLookupResourceByType((pointer *)&pFence, stuff->fid, RTFence, + client, DixDestroyAccess); + if (rc != Success) + return rc; + + FreeResource(stuff->fid, RT_NONE); + return client->noClientException; +} + +static int +ProcSyncQueryFence(ClientPtr client) +{ + REQUEST(xSyncQueryFenceReq); + xSyncQueryFenceReply rep; + SyncFence *pFence; + int rc; + + REQUEST_SIZE_MATCH(xSyncQueryFenceReq); + + rc = dixLookupResourceByType((pointer *)&pFence, stuff->fid, + RTFence, client, DixReadAccess); + if (rc != Success) + return rc; + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + + rep.triggered = pFence->funcs.CheckTriggered(pFence); + + if (client->swapped) + { + char n; + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + } + + WriteToClient(client, sizeof(xSyncQueryFenceReply), (char *) &rep); + return client->noClientException; +} + +static int +ProcSyncAwaitFence(ClientPtr client) +{ + REQUEST(xSyncAwaitFenceReq); + SyncAwaitUnion *pAwaitUnion; + SyncAwait *pAwait; + /* Use CARD32 rather than XSyncFence because XIDs are hard-coded to + * CARD32 in protocol definitions */ + CARD32 *pProtocolFences; + int status; + int len; + int items; + int i; + + REQUEST_AT_LEAST_SIZE(xSyncAwaitFenceReq); + + len = client->req_len << 2; + len -= sz_xSyncAwaitFenceReq; + items = len / sizeof(CARD32); + + if (items * sizeof(CARD32) != len) + { + return BadLength; + } + if (items == 0) + { + client->errorValue = items; /* XXX protocol change */ + return BadValue; + } + + if (!(pAwaitUnion = SyncAwaitPrologue(client, items))) + return BadAlloc; + + /* don't need to do any more memory allocation for this request! */ + + pProtocolFences = (CARD32 *) & stuff[1]; + + pAwait = &(pAwaitUnion+1)->await; /* skip over header */ + for (i = 0; i < items; i++, pProtocolFences++, pAwait++) + { + if (*pProtocolFences == None) /* XXX protocol change */ + { + /* this should take care of removing any triggers created by + * this request that have already been registered on sync objects + */ + FreeResource(pAwaitUnion->header.delete_id, RT_NONE); + client->errorValue = *pProtocolFences; + return SyncErrorBase + XSyncBadCounter; + } + + pAwait->trigger.pSync = NULL; + /* Provide acceptable values for these unused fields to + * satisfy SyncInitTrigger's validation logic + */ + pAwait->trigger.value_type = XSyncAbsolute; + XSyncIntToValue(&pAwait->trigger.wait_value, 0); + pAwait->trigger.test_type = 0; + + status = SyncInitTrigger(client, &pAwait->trigger, + *pProtocolFences, RTFence, + XSyncCAAllTrigger); + if (status != Success) + { + /* this should take care of removing any triggers created by + * this request that have already been registered on sync objects + */ + FreeResource(pAwaitUnion->header.delete_id, RT_NONE); + return status; + } + /* this is not a mistake -- same function works for both cases */ + pAwait->trigger.TriggerFired = SyncAwaitTriggerFired; + pAwait->trigger.CounterDestroyed = SyncAwaitTriggerFired; + /* event_threshold is unused for fence syncs */ + XSyncIntToValue(&pAwait->event_threshold, 0); + pAwait->pHeader = &pAwaitUnion->header; + pAwaitUnion->header.num_waitconditions++; + } + + SyncAwaitEpilogue(client, items, pAwaitUnion); + + return client->noClientException; +} + /* * ** Given an extension request, call the appropriate request procedure */ @@ -1770,6 +2165,18 @@ ProcSyncDispatch(ClientPtr client) return ProcSyncSetPriority(client); case X_SyncGetPriority: return ProcSyncGetPriority(client); + case X_SyncCreateFence: + return ProcSyncCreateFence(client); + case X_SyncTriggerFence: + return ProcSyncTriggerFence(client); + case X_SyncResetFence: + return ProcSyncResetFence(client); + case X_SyncDestroyFence: + return ProcSyncDestroyFence(client); + case X_SyncQueryFence: + return ProcSyncQueryFence(client); + case X_SyncAwaitFence: + return ProcSyncAwaitFence(client); default: return BadRequest; } @@ -1969,6 +2376,83 @@ SProcSyncGetPriority(ClientPtr client) return ProcSyncGetPriority(client); } +static int +SProcSyncCreateFence(ClientPtr client) +{ + REQUEST(xSyncCreateFenceReq); + char n; + + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH (xSyncCreateFenceReq); + swapl(&stuff->fid, n); + + return ProcSyncCreateFence(client); +} + +static int +SProcSyncTriggerFence(ClientPtr client) +{ + REQUEST(xSyncTriggerFenceReq); + char n; + + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH (xSyncTriggerFenceReq); + swapl(&stuff->fid, n); + + return ProcSyncTriggerFence(client); +} + +static int +SProcSyncResetFence(ClientPtr client) +{ + REQUEST(xSyncResetFenceReq); + char n; + + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH (xSyncResetFenceReq); + swapl(&stuff->fid, n); + + return ProcSyncResetFence(client); +} + +static int +SProcSyncDestroyFence(ClientPtr client) +{ + REQUEST(xSyncDestroyFenceReq); + char n; + + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH (xSyncDestroyFenceReq); + swapl(&stuff->fid, n); + + return ProcSyncDestroyFence(client); +} + +static int +SProcSyncQueryFence(ClientPtr client) +{ + REQUEST(xSyncQueryFenceReq); + char n; + + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH (xSyncQueryFenceReq); + swapl(&stuff->fid, n); + + return ProcSyncQueryFence(client); +} + +static int +SProcSyncAwaitFence(ClientPtr client) +{ + REQUEST(xSyncAwaitFenceReq); + char n; + + swaps(&stuff->length, n); + REQUEST_AT_LEAST_SIZE(xSyncAwaitFenceReq); + SwapRestL(stuff); + + return ProcSyncAwaitFence(client); +} static int SProcSyncDispatch(ClientPtr client) @@ -2005,6 +2489,18 @@ SProcSyncDispatch(ClientPtr client) return SProcSyncSetPriority(client); case X_SyncGetPriority: return SProcSyncGetPriority(client); + case X_SyncCreateFence: + return SProcSyncCreateFence(client); + case X_SyncTriggerFence: + return SProcSyncTriggerFence(client); + case X_SyncResetFence: + return SProcSyncResetFence(client); + case X_SyncDestroyFence: + return SProcSyncDestroyFence(client); + case X_SyncQueryFence: + return SProcSyncQueryFence(client); + case X_SyncAwaitFence: + return SProcSyncAwaitFence(client); default: return BadRequest; } @@ -2058,7 +2554,6 @@ SyncResetProc(ExtensionEntry *extEntry) RTCounter = 0; } - /* * ** Initialise the extension. */ @@ -2066,6 +2561,10 @@ void SyncExtensionInit(void) { ExtensionEntry *extEntry; + int s; + + for (s = 0; s < screenInfo.numScreens; s++) + miSyncSetup(screenInfo.screens[s]); if (RTCounter == 0) { @@ -2073,6 +2572,7 @@ SyncExtensionInit(void) } RTAlarm = CreateNewResourceType(FreeAlarm, "SyncAlarm"); RTAwait = CreateNewResourceType(FreeAwait, "SyncAwait"); + RTFence = CreateNewResourceType(FreeFence, "SyncFence"); if (RTAwait) RTAwait |= RC_NEVERRETAIN; RTAlarmClient = CreateNewResourceType(FreeAlarmClient, "SyncAlarmClient"); @@ -2099,6 +2599,7 @@ SyncExtensionInit(void) SetResourceTypeErrorValue(RTCounter, SyncErrorBase + XSyncBadCounter); SetResourceTypeErrorValue(RTAlarm, SyncErrorBase + XSyncBadAlarm); + SetResourceTypeErrorValue(RTFence, SyncErrorBase + XSyncBadFence); /* * Although SERVERTIME is implemented by the OS layer, we initialise it @@ -2242,7 +2743,7 @@ static void IdleTimeBlockHandler(pointer env, struct timeval **wt, pointer LastSelectMask) { XSyncValue idle, old_idle; - SyncTriggerList *list = IdleTimeCounter->pTriglist; + SyncTriggerList *list = IdleTimeCounter->sync.pTriglist; SyncTrigger *trig; if (!pIdleTimeValueLess && !pIdleTimeValueGreater) @@ -2263,7 +2764,7 @@ IdleTimeBlockHandler(pointer env, struct timeval **wt, pointer LastSelectMask) * immediately so we can reschedule. */ - for (list = IdleTimeCounter->pTriglist; list; list = list->next) { + for (list = IdleTimeCounter->sync.pTriglist; list; list = list->next) { trig = list->pTrigger; if (trig->CheckTrigger(trig, old_idle)) { AdjustWaitForDelay(wt, 0); @@ -2289,7 +2790,7 @@ IdleTimeBlockHandler(pointer env, struct timeval **wt, pointer LastSelectMask) idle, &overflow); timeout = min(timeout, XSyncValueLow32 (value)); } else { - for (list = IdleTimeCounter->pTriglist; list; list = list->next) { + for (list = IdleTimeCounter->sync.pTriglist; list; list = list->next) { trig = list->pTrigger; if (trig->CheckTrigger(trig, old_idle)) { timeout = min(timeout, 0); diff --git a/Xext/syncsdk.h b/Xext/syncsdk.h new file mode 100644 index 000000000..a72c58500 --- /dev/null +++ b/Xext/syncsdk.h @@ -0,0 +1,47 @@ +/* + * Copyright © 2010 NVIDIA Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef _SYNCSDK_H_ +#define _SYNCSDK_H_ + +#include "misync.h" + +extern _X_EXPORT int +SyncVerifyFence(SyncFence **ppFence, XID fid, ClientPtr client, Mask mode); + +#define VERIFY_SYNC_FENCE(pFence, fid, client, mode) \ + do { \ + int rc; \ + rc = SyncVerifyFence(&(pFence), (fid), (client), (mode)); \ + if (Success != rc) return rc; \ + } while (0) + +#define VERIFY_SYNC_FENCE_OR_NONE(pFence, fid, client, mode) \ + do { \ + pFence = 0; \ + if (None != fid) \ + VERIFY_SYNC_FENCE((pFence), (fid), (client), (mode)); \ + } while (0) + +#endif /* _SYNCSDK_H_ */ + diff --git a/Xext/syncsrv.h b/Xext/syncsrv.h index 6d0e3d64a..7ca1fba26 100644 --- a/Xext/syncsrv.h +++ b/Xext/syncsrv.h @@ -51,16 +51,8 @@ PERFORMANCE OF THIS SOFTWARE. #ifndef _SYNCSRV_H_ #define _SYNCSRV_H_ -#define CARD64 XSyncValue /* XXX temporary! need real 64 bit values for Alpha */ - -typedef struct _SyncCounter { - ClientPtr client; /* Owning client. 0 for system counters */ - XSyncCounter id; /* resource ID */ - CARD64 value; /* counter value */ - struct _SyncTriggerList *pTriglist; /* list of triggers */ - Bool beingDestroyed; /* in process of going away */ - struct _SysCounterInfo *pSysCounterInfo; /* NULL if not a system counter */ -} SyncCounter; +#include "misync.h" +#include "misyncstr.h" /* * The System Counter interface @@ -92,29 +84,6 @@ typedef struct _SysCounterInfo { -typedef struct _SyncTrigger { - SyncCounter *pCounter; - CARD64 wait_value; /* wait value */ - unsigned int value_type; /* Absolute or Relative */ - unsigned int test_type; /* transition or Comparision type */ - CARD64 test_value; /* trigger event threshold value */ - Bool (*CheckTrigger)( - struct _SyncTrigger * /*pTrigger*/, - CARD64 /*newval*/ - ); - void (*TriggerFired)( - struct _SyncTrigger * /*pTrigger*/ - ); - void (*CounterDestroyed)( - struct _SyncTrigger * /*pTrigger*/ - ); -} SyncTrigger; - -typedef struct _SyncTriggerList { - SyncTrigger *pTrigger; - struct _SyncTriggerList *next; -} SyncTriggerList; - typedef struct _SyncAlarmClientList { ClientPtr client; XID delete_id; @@ -148,7 +117,6 @@ typedef union { SyncAwait await; } SyncAwaitUnion; - extern pointer SyncCreateSystemCounter( char * /* name */, CARD64 /* inital_value */, @@ -171,6 +139,7 @@ extern void SyncChangeCounter( extern void SyncDestroySystemCounter( pointer pCounter ); + extern void InitServertime(void); extern void SyncExtensionInit(void); diff --git a/configure.ac b/configure.ac index c5abed67a..3021bdd33 100644 --- a/configure.ac +++ b/configure.ac @@ -788,7 +788,7 @@ WINDOWSWMPROTO="windowswmproto" APPLEWMPROTO="applewmproto >= 1.4" dnl Core modules for most extensions, et al. -SDK_REQUIRED_MODULES="[xproto >= 7.0.17] [randrproto >= 1.2.99.3] [renderproto >= 0.11] [xextproto >= 7.0.99.3] [inputproto >= 1.9.99.902] [kbproto >= 1.0.3] fontsproto" +SDK_REQUIRED_MODULES="[xproto >= 7.0.17] [randrproto >= 1.2.99.3] [renderproto >= 0.11] [xextproto >= 7.1.99] [inputproto >= 1.9.99.902] [kbproto >= 1.0.3] fontsproto" # Make SDK_REQUIRED_MODULES available for inclusion in xorg-server.pc AC_SUBST(SDK_REQUIRED_MODULES) @@ -1350,6 +1350,8 @@ FB_LIB='$(top_builddir)/fb/libfb.la' FB_INC='-I$(top_srcdir)/fb' MIEXT_SHADOW_INC='-I$(top_srcdir)/miext/shadow' MIEXT_SHADOW_LIB='$(top_builddir)/miext/shadow/libshadow.la' +MIEXT_SYNC_INC='-I$(top_srcdir)/miext/sync' +MIEXT_SYNC_LIB='$(top_builddir)/miext/sync/libsync.la' CORE_INCS='-I$(top_srcdir)/include -I$(top_builddir)/include' # SHA1 hashing @@ -1489,7 +1491,7 @@ AC_EGREP_CPP([I_AM_SVR4],[ AC_DEFINE([SVR4],1,[Define to 1 on systems derived from System V Release 4]) AC_MSG_RESULT([yes])], AC_MSG_RESULT([no])) -XSERVER_CFLAGS="$XSERVER_CFLAGS $CORE_INCS $XEXT_INC $COMPOSITE_INC $DAMAGE_INC $FIXES_INC $XI_INC $MI_INC $MIEXT_SHADOW_INC $MIEXT_LAYER_INC $MIEXT_DAMAGE_INC $RENDER_INC $RANDR_INC $FB_INC" +XSERVER_CFLAGS="$XSERVER_CFLAGS $CORE_INCS $XEXT_INC $COMPOSITE_INC $DAMAGE_INC $FIXES_INC $XI_INC $MI_INC $MIEXT_SYNC_INC $MIEXT_SHADOW_INC $MIEXT_LAYER_INC $MIEXT_DAMAGE_INC $RENDER_INC $RANDR_INC $FB_INC" dnl --------------------------------------------------------------------------- dnl DDX section. @@ -1502,7 +1504,7 @@ AC_MSG_RESULT([$XVFB]) AM_CONDITIONAL(XVFB, [test "x$XVFB" = xyes]) if test "x$XVFB" = xyes; then - XVFB_LIBS="$FB_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB" + XVFB_LIBS="$FB_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB" XVFB_SYS_LIBS="$XVFBMODULES_LIBS $GLX_SYS_LIBS" AC_SUBST([XVFB_LIBS]) AC_SUBST([XVFB_SYS_LIBS]) @@ -1523,7 +1525,7 @@ if test "x$XNEST" = xyes; then if test "x$have_xnest" = xno; then AC_MSG_ERROR([Xnest build explicitly requested, but required modules not found.]) fi - XNEST_LIBS="$FB_LIB $FIXES_LIB $MI_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $DIX_LIB $MAIN_LIB $OS_LIB" + XNEST_LIBS="$FB_LIB $FIXES_LIB $MI_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $DIX_LIB $MAIN_LIB $OS_LIB" XNEST_SYS_LIBS="$XNESTMODULES_LIBS $GLX_SYS_LIBS" AC_SUBST([XNEST_LIBS]) AC_SUBST([XNEST_SYS_LIBS]) @@ -1551,7 +1553,7 @@ if test "x$XORG" = xyes; then XORG_OSINCS='-I$(top_srcdir)/hw/xfree86/os-support -I$(top_srcdir)/hw/xfree86/os-support/bus -I$(top_srcdir)/os' XORG_INCS="$XORG_DDXINCS $XORG_OSINCS" XORG_CFLAGS="$XORGSERVER_CFLAGS -DHAVE_XORG_CONFIG_H" - XORG_LIBS="$COMPOSITE_LIB $FIXES_LIB $XEXTXORG_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB" + XORG_LIBS="$COMPOSITE_LIB $FIXES_LIB $XEXTXORG_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB" dnl ================================================================== dnl symbol visibility @@ -1886,7 +1888,7 @@ if test "x$XWIN" = xyes; then XWIN_SYS_LIBS=-lwinsock2 ;; esac - XWIN_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $RANDR_LIB $RENDER_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $OS_LIB" + XWIN_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $CONFIG_LIB $RANDR_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $DAMAGE_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $OS_LIB" XWIN_SYS_LIBS="$XWIN_SYS_LIBS $XWINMODULES_LIBS" AC_SUBST(XWIN_LIBS) AC_SUBST(XWIN_SERVER_NAME) @@ -1916,7 +1918,7 @@ if test "x$XQUARTZ" = xyes; then AC_DEFINE(XQUARTZ,1,[Have Quartz]) AC_DEFINE(ROOTLESS,1,[Build Rootless code]) - DARWIN_LIBS="$MI_LIB $OS_LIB $DIX_LIB $MAIN_LIB $FB_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $XPSTUBS_LIB" + DARWIN_LIBS="$MI_LIB $OS_LIB $DIX_LIB $MAIN_LIB $FB_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $XPSTUBS_LIB" AC_SUBST([DARWIN_LIBS]) AC_CHECK_LIB([Xplugin],[xp_init],[:]) @@ -1977,7 +1979,7 @@ if test "x$DMX" = xyes; then fi DMX_INCLUDES="$XEXT_INC $RENDER_INC $RECORD_INC" XDMX_CFLAGS="$DMXMODULES_CFLAGS" - XDMX_LIBS="$FB_LIB $MI_LIB $RENDER_LIB $RECORD_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $MIEXT_SHADOW_LIB $MIEXT_DAMAGE_LIB $XEXT_LIB $COMPOSITE_LIB $DAMAGE_LIB $MAIN_LIB $DIX_LIB $CONFIG_LIB $OS_LIB $FIXES_LIB" + XDMX_LIBS="$FB_LIB $MI_LIB $XEXT_LIB $RENDER_LIB $RECORD_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $MIEXT_SYNC_LIB $MIEXT_SHADOW_LIB $MIEXT_DAMAGE_LIB $COMPOSITE_LIB $DAMAGE_LIB $MAIN_LIB $DIX_LIB $CONFIG_LIB $OS_LIB $FIXES_LIB" XDMX_SYS_LIBS="$DMXMODULES_LIBS" AC_SUBST([XDMX_CFLAGS]) AC_SUBST([XDMX_LIBS]) @@ -2082,13 +2084,13 @@ if test "$KDRIVE" = yes; then # damage shadow extension glx (NOTYET) fb mi KDRIVE_INC='-I$(top_srcdir)/hw/kdrive/src' - KDRIVE_PURE_INCS="$KDRIVE_INC $MIEXT_DAMAGE_INC $MIEXT_SHADOW_INC $XEXT_INC $FB_INC $MI_INC" + KDRIVE_PURE_INCS="$KDRIVE_INC $MIEXT_SYNC_INC $MIEXT_DAMAGE_INC $MIEXT_SHADOW_INC $XEXT_INC $FB_INC $MI_INC" KDRIVE_OS_INC='-I$(top_srcdir)/hw/kdrive/linux' KDRIVE_INCS="$KDRIVE_PURE_INCS $KDRIVE_OS_INC" KDRIVE_CFLAGS="$XSERVER_CFLAGS -DHAVE_KDRIVE_CONFIG_H $TSLIB_CFLAGS" - KDRIVE_PURE_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $OS_LIB" + KDRIVE_PURE_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $OS_LIB" KDRIVE_LIB='$(top_builddir)/hw/kdrive/src/libkdrive.la' case $host_os in *linux*) @@ -2189,6 +2191,7 @@ record/Makefile config/Makefile mi/Makefile miext/Makefile +miext/sync/Makefile miext/damage/Makefile miext/shadow/Makefile miext/cw/Makefile diff --git a/dix/privates.c b/dix/privates.c index 687fa7aa0..d651258f6 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 4b3ed8694..4ac3c818c 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 */ /* @@ -50,6 +53,7 @@ cat > sdksyms.c << EOF #include "geext.h" #include "geint.h" #include "shmint.h" +#include "syncsdk.h" #if XINERAMA # include "panoramiXsrv.h" # include "panoramiX.h" diff --git a/include/privates.h b/include/privates.h index 9fb6ae84e..7ef2cb732 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/include/protocol-versions.h b/include/protocol-versions.h index c67446548..1d33bddcf 100644 --- a/include/protocol-versions.h +++ b/include/protocol-versions.h @@ -95,6 +95,10 @@ #define SERVER_SHM_MAJOR_VERSION 1 #define SERVER_SHM_MINOR_VERSION 1 +/* Sync */ +#define SERVER_SYNC_MAJOR_VERSION 3 +#define SERVER_SYNC_MINOR_VERSION 1 + /* Windows WM */ #define SERVER_WINDOWSWM_MAJOR_VERSION 1 #define SERVER_WINDOWSWM_MINOR_VERSION 0 diff --git a/miext/Makefile.am b/miext/Makefile.am index 84ab70855..bbedac2b5 100644 --- a/miext/Makefile.am +++ b/miext/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = damage shadow +SUBDIRS = sync damage shadow if COMPOSITE SUBDIRS += cw endif @@ -8,4 +8,4 @@ endif if XWIN_MULTIWINDOWEXTWM SUBDIRS += rootless endif -DIST_SUBDIRS = damage shadow cw rootless +DIST_SUBDIRS = sync damage shadow cw rootless diff --git a/miext/sync/Makefile.am b/miext/sync/Makefile.am new file mode 100644 index 000000000..36b2816d7 --- /dev/null +++ b/miext/sync/Makefile.am @@ -0,0 +1,14 @@ +noinst_LTLIBRARIES = libsync.la + +AM_CFLAGS = $(DIX_CFLAGS) + +INCLUDES = + +if XORG +sdk_HEADERS = misync.h misyncstr.h +endif + +libsync_la_SOURCES = \ + misync.c \ + misync.h \ + misyncstr.h diff --git a/miext/sync/misync.c b/miext/sync/misync.c new file mode 100644 index 000000000..bcc68a2bb --- /dev/null +++ b/miext/sync/misync.c @@ -0,0 +1,201 @@ +/* + * Copyright © 2010 NVIDIA Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * 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 new file mode 100644 index 000000000..1c82ea516 --- /dev/null +++ b/miext/sync/misync.h @@ -0,0 +1,77 @@ +/* + * Copyright © 2010 NVIDIA Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#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 new file mode 100644 index 000000000..40a865c9c --- /dev/null +++ b/miext/sync/misyncstr.h @@ -0,0 +1,86 @@ +/* + * Copyright © 2010 NVIDIA Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#ifndef _MISYNCSTR_H_ +#define _MISYNCSTR_H_ + +#include "dix.h" +#include + +#define CARD64 XSyncValue /* XXX temporary! need real 64 bit values for Alpha */ + +/* Sync object types */ +#define SYNC_COUNTER 0 +#define SYNC_FENCE 1 + +typedef struct _SyncObject { + ClientPtr client; /* Owning client. 0 for system counters */ + struct _SyncTriggerList *pTriglist; /* list of triggers */ + XID id; /* resource ID */ + unsigned char type; /* SYNC_* */ + Bool beingDestroyed; /* in process of going away */ +} SyncObject; + +typedef struct _SyncCounter { + SyncObject sync; /* Common sync object data */ + CARD64 value; /* counter value */ + struct _SysCounterInfo *pSysCounterInfo; /* NULL if not a system counter */ +} 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 */ +}; + +struct _SyncTrigger { + SyncObject *pSync; + CARD64 wait_value; /* wait value */ + unsigned int value_type; /* Absolute or Relative */ + unsigned int test_type; /* transition or Comparision type */ + CARD64 test_value; /* trigger event threshold value */ + Bool (*CheckTrigger)( + struct _SyncTrigger * /*pTrigger*/, + CARD64 /*newval*/ + ); + void (*TriggerFired)( + struct _SyncTrigger * /*pTrigger*/ + ); + void (*CounterDestroyed)( + struct _SyncTrigger * /*pTrigger*/ + ); +}; + +typedef struct _SyncTriggerList { + SyncTrigger *pTrigger; + struct _SyncTriggerList *next; +} SyncTriggerList; + +#endif /* _MISYNCSTR_H_ */ +