Renderscript 簡介
本指南介紹 Renderscript,並說明如何在以 API 層級 17 或更高版本為目標的 Xamarin.Android 應用程式中使用內建 Renderscript API。
概觀
Renderscript 是由 Google 建立的程式設計架構,旨在改善需要大量計算資源的 Android 應用程式效能。 它是以 C99 為基礎的低階高效能 API。 因為它是在 CPU、GPU 或 DSP 上執行的低階 API,所以 Renderscript 非常適合執行下列任一項的 Android 應用程式:
- 圖形
- 影像處理
- 加密
- 訊號處理
- 數學例程
Renderscript 會使用 clang
腳本,並將腳本編譯至組合至 APK 的 LLVM 位元組程序代碼。 第一次執行應用程式時,LLVM 位元組程式代碼會編譯成裝置上處理器的計算機程序代碼。 此架構可讓 Android 應用程式利用電腦程式代碼的優點,而開發人員不需要自行為裝置上的每個處理器撰寫它。
Renderscript 例程有兩個元件:
Renderscript 運行時間 – 這是負責執行 Renderscript 的原生 API。 這包括針對應用程式撰寫的任何 Renderscript。
來自 Android Framework 的 Managed 包裝函式 – Managed 類別,可讓 Android 應用程式控制轉譯腳本運行時間和腳本並與其互動。 除了架構提供的類別來控制 Renderscript 執行時間之外,Android 工具鏈還會檢查 Renderscript 原始程式碼,併產生 Managed 包裝函式類別以供 Android 應用程式使用。
下圖說明這些元件如何關聯:
在 Android 應用程式中使用 Renderscripts 有三個重要概念:
內容 – Android SDK 所提供的受控 API,可配置資源給 Renderscript,並允許 Android 應用程式從 Renderscript 傳遞和接收數據。
計算 核心 – 也稱為 根核心 或 核心,這是執行工作的例程。 核心與 C 函式非常類似;它是可平行處理的例程,將會在配置記憶體 中的所有數據上執行。
已配置的記憶體 – 資料會透過 配置來回傳遞至核心。 核心可能有一個輸入和/或一個輸出配置。
Android.Renderscripts 命名空間包含與 Renderscript 運行時間互動的類別。 特別是,類別 Renderscript
會管理 Renderscript 引擎的生命週期和資源。 Android 應用程式必須初始化一或多個 Android.Renderscripts.Allocation
物件。 配置是受控 API,負責配置和存取 Android 應用程式與 Renderscript 執行時間之間共用的記憶體。 一般而言,會針對輸入建立一個配置,並選擇性地建立另一個配置來保存核心的輸出。 Renderscript 執行時間引擎和相關聯的 Managed 包裝函式類別將管理配置所保留記憶體的存取權,Android 應用程式開發人員不需要執行任何額外的工作。
配置將包含一或多個 Android.Renderscripts.Elements。 元素是一種特製化類型,可描述每個配置中的數據。 輸出配置的元素類型必須符合輸入元素的類型。 執行時,Renderscript 會以平行方式逐一查看輸入配置中的每個元素,並將結果寫入輸出配置。 元素有兩種類型:
簡單類型 – 從概念上講,這與 C 數據類型
float
或char
相同。複雜類型 – 這個類型類似於 C
struct
。
Renderscript 引擎會執行運行時間檢查,以確保每個配置中的元素都與核心所需的專案相容。 如果 Allocation 中 Elements 的數據類型不符合核心預期的數據類型,則會擲回例外狀況。
所有 Renderscript 核心都會以子代的類型包裝 Android.Renderscripts.Script
類別。 類別 Script
是用來設定 Renderscript 的參數、設定適當的 Allocations
,然後執行 Renderscript。 Android SDK 中有兩 Script
個子類別:
Android.Renderscripts.ScriptIntrinsic
– 某些較常見的 Renderscript 工作會組合在 Android SDK 中,並由 ScriptIntrinsic 類別的子類別存取。 開發人員不需要採取任何額外的步驟,即可在其應用程式中使用這些腳本,因為它們已經提供。ScriptC_XXXXX
– 也稱為 使用者腳本,這些腳本是由開發人員撰寫,並封裝在 APK 中。 在編譯時期,Android 工具鏈會產生 Managed 包裝函式類別,以允許在 Android 應用程式中使用腳本。 這些產生的類別名稱是 Renderscript 檔案的名稱,前面加上ScriptC_
。 Xamarin.Android 未正式支援撰寫和納入使用者腳本,且超出本指南的範圍。
在這兩種類型中,只有 StringIntrinsic
Xamarin.Android 支援 。 本指南將討論如何在 Xamarin.Android 應用程式中使用內部腳本。
需求
本指南適用於以 API 層級 17 或更高版本為目標的 Xamarin.Android 應用程式。 本指南未涵蓋使用者文本的使用。
Xamarin.Android V8 支援連結庫會針對以舊版 Android SDK 為目標的應用程式,回移內嵌轉譯腳本 API。 將此套件新增至 Xamarin.Android 專案應該允許以舊版 Android SDK 為目標的應用程式利用內建腳本。
在 Xamarin.Android 中使用內建轉譯腳本
內部腳本是使用最少額外程式代碼執行密集運算工作的絕佳方式。 它們已經過微調,以在大型裝置交叉區段上提供最佳效能。 內部腳本的執行速度比 Managed 程式代碼快 10 倍,比自定義 C 實作快 2-3 倍並不常見。 內部腳本涵蓋許多典型的處理案例。 此內建文稿清單描述 Xamarin.Android 中的目前文稿:
ScriptIntrinsic3DLUT – 使用 3D 查找表將 RGB 轉換為 RGBA。
ScriptIntrinsicBLAS – 為 BLAS 提供高效能轉譯腳本 API。 BLAS (基本線性代數子程式) 是提供標準建置組塊來執行基本向量和矩陣運算的例程。
ScriptIntrinsicBlend – 將兩個配置混合在一起。
ScriptIntrinsicBlur – 將 Gaussian 模糊套用至配置。
ScriptIntrinsicColorMatrix – 將色彩矩陣套用至配置(即變更色彩、調整色調)。
ScriptIntrinsicConvolve3x3 – 將 3x3 色彩矩陣套用至配置。
ScriptIntrinsicConvolve5x5 – 將 5x5 色彩矩陣套用至配置。
ScriptIntrinsicLUT – 將個別通道查閱表套用至緩衝區。
ScriptIntrinsicResize – 用於執行 2D 配置重設大小的腳本。
ScriptIntrinsicYuvToRGB – 將 YUV 緩衝區轉換成 RGB。
如需每個內部文本的詳細數據,請參閱 API 檔。
接下來會說明在Android應用程式中使用 Renderscript 的基本步驟。
建立 Renderscript 内容 – Renderscript
類別是 Renderscript 內容周圍的 Managed 包裝函式,可控制初始化、資源管理和清除。 Renderscript 物件是使用 Factory 方法建立的,此方法會採用 RenderScript.Create
Android Context (例如 Activity) 做為參數。 下列程式代碼行示範如何初始化 Renderscript 內容:
Android.Renderscripts.RenderScript renderScript = RenderScript.Create(this);
建立設定 – 視內部文稿而定,可能需要建立一或兩 Allocation
個 。 Android.Renderscripts.Allocation
類別有數個處理站方法,可協助具現化內部函數的配置。 例如,下列代碼段示範如何建立位圖的配置。
Android.Graphics.Bitmap originalBitmap;
Android.Renderscripts.Allocation inputAllocation = Allocation.CreateFromBitmap(renderScript,
originalBitmap,
Allocation.MipmapControl.MipmapFull,
AllocationUsage.Script);
通常,您必須建立 Allocation
來保存文本的輸出數據。 下列代碼段示範如何使用 Allocation.CreateTyped
協助程式來具現化與原始類型相同的第二個 Allocation
類型:
Android.Renderscripts.Allocation outputAllocation = Allocation.CreateTyped(renderScript, inputAllocation.Type);
具現化腳本包裝函 式 – 每個內部腳本包裝函式類別都應該有協助程式方法(通常稱為 Create
),以便具現化該腳本的包裝函式物件。 下列代碼段是如何具現化 ScriptIntrinsicBlur
模糊物件的範例。 Element.U8_4
協助程式方法會建立一個 Element,描述 4 個字段的 8 位無符號整數值,適合用來存放對象數據的Bitmap
數據類型:
Android.Renderscripts.ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.Create(renderScript, Element.U8_4(renderScript));
指派 Allocation(s)、設定參數及執行腳本 – 類別 Script
提供 ForEach
實際執行 Renderscript 的方法。 這個方法會逐一查看 Element
持有輸入資料中的每個 Allocation
。 在某些情況下,可能需要提供 Allocation
保留輸出的 。
ForEach
將會覆寫輸出配置的內容。 為了繼續執行先前步驟中的代碼段,此範例示範如何指派輸入配置、設定參數,最後執行腳本(將結果複製到輸出配置):
blurScript.SetInput(inputAllocation);
blurScript.SetRadius(25); // Set a pamaeter
blurScript.ForEach(outputAllocation);
您可能想要查看具有 Renderscript 配方的影像模糊,這是如何在 Xamarin.Android 中使用內建腳本的完整範例。
摘要
本指南介紹 Renderscript,以及如何在 Xamarin.Android 應用程式中使用它。 它簡短地討論了什麼是 Renderscript,以及它在 Android 應用程式中的運作方式。 它描述 Renderscript 中的一些主要元件,以及使用者腳本與內嵌腳本之間的差異。 最後,本指南討論了在 Xamarin.Android 應用程式中使用內建腳本的步驟。