您的位置:首页 > 移动开发 > Android开发

Android高级Renderscript---Andvanced Renderscript(二)

2012-08-02 12:48 274 查看
函数

函数被反射到位于project_root/gen/package/name/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系统执行没有固定中断的功能,并提高效率。如果函数允许有返回值,那么调用将会被阻塞,一直到该函数被返回。

如果想要让Renderscript代码给Android框架返回一个值,请使用rsSendToClient()函数。

变量

被支持的变量类型会反射到位于project_root/gen/package/name/ScriptC_renderscript_filename的脚本类中,同时会给每个变量生成一组访问器方法。例如,如果在Renderscript代码中声明了以下变量:

uint32_t unsignedInteger=1;

那么就会生成下列代码:

privatelong mExportVar_unsignedInteger;

publicvoid set_unsignedInteger(long v){

    mExportVar_unsignedInteger = v;

    setVar(mExportVarIdx_unsignedInteger, v);

}

 

publiclong get_unsignedInteger(){

    return mExportVar_unsignedInteger;

}

结构(Structs)

结构会被反射成一个它自己的类,位于<project_root>/gen/com/example/renderscript/ScriptField_struct_name中,该类代表了一个struct数组,并允许给结果成员分配内存。例如,如果声明了以下结构:

typedef struct Point {
   float2 position;
   float size;
} Point_t;

那么在ScriptField_Pont.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运行时所请求的结构,并能够与内存中的这些结构进行交互。每个结构类都定义了以下的方法和构造器:

1. 被重载的构造器允许用来分配内存。ScriptField_struct_name(Renderscript rs, int count)构造器允许用count参数来定义想要分配内存的结构体的数量。ScriptField_struct_name(RenderScript
rs, int count, int usages)定义了一个额外的参数:usages,这个参数用来指定该内存所匹配的内存空间,共有四种内存空间的可能:

   A.USAGE_SCRIPT:在脚本的内存空间中来分配。如果没有指定内存空间,这是默认的内存空间。

   B.USAGE_GRAPHICS_TEXTURE:在GPU的纹理内存空间中进行分配。

   C.USAGE_GRAPHICS_VERTEX:在GPU的Vertex内存空间中进行分配。

   D.USAGE_GRAPHICS_CONSTANTS:在GPU的固定内存空间中进行分配,被分配的空间有不同的程序对象来使用。

通过OR操作符能够指定多种内存空间。这样做的用意是要告诉Renderscript运行时,你要访问指定的内存空间中的数据。下面的例子在脚本和Vertex内存空间都给定制的数据类型分配了内存:

 ScriptField_Point touchPoints =newScriptField_Point(myRenderscript,2,

Allocation.USAGE_SCRIPT |Allocation.USAGE_GRAPHICS_VERTEX);

2. 一个静态的嵌套类:Item,该类允许用对象的形式来创建一个struct的实例。如果要让struct在你的Android代码中更好的工作,那么这个嵌套类就会发挥作用。当完成对象的操作时,通过调用set(Item I, int
index, boolean copyNow)方法,能够把该对象放到被分配的内存中,并且把Item设置到数组中期望的位置。对于最新写入的内存,Renderscript运行时能够自动的访问。

3. 结构体中的每个字段都有获取和设置值的访问器方法。这些访问器的每个方法都会有一个index参数来指定要读写的数组中结构体。每个setter方法还有一个copyNow参数,它指定是否要把该内存立即同步给Renderscript运行时。要同步那些尚未同步的内存,请调用copyAll()方法。

4. createElement()方法创建一个内存中结构体的说明。该说明被用于把内存分配给其所代表的内存。

5. resize()方法工作很想C语言中reallc()方法,它允许你扩展之前分配的内存空间,并在该内存空间中保持之前创建的值。

6. copyAll()方法把在框架层设置的内存同步到Renderscript运行时。在调用一个成员的set方法时,能够指定一个布尔型的copyNow参数,该参数是true时,说明调用该法时需要同步内存。如果指定为false,你能够调用copyAll()方法,把所有属性的尚未同步的内存与Renderscript运行时同步。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息