« invoke で呼び出すシンプルな RenderScript | メイン | Unity での日本語描画 その1 »

2014年06月10日

Android:: RenderScript の invoke は非同期実行

    

前回のスクリプトを以下のように書き換えてログを見ればわかる。

Log.v( "Script:", "invoke");
mScript.invoke_add( 10, 20 );
Log.v( "Script:", "invoked");

ログには以下のように表示される。

V/Script:(31995): invoke
V/Script:(31995): invoked
V/Result:(31995): value:30

invoke も非同期で実行されているようだ。
では、finish を呼んでみたらどうだろうか?
つまり、以下のようにする。

Log.v( "Script:", "invoke");
mScript.invoke_add( 10, 20 );
mRS.finish();
Log.v( "Script:", "invoked");

V/Script:(32181): invoke
V/Script:(32181): invoked
V/Result:(32181): value:30

一緒だった。
finish は何も待っていない?
ドキュメントの finish を見てみると。
「Wait for any pending asynchronous opeations (such as copies to a RS allocation or RS script executions) to complete. 」と書いている。

RenderScript 側の rsSendToClient が問題か?
rsSendToClientBlocking で RenderScript 側がメッセージを送り終わるのを待つようにしてみる。
つまり、RenderScript 側を以下のようにしてみる。

void add( int a, int b ) {
  result[0] = a + b;
  rsSendToClientBlocking(1,result,1);
}

実行結果は以下の通り。

V/Script:(32590): invoke
V/Result:(32590): value:30
V/Script:(32590): invoked

また rsSendToClientBlocking を呼ぶが、finish を呼ばない場合は、以下のようなログになる。

V/Script:(7023): invoke
V/Script:(7023): invoked
V/Result:(7023): value:30

ちゃんと finish は終了を待っているし、invoke は非同期実行のようだ。
では、RenderScript 側を以下のようにして、mScript.get_value() でグローバル変数を得られるようにして、finish で待つとどうか?

int value;
void add( int a, int b ) {
  value = a + b;
  rsSendToClientBlocking(1);
}

結果は以下の通り。
value は反映されていない。

V/Script:(32736): invoke
V/Script:(32736): invoked
V/Result:(32736): value:0


mScript.set_value で invoke 呼び出し前に設定した値は、きちんと RenderScript 側で読めるが、やはり invoke の呼び出しのみでは、グローバル変数の結果が Java 側から get_xxx で読みだせないようだ。
Allocation には rsAllocationIoSend と言うメソッドがあるので、これで Allocation の形なら Java 側に値を返せそうではある。
Script.get_xxx は、いったいどのように使うのが正解なのだろうか……
rsSendToClient で値を返すしかないんだろうか。



投稿者 Takenori : 2014年06月10日 03:03




comments powered by Disqus
Total : Today : Yesterday : なかのひと