summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichel Dänzer <michel.daenzer@amd.com>2016-06-28 17:22:47 +0900
committerAdam Jackson <ajax@redhat.com>2016-07-15 09:53:07 -0400
commit401a8d6e1379133863e3271374dc21850d0d3cab (patch)
tree20b5e2d82f404d7229c167db98960689302ba691
parent033888e7766d226a179357d970223428c19c4b53 (diff)
dix: Work around non-premultiplied ARGB cursor data
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 <michel.daenzer@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--dix/cursor.c23
1 files changed, 23 insertions, 0 deletions
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: