Merge branch 'xsync-transition-bug-59644' into for-keith

This commit is contained in:
Peter Hutterer 2013-10-18 16:50:12 +10:00
commit f8662a1336
9 changed files with 158 additions and 63 deletions

View File

@ -392,9 +392,7 @@ ScreenSaverFreeSuspend(pointer value, XID id)
DeviceIntPtr dev; DeviceIntPtr dev;
UpdateCurrentTimeIf(); UpdateCurrentTimeIf();
nt_list_for_each_entry(dev, inputInfo.devices, next) nt_list_for_each_entry(dev, inputInfo.devices, next)
lastDeviceEventTime[dev->id] = currentTime; NoticeTime(dev, currentTime);
lastDeviceEventTime[XIAllDevices] = currentTime;
lastDeviceEventTime[XIAllMasterDevices] = currentTime;
SetScreenSaverTimer(); SetScreenSaverTimer();
} }
} }
@ -681,7 +679,7 @@ ProcScreenSaverQueryInfo(ClientPtr client)
pPriv = GetScreenPrivate(pDraw->pScreen); pPriv = GetScreenPrivate(pDraw->pScreen);
UpdateCurrentTime(); UpdateCurrentTime();
lastInput = GetTimeInMillis() - lastDeviceEventTime[XIAllDevices].milliseconds; lastInput = GetTimeInMillis() - LastEventTime(XIAllDevices).milliseconds;
rep = (xScreenSaverQueryInfoReply) { rep = (xScreenSaverQueryInfoReply) {
.type = X_Reply, .type = X_Reply,

View File

@ -699,6 +699,14 @@ SyncAwaitTriggerFired(SyncTrigger * pTrigger)
FreeResource(pAwaitUnion->header.delete_id, RT_NONE); FreeResource(pAwaitUnion->header.delete_id, RT_NONE);
} }
static CARD64
SyncUpdateCounter(SyncCounter *pCounter, CARD64 newval)
{
CARD64 oldval = pCounter->value;
pCounter->value = newval;
return oldval;
}
/* This function should always be used to change a counter's value so that /* This function should always be used to change a counter's value so that
* any triggers depending on the counter will be checked. * any triggers depending on the counter will be checked.
*/ */
@ -708,8 +716,7 @@ SyncChangeCounter(SyncCounter * pCounter, CARD64 newval)
SyncTriggerList *ptl, *pnext; SyncTriggerList *ptl, *pnext;
CARD64 oldval; CARD64 oldval;
oldval = pCounter->value; oldval = SyncUpdateCounter(pCounter, newval);
pCounter->value = newval;
/* run through triggers to see if any become true */ /* run through triggers to see if any become true */
for (ptl = pCounter->sync.pTriglist; ptl; ptl = pnext) { for (ptl = pCounter->sync.pTriglist; ptl; ptl = pnext) {
@ -1019,6 +1026,11 @@ SyncComputeBracketValues(SyncCounter * pCounter)
psci->bracket_greater = pTrigger->test_value; psci->bracket_greater = pTrigger->test_value;
pnewgtval = &psci->bracket_greater; pnewgtval = &psci->bracket_greater;
} }
else if (XSyncValueGreaterThan(pCounter->value, pTrigger->test_value) &&
XSyncValueGreaterThan(pTrigger->test_value, psci->bracket_less)) {
psci->bracket_less = pTrigger->test_value;
pnewltval = &psci->bracket_less;
}
} }
else if (pTrigger->test_type == XSyncNegativeComparison && else if (pTrigger->test_type == XSyncNegativeComparison &&
ct != XSyncCounterNeverDecreases) { ct != XSyncCounterNeverDecreases) {
@ -1028,52 +1040,53 @@ SyncComputeBracketValues(SyncCounter * pCounter)
psci->bracket_less = pTrigger->test_value; psci->bracket_less = pTrigger->test_value;
pnewltval = &psci->bracket_less; pnewltval = &psci->bracket_less;
} }
else if (XSyncValueLessThan(pCounter->value, pTrigger->test_value) &&
XSyncValueLessThan(pTrigger->test_value, psci->bracket_greater)) {
psci->bracket_greater = pTrigger->test_value;
pnewgtval = &psci->bracket_greater;
}
} }
else if (pTrigger->test_type == XSyncNegativeTransition && else if (pTrigger->test_type == XSyncNegativeTransition &&
ct != XSyncCounterNeverIncreases) { ct != XSyncCounterNeverIncreases) {
if (XSyncValueGreaterThan(pCounter->value, pTrigger->test_value) && if (XSyncValueGreaterOrEqual(pCounter->value, pTrigger->test_value) &&
XSyncValueGreaterThan(pTrigger->test_value, psci->bracket_less)) XSyncValueGreaterThan(pTrigger->test_value, psci->bracket_less)) {
{
psci->bracket_less = pTrigger->test_value;
pnewltval = &psci->bracket_less;
}
else if (XSyncValueEqual(pCounter->value, pTrigger->test_value) &&
XSyncValueGreaterThan(pTrigger->test_value,
psci->bracket_less)) {
/* /*
* The value is exactly equal to our threshold. We want one * If the value is exactly equal to our threshold, we want one
* more event in the negative direction to ensure we pick up * more event in the negative direction to ensure we pick up
* when the value is less than this threshold. * when the value is less than this threshold.
*/ */
psci->bracket_less = pTrigger->test_value; psci->bracket_less = pTrigger->test_value;
pnewltval = &psci->bracket_less; pnewltval = &psci->bracket_less;
} }
} else if (XSyncValueLessThan(pCounter->value, pTrigger->test_value) &&
else if (pTrigger->test_type == XSyncPositiveTransition && XSyncValueLessThan(pTrigger->test_value, psci->bracket_greater)) {
ct != XSyncCounterNeverDecreases) {
if (XSyncValueLessThan(pCounter->value, pTrigger->test_value) &&
XSyncValueLessThan(pTrigger->test_value, psci->bracket_greater))
{
psci->bracket_greater = pTrigger->test_value; psci->bracket_greater = pTrigger->test_value;
pnewgtval = &psci->bracket_greater; pnewgtval = &psci->bracket_greater;
} }
else if (XSyncValueEqual(pCounter->value, pTrigger->test_value) && }
XSyncValueLessThan(pTrigger->test_value, else if (pTrigger->test_type == XSyncPositiveTransition &&
psci->bracket_greater)) { ct != XSyncCounterNeverDecreases) {
if (XSyncValueLessOrEqual(pCounter->value, pTrigger->test_value) &&
XSyncValueLessThan(pTrigger->test_value, psci->bracket_greater)) {
/* /*
* The value is exactly equal to our threshold. We want one * If the value is exactly equal to our threshold, we
* more event in the positive direction to ensure we pick up * want one more event in the positive direction to
* when the value *exceeds* this threshold. * ensure we pick up when the value *exceeds* this
* threshold.
*/ */
psci->bracket_greater = pTrigger->test_value; psci->bracket_greater = pTrigger->test_value;
pnewgtval = &psci->bracket_greater; pnewgtval = &psci->bracket_greater;
} }
else if (XSyncValueGreaterThan(pCounter->value, pTrigger->test_value) &&
XSyncValueGreaterThan(pTrigger->test_value, psci->bracket_less)) {
psci->bracket_less = pTrigger->test_value;
pnewltval = &psci->bracket_less;
}
} }
} /* end for each trigger */ } /* end for each trigger */
if (pnewgtval || pnewltval) {
(*psci->BracketValues) ((pointer) pCounter, pnewltval, pnewgtval); (*psci->BracketValues) ((pointer) pCounter, pnewltval, pnewgtval);
}
} }
/* /*
@ -2619,7 +2632,7 @@ IdleTimeQueryValue(pointer pCounter, CARD64 * pValue_return)
} }
else else
deviceid = XIAllDevices; deviceid = XIAllDevices;
idle = GetTimeInMillis() - lastDeviceEventTime[deviceid].milliseconds; idle = GetTimeInMillis() - LastEventTime(deviceid).milliseconds;
XSyncIntsToValue(pValue_return, idle, 0); XSyncIntsToValue(pValue_return, idle, 0);
} }
@ -2638,7 +2651,7 @@ IdleTimeBlockHandler(pointer pCounter, struct timeval **wt, pointer LastSelectMa
return; return;
old_idle = counter->value; old_idle = counter->value;
IdleTimeQueryValue(NULL, &idle); IdleTimeQueryValue(counter, &idle);
counter->value = idle; /* push, so CheckTrigger works */ counter->value = idle; /* push, so CheckTrigger works */
if (less && XSyncValueLessOrEqual(idle, *less)) { if (less && XSyncValueLessOrEqual(idle, *less)) {
@ -2699,6 +2712,17 @@ IdleTimeBlockHandler(pointer pCounter, struct timeval **wt, pointer LastSelectMa
counter->value = old_idle; /* pop */ counter->value = old_idle; /* pop */
} }
static void
IdleTimeCheckBrackets(SyncCounter *counter, XSyncValue idle, XSyncValue *less, XSyncValue *greater)
{
if ((greater && XSyncValueGreaterOrEqual(idle, *greater)) ||
(less && XSyncValueLessOrEqual(idle, *less))) {
SyncChangeCounter(counter, idle);
}
else
SyncUpdateCounter(counter, idle);
}
static void static void
IdleTimeWakeupHandler(pointer pCounter, int rc, pointer LastSelectMask) IdleTimeWakeupHandler(pointer pCounter, int rc, pointer LastSelectMask)
{ {
@ -2713,10 +2737,24 @@ IdleTimeWakeupHandler(pointer pCounter, int rc, pointer LastSelectMask)
IdleTimeQueryValue(pCounter, &idle); IdleTimeQueryValue(pCounter, &idle);
if ((greater && XSyncValueGreaterOrEqual(idle, *greater)) || /*
(less && XSyncValueLessOrEqual(idle, *less))) { There is no guarantee for the WakeupHandler to be called within a specific
SyncChangeCounter(counter, idle); timeframe. Idletime may go to 0, but by the time we get here, it may be
non-zero and alarms for a pos. transition on 0 won't get triggered.
https://bugs.freedesktop.org/show_bug.cgi?id=70476
*/
if (LastEventTimeWasReset(priv->deviceid)) {
LastEventTimeToggleResetFlag(priv->deviceid, FALSE);
if (!XSyncValueIsZero(idle)) {
XSyncValue zero;
XSyncIntsToValue(&zero, 0, 0);
IdleTimeCheckBrackets(counter, zero, less, greater);
less = priv->value_less;
greater = priv->value_greater;
} }
}
IdleTimeCheckBrackets(counter, idle, less, greater);
} }
static void static void
@ -2734,6 +2772,9 @@ IdleTimeBracketValues(pointer pCounter, CARD64 * pbracket_less,
IdleTimeWakeupHandler, pCounter); IdleTimeWakeupHandler, pCounter);
} }
else if (!registered && (pbracket_less || pbracket_greater)) { else if (!registered && (pbracket_less || pbracket_greater)) {
/* Reset flag must be zero so we don't force a idle timer reset on
the first wakeup */
LastEventTimeToggleResetAll(FALSE);
RegisterBlockAndWakeupHandlers(IdleTimeBlockHandler, RegisterBlockAndWakeupHandlers(IdleTimeBlockHandler,
IdleTimeWakeupHandler, pCounter); IdleTimeWakeupHandler, pCounter);
} }

