2012-03-11 13 views
8

最近、Microsoft Acceleratorの動作と同様に、プログラマが使いやすいAPIを作成する目的でRenderScriptを使用しています。割り当てを使用してAndroid RenderScriptとの間で配列の値をやり取りする方法

RenderScriptレイヤーとの間で値を渡し、すべてを最も効率的な方法で実行したいと思っている現時点で問題になっています。これは私のソースコードの抽出です。

int[] A = new int[10]; 
    int[] B = new int[10]; 

    for (int i = 0; i < 10; i++) { 
     A[i] = 2; 
     B[i] = i; 
    } 
    intAdd(A, B); 

これはちょうど2つの基本的な配列を作成し、それらを値で塗りつぶし、それらをRenderScriptに送る関数を呼び出します。

private void intAdd(int[] A, int[] B) { 
    RenderScript rs = RenderScript.create(this); 
    ScriptC_rsintadd intaddscript = new ScriptC_rsintadd(rs, getResources(), R.raw.rsintadd); 
    mScript = intaddscript; 

    for(int i = 0; i < A.length; i++) { 
    setNewValues(mScript, A[i], B[i]); 
    intaddscript.invoke_intAdd(); 
    int C = getResult(mScript); 
    notifyUser.append(" " + C); 
    } 
} 

    public void setNewValues(Script script, int A, int B) { 
    mScript.set_numberA(A); 
    mScript.set_numberB(B); 
} 

public int getResult(Script script) { 
    int C = mScript.get_numberC(); 
    return C; 
} 

これは、次のrenderScriptコードに値のペアを送信します:

int numberA; 
int numberB; 
int numberC; 

void intAdd() { 
/*Add the two together*/ 
numberC = numberA + numberB; 
/*Send their values to the logcat*/ 
rsDebug("Current Value", numberC); 
} 

しかし、これには二つの問題があり、最初のものはのrenderScriptの非同期な性質であることと、Java層を意味値を要求します。スクリプトはまだ操作を実行していないか、すでに完了しています。出力の値を破棄し、次の値から開始します。また、RenderScriptのデバッグの可視性が低いため、表示方法がありません。

もう1つの問題は、非常に効率的ではないということです。コードでは、常に2つの数値を加算するRenderScript関数を呼び出しています。理想的には、配列をRenderScriptに渡して構造体に格納し、操作全体を多くのスクリプト呼び出しではなく1つのスクリプト呼び出しで実行したいと考えています。しかし、それを元に戻すためには、rsSendtoClient関数をユーザーに提示する必要があると思いますが、使用方法については何も見つかりませんでした。そして、好ましくは、私はrsForEach戦略を使いたいですが、もう一度情報は恐怖です。

誰かが何か考えがあるなら、私はとても感謝しています。ありがとう。

ウィル・スコット・ジャクソン

答えて

2

私は、これは、この時点であなたに助けになるかどうか分からないが、私はそれがのrenderScriptを介して動作することができますどのように痛みの多くを知っているので、ここでのヘルプ私はあります提供することができます。 rsSendToClient関数を使用するには、メッセージを送信する場所を作成したRenderScriptインスタンスに指示する必要があります。 RenderScript.RSMessageHandlerのサブクラスを作成し、run()メソッドをオーバーライドする必要があります

private void intAdd(int[] A, int[] B) { 
    RenderScript rs = RenderScript.create(this); 

    MySubclassedRSMessageHandler handler = new MySubclassedRSMessageHandler(); 
    rs.setMessageHandler(handler); 
    ScriptC_rsintadd intaddscript = new ScriptC_rsintadd(rs, getResources(), R.raw.rsintadd); 
    mScript = intaddscript; 

    for(int i = 0; i < A.length; i++) { 
      setNewValues(mScript, A[i], B[i]); 
      intaddscript.invoke_intAdd(); 
      int C = getResult(mScript); 
      notifyUser.append(" " + C); 
    } 
} 

:これは、次のような何かによって達成されます。あなたがまだいなければ、http://developer.android.com/reference/android/renderscript/RenderScript.RSMessageHandler.htmlを見てください。基本的には、非同期の性質を回避する方法はありませんが、私はそれがダブルエッジの剣であることがわかります。

非効率性については、RenderScriptインスタンスの作成を検討し、実行中のままにしておくことをお勧めします(必要ない場合は一時停止できますが、メモリ内にありますがスレッドを停止するので、 )。ここから構造体を作成し、反映されたJavaレイヤーからinvoke_myFunction(ここではいくつかの引数)を使用できます。

これは少なくとも少し役に立ちます。

2

私は同じ問題を抱えていました。 あなたのプログラムに問題がRSファイル内の追加機能が を実行する必要があるときには、知らないで、それは私はあなたと同じ問題を抱えていた

public void setNewValues(Script script, int A, int B) { 
mScript.set_numberA(A); 
mScript.set_numberB(B); 
mscript.invoke_intAdd(); 

} 
0

を動作するはずこれを試してみてください。私はrsSendtoClient関数は有用ではないと多くのバグを作成すると思います。その代わりに、ポインタを使用してメモリを割り当てて、結果を元に戻すのがはるかに簡単です。

私はこのような問題の解決策をお勧めします:Javaコードの使用では

int32_t *a; 
int32_t *b; 
int32_t *c; 

void intAdd() { 
    for(int i = 0; i<10;i++){ 
    c[i] = a[i] + b[i]; 
} 

このスニペット:

int[] B = new int[10]; 
    int[] A = new int[10]; 

    for (int i = 0; i < 10; i++) { 
     A[i] = 2; 
     B[i] = 1; 
    } 

    // provide memory for b using data in B 
    Allocation b = Allocation.createSized(rs, Element.I32(rs), B.length); 
    b.copyFrom(B); 
    inv.bind_b(b); 

    // provide memory for a using data in A 
    Allocation a = Allocation.createSized(rs, Element.I32(rs), A.length); 
    a.copyFrom(A); 
    inv.bind_a(a); 

    // create blank memory for c 
    inv.bind_c(Allocation.createSized(rs, Element.I32(rs), 10)); 

    // call intAdd function 
    inv.invoke_intAdd(); 

    // get result 
    int[] C = new int[10]; 
    inv.get_c().copyTo(C); 
    for (int i = 0; i < C.length; i++) { 
     System.out.println(C[i]); 
    } 

そしてこのrsintadd.rsで

はこのスニペットを使用しますLogcatでの結果です:

Result of C

あなたの最初の質問は、非同期についてです。スレッドを使用して結果を待つことができます。この例では、関数は十分速く、即座に出力をC配列に渡し、結果をlogcatに表示することができます。

2番目の質問は、関数を呼び出すことなくintAdd()関数を実装することです。上のコードは答えです。メソッドが完了するまで、Javaのint配列の任意の部分にアクセスできます(root()関数とは異なります)。

これは誰かを助けることを願っています:)

関連する問題