当前位置: 代码迷 >> Android >> Android高级Renderscript-Andvanced Renderscript(3)
  详细解决方案

Android高级Renderscript-Andvanced Renderscript(3)

热度:32   发布时间:2016-05-01 17:40:50.0
Android高级Renderscript---Andvanced Renderscript(三)

指针

指针被反射到位于<project_root>/gen/package/name/ScriptC_renderscript_filename的脚本类中。你能够给给结构体或其他任何Renderscript支持的类型声明指针,但是结构体不能够包含指针或嵌套数组。例如,如果你声明了下列的指向struct和int32_t的指针:

typedef struct Point {

   float2 position;

   float size;

} Point_t;

 

Point_t *touchPoints;

int32_t *intPointer;

那么就会有以下代码生成:

privateScriptField_Point mExportVar_touchPoints;
publicvoid bind_touchPoints(ScriptField_Point v){
    mExportVar_touchPoints = v;
    if(v ==null) bindAllocation(null, mExportVarIdx_touchPoints);
    else bindAllocation(v.getAllocation(), mExportVarIdx_touchPoints);
}
 
publicScriptField_Point get_touchPoints(){
    return mExportVar_touchPoints;
}
 
privateAllocation mExportVar_intPointer;
publicvoid bind_intPointer(Allocation v){
    mExportVar_intPointer = v;
    if(v ==null) bindAllocation(null, mExportVarIdx_intPointer);
    else bindAllocation(v, mExportVarIdx_intPointer);
}
 
publicAllocation get_intPointer(){
    return mExportVar_intPointer;
}

一个get方法和一个名叫bind_pointer_name(它代替了set()方法)的特殊方法被生成。这个方法允许把Android VM中分配的内存绑定到Renderscript运行时(不能在.rs文件中分配内存)。

分配内存的API

使用Renderscript的应用程序依然运行在Android VM中。但实际上,Renderscript代码是运行在原生系统中,并且需要访问在Android VM中分配的内存。要达到这个目的,就必须把在VM分配的内存绑定给Renderscript运行时。这个过程被叫做绑定,它允许Renderscript运行时跟它所请求的内存进行无缝的工作,但却不能明确的分配。最终的结果是跟C语言中调用malloc方法相同。这样做的好处就是Android VM能够像共享内存一样对Renderscript运行时层进行垃圾回收。只需要对动态分配的内存进行绑定。静态分配的内存在Renderscript代码编译时被自动的创建。

有一组API来支持这种内存分配系统,它们允许Android VM分配内存并提供与malloc调用类似的功能。这些类描述了内存应该如何分配,以及如何执行分配处理。为了更好的理解这些类是如何工作的,先思考一下与它们相关的malloc的简单调用是有好处的:

array = (int*)malloc(sizeof(int)*10);

这个malloc调用能够被分为两部分:1.要分配的内存单元的尺寸;2要分配有多少个这样的内存单元(10)。Android框架针对这两部分,提供了代表malloc自己的类。

Element类代表了malloc调用的sizeof(int)部分,并且封装了一个内存分配单元,如一个浮点值或一个一个结构体。Type类封装了Element类和要分配的元素的数量(在上面的例子中是10)。你可以把Type类看做是一个Element类的数组。Allocation类会基于给定Type类来进行实际的内存分配,并代表了实际被分配的内存。

在大多数情况中,都不需要直接调用这些分配内存的API。反射层的类会自动的使用这些API来生成代码,并且对于分配内存,你所需要做的所有事情就是:调用一个在反射层的一个类中所声明的构造器,然后把分配到的内存绑定到Renderscript。有些时候,你可能想要直接使用这些类来自己进行内存分配,如从一个资源中加载一张位图,或是想要把内存指针分配给原始数据类型。下表中更加详细的介绍了这个三个内存管理类:

Android 对象类型

说明

Element

一个Element对象代表了一个内存分配单元,并能够有两种形式:基本(basic)和复合(complex)。

一个基本的Element对象包含了一个单一的有效的Renderscript数据类型的数据组件。基本元素数据类型的例子包括:float值、float4向量或一个单一的RGB-565颜色;

复合Element包含了一个基本元素的列表,并且是用在Renderscript代码中声明的结构体来创建的。例如一个被分配的内存能够包含多个在内存中按顺序排列的结构体。每个结构体都被认为是它的元素,而不是结构体中的数据类型。

Type

Type类是一个分配内存的模板,并且由一个元素和多个维度组成。它描述了内存的布局(基本上是一个Element对象的数组),但并不给它所描述的数据分配内存

一个由5个维度组成的Type:X,Y,Z,LOD(细节层次的),Faces(立方体的面)。在可用的内存限制内,你能够给X,Y,Z分配任意正整数的值。分配一维的内存空间就是要让X维度的值大于0,而Y和Z维度要等于,以示其不存在。例如,X=10,Y=1代表被分配的内存有两个维度组成,X=10,Y=0则代表一个维度。LOD和Faces都是布尔值,用来指示其存在或不存在。

Allocation

一个Allocation会基于由Type所代表的内存描述,给应用程序提供了内存。被分配的内存能够同时存在多个内存空间中。如果一个内存空间被修改,必须明确的同步该内存,以便在所有存在的其他内存中,只有该内存被更新。

更新分配数据的使用以下两种主要方法之一:类型检查和非类型检查。对于简单的数组,用copyFrom函数从Android系统中复制数组,并把它拷贝到原生层内存来保存。非类型检查的变体因为它不支持结构体,所以允许Android系统来复制结构体数组。例如,如果有一个n个浮点数的数组,那么包含在float[n]或byte[n*4]的数组中的数据能够被复制。

 

  相关解决方案