I have not found any documentation but maybe I can give you some useful information about what I have investigated so far:
- Pointers are not available
- Kernel functions need the attribute
__attribute__((kernel))
otherwise compiler goes mad and expects pointer types, which are illegal
- Renderscript API can be used (at least everything I tried so far was working)
- Attribute "Min SDK version" must be set to "17" in AndroidManifest.xml -> "Uses Sdk"
I discovered most of the following information while reading the sources of the llvm-rs-cc compiler. Any further information or a link to a real documentation for Filterscript would appreciated!
Output allocation
In Filterscript you dont have a parameter for the output allocation. Instead you return the value to write at current position (this is the global thread id x
and y
):
uchar4 __attribute__((kernel)) root(uint32_t x, uint32_t y)
generates into:
public void forEach_root(Allocation aout)
Input allocation
You can optionally hand over an input allocation as parameter:
uchar4 __attribute__((kernel)) root(const uchar4 in, uint32_t x, uint32_t y)
generates into:
public void forEach_root(Allocation ain, Allocation aout)
Which is useful in only rare cases (e.g. point operators) because you can access the input allocation only at the current position.
Global allocation
If you want to do random access at input allocations than you will need global allocations. Here is a small example of a window operator using a global allocation that works for me.
blur.fs:
#pragma version(1)
#pragma rs java_package_name(com.example.myproject)
rs_allocation in;
uint32_t width;
uint32_t height;
uchar4 __attribute__((kernel)) root(uint32_t x, uint32_t y) {
uint4 sum = 0;
uint count = 0;
for (int yi = y-1; yi <= y+1; ++yi) {
for (int xi = x-1; xi <= x+1; ++xi) {
if (xi >= 0 && xi < width && yi >= 0 && yi < height) {
sum += convert_uint4(rsGetElementAt_uchar4(in, xi, yi));
++count;
}
}
}
return convert_uchar4(sum/count);
}
MainActivity.java:
...
mRS = RenderScript.create(this);
mInAllocation = Allocation.createFromBitmap(mRS, mBitmapIn,
Allocation.MipmapControl.MIPMAP_NONE,
Allocation.USAGE_SCRIPT);
mOutAllocation = Allocation.createTyped(mRS, mInAllocation.getType());
mScript = new ScriptC_blur(mRS, getResources(), R.raw.blur);
mScript.set_in(mInAllocation);
mScript.set_width(mBitmapIn.getWidth());
mScript.set_height(mBitmapIn.getHeight());
mScript.forEach_root(mOutAllocation);
mOutAllocation.copyTo(mBitmapOut);
...