Added slow but complete blit fallback

Don't try to RLE encode surfaces that have alpha channel and alpha modulation
Don't turn on blending when converting an RGB surface to RGBA format
Do turn on blending when converting colorkey to alpha channel

--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%403285
This commit is contained in:
Sam Lantinga 2008-12-02 17:14:04 +00:00
parent 7e7747ebec
commit 4a696cc335
6 changed files with 227 additions and 34 deletions

View file

@ -27,5 +27,144 @@
/* The ONE TRUE BLITTER
* This puppy has to handle all the unoptimized cases - yes, it's slow.
*/
void
SDL_Blit_Slow(SDL_BlitInfo * info)
{
const int flags = info->flags;
const Uint32 modulateR = info->r;
const Uint32 modulateG = info->g;
const Uint32 modulateB = info->b;
const Uint32 modulateA = info->a;
Uint32 srcpixel;
Uint32 srcR, srcG, srcB, srcA;
Uint32 dstpixel;
Uint32 dstR, dstG, dstB, dstA;
int srcy, srcx;
int posy, posx;
int incy, incx;
SDL_PixelFormat *src_fmt = info->src_fmt;
SDL_PixelFormat *dst_fmt = info->dst_fmt;
int srcbpp = src_fmt->BytesPerPixel;
int dstbpp = dst_fmt->BytesPerPixel;
srcy = 0;
posy = 0;
incy = (info->src_h << 16) / info->dst_h;
incx = (info->src_w << 16) / info->dst_w;
while (info->dst_h--) {
Uint8 *src;
Uint8 *dst = (Uint8 *) info->dst;
int n = info->dst_w;
srcx = -1;
posx = 0x10000L;
while (posy >= 0x10000L) {
++srcy;
posy -= 0x10000L;
}
while (n--) {
if (posx >= 0x10000L) {
while (posx >= 0x10000L) {
++srcx;
posx -= 0x10000L;
}
src =
(info->src + (srcy * info->src_pitch) + (srcx * srcbpp));
}
if (src_fmt->Amask) {
DISEMBLE_RGBA(src, srcbpp, src_fmt, srcpixel, srcR, srcG,
srcB, srcA);
} else {
DISEMBLE_RGB(src, srcbpp, src_fmt, srcpixel, srcR, srcG,
srcB);
srcA = 0xFF;
}
if (flags & SDL_COPY_COLORKEY) {
/* srcpixel isn't set for 24 bpp */
if (srcbpp == 24) {
srcpixel = (srcR << src_fmt->Rshift) |
(srcG << src_fmt->Gshift) | (srcB << src_fmt->Bshift);
}
if (srcpixel == info->colorkey) {
posx += incx;
dst += dstbpp;
continue;
}
}
if (dst_fmt->Amask) {
DISEMBLE_RGBA(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG,
dstB, dstA);
} else {
DISEMBLE_RGB(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG,
dstB);
dstA = 0xFF;
}
if (flags & SDL_COPY_MODULATE_COLOR) {
srcR = (srcR * modulateR) / 255;
srcG = (srcG * modulateG) / 255;
srcB = (srcB * modulateB) / 255;
}
if (flags & SDL_COPY_MODULATE_ALPHA) {
srcA = (srcA * modulateA) / 255;
}
if (flags & (SDL_COPY_BLEND | SDL_COPY_ADD)) {
/* This goes away if we ever use premultiplied alpha */
if (srcA < 255) {
srcR = (srcR * srcA) / 255;
srcG = (srcG * srcA) / 255;
srcB = (srcB * srcA) / 255;
}
}
switch (flags &
(SDL_COPY_MASK | SDL_COPY_BLEND | SDL_COPY_ADD |
SDL_COPY_MOD)) {
case 0:
dstR = srcR;
dstG = srcG;
dstB = srcB;
dstA = srcA;
break;
case SDL_COPY_MASK:
if (srcA) {
dstR = srcR;
dstG = srcG;
dstB = srcB;
}
break;
case SDL_COPY_BLEND:
dstR = srcR + ((255 - srcA) * dstR) / 255;
dstG = srcG + ((255 - srcA) * dstG) / 255;
dstB = srcB + ((255 - srcA) * dstB) / 255;
break;
case SDL_COPY_ADD:
dstR = srcR + dstR;
if (dstR > 255)
dstR = 255;
dstG = srcG + dstG;
if (dstG > 255)
dstG = 255;
dstB = srcB + dstB;
if (dstB > 255)
dstB = 255;
break;
case SDL_COPY_MOD:
dstR = (srcR * dstR) / 255;
dstG = (srcG * dstG) / 255;
dstB = (srcB * dstB) / 255;
break;
}
if (dst_fmt->Amask) {
ASSEMBLE_RGBA(dst, dstbpp, dst_fmt, dstR, dstG, dstB, dstA);
} else {
ASSEMBLE_RGB(dst, dstbpp, dst_fmt, dstR, dstG, dstB);
}
posx += incx;
dst += dstbpp;
}
posy += incy;
info->dst += info->dst_pitch;
}
}
/* vi: set ts=4 sw=4 expandtab: */