From 3aead2be03070cb8a927cbcd73185de826418803 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 20 Feb 2012 20:56:52 -0500 Subject: [PATCH] Fixed bug 1424 - Handling of alpha channel in Altivec accelerated blit functions evilbite 2012-02-19 09:38:21 PST There is only one Altivec accelerated blit function (ConvertAltivec32to32_prefetch() or ConvertAltivec32to32_noprefetch(), depending on the CPU used) that is supposed to handle all alpha combinations. This works as follows for every pixel line: 1. Blit single pixels until an aligned address is reached 2. Accelerated blit as far as possible 3. Blit single remaining pixels Part 2. is set up correctly to handle different combinations of the alpha channels of the participating surfaces. Parts 1. and 3. only do a simple copy of all the pixel's components from souce to destination. But when the source surface has no alpha channel (Amask is 0, e.g. the video surface) the surface's alpha value must be used instead. Otherwise crap (uninitialized data) is being copied to the destiniation's alpha channel. The attached patch is a quick'n'dirty solution to the problem. A more sophisticated solution might require separate functions for different combinations of the alpha channels of the participating surfaces. --- src/video/SDL_blit_N.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/video/SDL_blit_N.c b/src/video/SDL_blit_N.c index 309cdeb72..d94570dbf 100755 --- a/src/video/SDL_blit_N.c +++ b/src/video/SDL_blit_N.c @@ -707,6 +707,8 @@ ConvertAltivec32to32_noprefetch(SDL_BlitInfo * info) while ((UNALIGNED_PTR(dst)) && (width)) { bits = *(src++); RGBA_FROM_8888(bits, srcfmt, r, g, b, a); + if(!srcfmt->Amask) + a = srcfmt->alpha; *(dst++) = MAKE8888(dstfmt, r, g, b, a); width--; } @@ -734,6 +736,8 @@ ConvertAltivec32to32_noprefetch(SDL_BlitInfo * info) while (extrawidth) { bits = *(src++); /* max 7 pixels, don't bother with prefetch. */ RGBA_FROM_8888(bits, srcfmt, r, g, b, a); + if(!srcfmt->Amask) + a = srcfmt->alpha; *(dst++) = MAKE8888(dstfmt, r, g, b, a); extrawidth--; } @@ -790,6 +794,8 @@ ConvertAltivec32to32_prefetch(SDL_BlitInfo * info) DST_CHAN_DEST); bits = *(src++); RGBA_FROM_8888(bits, srcfmt, r, g, b, a); + if(!srcfmt->Amask) + a = srcfmt->alpha; *(dst++) = MAKE8888(dstfmt, r, g, b, a); width--; } @@ -821,6 +827,8 @@ ConvertAltivec32to32_prefetch(SDL_BlitInfo * info) while (extrawidth) { bits = *(src++); /* max 7 pixels, don't bother with prefetch. */ RGBA_FROM_8888(bits, srcfmt, r, g, b, a); + if(!srcfmt->Amask) + a = srcfmt->alpha; *(dst++) = MAKE8888(dstfmt, r, g, b, a); extrawidth--; }