Android 硬件加速流程和源碼分析(一)
我們在Android開發(fā)過程中多少會聽到硬件加速這個(gè)名詞,但是實(shí)際開發(fā)中好像基本和我們又沒有太多關(guān)系,那么到底什么是硬件加速? 加速了啥? 為啥要加速?
硬件加速簡單說來就是通過硬件GPU來處理anroid圖形界面的渲染,加速頁面渲染的速度.在開啟硬件加速的情況下,部分原來需要CPU完成的渲染工作丟給了專門處理圖形渲染的GPU,也部分解放了CPU的性能用于其他運(yùn)算,同時(shí)由于GPU的架構(gòu)就是專為圖形處理而生,GPU處理同樣的渲染工作會比CPU更高速高效.
貼一個(gè)GPU和CPU的一個(gè)對比的視頻連接,只是形象的說明GPU在圖形處理上的效率,但這并不是說明GPU就比CPU強(qiáng),只是各自專注的部分不一樣而已.
1. Android硬件加速介紹
從 Android 3.0(API 級別 11)開始,Android 2D 渲染管道支持硬件加速,也就是說,在 View的畫布上執(zhí)行的所有繪制操作都會使用 GPU。啟用硬件加速需要更多資源,因此應(yīng)用會占用更多內(nèi)存。
如果您的目標(biāo) API 級別為 14 及更高級別,則硬件加速默認(rèn)處于啟用狀態(tài),但也可以明確啟用該功能。如果您的應(yīng)用僅使用標(biāo)準(zhǔn)視圖和 Drawable,則全局啟用硬件加速不會造成任何不良繪制效果。不過,<font color=red>并非所有
2D 繪制操作都支持硬件加速,因此啟用硬件加速可能會影響您的部分自定義視圖或繪制調(diào)用</font>。
1.1 硬件加速相關(guān)設(shè)置
Android中,開發(fā)者可以分別在 Application/Activity/window/View級別開啟或者關(guān)閉硬件加速, 注意不是每個(gè)級別都想開就開,想關(guān)就關(guān)硬件加速,這個(gè)還得取決于他的上一個(gè)級別的硬件加速開關(guān)的設(shè)置狀態(tài).
- 窗口級別開啟硬件加速
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清單文件中的設(shè)置ActivityInfo info 和WindowManager.LayoutParams標(biāo)志位的共同判斷, ||說明 layoutParams中的標(biāo)志位只能開,不能關(guān)閉
-
為啥不能在視圖級別啟用硬件加速?
view中定義的方法isHardwareAccelerated表明了view是否支持硬件加速.
public boolean isHardwareAccelerated() { return mAttachInfo != null && mAttachInfo.mHardwareAccelerated; }但是view是否使用硬件加速由當(dāng)前 window
mAttachInfo.mHardwareAccelerated和當(dāng)前view的layerTypelayerType == LAYER_TYPE_SOFTWARE共同決定,mAttachInfo.mHardwareAccelerated 由window的flag決定,視圖級別可以設(shè)置View的layerType,簡單說來就是視圖級別可以決定自己不用硬件加速,但是當(dāng)window級別沒有使用硬件加速時(shí),視圖級別想用也沒得用,所以不能在視圖級別啟用硬件加速.
-
為啥有時(shí)自定義控件要禁止硬件加速?
因?yàn)锳ndroid canvas部分api不支持硬件加速 ,所以只能在自定義控件中調(diào)用
setLayerType(View.LAYER_TYPE_SOFTWARE, null)來表明當(dāng)前控件使用LAYER_TYPE_SOFTWARE類型繪制而不使用硬件加速繪制, View樹種其他控件不受影響該咋渲染還咋渲染,至于哪些api不支持硬件加速,請點(diǎn)擊這里下拉看官方說明.
1.2 軟件繪制和硬件加速的區(qū)別
-
基于軟件的繪制模型的繪制步驟
對層次結(jié)構(gòu)進(jìn)行無效化處理 invalidate()
繪制層次結(jié)構(gòu)
- 硬件加速繪制模型的繪制步驟
- 對層次結(jié)構(gòu)進(jìn)行無效化處理 invalidate()
- 記錄并更新顯示列表 DisplayList(DisplayList 很重要,下面詳解)
- 繪制顯示列表
/