From 401a8d6e1379133863e3271374dc21850d0d3cab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 28 Jun 2016 17:22:47 +0900 Subject: [PATCH] dix: Work around non-premultiplied ARGB cursor data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some games incorrectly use non-premultiplied ARGB cursor data, presumably because that's what Windows uses. On some hardware (and with SWcursor), this breaks areas of the cursor which are supposed to be transparent (and presumably also translucent areas, but that's less noticeable). This change checks for pixels with alpha == 0 and any non-alpha component != 0. If any such pixel is found, the data is assumed to be non-premultiplied and fixed up by multiplying the RGB components with the alpha component. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=92309 Signed-off-by: Michel Dänzer Reviewed-by: Alex Deucher --- dix/cursor.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/dix/cursor.c b/dix/cursor.c index e45945619..25d676779 100644 --- a/dix/cursor.c +++ b/dix/cursor.c @@ -288,6 +288,29 @@ AllocARGBCursor(unsigned char *psrcbits, unsigned char *pmaskbits, goto error; *ppCurs = pCurs; + + if (argb) { + size_t i, size = bits->width * bits->height; + + for (i = 0; i < size; i++) { + if ((argb[i] & 0xff000000) == 0 && (argb[i] & 0xffffff) != 0) { + /* ARGB data doesn't seem pre-multiplied, fix it */ + for (i = 0; i < size; i++) { + CARD32 a, 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; + + argb[i] = a << 24 | ar << 16 | ag << 8 | ab; + } + + break; + } + } + } + return Success; error: