在运行时编译renderscript代码

时间:2014-03-25 13:53:13

标签: java android renderscript

我想知道在Android应用程序运行时是否可以编写/修改renderscript代码。 我的主要目标是创建一个应用程序,用户可以在没有任何Java知识的情况下学习使用renderscript。应用程序的基本布局包括输入和输出图像,可以输入代码。这个应用程序的基本功能已经工作,这是一个界面的图像。 App layout

使用应用程序的直接反馈测试renderscript代码会很有用。

我已经对构建过程进行了研究,并提出了以下想法:

一个基本的“模板”renderscript文件,带有必要的全局变量,如in和out分配。

我的java代码将创建生成的java类的脚本对象,并对这些全局脚本变量进行基本初始化。 此模板.rs文件的根函数将为空,并且应该可以由用户在运行时实现。

当用户在app的主视图中键入他的代码时,代码将写入我自己的.rs文件,然后由llvm-rs-cc编译器编译,由应用程序调用。然后将生成的.bc复制到原始.bc文件的位置 模板。因为代码的唯一更改发生在根函数内部,所以没有必要对周围环境进行更改 java代码。

我目前遇到的问题是.bc文件捆绑在res / raw文件夹内的最终apk中, 这是应用程序无法访问的。因此,无法使用新生成的文件覆盖旧的.bc文件。

有没有(另一种)方法在运行时编译renderscript代码?

编辑:可以在此github链接中找到解决方案。有关详细信息,请查看this答案,阅读上一条评论

1 个答案:

答案 0 :(得分:2)

您必须至少改变生成的胶水类(ScriptC_mono)及其基础(ScriptC)。

<ExtremeHax>

读取.bc文件并将其传递给RenderScript的内部。据我所知,这是在ScriptC.internalCreate()内完成的,它连接到读取原始资源。您需要它来从您控制的位置读取您的文件。可能您只需要修改internalCreate(),但可能会出现需要更广泛编辑的复杂情况。

实施RuntimeScriptC后,您应该修改ScriptC_mono以继承该基类而不是ScriptC

正如您所指出的,由于您无法在运行时修改胶水类,因此您对rs代码所做的更改将非常有限。例如,您无法更改内核的签名。但是你可以进一步考虑这个问题:如果你放弃胶水类,你可以做任何你想要的改变。

通过索引而不是名称在胶水类中调用内核,并且在胶水类内部完成类型/元素检查。因此,即使您更改了内核的签名,只要您知道其索引及其输入和输出分配的类型,您仍然可以直接使用forEach()来调用它。

public class ScriptC_mono extends ScriptC {
  //...

  public void forEach_root(Allocation ain, Allocation aout) {
    // check ain
    if (!ain.getType().getElement().isCompatible(__U8_4)) {
        throw new RSRuntimeException("Type mismatch with U8_4!");
    }
    // check aout
    if (!aout.getType().getElement().isCompatible(__U8_4)) {
        throw new RSRuntimeException("Type mismatch with U8_4!");
            // Verify dimensions
    Type tIn = ain.getType();
    Type tOut = aout.getType();
    if ((tIn.getCount() != tOut.getCount()) ||
        (tIn.getX() != tOut.getX()) ||
        (tIn.getY() != tOut.getY()) ||
        (tIn.getZ() != tOut.getZ()) ||
        (tIn.hasFaces() != tOut.hasFaces()) ||
        (tIn.hasMipmaps() != tOut.hasMipmaps())) {
        throw new RSRuntimeException("Dimension mismatch between input and output parameters!");
    }
    forEach(mExportForEachIdx_root, ain, aout, null);
  }
}

</ExtremeHax>