0

I'm sending two variables to the RenderScript(RS) layer from android application. A function defined in RS layer accepts and adds these two variables and stores the result in a third variable. Now, I would like to get the value of this result_variable in the application space. (Android version 4.1+)

PS: I have tried using global-pointers in RS layer (as suggested by Google) to achieve the same however to no use.

Gagan
  • 1,497
  • 1
  • 12
  • 27

2 Answers2

1

You should be using an Allocation to transfer data between both sides (Java and RenderScript). If you declare an rs_allocation in your .rs file with a simple function:

rs_allocation ai;
void foo() {
    int i = rsGetElementAt_int(ai, 0);
    rsSetElementAt_int(ai, i + 1, 0);
}

You then create and attach an appropriate Allocation from the Java side:

RenderScript mRS = RenderScript.create(mCtx);
ScriptC_s mScript = new ScriptC_s(mRS);
Type t = new Type.Builder(mRS, Element.I32(mRS)).setX(1).create();
Allocation ai1 = Allocation.createTyped(mRS, t);
int i1[] = new int[1];
mScript.set_ai(ai1);
i1[0] = 777;
ai1.copyFrom(i1);  // Copies contents of i1 into ai1 Allocation
mScript.invoke_foo();
ai1.copyTo(i1);  // Copies contents of ai1 back to i1
// i1[0] now has the value 778

Obviously, you can use larger multidimensional buffers as well, but you just access them using 1 dimension from Java. You can also read/write these buffers from kernels (hence the Allocation parameters to forEach functions).

Stephen Hines
  • 2,612
  • 1
  • 13
  • 12
  • Hi Stephen, appreciate your reply on this. However I am looking for a solution that works on android ver. 4.1 and up. Isn't `rsSetElementAt_int` not available in android_v4.1 and v4.2? – Gagan Nov 28 '13 at 06:04
  • It would probably be much better if you do not target 4.1/4.2 directly. Instead you should be using the RS support library. Take a look at http://android-developers.blogspot.com/2013/09/renderscript-in-android-support-library.html for more details. – Stephen Hines Nov 28 '13 at 15:59
  • Current dynamics are such that the code should support Android 4.1 and above. I see your point with efficiency in using `Allocations`, however I've tested my elementary requirement using `rsSendToClient`, to transfer a significantly large array from RS to Java, and it works like a charm without any performance hit. – Gagan Nov 29 '13 at 05:24
0

Found answer to this following few Google links and few SO links. I'll try to summarise it (considering you have the basic renderscript-setup in this regard in place) for future-readers seeking answer to this:

  1. Call below API from RenderScript (Note: this requires including "rs_core.rsh" in your rs file)

    rsSendToClient(cmdID, &data, sizeof(data));

  2. In your Java file, define RSMessageHandler and override its run() method and put a switch-case construct on cmdID set in rsSendToClient. Then, link/set this handler with your RenderScript:

    mRenderScript.setMessageHandler(mRSMessageHandler);

    This answer gives more details on that.

I've also put a comment to the above answer on how to use the Data being sent from the RenderScript to Java Layer.

Hope this clears the method to pass the "processed" data from RenderScript to Java layer.

Community
  • 1
  • 1
Gagan
  • 1,497
  • 1
  • 12
  • 27
  • This is one way, but it is not really a great solution, since it entails a lot of overhead to pass messages like this for large data sets. I will write a more detailed example, but the short answer is that you should be using Allocation with copyFrom/copyTo (and then rs_allocation in your Script). – Stephen Hines Nov 27 '13 at 19:48