kumaryu日記
2009-10-15
_ [Riko] コンテキストとテスト
Textureの実装を整理したのでテストをしてたら落ちた。
調べていくとどうも必要なバッファオブジェクトのサイズが0になってしまっていた。
もっと調べていくとGCかかって解放しちゃってるな。
もちろん必要なオブジェクトはインスタンス変数に入ってるので解放なんかされない。しかしバッファオブジェクトはglGenBuffersで作っているのでかぶるわけは無いな。
複数のテストを通したときにだけ起きるんだがなんでだろう。
あ、複数のテスト間でウィンドウを作りなおしてるのが原因か。OpenGLのコンテキストも作りなおしだ。
- コンテキスト作る。
- バッファオブジェクト作る。
- コンテキスト消える。
- 2のバッファオブジェクトは消えるけど、RubyのラッパはGCまで生き残る。
- 新しいコンテキスト作る。
- バッファオブジェクト作る。しかし2のバッファオブジェクトと同じ名前になってしまう。
- GC発生。2のバッファオブジェクトが消える…はずが6のバッファオブジェクトが消えてしまう。
- 6のバッファオブジェクトを使おうとしてあれー?
他にも複数のテストを実行するとテクスチャがおかしくなったりしちゃうな。なんで以前に問題出てなかったのか謎だが。ちゃんとGCで消せてなかったんだろうか。
これを対処しようとするとめんどいな。
コンテキストが削除されたときにそこから作られたオブジェクトを解放して、RubyのラッパがGCされた時に再度解放しないようにするのがまともだろうな。
コンテキストの管理はRikoではやってないんだが、初期化、解放時にこれを呼べ、というくらいは出来るので問題はないだろう。
あとはバッファオブジェクトなりテクスチャオブジェクトなりを作ったときに、現在のコンテキストに教えてやらないといけない。
まあこれは難しくもないか。C++側で勝手にやればよさそう。
いまのところ同時に複数のコンテキストを扱うのには対応してないが、対応したときに共有コンテキストがあった場合はどうしよう。テクスチャとか共有できるんだが。これは参照カウント持ってあげればいいかな。
なんかちゃんと実装すると複数コンテキスト対応をやる必要が出てきそうだな。
でもテスト以外にはコンテキストを作ったり消したりって普通やらないから後回しでもいいかもな。