From b45c74f0f2868689e7ed695b33e8c60cd378df0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 25 Oct 2018 10:50:03 +0200 Subject: [PATCH] dix: Work around non-premultiplied ARGB cursor data harder Turns out some apps (e.g. the Civilization VI game) use non-premultiplied cursor data which doesn't have any pixels with 0 alpha but non-0 non-alpha, but can still result in visual artifacts. This uses the method suggested by Kamil in https://bugs.freedesktop.org/92309#c19: check for pixels where any colour component value is larger than the alpha value, which isn't possible with premultiplied alpha. There can still be non-premultiplied data which won't be caught by this, but that should result in slightly incorrect colours and/or blending at the worst, not wildly incorrect colours such as shown in the bug report below. Bugzilla: https://bugs.freedesktop.org/108355 Suggested-by: Kamil Paral --- dix/cursor.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/dix/cursor.c b/dix/cursor.c index 25d676779..9a088f043 100644 --- a/dix/cursor.c +++ b/dix/cursor.c @@ -293,12 +293,13 @@ AllocARGBCursor(unsigned char *psrcbits, unsigned char *pmaskbits, size_t i, size = bits->width * bits->height; for (i = 0; i < size; i++) { - if ((argb[i] & 0xff000000) == 0 && (argb[i] & 0xffffff) != 0) { + CARD32 a = argb[i] >> 24; + + if (argb[i] > (a << 24 | a << 16 | a << 8 | a)) { /* ARGB data doesn't seem pre-multiplied, fix it */ for (i = 0; i < size; i++) { - CARD32 a, ar, ag, ab; + CARD32 ar, ag, ab; - a = argb[i] >> 24; ar = a * ((argb[i] >> 16) & 0xff) / 0xff; ag = a * ((argb[i] >> 8) & 0xff) / 0xff; ab = a * (argb[i] & 0xff) / 0xff;