BREW での高速アルファブレンド
id:melpon:20060419 で書いた、
d = (tbl[ alpha | ((s >> 6) & 0x03e0) | ((d >> 11) ) ] << 11) | // R (tbl[ alpha | ((s >> 1) & 0x03e0) | ((d >> 6) & 0x001f) ] << 6) | // G (tbl[ alpha | ((s << 5) & 0x03e0) | ((d ) & 0x001f) ] << 0); // B
この線形補間テーブルを用いたアルファブレンドより高速にブレンドする方法を思いつきました。
uint32 AlphaBlend( uint32 src , uint32 dst , uint32 alpha ){ switch( alpha ){ case 0: return dst; case 1: src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); return (src & dst) + (((src ^ dst) & 0xf7de) >> 1); case 2: src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); return (src & dst) + (((src ^ dst) & 0xf7de) >> 1); case 3: src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); return (src & dst) + (((src ^ dst) & 0xf7de) >> 1); case 4: src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); return (src & dst) + (((src ^ dst) & 0xf7de) >> 1); case 5: src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); return (src & dst) + (((src ^ dst) & 0xf7de) >> 1); case 6: src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); return (src & dst) + (((src ^ dst) & 0xf7de) >> 1); case 7: src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); return (src & dst) + (((src ^ dst) & 0xf7de) >> 1); case 8: src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); return (src & dst) + (((src ^ dst) & 0xf7de) >> 1); case 9: src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); return (src & dst) + (((src ^ dst) & 0xf7de) >> 1); case 10: src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); return (src & dst) + (((src ^ dst) & 0xf7de) >> 1); case 11: src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); return (src & dst) + (((src ^ dst) & 0xf7de) >> 1); case 12: src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); return (src & dst) + (((src ^ dst) & 0xf7de) >> 1); case 13: src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); return (src & dst) + (((src ^ dst) & 0xf7de) >> 1); case 14: src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); return (src & dst) + (((src ^ dst) & 0xf7de) >> 1); case 15: src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); return (src & dst) + (((src ^ dst) & 0xf7de) >> 1); case 16: return (src & dst) + (((src ^ dst) & 0xf7de) >> 1); case 17: dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); return (src & dst) + (((src ^ dst) & 0xf7de) >> 1); case 18: dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); return (src & dst) + (((src ^ dst) & 0xf7de) >> 1); case 19: dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); return (src & dst) + (((src ^ dst) & 0xf7de) >> 1); case 20: dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); return (src & dst) + (((src ^ dst) & 0xf7de) >> 1); case 21: dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); return (src & dst) + (((src ^ dst) & 0xf7de) >> 1); case 22: dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); return (src & dst) + (((src ^ dst) & 0xf7de) >> 1); case 23: dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); return (src & dst) + (((src ^ dst) & 0xf7de) >> 1); case 24: dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); return (src & dst) + (((src ^ dst) & 0xf7de) >> 1); case 25: dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); return (src & dst) + (((src ^ dst) & 0xf7de) >> 1); case 26: dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); return (src & dst) + (((src ^ dst) & 0xf7de) >> 1); case 27: dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); return (src & dst) + (((src ^ dst) & 0xf7de) >> 1); case 28: dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); return (src & dst) + (((src ^ dst) & 0xf7de) >> 1); case 29: dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); src = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); return (src & dst) + (((src ^ dst) & 0xf7de) >> 1); case 30: dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); return (src & dst) + (((src ^ dst) & 0xf7de) >> 1); case 31: dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); dst = (src & dst) + (((src ^ dst) & 0xf7de) >> 1); return (src & dst) + (((src ^ dst) & 0xf7de) >> 1); case 32: return src; } return 0; }
software packed 演算で (src + dst) / 2 を繰り返しています。
これだけだと速いかどうかは微妙ですけど、まだまだ最適化できそう。