転送の高速化が上手くいかない
かなり悩んでいます・・・。
現在、Miyakoの拡張ライブラリで、ビットマップ転送の高速化を図っています。
SDLのサーフェスを引っ張ってきて、ビットマップを変換(カラーキー→αチャネル変換、HSV操作など)と同時に転送を行う処理を考えています。
今回の処理でやりたいことを順番に挙げてみます。
- 転送元からビットマップを取り込んでRGBAに変換
- 取得したRGBA値を変更
- 変更したRGBAをビットマップに戻す
これらを行う処理を現在実装しているのが以下のコードなのですが(分かりやすくなるように修正を加えています)・・・転送が遅いんです・・・。
640x480の画像を表示させるだけで100fps切るなんて(Core2Duo 3GHzマシンで計測)・・・。
これ、キャッシュを効かなくさせてるよなぁ・・・とか思っていても、本当にキャッシュなのかどうかも分からない。
とはいえども、このままほおっておくわけにも行かず、絶対にもっと早くなりそうな手法があるはず・・・。
でも、僕個人の対策だと、これ以上決定的な原因や対策がわからず、お手上げ状態です。
教授御願い致します・・・。
typedef MiyakoColor { Uint32 r; Uint32 g; Uint32 b; Uint32 a; }; typedef MiyakoSize { int w; int h; }; MiyakoColor src_color, dst_color; MiyakoSize size; // SDLのサーフェスを取得 SDL_Surface *src = ...; SDL_Surface *dst = ...; // size(転送サイズ)の決定(詳細は略) for(y=0; y<size.h; y++) { // 各ラインの先頭アドレスを取得 Uint32 *psrc = src->pixels + y * src->w; Uint32 *pdst = dst->pixels + y * dst->w; for(x=0; x<size.w; x++) { // 透明度を読み込み dst_color.a = (Uint32)(((*pdst & dst->format->Amask) >> dst->format->Ashift) << dst->format->Aloss); src_color.a = (Uint32)(((*psrc & src->format->Amask) >> src->format->Ashift) << src->format->Aloss); // 転送元画素が透明の時は何もしない if(src_color.a == 0){ psrc++; pdst++; continue; } // 転送先画素が透明 if(dst_color.a == 0 || src_color.a == 255){ *pdst = *psrc; psrc++; pdst++; continue; } // RGB値を読み込み dst_color.r = (Uint32)(((*pdst & dst->format->Rmask) >> dst->format->Rshift) << dst->format->Rloss); dst_color.g = (Uint32)(((*pdst & dst->format->Gmask) >> dst->format->Gshift) << dst->format->Gloss); dst_color.b = (Uint32)(((*pdst & dst->format->Bmask) >> dst->format->Bshift) << dst->format->Bloss); src_color.r = (Uint32)(((*psrc & src->format->Rmask) >> src->format->Rshift) << src->format->Rloss); src_color.g = (Uint32)(((*psrc & src->format->Gmask) >> src->format->Gshift) << src->format->Gloss); src_color.b = (Uint32)(((*psrc & src->format->Bmask) >> src->format->Bshift) << src->format->Bloss); // src_colorの変更処理(詳細は略) // 書き込み int a1 = src_color.a + 1; int a2 = 256 - src_color.a; *pdst = (((src_color.r * a1 + dst_color.r * a2) >> 8) >> dst->format->Rloss) << dst->format->Rshift | (((src_color.g * a1 + dst_color.g * a2) >> 8) >> dst->format->Gloss) << dst->format->Gshift | (((src_color.b * a1 + dst_color.b * a2) >> 8) >> dst->format->Bloss) << dst->format->Bshift | (255 >> dst->format->Aloss) << dst->format->Ashift; psrc++; pdst++; } }