New alpha blit mode

Hi there,

the default blit code for RGBA->RGBA blits leaves the destination alpha
channel untouched.

If one wants however to compose RGBA surfaces from other RGBA surfaces
by blitting, this is not necessarily a desired operation. What would
work in that case is, that the source alpha gets OR’ed into the
destination alpha. If one starts out with a black invisible image as
destination, the final, composed image turns out correctly.

This is a part of a working version of a the modified C-code blitter
that does this:

DUFFS_LOOP4( {  
            Uint32 pixel;
            unsigned sR; 
            unsigned sG; 
            unsigned sB; 
            unsigned sA; 
            unsigned dR; 
            unsigned dG; 
            unsigned dB;
            unsigned dA;
            DISEMBLE_RGBA(src, srcbpp, srcfmt, pixel, sR, sG, sB,

sA);
DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB,
dA);
ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB);
dA |= sA;
ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);
src += srcbpp;
dst += dstbpp;
}, width);

Could someone help in making modifications to a MMX blitter so it does
the above operation - a faster routine is important, since hardware
blitting on the video card can probably not do this and a software
blitter would be the default for this operation.

Cheers
Andreas

Andreas Schiffler wrote:

If one wants however to compose RGBA surfaces from other RGBA surfaces
by blitting, this is not necessarily a desired operation. What would
work in that case is, that the source alpha gets OR’ed into the
destination alpha.

oh dear, what a hack. How did you come to the conclusion that OR is the
right solution? It might look right in specific cases, but in general
it’s just Wrong. (Exercise: Write (by hand) the "multiplication table"
for binary OR, for the numbers 0…15. Ponder.)

we’ve discussed it here before, and the right way to compose two RGBA
images is to use the Porter-Duff OVER operator:

Cres = Csrc + (1 - Asrc) * Cdst

where Asrc is the alpha component of the source, and Cxxx are all four
components of the respective image. The problem with this is that it
only works for premultiplied alpha. It is easy to rewrite it so it takes
non-premultiplied images and yields a non-premultiplied result, but
in unfortunately involves 3 divisions for each pixel, and that’s why
SDL does not do it.

The next SDL release will allow the use of premultiplied alpha for this
and other reasons

Could someone help in making modifications to a MMX blitter so it does
the above operation - a faster routine is important, since hardware
blitting on the video card can probably not do this and a software
blitter would be the default for this operation.

The hardware can probably not do what you are proposing, but it may
very well support the OVER operator as described above

Hi again,

Hack? This IS a useful operation - alright it’s not mathematically
correct. Let me give an example …

Let’s assume one has a couple of RGBA SDL_ttf rendered text surfaces
(32bit to get antialiasing) and we to combine them into a final surface
(all off-screen) before blitting the combined surface onto the screen.
In that case most test pixels have alpha set to 255 (fully visible)
while the edges of the text are typically alpha <255 and everything else
is alpha=0. Blitting these using the standard blitter results in a
surface with the source alpha (the antialiasing info) beeing lost for
the final blit to screen since the alpha is uniformely set when the
combination surface is created. However the alpha-OR operation onto a
blank combination surface produces visually acceptable results and
allows the combined, anti-aliased text to show correctly.

Ciao
Andreas

Mattias Engdeg?rd wrote:>

Andreas Schiffler wrote:

If one wants however to compose RGBA surfaces from other RGBA surfaces
by blitting, this is not necessarily a desired operation. What would
work in that case is, that the source alpha gets OR’ed into the
destination alpha.

oh dear, what a hack. How did you come to the conclusion that OR is the
right solution? It might look right in specific cases, but in general
it’s just Wrong. (Exercise: Write (by hand) the "multiplication table"
for binary OR, for the numbers 0…15. Ponder.)

we’ve discussed it here before, and the right way to compose two RGBA
images is to use the Porter-Duff OVER operator:

Cres = Csrc + (1 - Asrc) * Cdst

where Asrc is the alpha component of the source, and Cxxx are all four
components of the respective image. The problem with this is that it
only works for premultiplied alpha. It is easy to rewrite it so it takes
non-premultiplied images and yields a non-premultiplied result, but
in unfortunately involves 3 divisions for each pixel, and that’s why
SDL does not do it.

The next SDL release will allow the use of premultiplied alpha for this
and other reasons

Could someone help in making modifications to a MMX blitter so it does
the above operation - a faster routine is important, since hardware
blitting on the video card can probably not do this and a software
blitter would be the default for this operation.

The hardware can probably not do what you are proposing, but it may
very well support the OVER operator as described above

Andreas Schiffler wrote:

Let’s assume one has a couple of RGBA SDL_ttf rendered text surfaces
(32bit to get antialiasing) and we to combine them into a final surface
(all off-screen) before blitting the combined surface onto the screen.

I recently wrote about that bug (in SDL_ttf) on this list, so I won’t
repeat it here

However the alpha-OR operation onto a
blank combination surface produces visually acceptable results and
allows the combined, anti-aliased text to show correctly.

if you think it looks good enough it’s all right for you, but it isn’t
a satisfactory general solution since it will give the wrong result
when stuff overlap at the edges. And if they don’t, you can just as well
do a non-alpha colourkey blit (with colourkey=0) to the RGBA destination.
This can also be faster