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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
diff --git a/src/video/SDL_blit_N.c b/src/video/SDL_blit_N.c
index 41615be..e73e58f 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;
}