How to pass array values to and from Android RenderScript using Allocations

强颜欢笑 提交于 2019-12-01 03:58:24

I'm not sure if this will be of help to you at this point but since I know how much of a pain it can be to work through RenderScript, here is the help I can offer. In order to use the rsSendToClient function, you need to instruct the RenderScript instance you created where to send messages to. This is accomplished by something such as:

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);
     }
}

It will be necessary to subclass RenderScript.RSMessageHandler and override the run() method. See http://developer.android.com/reference/android/renderscript/RenderScript.RSMessageHandler.html if you havn't already. Basically there is no way to get around the asynchronous nature which I find to be a double edged sword.

As for the inefficiency, I would consider creating a RenderScript instance, leave it running (you can pause it when not needed, will stay in memory but stop the threads, thus not incurring the construction cost each time you call a function). From here you can have your structures and then use invoke_myFunction(some arguments here) from the reflected Java layer.

Hopefully this helps at least a little bit.

I had the same problem. The problem with your program is that doesn't know when the add function in rs file should run ,try this it should work

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

}

I had the same problem with you. I think rsSendtoClient function is not useful and creates many bugs. Instead, using a pointer and allocate it a memory to bring result back to you is much easier.

I recommend the solution of your problem like this:

In rsintadd.rs use this snippet:

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

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

In your JAVA code use this snippet:

    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]);
    }

And this is your result on Logcat:

Your first question is about Asynchronous, you can use thread to wait result. In this example, the function is fast enough and instantly gives the output to C array so result can show on logcat.

Your second question is about implement intAdd() function without recalling it. The code above is the answer. You can access any part of int array in Java until the method is done ( different from root() function ).

Hope this can help someone :)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!