14

一个月前 Jelly Bean 4.2 发布时,Filterscript 也发布了。它似乎是一种语言,它是具有不同文件扩展名的 Renderscript 的下标。这就是我对语言的所有了解。

我已经阅读了整个 Internet 上存在的关于 Filterscript 的两个总段落,并.fs使用.pragma rs_fp_relaxed.rs

我的ADT是最新的公版(21.0.0),对Filterscript来说似乎太低了。 tools.android.com似乎有 21.0.1 Preview,但在发行说明中没有提到 Filterscript(实际上它只是一个错误修复版本)。任何地方都没有文档!

如何使用过滤器脚本?它的文档在哪里?

我试过的:

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

4

3 回答 3

17

我还没有找到任何文档,但也许我可以给你一些关于我迄今为止调查的有用信息:

  • 指针不可用
  • 内核函数需要该属性,__attribute__((kernel))否则编译器会发疯并期望指针类型,这是非法的
  • 可以使用Renderscript API(至少到目前为止我尝试的一切都有效)
  • AndroidManifest.xml 中的属性“Min SDK version”必须设置为“17”->“Uses Sdk”

我在阅读llvm-rs-cc 编译器的源代码时发现了以下大部分信息。任何进一步的信息或 Filterscript 真实文档的链接将不胜感激!

产出分配

在 Filterscript 中,您没有用于输出分配的参数。相反,您返回要在当前位置写入的值(这是全局线程 idxy):

uchar4 __attribute__((kernel)) root(uint32_t x, uint32_t y)

生成为:

public void forEach_root(Allocation aout)

输入分配

您可以选择将输入分配作为参数移交:

uchar4 __attribute__((kernel)) root(const uchar4 in, uint32_t x, uint32_t y)

生成为:

public void forEach_root(Allocation ain, Allocation aout)

这仅在极少数情况下有用(例如点运算符),因为您只能在当前位置访问输入分配。

全局分配

如果您想在输入分配中进行随机访问,那么您将需要全局分配。这是一个使用全局分配的窗口运算符的小例子,对我有用。

模糊.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);
...
于 2013-02-18T18:13:14.883 回答
10

这里有几件事:

  • 是的,我们在文档方面落后了。我们知道,我们一直很忙。这是我在不久的将来的议程。

  • FS 旨在作为 RS 的限制性更强的变体,为编译器后端提供额外的优化机会。今天,我们的 CPU 后端中没有任何无法从等效的 RS 文件中获得的文件,但 OEM 可能会使用 FS 文件而不是通用 RS 文件来提高其 SoC 的性能。一般来说,它需要__attribute__((kernel)),没有指针,也没有联合,并且 fp_relaxed 由文件类型隐含。

  • 主机端 API 完全相同;唯一的区别在于我们实际上作为内核二进制文件传递的内容。

对 ofp 的回答进行了一些小的更正:

  1. 您应该使用 rsGetElementAt_(type)。它比 rsGetElementAt 干净得多,因为您不需要强制转换或额外的取消引用或类似的东西。
  2. #pragma fp_relaxed 隐含在 .fs 扩展名中,在 FS 文件中不是必需的。
  3. 您不必包含 rs_allocation.rsh(所有 RS/FS 文件也隐含)。
于 2013-02-19T22:04:52.690 回答
-3

这里是过滤器脚本的完整介绍和很多演示。http://developer.android.com/guide/topics/renderscript/compute.html

于 2013-06-13T08:47:54.670 回答