BREW の高速転送
昔、RGB565 から RGB565 へ高速に転送するルーチンを書きました。
ふと思い出したので貼り付けておきます。
// dst: RGB565 // src: RGB565 // 透過色指定による透過転送 void Blt_RGB565_RGB565_Colorkey( word* dst, int dx, int dy, int dp, word* src, int sx, int sy, int sp, int w, int h, word key) { dst = (word*)((byte*)dst + dx * sizeof(word) + dy * dp ); src = (word*)((byte*)src + sx * sizeof(word) + sy * sp ); #ifdef WIN32 for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { if (src[x] != key) { dst[x] = src[x]; } } dst = (word*)((byte*)dst + dp); src = (word*)((byte*)src + sp); } #else uint32 jend = (uint32)((byte*)src + h * sp); uint32 ddp = dp - w * sizeof(word); uint32 dsp = sp - w * sizeof(word); uint32 al = (4 - ((uint32)src & 0x3)) & 0x3; if ((uint32)w * sizeof(word) < al) al = w * sizeof(word); uint32 iend8d = ((w - al) & 7) * sizeof(word); uint32 key2 = key << 16; uint32 mask = 0xffff; uint32 iend,iend8; uint32 alend; __asm { B jcomp jloop: ADD iend, src, w, LSL #1 SUB iend8, iend, iend8d ADD alend, src, al B alcomp alloop: LDRH r0, [src], #2 CMP r0, key STRNEH r0, [dst, #0] ADD dst, dst, #2 alcomp: CMP src, alend BLT alloop B icomp8 iloop8: LDMIA src!, {r1-r4} EORS r0, key2, r1, LSL #16 STRNEH r1, [dst, #0] AND r0, mask, r1, LSR #16 CMP r0, key STRNEH r0, [dst, #2] EORS r0, key2, r2, LSL #16 STRNEH r2, [dst, #4] AND r0, mask, r2, LSR #16 CMP r0, key STRNEH r0, [dst, #6] EORS r0, key2, r3, LSL #16 STRNEH r3, [dst, #8] AND r0, mask, r3, LSR #16 CMP r0, key STRNEH r0, [dst, #10] EORS r0, key2, r4, LSL #16 STRNEH r4, [dst, #12] AND r0, mask, r4, LSR #16 CMP r0, key STRNEH r0, [dst, #14] ADD dst, dst, #16 icomp8: CMP src, iend8 BLT iloop8 B icomp iloop: LDRH r0, [src], #2 CMP r0, key STRNEH r0, [dst, #0] ADD dst, dst, #2 icomp: CMP src, iend BLT iloop ADD dst, dst, ddp ADD src, src, dsp jcomp: CMP src, jend BLT jloop }; #endif }
基本的に1ラインの転送において、
1.src のポインタを 4 バイトでアライン
2.16 バイト(8 ピクセル)ほど一気にロードして転送するのを、16 バイト同時にロードできなくなるまで繰り返す
3.残りのバイトを転送
という動作を行っています。
前回のパレット転送と同じですね。
8ループ展開内での転送は ARM の命令やマスクをうまく使って高速化しようとした痕跡がありますね。
この辺の最適化は、
id:melpon:20051130
id:melpon:20051201
id:melpon:20051202
ここら辺で頑張ってたみたいです。