[PATCH RFC xserver] dix: Work around non-premultiplied ARGB cursor data

Alex Deucher alexdeucher at gmail.com
Fri Jul 15 13:30:07 UTC 2016


On Tue, Jun 28, 2016 at 4:22 AM, Michel Dänzer <michel at daenzer.net> wrote:
> From: Michel Dänzer <michel.daenzer at amd.com>
>
> 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 at amd.com>
> ---
>
> I'm on the fence about whether this is a good or bad idea.
>
> Pro:
> * Allows users with affected setups to play broken games
> * Less overhead than a corresponding workaround in the driver
>
> Con:
> * Makes the problem completely invisible to game developers, so once
>   it's in we can probably never remove it again
>
> Opinions?

Seems like a good idea to me.
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>


>
>  dix/cursor.c | 23 +++++++++++++++++++++++
>  1 file changed, 23 insertions(+)
>
> diff --git a/dix/cursor.c b/dix/cursor.c
> index e459456..25d6767 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:
> --
> 2.8.1
>
> _______________________________________________
> xorg-devel at lists.x.org: X.Org development
> Archives: http://lists.x.org/archives/xorg-devel
> Info: https://lists.x.org/mailman/listinfo/xorg-devel


More information about the xorg-devel mailing list