summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Jackson <ajax@redhat.com>2017-10-26 15:24:39 -0400
committerAdam Jackson <ajax@redhat.com>2018-01-22 14:07:25 -0500
commit693f0e21d55d6e9fe792d91e76e4168aa813db71 (patch)
treea9d11fa581df38d01d8b78372c0485e8c8a8c269
parent354c48304d27f75b7c33c03a0adb050c37788ccf (diff)
animcur: Run the timer from the device, not the screen
This is very slightly more efficient since the callback now doesn't need to walk every input device, instead we know exactly which device's cursor is being updated. AnimCurTimerNotify() gets outdented nicely as a result. A more important side effect is that we can stop using the TimerAbsolute mode and just pass in the relative delay. In AnimCurSetCursorPosition, we no longer need to rearm the timer with the new screen; it is enough to update the device's state. In AnimCurDisplayCursor we need to notice when we're switching from animated cursor to regular and cancel the existing timer. Reviewed-by: Robert Morell <rmorell@nvidia.com> Tested-by: Robert Morell <rmorell@nvidia.com> Signed-off-by: Adam Jackson <ajax@redhat.com> (cherry picked from commit 094a63d56fbfb9e23210cc9ac538fb198af37cee)
-rw-r--r--render/animcur.c87
1 files changed, 29 insertions, 58 deletions
diff --git a/render/animcur.c b/render/animcur.c
index 26a6026ae..9393b4018 100644
--- a/render/animcur.c
+++ b/render/animcur.c
@@ -55,6 +55,7 @@ typedef struct _AnimCurElt {
typedef struct _AnimCur {
int nelt; /* number of elements in the elts array */
AnimCurElt *elts; /* actually allocated right after the structure */
+ OsTimerPtr timer;
} AnimCurRec, *AnimCurPtr;
typedef struct _AnimScrPriv {
@@ -65,8 +66,6 @@ typedef struct _AnimScrPriv {
RealizeCursorProcPtr RealizeCursor;
UnrealizeCursorProcPtr UnrealizeCursor;
RecolorCursorProcPtr RecolorCursor;
- OsTimerPtr timer;
- Bool timer_set;
} AnimCurScreenRec, *AnimCurScreenPtr;
static unsigned char empty[4];
@@ -130,49 +129,27 @@ AnimCurCursorLimits(DeviceIntPtr pDev,
static CARD32
AnimCurTimerNotify(OsTimerPtr timer, CARD32 now, void *arg)
{
- ScreenPtr pScreen = arg;
+ DeviceIntPtr dev = arg;
+ ScreenPtr pScreen = dev->spriteInfo->anim.pScreen;
AnimCurScreenPtr as = GetAnimCurScreen(pScreen);
- DeviceIntPtr dev;
- Bool activeDevice = FALSE;
- CARD32 soonest = ~0; /* earliest time to wakeup again */
-
- for (dev = inputInfo.devices; dev; dev = dev->next) {
- if (IsPointerDevice(dev) && pScreen == dev->spriteInfo->anim.pScreen) {
- if (!activeDevice)
- activeDevice = TRUE;
-
- if ((INT32) (now - dev->spriteInfo->anim.time) >= 0) {
- AnimCurPtr ac = GetAnimCur(dev->spriteInfo->anim.pCursor);
- int elt = (dev->spriteInfo->anim.elt + 1) % ac->nelt;
- DisplayCursorProcPtr DisplayCursor;
-
- /*
- * Not a simple Unwrap/Wrap as this
- * isn't called along the DisplayCursor
- * wrapper chain.
- */
- DisplayCursor = pScreen->DisplayCursor;
- pScreen->DisplayCursor = as->DisplayCursor;
- (void) (*pScreen->DisplayCursor) (dev,
- pScreen,
- ac->elts[elt].pCursor);
- as->DisplayCursor = pScreen->DisplayCursor;
- pScreen->DisplayCursor = DisplayCursor;
-
- dev->spriteInfo->anim.elt = elt;
- dev->spriteInfo->anim.time = now + ac->elts[elt].delay;
- }
- if (soonest > dev->spriteInfo->anim.time)
- soonest = dev->spriteInfo->anim.time;
- }
- }
+ AnimCurPtr ac = GetAnimCur(dev->spriteInfo->anim.pCursor);
+ int elt = (dev->spriteInfo->anim.elt + 1) % ac->nelt;
+ DisplayCursorProcPtr DisplayCursor = pScreen->DisplayCursor;
- if (activeDevice)
- return soonest - now;
+ /*
+ * Not a simple Unwrap/Wrap as this isn't called along the DisplayCursor
+ * wrapper chain.
+ */
+ pScreen->DisplayCursor = as->DisplayCursor;
+ (void) (*pScreen->DisplayCursor) (dev, pScreen, ac->elts[elt].pCursor);
+ as->DisplayCursor = pScreen->DisplayCursor;
+ pScreen->DisplayCursor = DisplayCursor;
- as->timer_set = FALSE;
- return 0;
+ dev->spriteInfo->anim.elt = elt;
+ dev->spriteInfo->anim.time = now + ac->elts[elt].delay;
+
+ return ac->elts[elt].delay;
}
static Bool
@@ -198,17 +175,19 @@ AnimCurDisplayCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
pDev->spriteInfo->anim.pCursor = pCursor;
pDev->spriteInfo->anim.pScreen = pScreen;
- if (!as->timer_set) {
- TimerSet(as->timer, TimerAbsolute, pDev->spriteInfo->anim.time,
- AnimCurTimerNotify, pScreen);
- as->timer_set = TRUE;
- }
+ ac->timer = TimerSet(ac->timer, 0, ac->elts[0].delay,
+ AnimCurTimerNotify, pDev);
}
}
else
ret = TRUE;
}
else {
+ CursorPtr old = pDev->spriteInfo->anim.pCursor;
+
+ if (old && IsAnimCur(old))
+ TimerCancel(GetAnimCur(old)->timer);
+
pDev->spriteInfo->anim.pCursor = 0;
pDev->spriteInfo->anim.pScreen = 0;
ret = (*pScreen->DisplayCursor) (pDev, pScreen, pCursor);
@@ -227,12 +206,6 @@ AnimCurSetCursorPosition(DeviceIntPtr pDev,
Unwrap(as, pScreen, SetCursorPosition);
if (pDev->spriteInfo->anim.pCursor) {
pDev->spriteInfo->anim.pScreen = pScreen;
-
- if (!as->timer_set) {
- TimerSet(as->timer, TimerAbsolute, pDev->spriteInfo->anim.time,
- AnimCurTimerNotify, pScreen);
- as->timer_set = TRUE;
- }
}
ret = (*pScreen->SetCursorPosition) (pDev, pScreen, x, y, generateEvent);
Wrap(as, pScreen, SetCursorPosition, AnimCurSetCursorPosition);
@@ -307,11 +280,6 @@ AnimCurInit(ScreenPtr pScreen)
return FALSE;
as = GetAnimCurScreen(pScreen);
- as->timer = TimerSet(NULL, TimerAbsolute, 0, AnimCurTimerNotify, pScreen);
- if (!as->timer) {
- return FALSE;
- }
- as->timer_set = FALSE;
Wrap(as, pScreen, CloseScreen, AnimCurCloseScreen);
@@ -359,10 +327,14 @@ AnimCursorCreate(CursorPtr *cursors, CARD32 *deltas, int ncursor,
pCursor->id = cid;
+ ac = GetAnimCur(pCursor);
+ ac->timer = TimerSet(NULL, 0, 0, AnimCurTimerNotify, NULL);
+
/* security creation/labeling check */
rc = XaceHook(XACE_RESOURCE_ACCESS, client, cid, RT_CURSOR, pCursor,
RT_NONE, NULL, DixCreateAccess);
if (rc != Success) {
+ TimerFree(ac->timer);
dixFiniPrivates(pCursor, PRIVATE_CURSOR);
free(pCursor);
return rc;
@@ -372,7 +344,6 @@ AnimCursorCreate(CursorPtr *cursors, CARD32 *deltas, int ncursor,
* Fill in the AnimCurRec
*/
animCursorBits.refcnt++;
- ac = GetAnimCur(pCursor);
ac->nelt = ncursor;
ac->elts = (AnimCurElt *) (ac + 1);