You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
188 lines
7.0 KiB
188 lines
7.0 KiB
6 years ago
|
From 2a798845c62f54c921d6fad7fa7fab596dc7e11b Mon Sep 17 00:00:00 2001
|
||
|
From: Adam Jackson <ajax@redhat.com>
|
||
|
Date: Thu, 26 Oct 2017 15:24:39 -0400
|
||
|
Subject: [PATCH xserver 4/6] 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)
|
||
|
---
|
||
|
render/animcur.c | 85 +++++++++++++++++++-------------------------------------
|
||
|
1 file changed, 28 insertions(+), 57 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;
|
||
|
+ AnimCurPtr ac = GetAnimCur(dev->spriteInfo->anim.pCursor);
|
||
|
+ int elt = (dev->spriteInfo->anim.elt + 1) % ac->nelt;
|
||
|
+ DisplayCursorProcPtr DisplayCursor = pScreen->DisplayCursor;
|
||
|
|
||
|
- 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.
|
||
|
+ */
|
||
|
+ pScreen->DisplayCursor = as->DisplayCursor;
|
||
|
+ (void) (*pScreen->DisplayCursor) (dev, pScreen, ac->elts[elt].pCursor);
|
||
|
+ as->DisplayCursor = pScreen->DisplayCursor;
|
||
|
+ pScreen->DisplayCursor = 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;
|
||
|
|
||
|
- 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;
|
||
|
- }
|
||
|
- }
|
||
|
-
|
||
|
- if (activeDevice)
|
||
|
- return soonest - now;
|
||
|
-
|
||
|
- as->timer_set = FALSE;
|
||
|
- return 0;
|
||
|
+ 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);
|
||
|
|
||
|
--
|
||
|
2.14.3
|