Android硬件加速

最近項(xiàng)目中遇到了因?yàn)橛布铀僖鸬囊恍﹩栴},故這里深入學(xué)習(xí)了解一下關(guān)于硬件加速的一些東西

背景

什么是硬件加速丝里?

硬件加速是Android系統(tǒng)在繪制圖形時采取的一種方式犬金。

圖形的繪制,本質(zhì)上就是界面的渲染。在渲染界面的時候刻恭,是要經(jīng)過一系列計(jì)算的,這部分計(jì)算通常是邏輯較簡單扯夭,但數(shù)據(jù)量龐大的浮點(diǎn)運(yùn)算鳍贾。

在操作系統(tǒng)層面,有一個東西叫中央處理器——CPU交洗,他是計(jì)算機(jī)設(shè)備的核心器件之一骑科,主要功能是解釋計(jì)算機(jī)指令以及處理計(jì)算機(jī)軟件中的數(shù)據(jù)。除此之外构拳,計(jì)算機(jī)還有一個器件咆爽,叫做圖形處理器——GPU,他類似于CPU置森,但是是專門為運(yùn)行繪圖運(yùn)算的微處理器斗埂。

那么CPU和GPU的區(qū)別在哪里呢?

  • CPU內(nèi)部算數(shù)邏輯單元(ALU)較少凫海,控制器較復(fù)雜呛凶,適合進(jìn)行復(fù)雜的邏輯運(yùn)算
  • GPU控制器簡單,但是包含了較多的算數(shù)邏輯單元行贪,可并行運(yùn)行大量計(jì)算

結(jié)果顯而易見漾稀,因?yàn)榻缑驿秩镜挠?jì)算是邏輯簡單但是數(shù)據(jù)量很大的浮點(diǎn)運(yùn)算,所以如果使用CPU來對界面渲染做運(yùn)算建瘫,效果自然比不了GPU崭捍。

所以,硬件加速繪制圖形是一般會采用的軟件繪制就是由CPU來繪制的啰脚。硬件加速缕贡,就是通過底層代碼,將CPU中一部分不擅長的圖形計(jì)算轉(zhuǎn)換成GPU專用指令,然后交給GPU來完成晾咪。而對于Android來講收擦,硬件加速就是將View的繪制工作從原來的CPU轉(zhuǎn)交給GPU來做。

原理

硬件繪制之所以比軟件繪制“快速”谍倦,除了如上所述的獎一部分計(jì)算量交給更適合的硬件來做外塞赂,還有一個很重要的原因在于繪制區(qū)域即繪制內(nèi)容的選擇不一樣。

在關(guān)閉了硬件加速昼蛀,即采用軟件繪制時宴猾,繪制區(qū)域是這樣獲取的:從要執(zhí)行 invalidate() 方法的View開始,遍歷從跟View開始的整個View結(jié)構(gòu)叼旋,標(biāo)記出需要重新繪制的 臟區(qū)域仇哆。在這個過程中,除了我們直接修改的View需要繪制外夫植,其他的所有View讹剔,都可能因?yàn)檎谏w、相交等原因详民,被標(biāo)記為需要繪制延欠,這樣一來繪制的區(qū)域就會變的很大。這樣一來一旦開始繪制沈跨,搞不好會有很多“無辜”的View也被重新繪制由捎,雖然這些View未必真的需要被重繪。

而采用硬件加速時饿凛,就完全不一樣了狞玛。硬件繪制,首先將View抽象為 RenderNode 節(jié)點(diǎn)涧窒,將對View的繪制心肪,抽象為 DrawOp ,每個View不僅持有自己的繪制操作 DrawOp 組成的List杀狡,還持有其子View的繪制入口蒙畴,而 DrawOp 中保存有對應(yīng)的 OpenGL 繪制命令,這樣便形成了一個完整的樹狀結(jié)構(gòu)呜象。其次膳凝,硬件繪制是直接交給一個Render線程來執(zhí)行繪制的,而不是主線程恭陡,這樣也緩解了主線程的部分壓力蹬音。最后,在進(jìn)行實(shí)際繪制時休玩,每個View的實(shí)際繪制操作對應(yīng)于 DrawOp 著淆,在繪制時只需更新其中保存的繪制命令劫狠,即可完成這個View單獨(dú)的繪制,而不會影響到其他View永部。

問題

雖然硬件加速有很多優(yōu)點(diǎn)独泞,但是也有許多坑。

