最近看Android源碼,發現安卓動態壁紙中水面落葉,是使用renderScript實現的,於是對RenderScript進行了下研究:
RenderScript的官方網址:
https://developer.android.com/guide/topics/renderscript/index.html
renderScript 文檔簡單翻譯:
renderScript提供了一個平臺無關的計算引擎,該引擎在native級別工作,可以使用它來對你需要大量運算的app進行加速。
它使用不同類型指令集與體系架構的計算單元組成系統進行運算,在處理計算機圖像,視覺等方面尤其擅長,可以在設備所有可用處理器上並行執行,以使開發者不必關心調度與負載平衡的問題。
材料準備:
RenderScript的api從Android3.0(Api level 11)開始自帶,在低於3.0的機器上,可以通過support包來使用RenderScript。
搭建過程:
在應用程序模塊的應用程序文件夾打開build.gradle文件,
將一下設置添加上
android { compileSdkVersion 23 buildToolsVersion "23.0.3" defaultConfig { minSdkVersion 9 targetSdkVersion 19 renderscriptTargetApi 18//指定要生成字節碼版本 renderscriptSupportModeEnabled true//指定如果申城字節碼運行設備不支持目標版本,則 ~ //會退到兼容版本 } }
運行結構圖:
在確定可以使用renderScript api後,開始進行renderScript腳本的編寫。
在app/src/main路徑下新建一個文件夾,命名爲/rs,如果你使用的AndroidStudio,導入工程會發現該文件夾名自動變成了/renderScript;在該文件夾下新建.rs文件,在該文檔中編寫rs腳本。.rs文件必須是應用程序包的一部分,而不是在庫項目中。
renderScript腳本使用c99標準,是一種類C語言。
腳本結構如下:
#pragmaversion(1)// 聲明此腳本中使用的RenderScript內核語言版本
#pragma rsjava_package_name(com.winomtech.androidmisc.rs)//聲明本腳本反射出去的~ //Java文件的包名
void root(const uchar4 *in, uchar4 *out, uint32_t x,uint32_t y) {//kernel函數
}
void init() {//初始化函數,在root函數調用前會被調用一次,多用於變量初始化
}
一個rs腳本中可以有:
自定義變量:自動生成的ScriptC_XXX.java文件中生成所有非const變量的get和set方法
零個或多個可調用函數:單線程,可以在java代碼中調用,經常用來較大處理管線中的初始化設置或並行計算
零個或多個計算內核,kernel函數,是一些可調用函數的集合或者可以用來在數據集合中並行執行的函數。有兩種計算內核,不可調用
1 . Mappingkernel(foreach內核映射內核):對相同維度的集合進行操作的並行函數,默認情況下,對該維度想下的每個座標執行一次,可用於一次性地將輸入輸出到一個element中去,在上例中,
void root(const uchar4 *in, uchar4 *out, uint32_t x,uint32_t y)的參數in,根據傳遞給內核的輸入Allocation(數據集合,內存分配相關,我把它看做看做數據流)自動填充,內核處理完之後將返回值填充到out(輸出用的Allocation)中對應位置。默認情況下,每個allocation中的元素都要執行一次kernel函數。Kernel函數可以有一個或多個輸入,但只有一個輸出。Kernel函數可以自定義名字,不過要加_ _attribute_ _((kernel)) 前綴作爲標識具體見下文的例子。
2. Simplified kernel(簡化內核)