在运行时编译渲染脚本代码

DeG*_*seZ 6 java android renderscript

我想知道是否可以在 android 应用程序运行时编写/修改渲染脚本代码。我的主要目标是制作一个应用程序,用户可以在没有任何 Java 知识的情况下学习使用 renderscript。应用程序的基本布局将由输入和输出图像组成,并可以输入代码。此应用程序的基本功能已经在运行,这是界面图像。 应用布局

使用来自应用程序的直接反馈来测试渲染脚本代码会很有用。

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

一个基本的“模板”渲染脚本文件,具有必要的全局变量,如输入和输出分配。

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

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

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

有没有(另一种)方法可以在运行时编译渲染脚本代码?

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

Kie*_*etz 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);
  }
}
Run Code Online (Sandbox Code Playgroud)

</ExtremeHax>