Android 硬件加速流程和源码分析(一)
我们在Android开发过程中多少会听到硬件加速这个名词,但是实际开发中好像基本和我们又没有太多关系,那么到底什么是硬件加速? 加速了啥? 为啥要加速?
硬件加速简单说来就是通过硬件GPU来处理anroid图形界面的渲染,加速页面渲染的速度.在开启硬件加速的情况下,部分原来需要CPU完成的渲染工作丢给了专门处理图形渲染的GPU,也部分解放了CPU的性能用于其他运算,同时由于GPU的架构就是专为图形处理而生,GPU处理同样的渲染工作会比CPU更高速高效.
贴一个GPU和CPU的一个对比的视频连接,只是形象的说明GPU在图形处理上的效率,但这并不是说明GPU就比CPU强,只是各自专注的部分不一样而已.
1. Android硬件加速介绍
从 Android 3.0(API 级别 11)开始,Android 2D 渲染管道支持硬件加速,也就是说,在 View的画布上执行的所有绘制操作都会使用 GPU。启用硬件加速需要更多资源,因此应用会占用更多内存。
如果您的目标 API 级别为 14 及更高级别,则硬件加速默认处于启用状态,但也可以明确启用该功能。如果您的应用仅使用标准视图和 Drawable,则全局启用硬件加速不会造成任何不良绘制效果。不过,<font color=red>并非所有
2D 绘制操作都支持硬件加速,因此启用硬件加速可能会影响您的部分自定义视图或绘制调用</font>。
1.1 硬件加速相关设置
Android中,开发者可以分别在 Application/Activity/window/View级别开启或者关闭硬件加速, 注意不是每个级别都想开就开,想关就关硬件加速,这个还得取决于他的上一个级别的硬件加速开关的设置状态.
- 窗口级别开启硬件加速
window.setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED )
注意:您目前无法在窗口级别停用硬件加速
- 视图级别停用硬件加速
myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
注意:您目前无法在视图级别启用硬件加速
- 为啥不能窗口级别停用硬件加速?
Activity#attach()
final void attach(...
ActivityInfo info,
..
) {
...
mWindow.setWindowManager(
(WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
mToken, mComponent.flattenToString(),
(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
...
}
Window
public void setWindowManager(WindowManager wm, IBinder appToken, String appName,
boolean hardwareAccelerated) {
...
mHardwareAccelerated = hardwareAccelerated;
...
}
void adjustLayoutParamsForSubWindow(WindowManager.LayoutParams wp) {
if (mHardwareAccelerated ||
(mWindowAttributes.flags & FLAG_HARDWARE_ACCELERATED) != 0) {
//
wp.flags |= FLAG_HARDWARE_ACCELERATED;
}
}
以上代码可以看出window是否开启硬件加速取决于Activity清单文件中的设置ActivityInfo info
和WindowManager.LayoutParams
标志位的共同判断, ||
说明 layoutParams中的标志位只能开,不能关闭
-
为啥不能在视图级别启用硬件加速?
view中定义的方法isHardwareAccelerated表明了view是否支持硬件加速.
public boolean isHardwareAccelerated() { return mAttachInfo != null && mAttachInfo.mHardwareAccelerated; }
但是view是否使用硬件加速由当前 window
mAttachInfo.mHardwareAccelerated
和当前view的layerTypelayerType == LAYER_TYPE_SOFTWARE
共同决定,mAttachInfo.mHardwareAccelerated 由window的flag决定,视图级别可以设置View的layerType,简单说来就是视图级别可以决定自己不用硬件加速,但是当window级别没有使用硬件加速时,视图级别想用也没得用,所以不能在视图级别启用硬件加速.
-
为啥有时自定义控件要禁止硬件加速?
因为Android canvas部分api不支持硬件加速 ,所以只能在自定义控件中调用
setLayerType(View.LAYER_TYPE_SOFTWARE, null)
来表明当前控件使用LAYER_TYPE_SOFTWARE类型绘制而不使用硬件加速绘制, View树种其他控件不受影响该咋渲染还咋渲染,至于哪些api不支持硬件加速,请点击这里下拉看官方说明.
1.2 软件绘制和硬件加速的区别
-
基于软件的绘制模型的绘制步骤
对层次结构进行无效化处理 invalidate()
绘制层次结构
- 硬件加速绘制模型的绘制步骤
- 对层次结构进行无效化处理 invalidate()
- 记录并更新显示列表 DisplayList(DisplayList 很重要,下面详解)
- 绘制显示列表
/