Android進階Renderscript---Andvanced Renderscript(二)

來源:互聯網
上載者:User

函數

函數被反射到位於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()方法。www.2cto.com

4. createElement()方法建立一個記憶體中結構體的說明。該說明被用於把記憶體配置給其所代表的記憶體。

5. resize()方法工作很想C語言中reallc()方法,它允許你擴充之前分配的記憶體空間,並在該記憶體空間中保持之前建立的值。

6. copyAll()方法把在架構層設定的記憶體同步到Renderscript運行時。在調用一個成員的set方法時,能夠指定一個布爾型的copyNow參數,該參數是true時,說明調用該法時需要同步記憶體。如果指定為false,你能夠調用copyAll()方法,把所有屬性的尚未同步的記憶體與Renderscript運行時同步。

 

作者:FireOfStar


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.