因為 Render Script 的重要性似乎比我原先想像地還要厲害, 故整理 Render Script 的用法如下. 主要參考 Google 的文件 [註1].
1. Off line Compile:
以 llvm-rs-cc compile 一個 render script (rs) 檔案, 產生 bit code (bc) 檔案, 例如底下的 foo.bc. 如果不是編成 bit code, 也可以和其他的 Java 檔編成 .Java. 這個過程可以使用 Java Reflection 的概念.
Java Reflection 能夠分析未知的 class, 把新 class 裡面的 name of the constructors, declared fields 和 methods 都抓出來. 換言之, 我們原先所寫的 .rs 檔透過 Java Reflection 取得正確的 Java API 資訊, 產生確實可用的 Java code. 而不會在 run time 才發生錯誤. 包括 Python 也是這類的 script, 而 C# 也支援 reflection, 但 C++ 沒有這個觀念.
2. On Line JIT Flow
等到 .bc 檔和 Java 檔都準備好之後, .bc 檔進入到 Android 所支持的 libbcc, 而 Java code 進入到 Android 的 Dalvik JIT, 跑在 DVM 上. 由下圖可以看得出來, 只有 .bc 可以用 GPU 或 DSP 來執行, 而 Java 不能. 這就是 render script 大有前途的地方.
特別值得提的是 llvm-rs-cc 會做很多大量的優化, 以便產生可移植的 .bc 檔. 而 libbcc 就是一個輕量級的 compiler, 目標只是針對本地平台已知的特性優化.
上次提到 HoneyComb 首先釋出 rs 的 API, 此時它還沒有用到平行處理. 在 ICS 版, 有個 rsForEach() 把每個 reflected Java helper 都叫起來.
RS 的範例如下:
從參數我們可以得知, 它在計算 luminance = 0.299 red + 0.587 green + 0.114 blue, 不愧是 C99 like.
[註 1] http://llvm.org/devmtg/2011-11/Hines_AndroidRenderscript.pdf