如果您只需要double
在 RenderScript 上下文中复制一个,您可以声明一个非静态变量并使用自动生成的 getter/setter:
// whatever.rs
double hopper;
void root(const double *in, //...
// Whatever.java
mScript = new ScriptC_whatever(mRS);
double hopper = 1.234;
mScript.set_hopper(hopper);
如果需要完整分配,可以使用 NIO 将双精度数组编码为字节数组。然后,您可以使用 . 将它们复制到分配中copyFromUncheced
。我不知道如何以编程方式查询 RenderScript 上下文中的字节顺序——我发现我的需要通过反复试验来逆转。
// whatever.rs
double *target;
void root(const double *in, //...
// Whatever.java
public void copyDoublesTo(double[] entries, Allocation target)
throws IOException {
if (!target.getType().getElement().isCompatible(Element.F64(mRS)))
throw new RSRuntimeException("Type mismatch: Element != F64");
if (target.getType().getCount() != entries.length)
throw new RSRuntimeException("Type mismatch: wrong # of entries");
mScript.bind_target(target);
ByteArrayOutputStream bytes = new ByteArrayOutputStream(Double.SIZE * dim);
DataOutputStream longs = new DataOutputStream(bytes);
long temp;
for(int i=0; i!=dim; ++i) {
temp = Double.doubleToLongBits(entries[i]);
// reverse byte order:
temp = Long.reverseBytes(temp);
longs.writeLong(temp);
}
target.copyFromUnchecked(bytes.toByteArray());
}
您还可以Allocation
通过将其绑定到指针然后循环遍历您的数组来初始化您的double
,设置每个条目:
// whatever.rs
double *target;
void setTargetEntry(int index, double entry) {
target[index] = entry;
}
void root(const double *in, //...
public void copyDoublesTo(double[] entries, Allocation target) {
if (!target.getType().getElement().isCompatible(Element.F64(mRS))) {
throw new RSRuntimeException("Type mismatch: Element != F64");
}
if (target.getType().getCount() != entries.length) {
throw new RSRuntimeException("Type mismatch: wrong # of entries");
}
mScript.bind_target(target);
for(int i=0; i!=entries.length; ++i) {
mScript.invoke_setTargetEntry(i, entries[i]);
}
}
如果您需要double2
或类似的,只需在 Java 中交换double
即可Double2
。这比其他依赖于...创意打包方案的解决方案更自然地解决了您的问题,因此 RenderScript 将为您解决诸如字节顺序之类的讨厌问题。但是,它需要在分配上进行串行循环,这很慢
(并且您需要另一个来获取数据)。作为比较,当我测试这个复制 2^10 时float
平均 30 毫秒,而本机
copyTo
方法只需要 0.1 毫秒。(NIO方法大约需要2ms)