4bit パレットの転送(2)

昨日のルーチンだと、画像に変形を加えるようなルーチンだとうまくいかない。
インデックスの値の偶奇が交互に来ることを前提に作っているからだ。


変形を加えながら転送をする 8bit のルーチンが、

dst = (void*)((byte*)dst + dx * sizeof( void ) + dy * dp );
src = firstOffset( src , sx , sy );
for( int j = 0 ; j < h ; j++ ){
    for( int i = 0 ; i < w ; i++ ){
        uint32 x = transX( i , j );
        uint32 y = transY( i , j );
        dst[ i ] = pal[ src[ transform( x , y ) ] ];
    }
    dst = (void*)((byte*)dst + dstPitch);
}

こんなのだとすれば、4bit の転送ルーチンは、

int bit4 = 0x4 ^ *1 & 0xf;
        dst[ i ] = pal[ n ];
    }
    dst = (void*)((byte*)dst + dstPitch);
}

こうなる。
x を 1bit 右シフトした値を渡して転送元のインデックスを取り出し、そのままだと上位ビットを使用するのか下位ビットを使用するのか分からないので、x の下位 1bit を見て判断をしている。
bit4 を最初に計算しているのは、sx が奇数の場合は上位、下位ビットのフラグが逆になるからだ。


8bit インデックスのパレットと比べて、何クロックの差があるかを考えてみると、

1:  tmp1 = src[ transform( x >> 1 , y ) ];
2:  tmp2 = x & 0x1;
3:  tmp2 = (tmp2 << 2) ^ bit4;
4:  n = (tmp1 >> tmp2) & 0xf;

1行目のロードで x を右シフトしている部分で1クロック余分。
2行目で1クロック。
3行目、4行目はそれぞれ、

EOR     tmp2,bit4,tmp2,LSL #2
AND     n,r0,tmp1,LSR tmp2    ;r0 = 0xf

こうやって変換出来る(はず)なので、8bit と比べてたったの4クロックしか違わない。


多分 BREW2.1 だとほとんど同じ速度のハズ。。

*1:sx & 0x01) << 2); dst = (void*)((byte*)dst + dx * sizeof( void ) + dy * dp ); src = firstOffset( src , sx , sy ); for( int j = 0 ; j < h ; j++ ){ for( int i = 0 ; i < w ; i++ ){ uint32 x = transX( i ); uint32 y = transY( j ); uint32 n = (src[ transform( x >> 1 , y ) ] >> (((x & 0x1) << 2) ^ bit4