View File

@ -262,6 +262,11 @@ InputInfo inputInfo;
EventSyncInfoRec syncEvents; EventSyncInfoRec syncEvents;
static struct DeviceEventTime {
Bool reset;
TimeStamp time;
} lastDeviceEventTime[MAXDEVICES];
/** /**
* The root window the given device is currently on. * The root window the given device is currently on.
*/ */
@ -1043,33 +1048,73 @@ XineramaGetCursorScreen(DeviceIntPtr pDev)
#define TIMESLOP (5 * 60 * 1000) /* 5 minutes */ #define TIMESLOP (5 * 60 * 1000) /* 5 minutes */
static void static void
MonthChangedOrBadTime(InternalEvent *ev) MonthChangedOrBadTime(CARD32 *ms)
{ {
/* If the ddx/OS is careless about not processing timestamped events from /* If the ddx/OS is careless about not processing timestamped events from
* different sources in sorted order, then it's possible for time to go * different sources in sorted order, then it's possible for time to go
* backwards when it should not. Here we ensure a decent time. * backwards when it should not. Here we ensure a decent time.
*/ */
if ((currentTime.milliseconds - ev->any.time) > TIMESLOP) if ((currentTime.milliseconds - *ms) > TIMESLOP)
currentTime.months++; currentTime.months++;
else else
ev->any.time = currentTime.milliseconds; *ms = currentTime.milliseconds;
}
void
NoticeTime(const DeviceIntPtr dev, TimeStamp time)
{
lastDeviceEventTime[XIAllDevices].time = currentTime;
lastDeviceEventTime[dev->id].time = currentTime;
LastEventTimeToggleResetFlag(dev->id, TRUE);
LastEventTimeToggleResetFlag(XIAllDevices, TRUE);
} }
static void static void
NoticeTime(InternalEvent *ev, DeviceIntPtr dev) NoticeTimeMillis(const DeviceIntPtr dev, CARD32 *ms)
{ {
if (ev->any.time < currentTime.milliseconds) TimeStamp time;
MonthChangedOrBadTime(ev); if (*ms < currentTime.milliseconds)
currentTime.milliseconds = ev->any.time; MonthChangedOrBadTime(ms);
lastDeviceEventTime[XIAllDevices] = currentTime; time.months = currentTime.months;
lastDeviceEventTime[dev->id] = currentTime; time.milliseconds = *ms;
NoticeTime(dev, time);
} }
void void
NoticeEventTime(InternalEvent *ev, DeviceIntPtr dev) NoticeEventTime(InternalEvent *ev, DeviceIntPtr dev)
{ {
if (!syncEvents.playingEvents) if (!syncEvents.playingEvents)
NoticeTime(ev, dev); NoticeTimeMillis(dev, &ev->any.time);
}
TimeStamp
LastEventTime(int deviceid)
{
return lastDeviceEventTime[deviceid].time;
}
Bool
LastEventTimeWasReset(int deviceid)
{
return lastDeviceEventTime[deviceid].reset;
}
void
LastEventTimeToggleResetFlag(int deviceid, Bool state)
{
lastDeviceEventTime[deviceid].reset = state;
}
void
LastEventTimeToggleResetAll(Bool state)
{
DeviceIntPtr dev;
nt_list_for_each_entry(dev, inputInfo.devices, next) {
LastEventTimeToggleResetFlag(dev->id, FALSE);
}
LastEventTimeToggleResetFlag(XIAllDevices, FALSE);
LastEventTimeToggleResetFlag(XIAllMasterDevices, FALSE);
} }
/************************************************************************** /**************************************************************************
@ -1093,7 +1138,7 @@ EnqueueEvent(InternalEvent *ev, DeviceIntPtr device)
if (!xorg_list_is_empty(&syncEvents.pending)) if (!xorg_list_is_empty(&syncEvents.pending))
tail = xorg_list_last_entry(&syncEvents.pending, QdEventRec, next); tail = xorg_list_last_entry(&syncEvents.pending, QdEventRec, next);
NoticeTime((InternalEvent *)event, device); NoticeTimeMillis(device, &ev->any.time);
/* Fix for key repeating bug. */ /* Fix for key repeating bug. */
if (device->key != NULL && device->key->xkbInfo != NULL && if (device->key != NULL && device->key->xkbInfo != NULL &&
@ -5276,8 +5321,12 @@ InitEvents(void)
inputInfo.pointer = (DeviceIntPtr) NULL; inputInfo.pointer = (DeviceIntPtr) NULL;
for (i = 0; i < MAXDEVICES; i++) { for (i = 0; i < MAXDEVICES; i++) {
DeviceIntRec dummy;
memcpy(&event_filters[i], default_filter, sizeof(default_filter)); memcpy(&event_filters[i], default_filter, sizeof(default_filter));
lastDeviceEventTime[i] = currentTime;
dummy.id = i;
NoticeTime(&dummy, currentTime);
LastEventTimeToggleResetFlag(i, FALSE);
} }
syncEvents.replayDev = (DeviceIntPtr) NULL; syncEvents.replayDev = (DeviceIntPtr) NULL;

View File

@ -122,7 +122,6 @@ Bool party_like_its_1989 = FALSE;
Bool whiteRoot = FALSE; Bool whiteRoot = FALSE;
TimeStamp currentTime; TimeStamp currentTime;
TimeStamp lastDeviceEventTime[MAXDEVICES];
int defaultColorVisualClass = -1; int defaultColorVisualClass = -1;
int monitorResolution = 0; int monitorResolution = 0;

View File

@ -3089,9 +3089,7 @@ dixSaveScreens(ClientPtr client, int on, int mode)
DeviceIntPtr dev; DeviceIntPtr dev;
UpdateCurrentTimeIf(); UpdateCurrentTimeIf();
nt_list_for_each_entry(dev, inputInfo.devices, next) nt_list_for_each_entry(dev, inputInfo.devices, next)
lastDeviceEventTime[dev->id] = currentTime; NoticeTime(dev, currentTime);
lastDeviceEventTime[XIAllDevices] = currentTime;
lastDeviceEventTime[XIAllMasterDevices] = currentTime;
} }
SetScreenSaverTimer(); SetScreenSaverTimer();
} }

