From 74d83ead354ed969554ff9c7d69e7619d4d3e149 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 4 May 2015 21:47:40 -0700 Subject: [PATCH] Fixed bug 2976 - Fix RGBA<->RGBA blit that was broken with the optimization from Bug 11 id.zeta The optimization from Bug 11 added a code branch on cases where the source RGB masks match the destination RGB masks and a optimized blit function Blit4to4MaskAlpha that always overrides the source alpha info would be chosen. Unfortunately, the branch also errorneously took over the RGBA<->RGBA blitting cases where the source alpha info should be copied, while they would instead get overriden in Blit4to4MaskAlpha. The attached patch fixes that by handling the RGBA<->RGBA cases correctly in that branch with the original BlitNtoNCopyAlpha as well as uses an optimized Blit4to4CopyAlpha along the same vein. --- src/video/SDL_blit_N.c | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/src/video/SDL_blit_N.c b/src/video/SDL_blit_N.c index 41615be5755a6..e73e58ff0253c 100644 --- a/src/video/SDL_blit_N.c +++ b/src/video/SDL_blit_N.c @@ -2114,6 +2114,33 @@ Blit4to4MaskAlpha(SDL_BlitInfo * info) } } +/* blits 32 bit RGBA<->RGBA with both surfaces having the same R,G,B,A fields */ +static void +Blit4to4CopyAlpha(SDL_BlitInfo * info) +{ + int width = info->dst_w; + int height = info->dst_h; + Uint32 *src = (Uint32 *) info->src; + int srcskip = info->src_skip; + Uint32 *dst = (Uint32 *) info->dst; + int dstskip = info->dst_skip; + + /* RGBA->RGBA, COPY_ALPHA */ + while (height--) { + /* *INDENT-OFF* */ + DUFFS_LOOP( + { + *dst = *src; + ++dst; + ++src; + }, + width); + /* *INDENT-ON* */ + src = (Uint32 *) ((Uint8 *) src + srcskip); + dst = (Uint32 *) ((Uint8 *) dst + dstskip); + } +} + static void BlitNtoN(SDL_BlitInfo * info) { @@ -2562,8 +2589,17 @@ SDL_CalculateBlitN(SDL_Surface * surface) srcfmt->Rmask == dstfmt->Rmask && srcfmt->Gmask == dstfmt->Gmask && srcfmt->Bmask == dstfmt->Bmask) { - /* Fastpath C fallback: 32bit RGB<->RGBA blit with matching RGB */ - blitfun = Blit4to4MaskAlpha; + if (a_need == COPY_ALPHA) { + if (srcfmt->Amask == dstfmt->Amask) { + /* Fastpath C fallback: 32bit RGBA<->RGBA blit with matching RGBA */ + blitfun = Blit4to4CopyAlpha; + } else { + blitfun = BlitNtoNCopyAlpha; + } + } else { + /* Fastpath C fallback: 32bit RGB<->RGBA blit with matching RGB */ + blitfun = Blit4to4MaskAlpha; + } } else if (a_need == COPY_ALPHA) { blitfun = BlitNtoNCopyAlpha; }