animcur: Fix transitions between animated cursors

We weren't cancelling the old timer when changing cursors, making things
go all crashy. Logically we could always cancel the timer first, but
then we'd have to call TimerSet to re-arm ourselves, and GetTimeInMillis
is potentially expensive.

Reported-by: https://devtalk.nvidia.com/default/topic/1028172/linux/titan-v-ubuntu-16-04lts-and-387-34-driver-crashes-badly/post/5230967/#5230967
Signed-off-by: Adam Jackson <ajax@redhat.com>
Reviewed-by: Aaron Plattner <aplattner@nvidia.com>
Tested-by: Aaron Plattner <aplattner@nvidia.com>
This commit is contained in:
Adam Jackson 2018-01-09 10:54:05 -05:00
parent a09fbe6c82
commit de60245e05

View File

@ -151,11 +151,20 @@ AnimCurTimerNotify(OsTimerPtr timer, CARD32 now, void *arg)
return ac->elts[elt].delay;
}
static void
AnimCurCancelTimer(DeviceIntPtr pDev)
{
CursorPtr cur = pDev->spriteInfo->anim.pCursor;
if (IsAnimCur(cur))
TimerCancel(GetAnimCur(cur)->timer);
}
static Bool
AnimCurDisplayCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
{
AnimCurScreenPtr as = GetAnimCurScreen(pScreen);
Bool ret;
Bool ret = TRUE;
if (IsFloating(pDev))
return FALSE;
@ -165,8 +174,10 @@ AnimCurDisplayCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
if (pCursor != pDev->spriteInfo->anim.pCursor) {
AnimCurPtr ac = GetAnimCur(pCursor);
ret = (*pScreen->DisplayCursor)
(pDev, pScreen, ac->elts[0].pCursor);
AnimCurCancelTimer(pDev);
ret = (*pScreen->DisplayCursor) (pDev, pScreen,
ac->elts[0].pCursor);
if (ret) {
pDev->spriteInfo->anim.elt = 0;
pDev->spriteInfo->anim.pCursor = pCursor;
@ -176,15 +187,9 @@ AnimCurDisplayCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
AnimCurTimerNotify, pDev);
}
}
else
ret = TRUE;
}
else {
CursorPtr old = pDev->spriteInfo->anim.pCursor;
if (old && IsAnimCur(old))
TimerCancel(GetAnimCur(old)->timer);
AnimCurCancelTimer(pDev);
pDev->spriteInfo->anim.pCursor = 0;
pDev->spriteInfo->anim.pScreen = 0;
ret = (*pScreen->DisplayCursor) (pDev, pScreen, pCursor);