首先苔埋,一些Api方法是不支持硬件加速的懦砂。其次,在使用Webview時组橄,如果啟用了硬件加速荞膘,那么有時會出現(xiàn)花屏、閃爍等異常狀況玉工。

最后羽资,正如前面說的,由于不支持一些Api遵班,所以在做自定義View時屠升,有可能因?yàn)殚_啟硬件加速導(dǎo)致View的繪制效果不理想。

如何使用

一開始Android是默認(rèn)關(guān)閉硬件加速的费奸。從Android4.0版本開始弥激,默認(rèn)是開啟了硬件加速的进陡。硬件加速固然有很多優(yōu)點(diǎn)愿阐,但是由于種種原因(系統(tǒng)設(shè)計(jì)、歷史遺留趾疚、以及自身的局限性)導(dǎo)致在有些情況會出現(xiàn)一些問題缨历,這個時候又需要我們手動關(guān)閉了。

硬件加速的開關(guān)分為四個級別糙麦,分別為App級別辛孵、Activity級別、Window級別以及View級別赡磅。

  • App級別:直接在 AndroidManifest.xml 文件中魄缚, <application> 標(biāo)簽下加入一個屬性,屬性值為 true 為開啟焚廊, false 為關(guān)閉:
<application android:hardwareAccelerated="true">
  • Activity級別:類似于App級別冶匹,在 <activity> 標(biāo)簽下加入同樣的屬性:
<activity android:hardwareAccelerated="true">
  • Window級別: 在Window級別,只能通過Java代碼形式動態(tài)的開啟硬件加速而不能關(guān)閉:
getWindow().setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
  • View級別:View層比較特殊咆瘟,這里只允許關(guān)閉硬件加速嚼隘,而無法開啟。而且相關(guān)的接口并不是專門用來做硬件加速開關(guān)的袒餐,而是在給View設(shè)置Layer時“順便”關(guān)閉了硬件加速:
view.setLayerType(LAYER_TYPE_SOFTWARE, null); 

這個方法只是給View設(shè)置了一個LayerType飞蛹,而且參數(shù)有三種:LAYER_TYPE_SOFTWARE LAYER_TYPE_HARDWARE LAYER_TYPE_NONE谤狡,這是什么意思呢?關(guān)于這一部分卧檐,在官網(wǎng)中有詳細(xì)的解釋:

You currently cannot enable hardware acceleration at the view level. View layers have other functions besides disabling hardware acceleration. See View layers for more information about their uses.

官方說在View層只能關(guān)閉墓懂,不能開啟,至于為什么霉囚,引用一段扔物線大佬的解釋:

setLayerType() 這個方法拒贱,它的作用其實(shí)就是名字里的意思:設(shè)置 View Layer 的類型。所謂 View Layer佛嬉,又稱為離屏緩沖(Off-screen Buffer)逻澳,它的作用是單獨(dú)啟用一塊地方來繪制這個 View ,而不是使用軟件繪制的 Bitmap 或者通過硬件加速的 GPU暖呕。這塊「地方」可能是一塊單獨(dú)的 Bitmap斜做,也可能是一塊 OpenGL 的紋理(texture,OpenGL 的紋理可以簡單理解為圖像的意思)湾揽,具體取決于硬件加速是否開啟瓤逼。采用什么來繪制 View 不是關(guān)鍵,關(guān)鍵在于當(dāng)設(shè)置了 View Layer 的時候库物,它的繪制會被緩存下來霸旗,而且緩存的是最終的繪制結(jié)果,而不是像硬件加速那樣只是把 GPU 的操作保存下來再交給 GPU 去計(jì)算戚揭。通過這樣更進(jìn)一步的緩存方式诱告,View 的重繪效率進(jìn)一步提高了:只要繪制的內(nèi)容沒有變,那么不論是 CPU 繪制還是 GPU 繪制民晒,它們都不用重新計(jì)算精居,而只要只用之前緩存的繪制結(jié)果就可以了。

