与内存一起工作
在Renderscript中声明的非静态的、全局的变量会在编译时被分配内存。在Renderscript代码中能够直接使用这些变量来工作,而不必在Android框架层再给它们分配内存。Android框架层也能使用反射层类中生产的访问器方法来访问这些变量。如果这些变量在Renderscript运行时层被初始化,那么在Android框架层那些值也会被用于初始化对应值。如果全局变量被标记为const,那么就不会生成set方法。
注意:如果你使用了某些包含指针的Renderscript结构体,如rs_program_fragment和rs_allocation,那么首先就必须要获取Android框架层类的一个对象,然后调用该结构体的set方法把内存绑定Renderscript运行时。你不能在Renderscript运行时层直接操作这些结构体。这种限制不适用于用户定义的包含指针的结构体,因为它们不能够被导出到反射层类的首要位置。如果你视图声明一个非静态的、全局的包含指针的结构体,那么就会产生一个编译错误。
Renderscript也支持指针,但是必须在Android框架代码中明确分配内存。当在.rs文件中声明了一个全局指针时,你要通过合适反射层类来分配内存,并把该内存绑定给原生的Renderscript层。你能够从Android框架层跟该内存交互,就像跟Renderscript层一样,它给你提供了在最合适层来灵活修改变量的方法。
给Renderscript分配并绑定动态内存
要分配动态内存,就需要调用Script.FieldBase类的构造器,这是最普通的方法。另一个可选择的方法是手动的创建一个Allocation对象,这种方式需要诸如原始类型指针等内容。无论何时,简单而有效的方法是使用Script.FieldBase类的构造器。获得内存分配之后,调用被反射的指针的bind方法,把分配到的内存绑定到Renderscript运行时。
下面的例子给原始类型指针:intpointer和结构体指针:touchPoints都分配了内存,并且把分配到的内存绑定到Renderscript:
private RenderScript myRenderscript;
private ScriptC_example script;
private Resources resources;
public void init(RenderScript rs, Resources res) {
myRenderscript = rs;
resources = res;
//allocate memory for the struct pointer, calling the constructor
ScriptField_Point touchPoints = new ScriptField_Point(myRenderscript, 2);
//Create an element manually and allocate memory for the int pointer
intPointer = Allocation.createSized(myRenderscript, Element.I32(myRenderscript), 2);
//create an instance of the Renderscript, pointing it to the bytecode resource
mScript = new ScriptC_example(myRenderscript, resources, R.raw.example);
//bind the struct and int pointers to the Renderscript
mScript.bind_touchPoints(touchPoints);
script.bind_intPointer(intPointer);
...
}
读写内存
你能够读写在Renderscript运行时和Android框架层静态和动态分配的内存。
在Renderscript运行时层静态分配的内存受到单向通信的限制。当Renderscript代码改变了一个变量的值时,出于对效率的考虑,它是不会反向通知Android框架层的。在Android框架层设置的最新的值始终是在调用get方法期间被返回。但是,当Android框架代码修改了一个变量时,这种改变会自动的被通知到Renderscript运行时,或者在最后时刻完成同步。如果要从Renderscript运行时把数据发送给Android框架层,可以使用rsSendToClient()函数来克服这种限制。
当使用动态分配的内存进行工作时,如果你使用与其关联的指针修改了分配到的内存,那么在Renderscript运行时层的任何改变都会被反向传播给Android框架层。在Android框架层修改了一个对象,也会立即把把这种改变传播给Renderscript运行时层。