2009年04月09日

スレッドロック関数のエクスポート

前回、Blenderのマルチスレッドレンダリングで排他制御をするために必要な関数を探しました。
Blenderのソースコードのディレクトリ中の「source/blender/blenlib/intern/threads.c」にあるBLI_lock_thread()、BLI_unlock_thread()という2つの関数です。今回は、これらの関数をBlenderの外部のプログラム、テクスチャプラグインで使用できるようにエクスポートしてみたいと思います。

しかし、このような変更を加えるというのは、勝手にプラグインの仕様を変えてしまうようなものですが大丈夫なのでしょうか。結果から言うと全然大丈夫ではなくて、このような変更を加えたBlender本体とそれに合わせて作成されたテクスチャプラグインは、その組み合わせでのみ正しく動作します。修正版のBlenderで普通のテクスチャプラグインを使うことはできると思いますが、修正版Blender用のテクスチャプラグインを通常のBlenderから使用することはできません。
これについては、最終的にはvectexの機能をBlenderの本体の中に組み込むというようなことも考えてはいますが、とりあえずはこの方法でvectexをマルチスレッドレンダリング対応で使用できるようにしたいと思います。

Blenderのソースコードの中でテクスチャプラグインに関連する部分は、「/source/blender/blenpluginapi」というディレクトリの中に入っています。
pic090408_01.jpg pic090408_02.jpg

ここには、Blenderの実行ファイルのある場所に置かれている「plugins/include」ディレクトリの中にあるヘッダファイルと同じものがあります。その他に、「intern」というディレクトリがあって、そこにはpluginapi.cというファイルが入っています。
pic090408_03.jpg

pluginapi.cには、plugin.h、util.h、iff.hなどでエクスポートされている関数の本体が書かれています。スレッドをロックするための関数をエクスポートするためには、このファイルの適当な場所にエクスポートする関数を追加すればいいようです。他のエクスポートされている関数の記述をみると、実際にエクスポートされている関数名はBlenderの内部で使用している関数名とは微妙に違った名前に変更されているようです。今回は、lock_thread()、unlock_thread()というようにしてみました。Blenderの他の場所で同じ名前の関数が使われていないことを確認してあります。
pic090408_05.jpg
LIBEXPORT void lock_thread (int type)
{
    BLI_lock_thread(type);
}

LIBEXPORT void unlock_thread (int type)
{
    BLI_unlock_thread(type);
}
こんな風に関数の中でBLI_lock_thread()関数を使用するためには、この関数のプロトタイプ宣言の書かれているBLI_threads.hをインクルードする必要があるのですが、今回はたまたま他の部分でスレッドに関連する機能が使われていたらしく、すでにインクルードされていました。
pic090408_04.jpg

この他に、pluginapi.cというファイルの最後には、エクスポートされている全ての関数名が記述されているpluginapi_force_ref()という関数がありますので、この部分にも修正を加えます。
pic090408_10.jpg
        ...
        GET_INT_FROM_POINTER( gamwarp ) +
        GET_INT_FROM_POINTER( lock_thread ) +
        GET_INT_FROM_POINTER( unlock_thread );
}

pluginapi.cに行う修正はここまでです。
次に、ヘッダファイルにプロトタイプ宣言を追加します。エクスポートする関数の内容によって、plugin.h、util.h、iff.hのどのファイルに記述するべきかが違ってくるようですが、今回はmallocN()、callocN、freeN()などと同じ場所に置いておくのがよさそうに思いましたのでutil.hに書くことにしました。こちらにはBLI_lock_thread()関数に渡す引数「LOCK_IMAGE」と、ついでにもう一つ「LOCK_CUSTOM1」の定数のマクロ定義も追加しておきました。
pic090408_07.jpg
...
#define LOCK_IMAGE    0

#define LOCK_CUSTOM1    1
...
LIBIMPORT          void lock_thread (int type);
LIBIMPORT          void unlock_thread (int type);
...

そして、Linuxでは使用しませんが、Windowsでプラグインを作成する際に使用するplugin.DEFファイルにも修正が必要です。ファイルの最後に今回エクスポートした関数名を追加しました。
pic090408_08.jpg
...
lock_thread
unlock_thread
以上で、ソースファイルの修正は終了です。あとは、これらの修正が反映された状態でソースファイルからBlenderをビルドするだけです。Blenderをソースコードからビルドする方法については、以前書いたこちらの記事に参考になるページへのリンクがあります。
ということで、ビルド済みの修正版Blenderをこちらに用意しました。

Blender_modified_Linux64_090408.tar.gz
Blender_modified_Linux32_090408.tar.gz
Blender_modified_win32_090408.zip

今回は、SVNリポジトリからではなく、TARファイルとして配布されているBlender2.48aのソースコードを使用してビルドしています。
Linuxでのビルドはとくに問題なくできましたが、現在のところWindowsではFFMpeg関連のライブラリで問題が起こるようなので、コンパイルの設定でFFMpegを外しています。また、Windows版ではVisual C++ 2008 SP1の再頒布可能パッケージが必要なようです。Linuxでは、OpenAL、OpenEXRなどいくつかのライブラリをインストールしていないと動かない可能性があります。その場合、blenderの実行ファイルに対して「ldd」コマンドを実行すると、問題のあるライブラリを調べることができます。
pic090408_09.jpg

この修正版のBlenderは機能的には普通のものと何も変わらないので、現在のところはまったく意味がないです。次回は、この修正版のBlenderを使用してvectexに排他制御の組み込みを行う予定ですので、それまでもうしばらくお待ちください。
posted by mato at 00:07| Comment(0) | Blender | このブログの読者になる | 更新情報をチェックする
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。