android gpu 2d加速,Android中GPU硬件加速控制及其在2D图形绘制上的局限

图形的渲染可分为两种:软件渲染和硬件渲染。软件渲染是靠CPU计算各种坐标并绘制,主要是占用内存;硬件渲染是靠GPU,主要占用显存,一般的3D图形程序(OpenGL、DirectX)都是GPU加速的。

在Android3.0之前,2D绘图API只支持软件渲染模式,从Android3.0开始,2D绘图API开始支持GPU硬件渲染,即View中的Canvas的绘图操作会使用GPU,所以从Android 3.0(API Level 11)开始,View中就多了一些和硬件相关的方法。如果App的AndroidManifest.xml文件中定义的 targetSdkVersion大于或等于14(Android 4.0),那么Android会默认为App启用GPU渲染2D图形,我们也可以自己决定是否使用GPU,见下文。如果开启了GPU硬件加速,那么Android会用OpengGL绘图中常见的Display List技术对OpenGL ES中的绘图命令进行缓存,提高绘图效率与速度。关于Android中GPU硬件加速的Display List绘图机制会在以后专门写文章进行阐述,本文不做过多介绍。

控制是否使用GPU

我们也可以显式地启用或禁用GPU渲染,并且可以从多个Application、Activity、Window、View多个级别对其进行控制。

Application

在AndroidMenifest.xml的中添加如下的属性即可在整个App的所有Activity的View中启用GPU硬件加速渲染2D图形:

Activity

你既可以在Application级别上控制GPU是否启用,也可以在Activity级别对其就进行控制。比如你的App中有多个Activity,你想让大部分Activity启用GPU硬件加速,但有一个Activity你不想启用硬件加速,你可以通过以下的配置实现:

Window

如果你想要更加细粒度地对GPU的使用进行控制,你可以通过代码对指定的Window启用GPU硬件加速,如下代码所示:

getWindow().setFlags(

WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,

WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);

需要注意的是在运行时不能通过代码禁用掉某个Window的硬件加速。

View

你也可以在运行时通过如下代码为某个指定的View禁用掉GPU硬件加速:

if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){

//View从API Level 11才加入setLayerType方法

myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

}

View从API Level 11才加入setLayerType方法,所以在使用前需要判断一下当前系统运行的版本。 需要注意的是,在运行时不能通过代码为某个View启用GPU硬件加速。

判断当前是否处于硬件加速中

从Android 3.0(API Level 11)开始,View和Canvas类都加入了isHardwareAccelerated()方法,可以用于判断当前View和Canvas是否处于硬件加速中。

View.isHardwareAccelerated()

如果View的isHardwareAccelerated()方法返回true,仅仅表示该View被加入到一个处于硬件加速的Window中,其有可能仍然使用一个非硬件加速的Canvas进行实际的渲染。所以,通常来说View的isHardwareAccelerated()方法实际用处不太大。

Canvas.isHardwareAccelerated()

我们在View的onDraw回调方法中可以得到Canvas对象,如果Canvas的isHardwareAccelerated()方法返回true,那么表示当前Canvas是用GPU硬件加速渲染的,如果返回false就表示是用软件渲染的。通常,判断当前Canvas是否处于GPU硬件加速中对于绘制自定义的View来说比较重要,下面会解释。

硬件加速时2D图形绘制的局限

开启GPU硬件加速会提升程序的绘图效率,但是也存在一定的局限性。

启用GPU硬件加速会增加内存的使用。

Android中有些2D绘图API在GPU硬件加速时不能使用或者要到某个指定的版本才能使用。

Canvas

以下为Canvas中在GPU硬件加速时受限制的功能:

第一列是受限制的方法,第二列是开始支持的API Level,红叉代表到目前还不支持。

A132100485-190892.png_small.png

Paint

以下为Paint中在GPU硬件加速时受限制的功能:

A132102704-190892.png_small.png

Xfermode

以下为Xfermode在GPU硬件加速时受限制的功能:

A132104829-190892.png_small.png

Shader

以下为Shader在GPU硬件加速时受限制的功能:

A132106954-190892.png_small.png

Canvas缩放

Android中硬件加速的2D渲染管线最初只支持无缩放的绘图,这会导致在将缩放比例设置为很大的时候,绘图质量会明显降低。最初,GPU加速下的2D绘图操作会被渲染成一个缩放比例为1.0的纹理,然后GPU会将它缩放到指定比例尺。在API Level小于17的时候,随着缩放比例scale的变大,绘图质量就更加难以保证。下面的表格表示了从什么版本开始Android能在GPU硬件计算下正确处理2D图形的大比例缩放问题:

A132109032-190892.png_small.png

现在我们开发的App一般将targetSdkVersion写为最新版本,肯定大于API Level 14了,并且市场上的手机绝大部分都是Android 4.0以上的,所以我们现在开发的App默认情况下在绝大部分手机上基本都是默认开启了GPU硬件加速的。如果我们自己要自定义一个View,我们要重写其onDraw方法,通过调用各种绘图方法实现复杂的效果,但是如果我们调用的API在GPU硬件加速下不支持的话,就画不出我们想要的效果,举个例子,比如我们想在自定义View中绘制一个具有模糊效果的椭圆,需要调用画笔Paint的setMaskFilter()方法,但是我们通过上面的受限API列表可以发现,在GPU硬件加速下,Pait的setMaskFilter()方法不被支持,虽然调用不报错,但是不会起到任何效果。为了画出我们想要的效果,我们可以通过View的setLayerType(View.LAYER_TYPE_SOFTWARE, null)方法单独把我们的View禁用掉GPU硬件加速,这样在软件渲染模式下所有的2D绘图API都可以正常使用了。

最后有点需要说明,上述Android在GPU硬件加速下2D图形绘制API存在的局限问题是基于当前最新API Level 23的,随着以后更新Android版本的发布,可能上述受限API会逐渐在GPU下得到更好的支持。

希望本文对大家初步了解Android中GPU硬件渲染2D图形有所帮助,后面会写文章深入探讨Android在GPU硬件渲染下绘制2D图形的Display List机制。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值