简体   繁体   中英

Can one use RenderScript's rsForEach on a non-root kernel?

Can one invoke a non-root RenderScript kernel using rsForEach ? There are many examples of using rsForEach to call the root kernel from within an invokable RenderScript function:

These bind the script itself to a variable in the RenderScript context, then invoke the root kernel from within RenderScript. For example, in the Activity class:

...
mScript = new ScriptC_gradient(mRS);
// bind Allocations and mScript to variables in the RenderScript context:
mScript.set_gIn(mImageAllocation);
mScript.set_gOut(mGradientAllocation);
mScript.set_gScript(mScript);
// invoke gradient function:
mScript.invoke_gradient();
...

And in gradient.rs :

#pragma version(1)
#pragma rs java_package_name(com.example.android.rs.hellocompute)

rs_allocation gOut;
rs_allocation gIn;
rs_script gScript;

void gradient() {
  rsForEach(gScript, gIn, gOut);
}
void root(const uchar4 *v_in, uchar4 *v_out, ...

But if I have another kernel gray could I invoke it after root , inside gradient ?

// I thought it would look like this:
void gradient() {
  rsForEach(gScript, gIn, gOut);
  rsForEach(gScript, gIn, gOut, NULL, NULL, gExportForEachIdx_gray);
}
// Or:
void gradient() {
  rsForEach(gScript, gIn, gOut);
  rsSetMainKernel(&gScript, "gray");
  rsForEach(gScript, gIn, gOut);
}

But the documentation for rsForEach seems to indicate that it doesn't support anything like this. Perhaps it can be accomplished by setting something in a rs_script_call_t , but the doc is rather terse about that type: (Retrieved 20 September 2013)

 typedef struct rs_script_call rs_script_call_t** 

Structure to provide extra information to a rsForEach call. Primarly used to restrict the call to a subset of cells in the allocation.

This question is mostly out of curiosity- I expect the preferred method is to call them from Java:

...
mScript = new ScriptC_gradient(mRS);
// bind Allocations and mScript to variables in the RenderScript context:
mScript.forEach_root(mImageAllocation, mGradientAllocation);
mScript.forEach_gray(mGradientAllocation, mGrayGradientAllocation);
...

These seem to be synchronized. If one defines root and gray as follows:

void root(...) { rsDebug("root", 0,0);  }
void gray(...) { rsDebug("gray", 1,1);  }

then calling forEach_root then forEach_gray causes "root, {0,0}" to be logged NxM times before it starts logging "gray, {1,1}" - I haven't found documentation that guarantees that, though. Anybody know where that is?

Unfortunately we don't currrently have a way to invoke a non-root RenderScript kernel using rsForEach() from the script. You will have to call into it from Java directly. You could also put the second kernel in another Script as root() and then bind that rs_script as well (eg you can have gScriptGradient and gScriptGray and execute them sequentially from a single invoke in your primary Script).

I initially missed your second question about synchronization between parallel kernels. They are indeed ordered. Although kernels are launched asynchronously, the second kernel will not run until the first kernel is complete.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM