render: Use OsTimer for animated cursor timing

This replaces the block/wakeup handlers with an OsTimer. This also
avoids problems with performing rendering during the wakeup handler.

Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Keith Packard <keithp@keithp.com>
This commit is contained in:
Keith Packard 2015-11-11 22:02:15 -08:00 committed by Adam Jackson
parent 49c0f2413d
commit e51ea53b26

View File

@ -59,15 +59,14 @@ typedef struct _AnimCur {
typedef struct _AnimScrPriv { typedef struct _AnimScrPriv {
CloseScreenProcPtr CloseScreen; CloseScreenProcPtr CloseScreen;
ScreenBlockHandlerProcPtr BlockHandler;
CursorLimitsProcPtr CursorLimits; CursorLimitsProcPtr CursorLimits;
DisplayCursorProcPtr DisplayCursor; DisplayCursorProcPtr DisplayCursor;
SetCursorPositionProcPtr SetCursorPosition; SetCursorPositionProcPtr SetCursorPosition;
RealizeCursorProcPtr RealizeCursor; RealizeCursorProcPtr RealizeCursor;
UnrealizeCursorProcPtr UnrealizeCursor; UnrealizeCursorProcPtr UnrealizeCursor;
RecolorCursorProcPtr RecolorCursor; RecolorCursorProcPtr RecolorCursor;
OsTimerPtr timer;
Bool timer_set;
} AnimCurScreenRec, *AnimCurScreenPtr; } AnimCurScreenRec, *AnimCurScreenPtr;
static unsigned char empty[4]; static unsigned char empty[4];
@ -129,28 +128,23 @@ AnimCurCursorLimits(DeviceIntPtr pDev,
} }
/* /*
* This has to be a screen block handler instead of a generic * The cursor animation timer has expired, go display any relevant cursor changes
* block handler so that it is well ordered with respect to the DRI * and compute a new timeout value
* block handler responsible for releasing the hardware to DRI clients
*/ */
static void static CARD32
AnimCurScreenBlockHandler(ScreenPtr pScreen, AnimCurTimerNotify(OsTimerPtr timer, CARD32 now, void *arg)
void *pTimeout, void *pReadmask)
{ {
ScreenPtr pScreen = arg;
AnimCurScreenPtr as = GetAnimCurScreen(pScreen); AnimCurScreenPtr as = GetAnimCurScreen(pScreen);
DeviceIntPtr dev; DeviceIntPtr dev;
Bool activeDevice = FALSE; Bool activeDevice = FALSE;
CARD32 now = 0, soonest = ~0; /* earliest time to wakeup again */ CARD32 soonest = ~0; /* earliest time to wakeup again */
Unwrap(as, pScreen, BlockHandler);
for (dev = inputInfo.devices; dev; dev = dev->next) { for (dev = inputInfo.devices; dev; dev = dev->next) {
if (IsPointerDevice(dev) && pScreen == dev->spriteInfo->anim.pScreen) { if (IsPointerDevice(dev) && pScreen == dev->spriteInfo->anim.pScreen) {
if (!activeDevice) { if (!activeDevice)
now = GetTimeInMillis();
activeDevice = TRUE; activeDevice = TRUE;
}
if ((INT32) (now - dev->spriteInfo->anim.time) >= 0) { if ((INT32) (now - dev->spriteInfo->anim.time) >= 0) {
AnimCurPtr ac = GetAnimCur(dev->spriteInfo->anim.pCursor); AnimCurPtr ac = GetAnimCur(dev->spriteInfo->anim.pCursor);
@ -180,13 +174,11 @@ AnimCurScreenBlockHandler(ScreenPtr pScreen,
} }
if (activeDevice) if (activeDevice)
AdjustWaitForDelay(pTimeout, soonest - now); TimerSet(as->timer, TimerAbsolute, soonest, AnimCurTimerNotify, pScreen);
(*pScreen->BlockHandler) (pScreen, pTimeout, pReadmask);
if (activeDevice)
Wrap(as, pScreen, BlockHandler, AnimCurScreenBlockHandler);
else else
as->BlockHandler = NULL; as->timer_set = FALSE;
return 0;
} }
static Bool static Bool
@ -212,8 +204,11 @@ AnimCurDisplayCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
pDev->spriteInfo->anim.pCursor = pCursor; pDev->spriteInfo->anim.pCursor = pCursor;
pDev->spriteInfo->anim.pScreen = pScreen; pDev->spriteInfo->anim.pScreen = pScreen;
if (!as->BlockHandler) if (!as->timer_set) {
Wrap(as, pScreen, BlockHandler, AnimCurScreenBlockHandler); TimerSet(as->timer, TimerAbsolute, pDev->spriteInfo->anim.time,
AnimCurTimerNotify, pScreen);
as->timer_set = TRUE;
}
} }
} }
else else
@ -239,8 +234,11 @@ AnimCurSetCursorPosition(DeviceIntPtr pDev,
if (pDev->spriteInfo->anim.pCursor) { if (pDev->spriteInfo->anim.pCursor) {
pDev->spriteInfo->anim.pScreen = pScreen; pDev->spriteInfo->anim.pScreen = pScreen;
if (!as->BlockHandler) if (!as->timer_set) {
Wrap(as, pScreen, BlockHandler, AnimCurScreenBlockHandler); TimerSet(as->timer, TimerAbsolute, pDev->spriteInfo->anim.time,
AnimCurTimerNotify, pScreen);
as->timer_set = TRUE;
}
} }
ret = (*pScreen->SetCursorPosition) (pDev, pScreen, x, y, generateEvent); ret = (*pScreen->SetCursorPosition) (pDev, pScreen, x, y, generateEvent);
Wrap(as, pScreen, SetCursorPosition, AnimCurSetCursorPosition); Wrap(as, pScreen, SetCursorPosition, AnimCurSetCursorPosition);
@ -316,9 +314,14 @@ AnimCurInit(ScreenPtr pScreen)
as = (AnimCurScreenPtr) malloc(sizeof(AnimCurScreenRec)); as = (AnimCurScreenPtr) malloc(sizeof(AnimCurScreenRec));
if (!as) if (!as)
return FALSE; return FALSE;
Wrap(as, pScreen, CloseScreen, AnimCurCloseScreen); as->timer = TimerSet(NULL, TimerAbsolute, 0, AnimCurTimerNotify, pScreen);
if (!as->timer) {
free(as);
return FALSE;
}
as->timer_set = FALSE;
as->BlockHandler = NULL; Wrap(as, pScreen, CloseScreen, AnimCurCloseScreen);
Wrap(as, pScreen, CursorLimits, AnimCurCursorLimits); Wrap(as, pScreen, CursorLimits, AnimCurCursorLimits);
Wrap(as, pScreen, DisplayCursor, AnimCurDisplayCursor); Wrap(as, pScreen, DisplayCursor, AnimCurDisplayCursor);