Android高級Renderscript—Andvanced Renderscript(四)

與內存一起工作

在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運行時層。

 作者:FireOfStar
 

發佈留言