DevTermでフレームバッファ直描き!

f:id:PocketGriffon:20220127102044j:plain

特に珍しい事をしたワケではないので、今回は控えめに行きます(^^;;

 

先日、DevTerm上でRetroArchを動かし、X68000エミュレータの動きを最適化してみた。

その流れで「もっと高速な表示ってないのかしら…」と素朴な疑問が。

DevTerm専用で良いからドライバ書いてみようかな……なんてことを頭の片隅で思ってしまったから大変だ!!ヽ(=´▽`=)ノ

 

結論から先に書くと「簡単じゃない」でした(^^;

RetroArchの表示用ドライバ、PX68kのように共有ライブラリ化されていると思っていたら、RetroArchのソース(https://github.com/libretro/RetroArch)に内包されてるっぽい。つまりRetroArchの実行バイナリに含まれている。

RetroArchを独自でビルドし直す気力もないので、早々に諦める流れとなった。

でも頭の片隅にアイディアとして出ていた「フレームバッファ直描きしたら速いんじゃね?」というのがあったので、RetroArchとは別に実験してみる事にした!(^^)

 

フレームバッファ

Linuxフレームバッファ(表示メモリ)にアクセスするのは、/dev/fb0というデバイスを介して行う。この辺り、昔っからある方法なので別段特別な事ではないけれども、特にRaspberryPiを使っている人ならばどこかで聞いたことはあるだろう。

 

私もpomeraでプログラムをしている時(pomeraLinuxをインストール出来る)、X-Windowを起動するとマウスなども繋げる必要があって面倒だったため、フレームバッファに直描きするプログラムを良く書いていた(^-^)

 

DevTermでフレームバッファを扱う際には、ちょっとだけおまじないが必要。CTRL+ALT+F1(CTRL+ALT+Fn+1)を押すと画面が切り替わる。

f:id:PocketGriffon:20220127113358j:plain

このキーは仮想コンソールを切り替えるモノだ。X-Windowが動いてる状態では/dev/fb0へのアクセスがうまくいかないので、コンソールを切り替える。

 

この実験をしている最中に、コンソールで漢字を表示するkonというコマンドを思い出した。当時はまだまだメモリが少ない時代で、目一杯背伸びをして16MBが限界だったときの頃。

X-Windowを起動するよりもコンソールで漢字を表示した方が消費メモリが少なくていいぜ…と思って愛用してた。今ではfbtermがあるのでkonを使う機会は無いが、私の中ではDOS/Vが出てきた時のようなエポックメイキング的なツールに感じていた(^-^)

 

フレームバッファへのアクセス方法

フレームバッファへのアクセス方法は主に2つかなーと思う。

通常のファイルのように扱う

メモリにマッピングして扱う

どちらの方法でも問題なくアクセス出来るけれど、手元でテストした感じではメモリマッピングした方がはるかに高速アクセスが出来るようだ。

 

ファイルとしてアクセスするのは本当に普通のファイルと同じ。

/dev/fb0をopenし、seekしたりfwriteしたりして、最後にcloseする。

短いプログラムを載せようかと思ったけど、あまりに基本的すぎて辞めてしまった(^^;;

 

せっかくなのでフレームバッファをメモリにマッピングして操作する方法を紹介してみる。

f:id:PocketGriffon:20220127115718j:plain

すんごい要約して書いちゃってるけど、要は *m 以降にデータを書いていけば、それがそのまま画面へ出力される。いたってシンプルな方法だ(^-^)

描けば表示、読めばスクリーンショットが作れるという超お手軽なものとなる(^^)

 

それで最初に画面へ描画してみた結果がこちら。

f:id:PocketGriffon:20220127120014j:plain

……ありゃ??想像と違う!!(^^;;;

 

f:id:PocketGriffon:20220127120042j:plain

本体を90度傾けてやると、ちゃんとFM-7が起動した画面が見える(^^)

なんと、フレームバッファの原点が左上でなくて左下だった!

 

最近、RaspberryPi Picoとか使っていたので液晶の原点が違うというのはよくある話として慣れっこになっていたが、DevTermの場合はちょっと勝手が違う…(-_-;;

別の仮想コンソール上でX-Windowも動いてるのでGPU側の設定変えるわけにもいかん。

ここはプログラムで90度回転させてやる必要がありそうね。

 

f:id:PocketGriffon:20220127120705j:plain

単純に90度回転させてみたら、今度は上方向が隠れて表示されない!

試してみたところ、だいたい8ドットくらいは上に隠れてしまうようだ。まるでブラウン管時代のように安全フレームを考慮せねばならない(^^;;

 

f:id:PocketGriffon:20220127121137j:plain

上左を16ドットずつずらしてみた!

よしよし、キレイな表示になったじゃなーい!(^-^)

 

実験結果

この状態でデモンストレーションプログラムを動かしてみたのがこちら↓

6809エミュレーションを最高速で動かしてしまっているので分かりづらいけれど、少なくとも表示で遅くなってる感じはまったくしない。

動的に90度回転させているのにこの速度が出たのは嬉しい。

あらかじめVRAMから色データを生成するタイミングで回転させてやれば、もっと速度が出るとは思うけれど、そこまではチャレンジしなかった(^^)

 

ちなみにSDL2経由X-Window表示だとこんな速度になる。

動画の長さから察するに、だいたい3倍くらいの表示速度差があるみたいだ!

思った以上の差が出てくれたので、ブログ的にはおいしい結果だ!(^^;;

 

この動画、撮影始めていきなりウィンドウが表示されるけど、これはssh経由でログインした端末から操作している。X-Window上で動くプログラムであれば、環境変数DISPLAYを正しく設定してやる事で、任意の画面へ出力する事が可能だ。

 

sshでログインしているshell上から、以下のように打ち込むとDevTerm本体の液晶に目玉が表示される。

  export DISPLAY=:0

  xeyes

この指定だと常に画面中央に表示されるので、細かい座標の設定は-geometryオプションで指定してやれば良い(^^)

 

おわりに

今回はフレームバッファへの直描きをしてみたけれど、どうだっただろうか?

X-Window上で動作するRetroArchで利用できる仕組みではなかったのが残念だ(T-T)

機会があったらRetroArchのビルドもやってみたいけど、優先度は低くなりそう(^^;

 

ではまた次回!(^^)ノ

 

追記

RG351MPでも同じことを実験してみた!

SDL2経由で表示をするプログラムを組んで動かした事があったけれども、それに比べるとやっぱり3倍速くらいになってるかも知れない(^^)

 

DevTermとは違い、こっちは画面の原点が素直な左上。そのためフレームバッファへ書き込むプログラムが超単純のmemcpyで終わった!(^^;; その分速いはず。

 

EmulationStationが動いてる間はずっとダブルバッファ描画になっているようで、プログラムでフレームバッファをアクセスしても、もう片方の画面へのアクセスが出来ず点滅してしまう。EmulationStationを終わらせると動作不安定になってしまうので、このテストはスクリーンセーバー(設定しなければ真っ黒画面)にして動かしている(^^;