I find it weird, I thought I should mention, that in Max ReadPixel and WritePixel require ARGB values, whereas there is no PF_ARGB8888 format for pixmaps. What's the point? It would be better and more consistent and useful to return RGBA and to write RGBA by default. Otherwise they should provide a PF_ARGB8888 format. Notice how I had to rearrange the pixel format on the fly within the main loop after using ReadPixel() - a timewaster.
In the demo code above I had to one moment be doing RGBA and the next ARGB (see the dummy alpha routine), a bit confusing at first.
I also should explain that I used things like Green:+(((DestPixel Shl 8) Shr 24) * Alpha) with the two shifts, because I think this is faster than using an `and` with a mask. Shifts don't require a read of the mask from memory. Shifting left by 8 chops off the top 8 bits and sets them to 0, then shifting right by 24 moves it into the lowest byte ready for multiplying by alpha. I think two shifts is going to be faster than a an `and` and a shift. The mask would have to be an Int so doing $FF as an immediate value wouldn't ensure it would be included in the opcode at the assembler level.
It might be worth your while moving the "DestPixel=DestBase[X] 'Read full pixel" line up a couple of lines to after the Green= line - just to possibly pipeline things a bit better - it can be reading the dest pixel while you're working on other stuff, rather than having to wait for the pixel to be read before the "Red:+((DestPixel Shr 24) * Alpha)" line has to be executed. Might help, dunno.
You might convert the Floats into Doubles for more accuracy - I notice a few anomalies along edges of source rows/columns where you see a the column shift right, then left for one pixel, then right for one, then back left again which can make the image look `bitty`. But that will probably slow it down.
I also don't know if the instances of DestBase[X] are as fast as using DestBase[0] and modifying the DestBase variable with DestBase:+1 in the loop.
It also might be a little bit faster to put the whole alphablending stuff into a single line as part of the pixel write. That would cut out the saving of values into variables along the way.
Also, the OpWidth and OpHeight don't have to be the size of the source pixmap, they can be smaller. e.g. 128x128. You could also do Flip 0 to gain a little bit ;-D
In the demo code above I had to one moment be doing RGBA and the next ARGB (see the dummy alpha routine), a bit confusing at first.
I also should explain that I used things like Green:+(((DestPixel Shl 8) Shr 24) * Alpha) with the two shifts, because I think this is faster than using an `and` with a mask. Shifts don't require a read of the mask from memory. Shifting left by 8 chops off the top 8 bits and sets them to 0, then shifting right by 24 moves it into the lowest byte ready for multiplying by alpha. I think two shifts is going to be faster than a an `and` and a shift. The mask would have to be an Int so doing $FF as an immediate value wouldn't ensure it would be included in the opcode at the assembler level.
It might be worth your while moving the "DestPixel=DestBase[X] 'Read full pixel" line up a couple of lines to after the Green= line - just to possibly pipeline things a bit better - it can be reading the dest pixel while you're working on other stuff, rather than having to wait for the pixel to be read before the "Red:+((DestPixel Shr 24) * Alpha)" line has to be executed. Might help, dunno.
You might convert the Floats into Doubles for more accuracy - I notice a few anomalies along edges of source rows/columns where you see a the column shift right, then left for one pixel, then right for one, then back left again which can make the image look `bitty`. But that will probably slow it down.
I also don't know if the instances of DestBase[X] are as fast as using DestBase[0] and modifying the DestBase variable with DestBase:+1 in the loop.
It also might be a little bit faster to put the whole alphablending stuff into a single line as part of the pixel write. That would cut out the saving of values into variables along the way.
Also, the OpWidth and OpHeight don't have to be the size of the source pixmap, they can be smaller. e.g. 128x128. You could also do Flip 0 to gain a little bit ;-D