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

﹥>﹥吖頭↗ 提交于 2019-11-30 04:57:33

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

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).

here is full introduction of filter script and a lot demos. http://developer.android.com/guide/topics/renderscript/compute.html

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