指標
指標被反射到位於<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]的數組中的資料能夠被複製。 |