週刊mosh - Portの修正 / 描画リストの生成インターフェース

今年のmoshはそろそろ始動。

報告されたバグ

equal-hash2題。
R6RSではequal?は循環構造があったとしても停止しないといけない。これはR7RSでも同様。R6RSのequal-hashはequal?同様停止性を保証する必要があるが、moshのequal-hashは単純に再帰する形で実装しているので循環構造を与えると停止しなくなる。
うーん。。equal-hashのためにhash-tableを持つのもどうかというのも有るけど、かといって"N回再帰したら打ち切り"という実装もどうか。。
あと、moshのequal-hashはある種類以外のオブジェクトは単純にobject→pointerの結果を返すよう実装されているので、equal?の成立するオブジェクト同士でもequal-hashが違うケースが生じる(bignumやbytevector等)。
ちなみに、個人的にはbytevectorをキーにするハッシュにはbytevector-hashを実装して使っている。キーが任意オブジェクトってあまり使ったこと無いなそういえば。。

描画リストの生成インターフェース

最近ゲームやUIのプロトタイピングをmoshでやっているので、cairoのバインディングをそれなりに真面目に作る必要が生じてきた。特に、SVG2ではメッシュグラデーションの導入が決定しているので、それをサポートしている最近のcairoを試したいというのもある。
描画リストの生成インターフェースにはなかなか決定打が無いように思える。多分普及している言語での実装だと(そもそも描画リストインターフェースを持っている)OpenGLバインディングくらいで、他のバインディングは描画のためのメソッド単位でバインディングをしているように見える。
(ちなみに、OpenGL ESにはこの手の描画リストインターフェースしかないので、WebGLも描画リストインターフェースしか持たないことになる。個人的にはOpenGL ES以外のOpenGLインターフェースのbindingを作る予定は無いので、mosh的にはすべての描画は描画リストで行う方向にしていきたい。Windows上のOpenGL ESは微妙な状況が続いていたが、ChromeのANGLEがかなりマトモになってきたのでmoshではそれを採用する予定。)
Schemeはせっかくlistをネイティブのオブジェクトとしてもっているので、なんとかこのlistとAPIやグラフィックスハードウェアの"描画リスト"を上手いこと関連付けたい。。
というわけで、今回のcairoバインディングは"kick"という描画リスト実行インターフェースと、リソースの生成/破棄インターフェースだけに絞ってみた。
kickは:

  • 頂点リスト(doubleの配列)
  • コマンドリスト(char配列)
  • 行列リスト(cairo2x3行列の配列)
  • オブジェクトリスト(ポインタの配列)
  • cairoコンテキスト

の4つの配列とコンテキストを取って、実際の描画を行う。頂点リストはスタック状に消費されていく(例えば、Move Toコマンドなら2エントリを消費する)が、他のリストはindexを使用してアクセスする。頂点リストは頂点以外にもRGBA値のようなdouble値全般に利用される。
今のところ未実装だが、将来的にはkickを別のスレッドで行うインターフェースを作って、リストの生成と実際の描画を並行して行えるようにしたい。
もちろん重要なのは、このkickにあたえるコマンド列をどうやって生成するかという点になるが、いまのところ上手い考察ができていない。特に:

  • 描画リストから描画リストをcallできるようにすべきか

例えば将棋ゲームをこのインターフェースで実装するとして、"歩"を描画するための頂点リストを18個用意するよりは、一つの頂点リストを少しずつ"ずらして"(描画APIは頂点入力をずらすためのAPIを大抵持っている)描画するのが好ましいといえる。
これをやるためには、描画リストから描画リストをcallできるようにする必要がある。
また、描画リストのcallは、描画リストをマルチスレッドで生成するときにかなり役に立つ。

  • 描画リストのパッチ

描画の拡大率を変えたいとか、色を変えたいとなったときに、描画リストをパッチして他の部分を再利用したくなる。
しかし、描画リストに対するパッチインターフェースを作るのは地味に難しい。普通の手段ではパッチする部分を指定するためにラベル等の概念を導入する必要があるし、マルチスレッドでレンダリングを行うなら、レンダリング中の描画リストに対する保護も必要になる。