View File

@ -314,9 +314,20 @@ GetCurrentRootWindow(DeviceIntPtr pDev);
extern _X_EXPORT WindowPtr extern _X_EXPORT WindowPtr
GetSpriteWindow(DeviceIntPtr pDev); GetSpriteWindow(DeviceIntPtr pDev);
extern _X_EXPORT void
NoticeTime(const DeviceIntPtr dev,
TimeStamp time);
extern _X_EXPORT void extern _X_EXPORT void
NoticeEventTime(InternalEvent *ev, NoticeEventTime(InternalEvent *ev,
DeviceIntPtr dev); DeviceIntPtr dev);
extern _X_EXPORT TimeStamp
LastEventTime(int deviceid);
extern _X_EXPORT Bool
LastEventTimeWasReset(int deviceid);
extern _X_EXPORT void
LastEventTimeToggleResetFlag(int deviceid, Bool state);
extern _X_EXPORT void
LastEventTimeToggleResetAll(Bool state);
extern void extern void
EnqueueEvent(InternalEvent * /* ev */ , EnqueueEvent(InternalEvent * /* ev */ ,

View File

@ -144,7 +144,6 @@ typedef struct _WorkQueue {
} WorkQueueRec; } WorkQueueRec;
extern _X_EXPORT TimeStamp currentTime; extern _X_EXPORT TimeStamp currentTime;
extern _X_EXPORT TimeStamp lastDeviceEventTime[MAXDEVICES];
extern _X_EXPORT int extern _X_EXPORT int
CompareTimeStamps(TimeStamp /*a */ , CompareTimeStamps(TimeStamp /*a */ ,

View File

@ -561,7 +561,7 @@ NextDPMSTimeout(INT32 timeout)
static CARD32 static CARD32
ScreenSaverTimeoutExpire(OsTimerPtr timer, CARD32 now, pointer arg) ScreenSaverTimeoutExpire(OsTimerPtr timer, CARD32 now, pointer arg)
{ {
INT32 timeout = now - lastDeviceEventTime[XIAllDevices].milliseconds; INT32 timeout = now - LastEventTime(XIAllDevices).milliseconds;
CARD32 nextTimeout = 0; CARD32 nextTimeout = 0;
#ifdef DPMSExtension #ifdef DPMSExtension

View File

@ -1391,7 +1391,7 @@ recv_alive_msg(unsigned length)
if (SessionRunning && AliveSessionID == SessionID) { if (SessionRunning && AliveSessionID == SessionID) {
/* backoff dormancy period */ /* backoff dormancy period */
state = XDM_RUN_SESSION; state = XDM_RUN_SESSION;
if ((GetTimeInMillis() - lastDeviceEventTime[XIAllDevices].milliseconds) > if ((GetTimeInMillis() - LastEventTime(XIAllDevices).milliseconds) >
keepaliveDormancy * 1000) { keepaliveDormancy * 1000) {
keepaliveDormancy <<= 1; keepaliveDormancy <<= 1;
if (keepaliveDormancy > XDM_MAX_DORMANCY) if (keepaliveDormancy > XDM_MAX_DORMANCY)