to get faster...

ここしばらくmosh canvasでいくつかプログラムを書いてみたけど、やっぱり今の構成だと速度がかなり不味いということが分かった。
観測によると、描画命令列の変換をランタイムに行うのが不味いので、可能な限り静的な構成にしないといけない。

コンテキスト描画APIの廃止

まず、(遅い)コンテキスト描画は廃止した。なるべくプリミティブ描画命令は使ってほしく無いのでそういうメッセージが伝わるように。
canvas simple APIは単にcanvas APIに改名して、もっとずっと高機能なAPIを別に用意することにする。

オブジェクトの明確化

penやbitmap等は特定の手続きで生成するようにする。これらは全部OpenVGにあわせる。つまり、

  • path - これは描画命令列から作る
  • stroke-parameters (pen) - 名前が長いのでcanvasではpenと呼ぶ
  • paint - fillのパラメタ
  • image

を、描画コンテキスト(今後これをcanvasと呼ぶ)と関連付けられた形で管理する。
これらはcanvasに"アップロード"できるようにし、アップロードしたオブジェクトはcanvasを破棄したときに自動的に破棄される。このデザインにより、2つ以上のcanvasを連携させることは出来ない。
アニメーションなどの都合で、アップロードしたオブジェクトをinvalidateできるようにした。in-placeな描画もサポートするべきかもしれない。

描画命令emitの再構成

最初のリリースではcairoだけをサポートするつもりだけど、Windows上ではGDI+、他の環境ではOpenVGを使ってハードウェアアクセラレーションできる*1ようにする。他にSVG等もサポートできると良いかも知れない。
OpenVGやGDI+では2次、3次ベジェ、楕円をプリミティブとして使えるが、cairoのプリミティブには(男らしいことに)3次ベジェと直線しかない。cairoのAPIでは円を描くこともできるが、これは内部的に3次ベジェに変換されている。

描画命令のセットを選ぶのは地味に難しい問題で、当初の候補はSVGだった。SVGには長方形や楕円などがプリミティブとして用意されている。
最終的にSVGでなくOpenVGのプリミティブを選んだのは、ハードウェア実装が多いことと、描画の単純化はポストプロセスで十分行えることに拠る。

*1:Windows上のGDI/GDI+アクセラレーションが行われるかどうかは微妙な問題としか言いようが無い(XP/Vista/Win7で状況が異なる)。どのWindowsであっても、BitBltやAlphaBlendは基本的にハードウェアに支援されるので、これらが可能なビットマップ上で全てを処理することは十分に意義が有る。