Nanashi-soft○プログラマ専用○PS3 Linux SDL○
現状は RSXの仕様が隠蔽されていて、実質フレームバッファしか使用できません(2007/02現在)
「それだと何もできない」と思っている人が多いので、どのくらいダメなの? 本当にダメなの? という所を検証してみました
まずはベンチマークを取る為の雛形を作成しました
1秒間に何回描画できるのか? を測ります。それが一番分かり易いでしょう
ちなみに、この雛形状態だと 231298fpsでしたw
#include "SDL.h" int main(int args,char *argp[]){ //初期化 if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) < 0){ return -1; } SDL_Surface *screen=SDL_SetVideoMode(1920,1080,32,SDL_SWSURFACE); if(screen == NULL){ SDL_Quit(); return -1; } int done = 0; SDL_Event event; int fps=0; Uint32 t1=SDL_GetTicks(); while(!done){ while(SDL_PollEvent(&event)){ switch(event.type){ case SDL_QUIT: done = 1; break; case SDL_KEYDOWN: if(event.key.keysym.sym == SDLK_ESCAPE){ done = 1; } break; } } //ここに処理を追加して変化を見る if(SDL_GetTicks() < t1 + 1000){ fps++; } else{ printf("fps=%d\n", fps); fps=0; t1=SDL_GetTicks(); } } SDL_Quit(); }
RGB(24bit)で羅列したデータを、直接描画して測ってみます
グローバル変数にこの裏画面を生成して、SDL_CreateRGBSurfaceFromでサーフェスにします
~ unsigned char gUra[1920*1080*3];//裏画面 ~ int main(int args,char *argp[]){ ~ while(!done){ ~ //ここに処理を追加して変化を見る SDL_Surface *bitmap = SDL_CreateRGBSurfaceFrom((void *)gUra,1920,1080,24,1920*3,0xff0000,0xff00,0xff,0); SDL_BlitSurface(bitmap,NULL,screen,NULL); SDL_UpdateRect(screen,0,0,0,0); ~
これを計測すると 5fpsでしたよ(*'-')
うはw 5fpsじゃ何も作れないよorz
……と思ったら、そこで終わりです
このような際物機器では、自動で最適化される事がありません
自力で最適化して、速度を上げていくのが常識なのです
データをそのまま渡してしまった事が間違いだと思うので、今度はフレームバッファのフォーマットに自力で合わせてから送ってみます
unsigned char gUra[1920*1080*3];//裏画面 Uint32 pix[1920*1080];//ワーク用画面 ~ int main(int args,char *argp[]){ ~ //ここに処理を追加して変化を見る int x, y; Uint32 *pixp = pix; unsigned char *gUrap=gUra; for(y=0; y < 1080; y++){ for(x=0; x < 1920; x++){ unsigned int r = *gUrap++; unsigned int g = *gUrap++; unsigned int b = *gUrap++; *pixp++ = (r << 16) + (g << 8) + b; } } SDL_Surface *bitmap = SDL_CreateRGBSurfaceFrom((void *)pix,1920,1080,32,1920*3,0xff0000,0xff00,0xff,0); SDL_BlitSurface(bitmap,NULL,screen,NULL); SDL_UpdateRect(screen,0,0,0,0); ~
このままだとやっぱり 5fpsです
コンパイラオプションに最適化を付けると、劇的にスピードアップします
gcc -O2 -o 「拡張子無しファイル名」「ファイル名」 `sdl-config --cflags --libs`
そうすると、25fps出ました(^_^)
更に、この場合SDL_SWSURFACEを SDL_HWSURFACEにするだけで 36fpsにアップします
blitが高速化される為だと思われます
ふと思いました
裏画面を最初からフレームバッファと同じフォーマットにしておいたらどうでしょう?
PS3はハード的に固定なので、専用であればそれで良いはずです
Uint32 gUra[1920*1080*4];//裏画面 ~ int main(int args,char *argp[]){ ~ //ここに処理を追加して変化を見る SDL_Surface *bitmap = SDL_CreateRGBSurfaceFrom((void *)gUra,1920,1080,32,1920*3,0xff0000,0xff00,0xff,0); SDL_BlitSurface(bitmap,NULL,screen,NULL); SDL_UpdateRect(screen,0,0,0,0);
裏画面と実画面の構造が同じなので、変換する必要が無い
こうすると 105fpsでました!
更に、グローバルでは無くヒープの方に置いて実験してみたところ……
int main(int args,char *argp[]){ Uint32 *gUra=(Uint32*)malloc(1920*1080*4);//ワーク用画面 ~ while(!done){ ~ //ここに処理を追加して変化を見る SDL_Surface *bitmap = SDL_CreateRGBSurfaceFrom((void *)gUra,1920,1080,32,1920*3,0xff0000,0xff00,0xff,0); SDL_BlitSurface(bitmap,NULL,screen,NULL); SDL_UpdateRect(screen,0,0,0,0);
そうすると 229fpsでました(*'-')
以上の検証より、SDLでは、実画面に合わせたフォーマットのデータを扱う事によりスピードアップすると言うことが分かりました
逆に言えば、独自フォーマットを使用すると劇的に速度低下を起こすと言う事ですので、注意が必要ですね
全グラフィックをハードウェアサーフェス上に置いて、それを表示したらもっと速いでしょう
フルHD(1920×1080画面で毎秒60コマ表示)も夢では無いかも知れませんよ
ぜひ、みなさんもチャレンジしてみて下さい