[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