所以潜必,如果給View設(shè)置了Layer靴姿,且值為SOFTWARE,那么就是用軟件來做View Layer磁滚,自然就關(guān)閉了硬件加速佛吓。而如果硬件加速已經(jīng)關(guān)閉,參數(shù)HARDWARE的作用跟SOFTWARE一樣垂攘,自然也無法開啟硬件加速维雇。而值為NONE時,直接就關(guān)閉了ViewLayer搜贤,所以在View層只能關(guān)閉谆沃、不能開啟,正如官方文檔所說:

  • LAYER_TYPE_NONE: The view is rendered normally and is not backed by an off-screen buffer. This is the default behavior.
  • LAYER_TYPE_HARDWARE: The view is rendered in hardware into a hardware texture if the application is hardware accelerated. If the application is not hardware accelerated, this layer type behaves the same as LAYER_TYPE_SOFTWARE.
  • LAYER_TYPE_SOFTWARE: The view is rendered in software into a bitmap.
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末仪芒,一起剝皮案震驚了整個濱河市唁影,隨后出現(xiàn)的幾起案子耕陷,更是在濱河造成了極大的恐慌,老刑警劉巖据沈,帶你破解...
    沈念sama閱讀 218,607評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件哟沫,死亡現(xiàn)場離奇詭異,居然都是意外死亡锌介,警方通過查閱死者的電腦和手機(jī)嗜诀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,239評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來孔祸,“玉大人隆敢,你說我怎么就攤上這事〈藁郏” “怎么了拂蝎?”我有些...
    開封第一講書人閱讀 164,960評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長惶室。 經(jīng)常有香客問我温自,道長,這世上最難降的妖魔是什么皇钞? 我笑而不...
    開封第一講書人閱讀 58,750評論 1 294
  • 正文 為了忘掉前任悼泌,我火速辦了婚禮,結(jié)果婚禮上夹界,老公的妹妹穿的比我還像新娘馆里。我一直安慰自己,他們只是感情好掉盅,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,764評論 6 392
  • 文/花漫 我一把揭開白布也拜。 她就那樣靜靜地躺著以舒,像睡著了一般趾痘。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蔓钟,一...
    開封第一講書人閱讀 51,604評論 1 305
  • 那天永票,我揣著相機(jī)與錄音,去河邊找鬼滥沫。 笑死侣集,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的兰绣。 我是一名探鬼主播世分,決...
    沈念sama閱讀 40,347評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼缀辩!你這毒婦竟也來了臭埋?” 一聲冷哼從身側(cè)響起踪央,我...
    開封第一講書人閱讀 39,253評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎瓢阴,沒想到半個月后畅蹂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,702評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡荣恐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,893評論 3 336
  • 正文 我和宋清朗相戀三年液斜,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片叠穆。...
    茶點(diǎn)故事閱讀 40,015評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡少漆,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出硼被,到底是詐尸還是另有隱情检疫,我是刑警寧澤,帶...
    沈念sama閱讀 35,734評論 5 346
  • 正文 年R本政府宣布祷嘶,位于F島的核電站屎媳,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏论巍。R本人自食惡果不足惜烛谊,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,352評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望嘉汰。 院中可真熱鬧丹禀,春花似錦、人聲如沸鞋怀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,934評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽密似。三九已至焙矛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間残腌,已是汗流浹背村斟。 一陣腳步聲響...
    開封第一講書人閱讀 33,052評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留抛猫,地道東北人蟆盹。 一個月前我還...
    沈念sama閱讀 48,216評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像闺金,于是被迫代替她去往敵國和親逾滥。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,969評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 繪制基礎(chǔ) 安卓繪制框架 Choreographer繪制調(diào)度器败匹。用于控制各個Surface的刷新步調(diào)寨昙,讓所以Surf...
    倦飛知還閱讀 1,417評論 0 1
  • 所謂硬件加速面哥,指的是把某些計(jì)算工作交給專門的硬件來做,而不是和普通的計(jì)算工作一樣交給CPU 來處理毅待。這樣不僅減輕了...
    阿LA哩閱讀 2,727評論 0 4
  • 硬件加速的原理 將view的繪制函數(shù)轉(zhuǎn)化成OpenGL中的函數(shù)來完成繪制尚卫。 軟件繪制與硬件繪制的區(qū)別 軟件繪制在軟...
    wanderingGuy閱讀 403評論 0 1
  • 翻譯自google官方文檔:https://developer.android.com/guide/topics/...
    曾是放牛娃閱讀 2,775評論 0 4
  • 硬件加速,直觀上說就是依賴GPU實(shí)現(xiàn)圖形繪制加速尸红,軟硬件加速的區(qū)別主要是圖形的繪制究竟是GPU來處理還是CPU吱涉,如...
    看書的小蝸牛閱讀 36,269評論 16 141