第1章 RenderScript

RenderScript提供一个独立于平台并在本地运行的计算引擎,用它来加速你需要大量计算能力的应用。RenderScript是一个运行与Android上计算密集型的高性能架构。RenderScript主要是面向数据的并行计算,虽然串行计算密集型负载也不错。RenderScript运行时将在所有可用的处理器上并行工作,如多核CPU,GPU或DSP,让你专注于算法而不是调度工作或负载均衡。RenderScript对于图像处理,计算摄影或计算机视觉这样的应用程序尤其有用。对于RenderScript,你先要明白两个概念:

1.高性能计算内核由C99语言编写

2.Java API用于管理RenderScript的资源寿命和控制核心的执行

1.1 写一个RenderScript内核

一个RenderScript内核通常驻留在一个.rs文件中,它在<project_root>/src/目录下,每一个rs文件被叫做一个脚本。每个脚本包含它自己的一套内核,函数和变量。一个脚本可以包含:

◆编译指示声明(#pragma version(1))用来声明一个RenderScript内核语言的版本。目前,1是唯一的有效值

◆编译指示声明(#pragma rs java_package_name(com.example.app))用来声明一个Java类的包名

◆一些调用函数。一个调用函数是一个单线程RenderScript函数,你能从你的java代码中使用任意参数来调用。这些经常用于初始化设置或在一个巨大的处理管道内进行串行计算。

◆一些脚本的全局变量,一个脚本的全局变量等价于一个在C中的全局变量。你能从java代码中访问脚本全局变量,并且这些变量经常被用于参数传递到RenderScript内核中。

◆一些计算内核,一个内核是一个并行函数,执行配置中的每一个元素。

下面是一个简单的例子:如代码清单1-1所示:

uchar4 __attribute__((kernel)) invert(uchar4 in, uint32_t x, uint32_t y) {

  uchar4 out = in;

  out.r = 255 - in.r;

  out.g = 255 - in.g;

  out.b = 255 - in.b;

  return out;

}

代码清单1-1

在许多方面,这是一个标准的C函数。第一个显著的特点是__attribute__((kernel))应用函数原型。这是指此函数是一个RenderScript内核而不是调用函数。接下来的特性是在参数及其类型。在RenderScript内核,这是一个特殊的参数,它自动填充基于输入配置传递给内核启动。默认情况下,内核跨整个配置运行,在配置中每个元素都带一个内核执行体。第三个显著的特性是内核的返回类型。在输出配置中,返回的值从内核自动写入到适当的位置。RenderScript运行时检查以确保输入和输出元素配置匹配内核原型,如果它们不匹配,则抛出一个异常。

一个内核可以有一个输入配置或一个输出配置,或两者都有。一个内核可能没有一个以上的输入或输出配置。如果一个以上的输入和输入是必须的,那些对象将结合rs_allocation 脚本全局变量并通过rsGetElementAt_type()或rsSetElementAt_type()从一个内核或者调用函数访问。一个内核可以使用X,Y,Z参数访问当前执行的坐标。这些参数是可选的,但坐标的参数类型必须是uint32_t

一个可选的init()函数。一个init()函数是一种特殊类型的调用函数,当脚本首次实例化时,需要调用它。这使得一些计算自动发生在脚本创建时。

一些静态脚本全局变量和函数。静态脚本全局变量几乎等价于脚本全局变量,只是静态不允许从java代码调用。静态函数是一个标准的C函数,它能被任意内核或调用函数调用,而不用暴露在Java API。如果一个脚本全局变量或函数不需要从java代码中调用,那么强烈建议声明为静态的。

设置浮点精度

你可以在一个脚本中控制所需的浮点精度,如果完整的IEEE 754-2008标准是有用的。那么以下编译指示可以设置一个不同的浮点精度等级:

◆#pragma rs_fp_full (默认如果没有什么被指定): 应用程序需要通过IEEE754-2008标准的浮点精度概述。

◆#pragma rs_fp_relaxed应用程序不需要严格的IEEE 754-2008标准并可以允许不精确,对于de-norms计算这种模式启动了清零(flush-to-zero),并且向零舍入(round-towards-zero)。

◆#pragma rs_fp_imprecise 应用程序不具有严格的精度要求。这种模式可以使一切rs_fp_relaxed 按照以下操作:

操作导致-0.0被+0.0代替返回

操作在INF和NAN在未定义。

大多数应用程序可以使用relaxed无任何副作用。这对于一些只提供relaxed精度的架构并需要额外优化的情况来说,这是非常有益的。(如SIMD CPU指令)

1.2 访问RenderScript API

当开发使用RenderScript开发Android应用程序时,你能通过以下其中一种方式来访问API:

◆android.renderscript这个API在Android3.0以上是可用的,这些对于RenderScript都是原始API并且当前没有更新。

◆android.support.v8.renderscript这个API需要通过Support Library才可用,这样允许你在Android2.2或更高版本中使用他们

官方强烈推荐使用Support Library API来访问RenderScript。因为它们包含计算框架最新的改进以及支持更广泛的设备兼容性。下面我们来使用RenderScript Support Library APIs

为了使用这个API,必须配置我们的开发环境。首选需要Android SDK Tool为22.2或更高。Android SDK Build 为18.1.0或更高。你能通过Android SDK Manager来更新安装版本。注意RSSL(RenderScript Support Library)API目前不支持Android Studio或Gradle编译。下面我们将在Eclipse中使用RSSL:

1.确保你有必要的Android SDK版本和编译工具版本

2.打开项目中的project.properties文件

3.添加以下几行到文件中

renderscript.target=18

renderscript.support.mode=true

sdk.buildtools=18.1.0

4.在你的类中使用RenderScript,导入Support Library:

import android.support.v8.renderscript.*;

project.properties设置了以上几行来控制Android在编译时的行为:

◆renderscript.target指定生成的字节码版本。官方推荐你设置这个值为可用的最高值并且设置renderscript.support.mode为true。从11到最新的API LEVEL在这之间设置任意整形值都是合法的。如果你的最小SDK版本在manifest中指定的值也为当前的SDK版本的较高值,那么renderscript.target将被忽略并且将目标值设置为最小SDK版本。

◆renderscript.support.mode如果它在不支持目标版本的设备上运行时,指定生成的字节码回滚兼容版本

◆sdk.buildtools指Android SDK编译工具使用的版本。这个值被设置为18.1.0或更高,如果你不指定这个值,会使用你当前最高安装的编译工具版本。你应该设置这个值,确保在不同的开发机器上保持一致性

1.3 在Java代码中使用RenderScript

在Java代码中使用RS需要依赖android.renderscript或android.support.v8.renderscript包。大多数应用程序遵循基本的使用模式

1.初始化一个RenderScript的context。这个RenderScript context在create(Context)中被创建,确保RenderScript能被使用并且提供一个对象来控制后来的RenderScript对象的生命周期。你应该考虑context创建与一个潜在的长时间运行的操作,因为它可能在不同的硬件块创建资源,如果可能的话,它不应该在应用程序的关键路径。通常,一个应用程序在一个时间内只有一个单一的RenderScript context。

2.通过一个叫脚本创建至少一个Allocation。一个Allocation是一个RenderScript对象,它提供一个固定的数据量存储。在脚本中的内核带来Allocation对象作为它们的输入输出,当作为脚本全局变量绑定时,并且Allocation对象在内核中能被rsGetElementAt_type()和 rsSetElementAt_type()访问。Allocation对象允许从java代码到RenderScript代码传递数组,相反的方向也可以。Allocation对象通常使用createTyped(RenderScript, Type)或createFromBitmap(RenderScript, Bitmap)来创建。

3.创建任意脚本是必要的。在使用RenderScript时,有2种脚本类型可用:

ScriptC:这些都是用户定义的脚本描述在上面(1.1写一个RenderScript内核)小节中。每个脚本有一个Java类反射,通过RenderScript编译器可以很容易的从java代码中访问脚本;这个类命名被ScriptC_filename。例如如果内核位于invert.rs中并且RenderScript context已经位于mRS中,java代码实例化脚本的方法如下:

ScriptC_invert invert = new ScriptC_invert(mRenderScript);

ScriptIntrinsic:这些是常见的操作:如高斯模糊,回旋,图像融合。更多信息,请参考ScriptIntrinsic的子类。

4.数据填充Allocation。除了用android.renderscript创建Allocation,在首次创建时一个Allocation也能被空数据填充。为了填充一个Allocation,在Allocation里使用一个copy方法。

5. 设置必要的脚本全局变量。全局变量命令规则最好使用set_globalname。例如,为了设置一个int类型的elements名字变来那个,使用java方法set_elements(int)。RenderScript对象在内核中也能被设置,例如,rs_allocation变量命名为lookup,能被方法set_lookup(allocation)设置。

6.启动适当的内核。方法来启动一个给定的内核将被反射到同样的ScriptC_filename类使用名为forEach_kernelanme()的方法。这些启动器是异步的,并且启动将按照他们的启动顺序被序列化。依赖你内核参数,这个方法将带来一个或者两个Allcation。默认情况下,一个内核将执行整个输入或输出Allcation;通过适当的Script.LaunchOptions作为最后一个参数到forEach方法来执行完一个Allcation的子集。调用函数能使用invoke_functionname方法来启动,在同样的ScriptrC_filename类中被反射。

7.出于Allocation对象复制数据。为了使用java代码从Allocation中访问数据,数据必须在Allocation中使用一个copy方法复制到java缓冲区, 这些函数将和异步内核一起同步并作为必要的函数启。

8.拆除RenderScript context。RenderScript context能通过destroy()方法或通过垃圾回收来摧毁。这将导致后面使用任意附属到context的对象抛出一个异常。

第三部分:Android 应用程序接口指南---第五节:计算---第一章 RenderScript的更多相关文章

  1. 第三部分:Android 应用程序接口指南---第四节:动画和图形---第一章 属性动画及动画与图形概述

    第1章 属性动画及动画与图形概述 Android提供了一系列强大的API来把动画加到UI元素中,以及绘制自定义的2D和3D图像中去.下面的几节将综述这些可用的API以及系统的功能,同时帮你做出最优的选 ...

  2. 第三部分:Android 应用程序接口指南---第二节:UI---第四章 Action Bar

    第4章 Action Bar Action Bar是一个能用于确定应用程序和用户的位置,并提供给用户操作和导航模式的窗口功能.如果需要显著地展示当前用户的操作或导航,应该使用Action Bar,因为 ...

  3. 第三部分:Android 应用程序接口指南---第一节:应用程序组件---第一章1-1.Fragment

    第1-1章 Fragments 在Activity中的fragment代表的是一种行为或用户界面的一部分.你可以在activity中结合多个fragments创建一个多面板UI,并可以在多个activ ...

  4. 第三部分:Android 应用程序接口指南---第二节:UI---第一章 用户界面和布局

    第1章 用户界面和布局 应用程序的用户界面就是用户能看到并可以与它交互的任何东西.Android提供多种预置的UI组件,如结构化布局对象和允许你为应用程序创建图形用户界面的UI控件.Android也会 ...

  5. 第三部分:Android 应用程序接口指南---第二节:UI---第二章 输入控件

    第2章 输入控件 输入控件是应用程序中用户接口的一种交互式组件.Android提供了大量的可供人们在UI中使用的控件,比如按钮.文本区域.(带滑块的)进度条.复选框.缩放按钮以及切换按钮等等. 在UI ...

  6. 第三部分:Android 应用程序接口指南---第二节:UI---第三章 菜单

    第3章 菜单 在许多不同类型的应用中,菜单通常是一种用户界面组件.为了提供给用户提供熟悉且一致的体验,你需要使用菜单API来展示用户动作和你Activity中的其他选项. 从安卓3.0系统(API l ...

  7. 第三部分:Android 应用程序接口指南---第二节:UI---第五章 设置(Settings)

    第5章 设置(Settings) 应用程序通常包括允许用户修改应用程序的特性和行为的设置功能.例如,一些应用程序允许用户指定通知是否启用或指定多久使用云同步数据.如果你想要为你的应用程序提供设置,你应 ...

  8. 第三部分:Android 应用程序接口指南---第二节:UI---第六章 对话框

    第6章 对话框 一个对话框是一个小窗口,提示用户做出决定或输入额外的信息,一个对话框不填充屏幕并且通常用于在程序运行时中断,然后弹出通知提示用户,从而直接影响到正在运行的程序.图6-1就是对话框的外观 ...

  9. 第三部分:Android 应用程序接口指南---第二节:UI---第八章 Toast通知

    第8章 Toast通知 Toast通知是在窗口前面弹出的信息.它只占有信息所需要的空间量,并且用户当前的activity仍然是可见的.可互动的.这种通知自动地淡入和淡出,它不接受交互事件.他相当于一种 ...

随机推荐

  1. BZOJ3514 Codechef MARCH14 GERALD07加强版 LCT

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3514 题意概括 N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. N ...

  2. 为什么NULL指针也能访问成员函数?(但不能访问成员变量)

    查看更加详细的解析请参考这篇文章:http://blog.51cto.com/9291927/2148695 看一个静态绑定的例子: 1 #include <iostream> 2 3 u ...

  3. pyrhon SQLite数据库

    pyrhon SQLite数据库 目录 介绍 导入模块 创建数据库/打开数据库 创建表 在表中插入行 查询/修改 删除表中的行 删除表 介绍 Python SQLITE数据库是一款非常小巧的嵌入式开源 ...

  4. IdentityServer4-端点

    一.发现端点 二.授权端点 三.令牌端点 四.UserInfo端点 五.Introspection端点 六.撤销端点 七.结束会话端点 一.发现端点 发现端点可用于检索有关IdentityServer ...

  5. Linux配置Redis外网访问

    下载:redis-3.2.5.tar.gz 拷贝到指定目录解压:tar -xzvf redis-3.2.5.tar.gz 进入到解压目录redis-3.2.5下安装: makemake install ...

  6. CSDN 博客 美化 个性化

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha ========= ======== <a href=" http:// ...

  7. 20172302《程序设计与数据结构》实验三 敏捷开发与XP实践报告

    课程:<程序设计与数据结构> 班级: 1723 姓名: 侯泽洋 学号:20172302 实验教师:王志强老师 实验日期:2018年5月16日 必修/选修: 必修 1.实验内容 (1)代码规 ...

  8. tomcat出现Error in dependencyCheck java.io.IOException: invalid manifest format

    我只能说这个错误很坑爹,检查了很多地方都没问题,结果最后在MANIFEST.MF 里面把所有的空的行都删掉就好了.坑爹有木有.

  9. angular2项目关于动画的处理

    animations动画在angular2官网里面已经讲解很详细了,那么动画功能在实际项目中应该如何组织文件,动画文件放在哪个位置,如何来组织结构使得动画模块和其他模块之间运作调理清晰呢,下面参照Ni ...

  10. tomcat配置问题

    1.首先安装JDK和Tomcat(我的tomcat是解压缩版的) 2.配置JDK环境变量 3.配置tomcat环境变量 4.在MyEcliipse中配置JDK(可以使用MyEclipse自带的tomc ...