• スポンサードリンク

RenderScriptをNDKから使ってみた

Android NDK

RenderScriptをNDKから使う時に、NDK付属のサンプル以外に参考になるのがあまり無いようなので簡単なメモを載せておきます。

Android.mk

まずは、Android.mkには次の項目を追加しておきます。

また、NDKからRenderScriptを使うにはlibRSSupport.soというプレビルドの共有ライブラリが必要になるので、Android.mkの最後に

というのも付け加えておく必要があります。
なお、スタティックライブラリとして一旦別モジュールとしてビルドする場合には次のようにします。

Application.mk

Application.mkにはSTLの指定が必要です。

ちなみに、APP_PLATFORMをandroid-19よりも低くすると、ファイルが見つかりまへんと怒られてビルド出来ないので、素直にAPP_PLATFORM := android-19としましょう。なおここでandroid-19としていても、RenderScriptに関する限りはAPI19未満でも動きます。

使う時は、Java側から呼び出すのであれば、自分で作った共有ライブラリに加えて、libRSSupport.soもロードする必要があります。

スクリプトで入出力のサイズが異なる場合

これはNDKとは何の関係も無いけど、RenderScriptでは、普通はOpenGLのシェーダーと一緒で、入力データと出力データは同じサイズ(個数)にする必要があります。また同じ位置のデータしか参照できません。型は違っててもOK。でも時には入力と出力のサイズを変えたい時や、あるいは違う位置の値を参照したい時も有りますよね。
そういう時には、サイズは出力側に合わせて入力側にはダミーのデータをあてがいます。
実際に使う入力値としてはグローバルのallocationを割り当てて、各関数内ではrsGetElementAt_xxxでアクセスします。
例えばこんなスクリプトを作ります。[unsigned int ✕ 2] ✕ width ✕ heightのデータを受け取って、[unsigned int ✕ 4] ✕ width ✕ heightのデータとして返します。・・・あっ入力と出力のサイズが一緒だった(^_^;)違う位置を参照してるからいっか。いったい何の計算してるんでしょうねぇ(^_^)

すると、ScriptC_test.hとScriptC_test.cppが出来ます。
呼び出すにはこんな感じにします。

6行目では端末内でコンパイルされたスクリプトをキャッシュするためのディレクトリを渡しています。JavaのContext#getCacheDirメソッドで取得できるディレクトリを渡すのが一番無難だと思います。
17行目がこの例でのみそで、スクリプト内でグローバル変数を宣言することで、それぞれ専用のsetter/getterが生成されるので、それを使ってスクリプト内のグルーバル変数にアクセスします。この例では、

の2つの関数が生成されます。ちなみに、グローバル変数として定義するのは、型はもちろんサイズも入力/出力データと異なっていても構いません。Allocation(配列)に限らずintやfloatといったプリミティブな型でもOKです。通常は入力/出力データ配列の要素1つずつにしかアクセスできませんが、このようにしてグローバル変数として配列全体を渡すことで、任意の要素にアクセスすることが出来るようになります。
また、関数名はrootに限りませんし、1つのスクリプトファイル内に複数の関数を含んでも大丈夫です。例えば関数abcdと関数efghを定義すればそれぞれforEach_abcdとforEach_efghで実行できます。

« »

  • スポンサードリンク