Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where is the filterscript documentation (and how can I use it)? [closed]

When Jelly Bean 4.2 was announced a month ago, Filterscript was also announced. It appears to be a language that is a subscript of Renderscript with a different file extension. And that's about all I know about the language.

I have read the two total paragraphs that exist about Filterscript on the entire Internet and created a small .fs file with pragma rs_fp_relaxed, but it does not get picked up by the ADT builders like a normal .rs file is in the same location.

My ADT is the latest public version (21.0.0), which seems to be too low for Filterscript. tools.android.com appears to have 21.0.1 Preview, but there is no mention of Filterscript in the release notes (in fact its just a bugfix release). There's just no documentation anywhere!

How can I use Filterscript? Where is its documentation?

What I have tried:

https://www.google.com/search?q=filterscript+site:android.com&tbs=li:1

http://developer.android.com/about/versions/android-4.2.html#Renderscript

http://developer.android.com/tools/sdk/eclipse-adt.html#notes

http://tools.android.com/recent/2101preview1

like image 203
eternalmatt Avatar asked Dec 17 '12 15:12

eternalmatt


2 Answers

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);
...
like image 147
oreiche Avatar answered Oct 15 '22 06:10

oreiche


Couple things here:

  • Yeah, we are behind on docs. We know, we've been busy. It's on my agenda for the relatively near future.

  • FS is intended as a more restrictive variant of RS that enables additional optimization opportunities for compiler backends. We don't have any of those in our CPU backend today that aren't available from equivalent RS files, but it is possible that an OEM may improve performance on their SoCs with FS files versus generic RS files. In general, it requires __attribute__((kernel)), no pointers, and no unions, and fp_relaxed is implied by the file type.

  • The host-side API is completely identical; the only difference is in what we actually pass around as the kernel binaries.

Some minor corrections to ofp's answer:

  1. You should be using rsGetElementAt_(type). It's significantly cleaner than rsGetElementAt because you don't need casting or additional dereferencing or anything like that.
  2. #pragma fp_relaxed is implied from the .fs extension and is not necessary in FS files.
  3. You don't have to include rs_allocation.rsh (it's implied as well for all RS/FS files).
like image 43
Tim Murray Avatar answered Oct 15 '22 07:10

Tim Murray