mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-09-05 19:08:12 +00:00
Restore BlitARGB 555 and 565 blending algorithms
This commit is contained in:

committed by
Sam Lantinga

parent
5cec91e27a
commit
8e3afd56f5
@@ -952,6 +952,97 @@ static void Blit555to555SurfaceAlpha(SDL_BlitInfo *info)
|
||||
}
|
||||
}
|
||||
|
||||
/* fast ARGB8888->RGB565 blending with pixel alpha */
|
||||
static void BlitARGBto565PixelAlpha(SDL_BlitInfo *info)
|
||||
{
|
||||
int width = info->dst_w;
|
||||
int height = info->dst_h;
|
||||
Uint32 *srcp = (Uint32 *)info->src;
|
||||
int srcskip = info->src_skip >> 2;
|
||||
Uint16 *dstp = (Uint16 *)info->dst;
|
||||
int dstskip = info->dst_skip >> 1;
|
||||
|
||||
while (height--) {
|
||||
/* *INDENT-OFF* */ /* clang-format off */
|
||||
DUFFS_LOOP4({
|
||||
Uint32 s = *srcp;
|
||||
unsigned alpha = s >> 27; /* downscale alpha to 5 bits */
|
||||
/* FIXME: Here we special-case opaque alpha since the
|
||||
compositioning used (>>8 instead of /255) doesn't handle
|
||||
it correctly. Also special-case alpha=0 for speed?
|
||||
Benchmark this! */
|
||||
if (alpha) {
|
||||
if (alpha == (SDL_ALPHA_OPAQUE >> 3)) {
|
||||
*dstp = (Uint16)((s >> 8 & 0xf800) + (s >> 5 & 0x7e0) + (s >> 3 & 0x1f));
|
||||
} else {
|
||||
Uint32 d = *dstp;
|
||||
/*
|
||||
* convert source and destination to G0RAB65565
|
||||
* and blend all components at the same time
|
||||
*/
|
||||
s = ((s & 0xfc00) << 11) + (s >> 8 & 0xf800)
|
||||
+ (s >> 3 & 0x1f);
|
||||
d = (d | d << 16) & 0x07e0f81f;
|
||||
d += (s - d) * alpha >> 5;
|
||||
d &= 0x07e0f81f;
|
||||
*dstp = (Uint16)(d | d >> 16);
|
||||
}
|
||||
}
|
||||
srcp++;
|
||||
dstp++;
|
||||
}, width);
|
||||
/* *INDENT-ON* */ /* clang-format on */
|
||||
srcp += srcskip;
|
||||
dstp += dstskip;
|
||||
}
|
||||
}
|
||||
|
||||
/* fast ARGB8888->RGB555 blending with pixel alpha */
|
||||
static void BlitARGBto555PixelAlpha(SDL_BlitInfo *info)
|
||||
{
|
||||
int width = info->dst_w;
|
||||
int height = info->dst_h;
|
||||
Uint32 *srcp = (Uint32 *)info->src;
|
||||
int srcskip = info->src_skip >> 2;
|
||||
Uint16 *dstp = (Uint16 *)info->dst;
|
||||
int dstskip = info->dst_skip >> 1;
|
||||
|
||||
while (height--) {
|
||||
/* *INDENT-OFF* */ /* clang-format off */
|
||||
DUFFS_LOOP4({
|
||||
unsigned alpha;
|
||||
Uint32 s = *srcp;
|
||||
alpha = s >> 27; /* downscale alpha to 5 bits */
|
||||
/* FIXME: Here we special-case opaque alpha since the
|
||||
compositioning used (>>8 instead of /255) doesn't handle
|
||||
it correctly. Also special-case alpha=0 for speed?
|
||||
Benchmark this! */
|
||||
if (alpha) {
|
||||
if (alpha == (SDL_ALPHA_OPAQUE >> 3)) {
|
||||
*dstp = (Uint16)((s >> 9 & 0x7c00) + (s >> 6 & 0x3e0) + (s >> 3 & 0x1f));
|
||||
} else {
|
||||
Uint32 d = *dstp;
|
||||
/*
|
||||
* convert source and destination to G0RAB65565
|
||||
* and blend all components at the same time
|
||||
*/
|
||||
s = ((s & 0xf800) << 10) + (s >> 9 & 0x7c00)
|
||||
+ (s >> 3 & 0x1f);
|
||||
d = (d | d << 16) & 0x03e07c1f;
|
||||
d += (s - d) * alpha >> 5;
|
||||
d &= 0x03e07c1f;
|
||||
*dstp = (Uint16)(d | d >> 16);
|
||||
}
|
||||
}
|
||||
srcp++;
|
||||
dstp++;
|
||||
}, width);
|
||||
/* *INDENT-ON* */ /* clang-format on */
|
||||
srcp += srcskip;
|
||||
dstp += dstskip;
|
||||
}
|
||||
}
|
||||
|
||||
/* General (slow) N->N blending with per-surface alpha */
|
||||
static void BlitNtoNSurfaceAlpha(SDL_BlitInfo *info)
|
||||
{
|
||||
@@ -1127,6 +1218,13 @@ SDL_BlitFunc SDL_CalculateBlitA(SDL_Surface *surface)
|
||||
}
|
||||
|
||||
case 2:
|
||||
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) {
|
||||
return BlitARGBto565PixelAlpha;
|
||||
} else if (df->Gmask == 0x3e0) {
|
||||
return BlitARGBto555PixelAlpha;
|
||||
}
|
||||
}
|
||||
return BlitNtoNPixelAlpha;
|
||||
|
||||
case 4:
|
||||
|
Reference in New Issue
Block a user