在Java中,我有这个代码用于为intPointer创建分配。但是在renderscript计算之后,我无法获得分配的值。没有copyTo(int)方法只有byte [],short [],int [],float [],bitmap。
//Create Allocation
Allocation intPointer = Allocation.createSized(renderScript, Element.I32(renderScript), 2);
convolution.bind_intPointer(intPointer);
convolution.forEach_root(allocationOut);
[...]
//read Allocation, not working
int[] ints = new int[]{0x01234567};
intPointer.copyTo(ints); //does not overwrite the ints the line above
int i = (int)ints[0];
Log.d("ints", String.valueOf(i));
的renderScript:
#pragma version(1)
#pragma rs java_package_name(package com.ap.wificam)
#pragma rs_fp_imprecise
rs_allocation input;
rs_allocation mask;
int32_t *intPointer = 0;
void root(uchar4* out, uint32_t x, uint32_t y) {
//do some stuff
if((sum.x + sum.y + sum.z)/3 > *intPointer)
*intPointer = (sum.x + sum.y + sum.z)/3; //wirte data to intPointer
*out = convert_uchar4(sum);
}
Log.d(“ints”,String.valueOf(i));给了我D/ints﹕ 19088743
和rsDebug(“rs”,* intPointer); 2045 0x7fd
如何从分配中获取我的int值?
答案 0 :(得分:0)
您的RenderScript设置似乎是正确的,但我认为您在正确初始化分配中的数据时遇到了问题。
由于您在比较sum
平均值是否大于*intPointer
时是否正在读取RenderScript内的分配值,因此您需要确保该值的起始值是实际上是在期待。否则它将具有未初始化的数据,并且>
比较将在大多数时间失败。
我想这就是你试图用int32_t *intPointer = 0;
做的事情,但这并不是用C语言初始化指针数据的正确方法。最简单的方法是从Java做一个数据副本吧创建分配后:
Allocation intPointer = Allocation.createSized(renderScript, Element.I32(renderScript), 2);
intPointer.copy1DRangeFrom(0, 2, new int[2]);
convolution.bind_intPointer(intPointer);
这将确保RS内核开始时所有值都为0(因为在Java中,new int[2]
创建一个0初始化数组)。
此外,您的代码可能不完全是线程安全的。由于您将有许多线程同时读取和写入单个*intPointer
地址,因此您可能遇到同步问题,其中您获得的最终值可能是也可能不是所有线程的真正全局最大值。
我建议您不要这样做,而是将所有 (sum.x + sum.y + sum.z)/3
值存储在与输入数据一样大的分配中,然后将该分配复制回Java并从在那里,对其数组进行简单的循环以找到最大值。
从RenderScript内核中正确并行化最大算法实际上有点难以做到(如果您感兴趣,可以阅读我前段时间发布的this other answer更多详细信息),为了简单起见,如上所述,你最好从Java中找到最大值。