Don't use BlitARGBto555PixelAlpha() for SDL_PIXELFORMAT_ARGB1555

This didn't properly take into account destination alpha.

Fixes https://github.com/libsdl-org/SDL/issues/8401

(cherry picked from commit 1aea43846e)
(cherry picked from commit c9f3cbe02f)
This commit is contained in:
Sam Lantinga 2024-09-25 21:54:05 -07:00
parent b6535836aa
commit 235c87dc92

View file

@ -1222,10 +1222,9 @@ static void BlitARGBto565PixelAlpha(SDL_BlitInfo *info)
DUFFS_LOOP4({ DUFFS_LOOP4({
Uint32 s = *srcp; Uint32 s = *srcp;
unsigned alpha = s >> 27; /* downscale alpha to 5 bits */ unsigned alpha = s >> 27; /* downscale alpha to 5 bits */
/* FIXME: Here we special-case opaque alpha since the /* Here we special-case opaque alpha since the
compositioning used (>>8 instead of /255) doesn't handle compositioning used (>>8 instead of /255) doesn't handle
it correctly. Also special-case alpha=0 for speed? it correctly. */
Benchmark this! */
if (alpha) { if (alpha) {
if (alpha == (SDL_ALPHA_OPAQUE >> 3)) { if (alpha == (SDL_ALPHA_OPAQUE >> 3)) {
*dstp = (Uint16)((s >> 8 & 0xf800) + (s >> 5 & 0x7e0) + (s >> 3 & 0x1f)); *dstp = (Uint16)((s >> 8 & 0xf800) + (s >> 5 & 0x7e0) + (s >> 3 & 0x1f));
@ -1235,8 +1234,7 @@ static void BlitARGBto565PixelAlpha(SDL_BlitInfo *info)
* convert source and destination to G0RAB65565 * convert source and destination to G0RAB65565
* and blend all components at the same time * and blend all components at the same time
*/ */
s = ((s & 0xfc00) << 11) + (s >> 8 & 0xf800) s = ((s & 0xfc00) << 11) + (s >> 8 & 0xf800) + (s >> 3 & 0x1f);
+ (s >> 3 & 0x1f);
d = (d | d << 16) & 0x07e0f81f; d = (d | d << 16) & 0x07e0f81f;
d += (s - d) * alpha >> 5; d += (s - d) * alpha >> 5;
d &= 0x07e0f81f; d &= 0x07e0f81f;
@ -1268,21 +1266,19 @@ static void BlitARGBto555PixelAlpha(SDL_BlitInfo *info)
unsigned alpha; unsigned alpha;
Uint32 s = *srcp; Uint32 s = *srcp;
alpha = s >> 27; /* downscale alpha to 5 bits */ alpha = s >> 27; /* downscale alpha to 5 bits */
/* FIXME: Here we special-case opaque alpha since the /* Here we special-case opaque alpha since the
compositioning used (>>8 instead of /255) doesn't handle compositioning used (>>8 instead of /255) doesn't handle
it correctly. Also special-case alpha=0 for speed? it correctly. */
Benchmark this! */
if (alpha) { if (alpha) {
if (alpha == (SDL_ALPHA_OPAQUE >> 3)) { if (alpha == (SDL_ALPHA_OPAQUE >> 3)) {
*dstp = (Uint16)((s >> 9 & 0x7c00) + (s >> 6 & 0x3e0) + (s >> 3 & 0x1f)); *dstp = (Uint16)((s >> 9 & 0x7c00) + (s >> 6 & 0x3e0) + (s >> 3 & 0x1f));
} else { } else {
Uint32 d = *dstp; Uint32 d = *dstp;
/* /*
* convert source and destination to G0RAB65565 * convert source and destination to G0RAB55555
* and blend all components at the same time * and blend all components at the same time
*/ */
s = ((s & 0xf800) << 10) + (s >> 9 & 0x7c00) s = ((s & 0xf800) << 10) + (s >> 9 & 0x7c00) + (s >> 3 & 0x1f);
+ (s >> 3 & 0x1f);
d = (d | d << 16) & 0x03e07c1f; d = (d | d << 16) & 0x03e07c1f;
d += (s - d) * alpha >> 5; d += (s - d) * alpha >> 5;
d &= 0x03e07c1f; d &= 0x03e07c1f;
@ -1452,7 +1448,7 @@ SDL_BlitFunc SDL_CalculateBlitA(SDL_Surface *surface)
if (sf->BytesPerPixel == 4 && sf->Amask == 0xff000000 && sf->Gmask == 0xff00 && ((sf->Rmask == 0xff && df->Rmask == 0x1f) || (sf->Bmask == 0xff && df->Bmask == 0x1f))) { if (sf->BytesPerPixel == 4 && sf->Amask == 0xff000000 && sf->Gmask == 0xff00 && ((sf->Rmask == 0xff && df->Rmask == 0x1f) || (sf->Bmask == 0xff && df->Bmask == 0x1f))) {
if (df->Gmask == 0x7e0) { if (df->Gmask == 0x7e0) {
return BlitARGBto565PixelAlpha; return BlitARGBto565PixelAlpha;
} else if (df->Gmask == 0x3e0) { } else if (df->Gmask == 0x3e0 && !df->Amask) {
return BlitARGBto555PixelAlpha; return BlitARGBto555PixelAlpha;
} }
} }