サイログ。

~雑多な記事置き場~

転送の高速化が上手くいかない

かなり悩んでいます・・・。

現在、Miyakoの拡張ライブラリで、ビットマップ転送の高速化を図っています。
SDLサーフェスを引っ張ってきて、ビットマップを変換(カラーキー→αチャネル変換、HSV操作など)と同時に転送を行う処理を考えています。

今回の処理でやりたいことを順番に挙げてみます。

  1. 転送元からビットマップを取り込んでRGBAに変換
  2. 取得したRGBA値を変更
  3. 変更した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++;
    }
  }