diff --git a/U_0001-animcur-Use-fixed-size-screen-private.patch b/U_0001-animcur-Use-fixed-size-screen-private.patch new file mode 100644 index 0000000..a8dc2a9 --- /dev/null +++ b/U_0001-animcur-Use-fixed-size-screen-private.patch @@ -0,0 +1,71 @@ +From 26841b2c9ea03fda8b2d0da254e0344fd2a3afce Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Thu, 26 Oct 2017 13:40:57 -0400 +Subject: [PATCH] animcur: Use fixed-size screen private + +Reviewed-by: Robert Morell +Tested-by: Robert Morell +Signed-off-by: Adam Jackson +(cherry picked from commit 3abbdb7318018584a27220737bd92081ce8ee67c) +--- + render/animcur.c | 16 ++++------------ + 1 file changed, 4 insertions(+), 12 deletions(-) + +diff --git a/render/animcur.c b/render/animcur.c +index 52e6b8b79..3f85f9a4f 100644 +--- a/render/animcur.c ++++ b/render/animcur.c +@@ -77,12 +77,9 @@ static CursorBits animCursorBits = { + + static DevPrivateKeyRec AnimCurScreenPrivateKeyRec; + +-#define AnimCurScreenPrivateKey (&AnimCurScreenPrivateKeyRec) +- + #define IsAnimCur(c) ((c) && ((c)->bits == &animCursorBits)) + #define GetAnimCur(c) ((AnimCurPtr) ((((char *)(c) + CURSOR_REC_SIZE)))) +-#define GetAnimCurScreen(s) ((AnimCurScreenPtr)dixLookupPrivate(&(s)->devPrivates, AnimCurScreenPrivateKey)) +-#define SetAnimCurScreen(s,p) dixSetPrivate(&(s)->devPrivates, AnimCurScreenPrivateKey, p) ++#define GetAnimCurScreen(s) ((AnimCurScreenPtr)dixLookupPrivate(&(s)->devPrivates, &AnimCurScreenPrivateKeyRec)) + + #define Wrap(as,s,elt,func) (((as)->elt = (s)->elt), (s)->elt = func) + #define Unwrap(as,s,elt) ((s)->elt = (as)->elt) +@@ -101,9 +98,7 @@ AnimCurCloseScreen(ScreenPtr pScreen) + Unwrap(as, pScreen, RealizeCursor); + Unwrap(as, pScreen, UnrealizeCursor); + Unwrap(as, pScreen, RecolorCursor); +- SetAnimCurScreen(pScreen, 0); + ret = (*pScreen->CloseScreen) (pScreen); +- free(as); + return ret; + } + +@@ -308,15 +303,13 @@ AnimCurInit(ScreenPtr pScreen) + { + AnimCurScreenPtr as; + +- if (!dixRegisterPrivateKey(&AnimCurScreenPrivateKeyRec, PRIVATE_SCREEN, 0)) ++ if (!dixRegisterPrivateKey(&AnimCurScreenPrivateKeyRec, PRIVATE_SCREEN, ++ sizeof(AnimCurScreenRec))) + return FALSE; + +- as = (AnimCurScreenPtr) malloc(sizeof(AnimCurScreenRec)); +- if (!as) +- return FALSE; ++ as = GetAnimCurScreen(pScreen); + as->timer = TimerSet(NULL, TimerAbsolute, 0, AnimCurTimerNotify, pScreen); + if (!as->timer) { +- free(as); + return FALSE; + } + as->timer_set = FALSE; +@@ -329,7 +322,6 @@ AnimCurInit(ScreenPtr pScreen) + Wrap(as, pScreen, RealizeCursor, AnimCurRealizeCursor); + Wrap(as, pScreen, UnrealizeCursor, AnimCurUnrealizeCursor); + Wrap(as, pScreen, RecolorCursor, AnimCurRecolorCursor); +- SetAnimCurScreen(pScreen, as); + return TRUE; + } + +-- +2.13.6 + diff --git a/U_0002-animcur-Return-the-next-interval-directly-from-the-t.patch b/U_0002-animcur-Return-the-next-interval-directly-from-the-t.patch new file mode 100644 index 0000000..9fe4d54 --- /dev/null +++ b/U_0002-animcur-Return-the-next-interval-directly-from-the-t.patch @@ -0,0 +1,38 @@ +From 354c48304d27f75b7c33c03a0adb050c37788ccf Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Thu, 26 Oct 2017 13:53:06 -0400 +Subject: [PATCH] animcur: Return the next interval directly from the timer + callback + +If the return value is non-zero here, DoTimer() will automatically rearm +the timer for the new (relative) delay. 'soonest' is in absolute time, +so subtract off 'now' and return that. + +Reviewed-by: Robert Morell +Tested-by: Robert Morell +Signed-off-by: Adam Jackson +(cherry picked from commit cc3241a712684f8c7147f5688e9ee3ecb5a93b87) +--- + render/animcur.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/render/animcur.c b/render/animcur.c +index 3f85f9a4f..26a6026ae 100644 +--- a/render/animcur.c ++++ b/render/animcur.c +@@ -169,10 +169,9 @@ AnimCurTimerNotify(OsTimerPtr timer, CARD32 now, void *arg) + } + + if (activeDevice) +- TimerSet(as->timer, TimerAbsolute, soonest, AnimCurTimerNotify, pScreen); +- else +- as->timer_set = FALSE; ++ return soonest - now; + ++ as->timer_set = FALSE; + return 0; + } + +-- +2.13.6 + diff --git a/U_0003-animcur-Run-the-timer-from-the-device-not-the-screen.patch b/U_0003-animcur-Run-the-timer-from-the-device-not-the-screen.patch new file mode 100644 index 0000000..0d109eb --- /dev/null +++ b/U_0003-animcur-Run-the-timer-from-the-device-not-the-screen.patch @@ -0,0 +1,188 @@ +From 693f0e21d55d6e9fe792d91e76e4168aa813db71 Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Thu, 26 Oct 2017 15:24:39 -0400 +Subject: [PATCH] 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 +Tested-by: Robert Morell +Signed-off-by: Adam Jackson +(cherry picked from commit 094a63d56fbfb9e23210cc9ac538fb198af37cee) +--- + render/animcur.c | 87 +++++++++++++++++++------------------------------------- + 1 file 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); + +-- +2.13.6 + diff --git a/U_0004-animcur-Fix-transitions-between-animated-cursors.patch b/U_0004-animcur-Fix-transitions-between-animated-cursors.patch new file mode 100644 index 0000000..2d86b5b --- /dev/null +++ b/U_0004-animcur-Fix-transitions-between-animated-cursors.patch @@ -0,0 +1,78 @@ +From 5e83ebd76738455c443a66024b0b5eb92930b36c Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Tue, 9 Jan 2018 10:54:05 -0500 +Subject: [PATCH] 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 +Reviewed-by: Aaron Plattner +Tested-by: Aaron Plattner +(cherry picked from commit de60245e05c0d2528d4ff42557a044387e53315c) +--- + render/animcur.c | 25 +++++++++++++++---------- + 1 file changed, 15 insertions(+), 10 deletions(-) + +diff --git a/render/animcur.c b/render/animcur.c +index 9393b4018..e585a8f23 100644 +--- a/render/animcur.c ++++ b/render/animcur.c +@@ -152,11 +152,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; +@@ -166,8 +175,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.time = +@@ -179,15 +190,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); +-- +2.13.6 + diff --git a/u_cursors-animation.patch b/u_cursors-animation.patch deleted file mode 100644 index 7f76966..0000000 --- a/u_cursors-animation.patch +++ /dev/null @@ -1,34 +0,0 @@ -Author: Илья Индиго -Subject: [PATCH] render: Reset animated cursor timer when sprite changes. -Patch-Mainline: To be upstreamed -Git-commit: 1c4545021f835f077362e7364d28752b7d6e968e -References: boo#1020061 -Signed-off-by: Michal Srb - -Previously the timer would not reset if the sprite changed and timer from a -previous animated cursor was pending. That caused trouble with non-looped -animated cursors that use very long delay on the last frame to prevent looping. -No animation played after such non-looped animation played once. ---- - render/animcur.c | 8 +++----- - 1 file changed, 3 insertions(+), 5 deletions(-) - -diff --git a/render/animcur.c b/render/animcur.c -index 52e6b8b79..4216c3a40 100644 ---- a/render/animcur.c -+++ b/render/animcur.c -@@ -204,11 +204,9 @@ 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; -- } -+ TimerSet(as->timer, TimerAbsolute, pDev->spriteInfo->anim.time, -+ AnimCurTimerNotify, pScreen); -+ as->timer_set = TRUE; - } - } - else diff --git a/xorg-x11-server.changes b/xorg-x11-server.changes index b2ab804..76b0b01 100644 --- a/xorg-x11-server.changes +++ b/xorg-x11-server.changes @@ -1,3 +1,15 @@ +------------------------------------------------------------------- +Fri Feb 9 15:13:00 UTC 2018 - sndirsch@suse.com + +- U_0001-animcur-Use-fixed-size-screen-private.patch, + U_0002-animcur-Return-the-next-interval-directly-from-the-t.patch, + U_0003-animcur-Run-the-timer-from-the-device-not-the-screen.patch, + U_0004-animcur-Fix-transitions-between-animated-cursors.patch + * There is a bug in version 1.19 of the X.org X server that can + cause an infinite recursion in the animated cursor code, which + has been fixed by these patches (boo#1080312) +- supersedes u_cursors-animation.patch (boo#1020061) + ------------------------------------------------------------------- Tue Jan 9 16:30:28 UTC 2018 - mwilck@suse.com diff --git a/xorg-x11-server.spec b/xorg-x11-server.spec index 2ca1401..36ac111 100644 --- a/xorg-x11-server.spec +++ b/xorg-x11-server.spec @@ -198,7 +198,6 @@ Patch9: u_xorg-wrapper-build-Build-position-independent-code.patch Patch100: u_01-Improved-ConfineToShape.patch Patch101: u_02-DIX-ConfineTo-Don-t-bother-about-the-bounding-box-when-grabbing-a-shaped-window.patch # PATCH-FIX-UPSTREAM u_x86emu-include-order.patch schwab@suse.de -- Change include order to avoid conflict with system header, remove duplicate definitions -Patch103: u_cursors-animation.patch Patch104: u_xorg-server-xdmcp.patch Patch112: u_render-Cast-color-masks-to-unsigned-long-before-shifting-them.patch @@ -222,6 +221,11 @@ Patch1162: b_cache-xkbcomp-output-for-fast-start-up.patch Patch1211: b_0001-Prevent-XSync-Alarms-from-senslessly-calling-CheckTr.patch Patch1222: b_sync-fix.patch +Patch1301: U_0001-animcur-Use-fixed-size-screen-private.patch +Patch1302: U_0002-animcur-Return-the-next-interval-directly-from-the-t.patch +Patch1303: U_0003-animcur-Run-the-timer-from-the-device-not-the-screen.patch +Patch1304: U_0004-animcur-Fix-transitions-between-animated-cursors.patch + %description This package contains the X.Org Server. @@ -331,7 +335,6 @@ sh %{SOURCE92} --verify . %{SOURCE91} # %patch100 -p1 #%patch101 -p1 -%patch103 -p1 %patch104 -p1 %patch112 -p1 @@ -362,6 +365,11 @@ sh %{SOURCE92} --verify . %{SOURCE91} ### patch222 might not be applicable anymore #%patch1222 -p1 +%patch1301 -p1 +%patch1302 -p1 +%patch1303 -p1 +%patch1304 -p1 + %build test -e source-file-list || \ find -L . -type f \! -name '*.orig' \! -path ./source-file-list > \