summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2010-12-06 19:51:06 -0800
committerKeith Packard <keithp@keithp.com>2010-12-06 19:51:06 -0800
commitf5b8bd620f91214c0b87e9b04d57015655792352 (patch)
tree25a8ad5fbc4d4451a0e34025b656e23e16fdd8db
parent01e9fa7da389fc7ab834b4234b8484514144b7f4 (diff)
parent8127c83c81bf64369a8ba2999088226d14e0b128 (diff)
Merge remote branch 'jajones/for-keith'
-rw-r--r--COPYING2
-rw-r--r--Xext/Makefile.am3
-rw-r--r--Xext/sync.c899
-rw-r--r--Xext/syncsdk.h47
-rw-r--r--Xext/syncsrv.h37
-rw-r--r--configure.ac23
-rw-r--r--dix/privates.c1
-rwxr-xr-xhw/xfree86/loader/sdksyms.sh4
-rw-r--r--include/privates.h1
-rw-r--r--include/protocol-versions.h4
-rw-r--r--miext/Makefile.am4
-rw-r--r--miext/sync/Makefile.am14
-rw-r--r--miext/sync/misync.c201
-rw-r--r--miext/sync/misync.h77
-rw-r--r--miext/sync/misyncstr.h86
15 files changed, 1156 insertions, 247 deletions
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 <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"
+#include "pixmapstr.h"
#include "resource.h"
#include "opaque.h"
#include <X11/extensions/syncproto.h>
#include "syncsrv.h"
+#include "syncsdk.h"
+#include "protocol-versions.h"
#include <stdio.h>
#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 (SYNC_COUNTER == pTrigger->pSync->type)
+ {
+ pCounter = (SyncCounter *)pTrigger->pSync;
- if (IsSystemCounter(pTrigger->pCounter))
- SyncComputeBracketValues(pTrigger->pCounter);
+ 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)
+
+ if (SYNC_FENCE == pSync->type)
{
- client->errorValue = pTrigger->test_type;
- return BadValue;
+ pTrigger->CheckTrigger = SyncCheckTriggerFence;
}
- /* select appropriate CheckTrigger function */
-
- switch (pTrigger->test_type)
+ else
{
- case XSyncPositiveTransition:
- pTrigger->CheckTrigger = SyncCheckTriggerPositiveTransition;
- break;
- case XSyncNegativeTransition:
- pTrigger->CheckTrigger = SyncCheckTriggerNegativeTransition;
- break;
- case XSyncPositiveComparison:
- pTrigger->CheckTrigger = SyncCheckTriggerPositiveComparison;
- break;
- case XSyncNegativeComparison:
- pTrigger->CheckTrigger = SyncCheckTriggerNegativeComparison;
- break;
+ 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;
}
+
+ if (SYNC_COUNTER == pAwait->trigger.pSync->type)
+ {
+ 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, pAwait->trigger.pCounter->value,
- pAwait->trigger.test_value, &overflow);
+ /* "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 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 ( ((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 SyncCounter *
-SyncCreateCounter(ClientPtr client, XSyncCounter id, CARD64 initialvalue)
+static SyncObject *
+SyncCreate(ClientPtr client, XID id, unsigned char type)
{
- SyncCounter *pCounter;
+ SyncObject *pSync;
+ RESTYPE resType;
- if (!(pCounter = malloc(sizeof(SyncCounter))))
+ 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, RTCounter, (pointer) pCounter))
+ if (!AddResource(id, resType, (pointer) pSync))
{
- free(pCounter);
+ switch (type) {
+ case SYNC_FENCE:
+ dixFreeObjectWithPrivates((SyncFence *)pSync, PRIVATE_SYNC_FENCE);
+ break;
+ default:
+ free(pSync);
+ }
+
return NULL;
}
- pCounter->client = client;
- pCounter->id = id;
+ 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 = (SyncCounter *)SyncCreate(client,
+ id,
+ SYNC_COUNTER)))
+ return NULL;
+
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)
- 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);
+ if (!(pAwaitUnion = SyncAwaitPrologue(client, items)))
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);
-
- /* see if any of the triggers are already true */
+ SyncAwaitEpilogue(client, items, pAwaitUnion);
- 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 <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);
+ 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 <dix-config.h>
+#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 <dix-config.h>
+#endif
+
+#ifndef _MISYNCSTR_H_
+#define _MISYNCSTR_H_
+
+#include "dix.h"
+#include <X11/extensions/syncconst.h>
+
+#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_ */
+