RenderScript分配。从分配中读取int

时间:2014-03-01 16:28:16

标签: android renderscript

在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值?

1 个答案:

答案 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中找到最大值。