什么是RenderScript
RenderScript 是用于在 Android 上以高性能运行计算密集型任务的框架。RenderScript 主要用于数据并行计算,不过串行工作负载也可以从中受益。RenderScript 运行时可在设备上提供的多个处理器(如多核 CPU 和 GPU)间并行调度工作。这样您就能够专注于表达算法而不是调度工作。RenderScript 对于专注于图像处理、计算摄影或计算机视觉的应用来说尤其有用。
使用RenderScript的效果图
| 效果名 | 原图 | 效果图 |
|---|---|---|
| 灰度 | ![]() image.png
|
![]() image.png
|
| 高斯模糊 | ![]() image.png
|
![]() image.png
|
| 卷积 | ![]() image.png
|
![]() image.png
|
| 颜色matrix | ![]() image.png
|
![]() image.png
|
RenderScript内核
自定义 RenderScript 内核
- 在<project_root>/src/建立.rs目录,并创建demo.rs文件
- 声明
一个版本声明:#pragma version(1),用于声明此脚本中使用的 RenderScript 内核语言的版本。目前,1 是唯一有效的值。
一个包名声明:#pragma rs java_package_name(com.example.app),用于声明从此脚本中反映的 Java 类的软件包名称。请注意,您的 .rs 文件必须是应用软件包的一部分,且不在库项目中。
0个或者多个可调用函数。可调用函数是单线程 RenderScript 函数,您可以使用任意参数从 Java 代码调用该函数。可调用函数通常用于较大处理流水线中的初始设置或串行计算。
0个或者多个脚本全局变量。脚本全局变量类似于 C 中的全局变量。您可以通过 Java 代码访问脚本全局变量,并且这些变量通常用于向 RenderScript 内核传递参数。
0个或者多个计算内核。计算内核是函数或函数集合,可指导 RenderScript 运行时跨一组数据并行执行。计算内核分为两种类型:映射内核(也称为 foreach 内核)和归约内核。
映射内核是并行函数,可对相同维度的一组 Allocations 执行操作。默认情况下,它会对这些维度中的每个坐标执行一次。
归约内核是一系列函数,可对维度相同的一组输入Allocations执行操作。默认情况下,其accumulator 函数会对这些维度中的每个坐标执行一次。归约内核通常(但并非专门)用于将一组输入 Allocations“归约”为一个值。
系统内置内核
| 类名 | 用途 |
|---|---|
| ScriptIntrinsicBlur | 高斯模糊 |
| ScriptIntrinsicResize | 改变二维的大小,例如改变图片的大小 |
| ScriptIntrinsicYuvToRGB | YUV转RGB |
| ScriptIntrinsicColorMatrix | 颜色变换 |
| ScriptIntrinsicConvolve3x3 | 3*3卷积 |
| ScriptIntrinsicConvolve5x5 | 5*5卷积 |
| ScriptIntrinsicHistogram | 直方图 |
| ScriptIntrinsicBlend | 混合 |
| ScriptIntrinsicLUT | ? |
| ScriptIntrinsic3DLUT | ? |
| ScriptIntrinsicBLAS | ? |
通过 Java 访问 RenderScript API
在开发使用 RenderScript 的 Android 应用时,您可以通过以下两种方式之一从 Java 访问其 API:
-
android.renderscript- 此类软件包中的 API 在搭载 Android 3.0(API 级别 11)及更高版本的设备上可用。 -
android.support.v8.renderscript- 此软件包中的 API 通过支持库提供,可供您在搭载 Android 2.3(API 级别 9)及更高版本的设备上使用。
其利弊如下所示:
- 如果您使用支持库 API,无论您使用哪些 RenderScript 功能,应用的 RenderScript 部分都会与搭载 Android 2.3(API 级别 9)及更高版本的设备兼容。与使用原生 (
android.renderscript) API 相比,它可让您的应用在更多设备上运行。 - 某些 RenderScript 功能无法通过支持库 API 使用。
- 如果您使用支持库 API,您开发的 APK 会比使用原生 (
android.renderscript) API 开发的 APK 更大(可能会大幅增大)。
使用 RenderScript 支持库 API
- 确保您已安装所需的 Android SDK 版本(Android SDK Tools 修订版 22.2 或更高版本,Android SDK Build-tools 修订版 18.1.0 或更高版本)
- 更新 Android 构建流程的设置,以包含 RenderScript 设置:
android {
compileSdkVersion 28
defaultConfig {
minSdkVersion 9
targetSdkVersion 19
renderscriptTargetApi 18 // 指定要生成的字节码版本。不会影响build.gradle的设置的minSdkVersion版本。
renderscriptSupportModeEnabled true // 指定当运行生成的字节码所在的设备不支持目标版本,生成的字节码应回退到兼容版本。
}
}
- 在使用 RenderScript 的应用类中,添加对支持库类的导入操作:
import android.support.v8.renderscript.*
RenderScript运行时层
RenderScript 代码在紧凑且明确定义的运
行时层进行编译和执行。RenderScript 运行时 API 支持密集型计算,它们具有可移植性,并且能够根据处理器上可用的核心数量自动扩缩。
注意:NDK 中的标准 C 函数必须保证能在 CPU 上运行,从而使 RenderScript 无法访问这些库,因为 RenderScript 经过设计,能够在不同类型的处理器上运行。
您可以在 Android 项目的 src/ 目录中的 .rs 和 .rsh 文件内定义您的 RenderScript 代码。该代码由作为 Android 构建的一部分运行的 llvm 编译器编译为中间字节码。当您的应用在设备上运行时,该字节码随后会由设备上的另一个 llvm 编译器即时编译为机器代码。该机器代码针对设备进行了优化,也进行了缓存,因此后续使用已启用 RenderScript 的应用时不会重新编译该字节码。

rs字节码存放位置:和java反应层在同一包名下,名字为rs文件名+BitCode。例如demo.rs文件的java反应层为ScripC_demo,字节码为demoBitCode。

反应层
反映层是 Android 构建工具生成的一组类,可允许从 Android 框架访问 RenderScript 运行时。此层还提供了多种方法和构造函数,允许您为 RenderScript 代码中定义的指针分配和使用内存。以下列表介绍了反映的主要组件:
- 您创建的每个
.rs文件都会生成到名为project_root/gen/package/name/ScriptC_*renderscript_filename*且类型为ScriptC 的类中。此文件是您的.rs文件的.java版本,您可以从 Android 框架中调用它。 -
struct将反映到其自己名为project_root/gen/package/name/ScriptField_struct_name的类中,该类扩展了Script.FieldBase。此类表示struct的数组,允许您为此struct的一个或多个实例分配内存。




