如何在RenderScript中使用数组分配

时间:2014-06-04 12:06:58

标签: android arrays allocation renderscript

我已经使用RenderScript工作了几天,但我无法弄清楚如何将数组从Java传递到RenderScript。我看到了一些例子,但没有一个能为我工作,而且我因为缺乏文档而陷入困境。

在此代码中,我尝试在bb和 coords 数组之间对root()接收的 中的每个索引进行一些检查:

RenderScript代码:

#pragma version(1)
#pragma rs java_package_name(com.me.example)

int4 bb;

rs_allocation coords;

void __attribute__((kernel)) root(int32_t in) 
{
   int index = in;

   if(bb[index] > rsGetElementAt_int(coords, index))
   {
       if(bb[index + 1] > rsGetElementAt_int(coords, index + 1))
       {
             //do something
       }
   }  
}

Java代码:

RenderScript mRS = RenderScript.create(this);        
ScriptC_script script = new ScriptC_script(mRS, getResources(), R.raw.match); 

// This arrays comes with data from another place
int[] indices; 
int[] coords;

// Create allocations
Allocation mIN = Allocation.createSized(mRS, Element.I32(mRS), indices.length);  
Allocation mOUT = Allocation.createSized(mRS, Element.I32(mRS), indices.length); 
Allocation coordsAlloc = Allocation.createSized(mRS, Element.I32(mRS), coords.length);    

// Fill it with data
mIN.copyFrom(indices);
coordsAlloc.copyFrom(coords);

// Set the data array
script.set_coords(coordsAlloc);

// Create bb and run
script.set_bb(new Int4 (x, y, width, height));
script.forEach_root(mIN);       

当我执行它时,我在 set_coords()语句中出现此错误:

  

Script :: setVar无法设置分配,无效的插槽索引

程序退出:

  

致命信号11(SIGSEGV)位于0x00000000(代码= 1),线程12274 ......

2 个答案:

答案 0 :(得分:0)

问题是rs_allocation是一个不透明的句柄,而不是反映的set_*()方法所理解的原始或自定义结构。更改您的RS代码,使coords为int32_t *,并为长度设置第二种类型:

int32_t *coords; int32_t coordsLen; ... void attribute((kernel)) root(int32_t in) { int index = in;

if(bb[index] > coords[index]) { if(bb[index + 1] > coords[index + 1]) { //do something } }
}

然后在你的Java代码中创建分配,但现在必须使用反射方法set_coordsLen()设置coordLen(这样你可以正确地检查你的RS代码,这里没有显示)然后你必须< b>将 Java端阵列绑定到RS分配:

... Allocation coordsAlloc = Allocation.createSized(mRS, Element.I32(mRS), coords.length);

// Fill it with data mIN.copyFrom(indices); coordsAlloc.copyFrom(coords);

// Set the data array script.set_coordsLen(coords.length); script.bind_coords(coordsAlloc);

// Create bb and run script.set_bb(new Int4 (x, y, width, height)); script.forEach_root(mIN);

答案 1 :(得分:0)

谢谢你的回复拉里。我尝试了你的方法,我在 set_coordsLen()语句中遇到了一个新错误。

  

Script :: setSlot无法设置分配,无效的插槽索引

所以我开始认为我的脚本中必须有另一个问题。我从一开始就检查了一切,然后在另一堂课中发现了问题。我从另一个.rs文件(copypaste fail)创建我的脚本错误:

ScriptC_script exmple = new ScriptC_script(mRS, getResources(), R.raw.exmple);
ScriptC_script script = new ScriptC_script(mRS, getResources(), R.raw.exmple);

而不是:

ScriptC_script exmple = new ScriptC_script(mRS, getResources(), R.raw.exmple);
ScriptC_script script = new ScriptC_script(mRS, getResources(), R.raw.script); 

我收到了这些错误,因为我在不存在的变量上设置了分配。这个小小的(也是可耻的)错误让我付出了太多的挫折感。 Eclipse让我调用set方法仍然很奇怪。

我尝试了两种传递数组的方法,而这两种方法都是。我更喜欢你的。

P.D:我看了你的AnDevCon演示视频。再次感谢您分享您对RS的了解。