功能
功能反映到脚本类本身,位于project_root / GEN /包/名/ ScriptC_renderscript_filename。例如,如果你声明下面的函数在RenderScript的代码:
void touch(float x, float y, float pressure, int id) { if (id >= 10) { return; } touchPos[id].x = x; touchPos[id].y = y; touchPressure[id] = pressure; }然后将以下代码生成:
public void invoke_touch(float x, float y, float pressure, int id) { FieldPacker touch_fp = new FieldPacker(16); touch_fp.addF32(x); touch_fp.addF32(y); touch_fp.addF32(pressure); touch_fp.addI32(id); invoke(mExportFuncIdx_touch, touch_fp); }
功能不能有一个返回值,因为RenderScript系统被设计为异步的。当你的Android框架代码调用到RenderScript,呼叫排队,并在执行时可能。此限制允许RenderScript系统功能,无需不断中断,提高了效率。如果职能允许有返回值,调用将阻塞,直到返回的值。
uint32_t unsignedInteger = 1;然后将以下代码生成:
private long mExportVar_unsignedInteger; public void set_unsignedInteger(long v){ mExportVar_unsignedInteger = v; setVar(mExportVarIdx_unsignedInteger, v); } public long get_unsignedInteger(){ return mExportVar_unsignedInteger; }
typedef struct Point { float2 position; float size; } Point_t;那么下面的代码在ScriptField_Point.java产生:
package com.example.android.rs.hellocompute; import android.renderscript.*; import android.content.res.Resources; /** * @hide */ public class ScriptField_Point extends android.renderscript.Script.FieldBase { static public class Item { public static final int sizeof = 12; Float2 position; float size; Item() { position = new Float2(); } } private Item mItemArray[]; private FieldPacker mIOBuffer; public static Element createElement(RenderScript rs) { Element.Builder eb = new Element.Builder(rs); eb.add(Element.F32_2(rs), "position"); eb.add(Element.F32(rs), "size"); return eb.create(); } public ScriptField_Point(RenderScript rs, int count) { mItemArray = null; mIOBuffer = null; mElement = createElement(rs); init(rs, count); } public ScriptField_Point(RenderScript rs, int count, int usages) { mItemArray = null; mIOBuffer = null; mElement = createElement(rs); init(rs, count, usages); } private void copyToArray(Item i, int index) { if (mIOBuffer == null) mIOBuffer = new FieldPacker(Item.sizeof * getType().getX()/* count */); mIOBuffer.reset(index * Item.sizeof); mIOBuffer.addF32(i.position); mIOBuffer.addF32(i.size); } public void set(Item i, int index, boolean copyNow) { if (mItemArray == null) mItemArray = new Item[getType().getX() /* count */]; mItemArray[index] = i; if (copyNow) { copyToArray(i, index); mAllocation.setFromFieldPacker(index, mIOBuffer); } } public Item get(int index) { if (mItemArray == null) return null; return mItemArray[index]; } public void set_position(int index, Float2 v, boolean copyNow) { if (mIOBuffer == null) mIOBuffer = new FieldPacker(Item.sizeof * getType().getX()/* count */); if (mItemArray == null) mItemArray = new Item[getType().getX() /* count */]; if (mItemArray[index] == null) mItemArray[index] = new Item(); mItemArray[index].position = v; if (copyNow) { mIOBuffer.reset(index * Item.sizeof); mIOBuffer.addF32(v); FieldPacker fp = new FieldPacker(8); fp.addF32(v); mAllocation.setFromFieldPacker(index, 0, fp); } } public void set_size(int index, float v, boolean copyNow) { if (mIOBuffer == null) mIOBuffer = new FieldPacker(Item.sizeof * getType().getX()/* count */); if (mItemArray == null) mItemArray = new Item[getType().getX() /* count */]; if (mItemArray[index] == null) mItemArray[index] = new Item(); mItemArray[index].size = v; if (copyNow) { mIOBuffer.reset(index * Item.sizeof + 8); mIOBuffer.addF32(v); FieldPacker fp = new FieldPacker(4); fp.addF32(v); mAllocation.setFromFieldPacker(index, 1, fp); } } public Float2 get_position(int index) { if (mItemArray == null) return null; return mItemArray[index].position; } public float get_size(int index) { if (mItemArray == null) return 0; return mItemArray[index].size; } public void copyAll() { for (int ct = 0; ct < mItemArray.length; ct++) copyToArray(mItemArray[ct], ct); mAllocation.setFromFieldPacker(0, mIOBuffer); } public void resize(int newSize) { if (mItemArray != null) { int oldSize = mItemArray.length; int copySize = Math.min(oldSize, newSize); if (newSize == oldSize) return; Item ni[] = new Item[newSize]; System.arraycopy(mItemArray, 0, ni, 0, copySize); mItemArray = ni; } mAllocation.resize(newSize); if (mIOBuffer != null) mIOBuffer = new FieldPacker(Item.sizeof * getType().getX()/* count */); } }生成的代码提供给你作为一个方便由RenderScript运行时所需的结构分配内存,并在内存结构交互。每个结构的类定义了以下方法和构造函数:
ScriptField_Point touchPoints = new ScriptField_Point(myRenderScript, 2, Allocation.USAGE_SCRIPT | Allocation.USAGE_GRAPHICS_VERTEX);静态嵌套类,项目,可以让你创建结构的实例,以对象的形式。如果它使更多的意义在你的Android的代码结构来解决这个嵌套类是非常有用的。当您完成操作物体,可以通过调用一套推对象分配的内存(项目我,INT指数,布尔copyNow)和项目设置到阵列中所需的位置。该RenderScript运行时自动访问新写入的内存。
typedef struct Point { float2 position; float size; } Point_t; Point_t *touchPoints; int32_t *intPointer;然后将以下代码中产生:
private ScriptField_Point mExportVar_touchPoints; public void bind_touchPoints(ScriptField_Point v) { mExportVar_touchPoints = v; if (v == null) bindAllocation(null, mExportVarIdx_touchPoints); else bindAllocation(v.getAllocation(), mExportVarIdx_touchPoints); } public ScriptField_Point get_touchPoints() { return mExportVar_touchPoints; } private Allocation mExportVar_intPointer; public void bind_intPointer(Allocation v) { mExportVar_intPointer = v; if (v == null) bindAllocation(null, mExportVarIdx_intPointer); else bindAllocation(v, mExportVarIdx_intPointer); } public Allocation get_intPointer() { return mExportVar_intPointer; }生成一个GET方法和一种特殊的方法命名bind_pointer_name(而不是set()方法)。这种方法允许你绑定是在Android虚拟机分配到RenderScript运行时(你不能在你的.RS文件分配内存)内存。欲了解更多信息,请参阅使用分配的内存工作。
array = (int *)malloc(sizeof(int)*10);malloc调用可以分为两部分:被分配的内存的大小(sizeof的(INT)),以及如何内存的许多单位应分配(10)。 Android框架提供了这两个部分类以及一个类来表示的malloc本身。
Android的对象类型说明
Element
一个元素描述的存储器分配的一个单元,并可以有两种形式:基本的或复杂的。
一个基本元件包含任何有效RenderScript数据类型的数据的一个单一的组件。基本元素的数据类型的实例包括一个浮点值,一个float4载体或单一的RGB-565色。
复杂的元素包含基本元素的列表,从您在RenderScript代码声明结构被创建。例如分配可以包含在内存中的顺序排列的多个结构。每个结构被认为是它自己的元件,而不是该结构中的每个数据类型。
Type
A型是一个存储器分配模板和由一个元件和一个或多个尺寸。它描述了存储器的布局(基本上元件的阵列),但不分配用于它描述数据存储器。
A型由五个维度:X,Y,Z,LOD(层次细节)和面(的立方体贴图)。可以分配在X,Y,Z尺寸可用内存的限制范围内的任何正整数值。单个维度分配具有大于零的X尺寸而Y和Z维度是零,以指示不存在。例如,为X = 10的分配,Y = 1被认为是二维并且x = 10,Y = 0被认为是一维的。 LOD值和面尺寸为布尔值,表明存在或不存在。
Allocation
分配为基于由一个类型所表示的存储器的描述应用的存储器。分配的内存可以在很多存储空间同时存在。如果存储器在一个空间改性,必须明确同步存储器,使得它在所有在它存在的其他空间更新。
分配数据上传两种主要方法之一:进行类型检查和类型选中。对于简单的数组还有的copyfrom()即采取从Android系统中的数组并将其复制到本机的内存层存储的功能。未选中的变种允许Android系统,以结构数组,因为它不支持结构拷贝过来。例如,如果存在为n float数组分配,包含在浮子[n]的数组或字节[N * 4]数组可以被复制的数据。
使用内存
您在RenderScript声明非静态的,全局变量在编译时分配的内存。您可以直接与这些变量在RenderScript代码工作,而无需在Android框架水平为它们分配内存。 Android框架层也可以访问这些变量与在反射层类生成所提供的存取方法。如果这些变量在运行时RenderScript初始化层,这些值用在Android框架层初始化相应的值。如果全局变量被标记为const,则不会产生一套方法。
注:如果您使用的是包含指针,如s_program片段rs_allocation一定RenderScript结构,你必须获得相应的Android框架类的一个对象,然后再调用set方法为结构内存绑定到RenderScript运行。在RenderScript运行时层不能直接操纵这些结构。这一限制不适用于包含指针,因为它们不能在第一时间被导出到反射层类的用户定义的结构。如果您尝试声明包含一个指向非静态,全局结构生成一个编译器错误。
RenderScript也有三分球支持,但是你必须明确地在你的Android框架代码分配内存。当您在.RS文件中声明全局指针,您可以通过适当的反射层类的分配内存和绑定内存到本机RenderScript层。您可以从Android框架层还有RenderScript层,它为您提供了灵活地修改在最合适的层变量此内存交互。
分配和结合动态内存到RenderScript
要动态分配内存空间,你需要调用一个Script.FieldBase类,这是最常见的方式的构造。另一种方法是手动创建的分配,这是需要的东西,如基本类型的指针。您应该使用Script.FieldBase类构造函数时提供的简单性。获得的内存分配后,呼叫指示器的反射bind方法到分配的存储器结合到RenderScript运行时。
下面的例子分配内存两种基本类型的指针,intPointer,和一个指向一个结构,接触点。它也结合了内存到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); ... }读取和写入内存
typedef struct Point { int x; int y; } Point_t; Point_t point;您可以在rsfile.rs赋值给这个结构一样,直接。这些值不会传播回Android框架级别:
point.x = 1; point.y = 1;你可以在这样的Android框架层赋值给结构。这些值传播回RenderScript运行级别:
ScriptC_rsfile mScript; ... Item i = new ScriptField_Point.Item(); i.x = 1; i.y = 1; mScript.set_point(i);您可以阅读你这样的RenderScript代码值:
rsDebug("Printing out a Point", point.x, point.y);你可以用下面的代码Android框架层读取值。请记住,如果一个人被定为Android框架水平这个代码只返回一个值。你会得到一个空指针异常,如果你只设置在RenderScript运行级别的值:
Log.i("TAGNAME", "Printing out a Point: " + mScript.get_point().x + " " + mScript.get_point().y); System.out.println(point.get_x() + " " + point.get_y());读取和写入全球指针
typedef struct Point { int x; int y; } Point_t; Point_t *point;假设你在Android框架层已分配的内存,您可以在结构正常访问值。你通过它的指针变量做出的struct任何更改都会自动提供给Android框架层:
point[index].x = 1; point[index].y = 1;您可以读取和写入值在Android框架层的指针,以及:
ScriptField_Point p = new ScriptField_Point(mRS, 1); Item i = new ScriptField_Point.Item(); i.x=100; i.y = 100; p.set(i, 0, true); mScript.bind_point(p); points.get_x(0); //read x and y from index 0 points.get_x(0);一旦内存已经绑定,您不必每次进行更改值时重新绑定内存到RenderScript运行。