[TOC]
Android圖形顯示子系統(tǒng)概述
Android圖形顯示系統(tǒng)邦危,是Android比較重要的一個(gè)子系統(tǒng)洋侨,和很多其他子系統(tǒng)的關(guān)聯(lián)緊密。想象一下倦蚪,沒(méi)有圖形顯示系統(tǒng)的手機(jī)是什么樣子希坚,可能連對(duì)講機(jī)都不如吧。圖形顯示系統(tǒng)比較復(fù)雜陵且,從Android誕生到現(xiàn)在裁僧,幾經(jīng)修改,已經(jīng)變的越來(lái)越龐大了慕购」總的說(shuō)來(lái),圖形顯示系統(tǒng)可以分為兩大部分來(lái)理解:
- 圖形系統(tǒng)
- 顯示系統(tǒng)
圖形系統(tǒng)
圖形系統(tǒng)也就是圖形支持系統(tǒng)脓钾,提供繪圖和圖形處理支持售睹。包括最初的2D繪圖API Skia,后來(lái)的3D繪圖API OpenGLES可训,RenderScript昌妹,OpenCV,到最近的Vulkan握截。也包括圖片解碼庫(kù)飞崖,jpg,png谨胞,gif等固歪。以及它們所需要的各種Driver支持。
但是Android為了方便大家胯努,我們?cè)谧鰬?yīng)用開(kāi)發(fā)的時(shí)候牢裳,并不用大家直接用各種API去繪制界面,也不用直接用解碼庫(kù)去解碼叶沛。Android已經(jīng)給大家提供了一個(gè)界面繪制機(jī)制蒲讯,有很多widget和view,Android的應(yīng)用開(kāi)發(fā)者灰署,用現(xiàn)有的widget就能夠繪制出比較酷炫的界面判帮。
Android提供的大多view和widget都是2D的繪圖局嘁,2D繪圖比較慢,也發(fā)揮不出GPU的作用晦墙,因此Android又設(shè)計(jì)了一套加速系統(tǒng)悦昵,硬件加速。其目的就是將2D的繪圖操作轉(zhuǎn)換為一個(gè)個(gè)的3D(Opengl)繪圖晌畅,再采用部分更新的方式但指,只去重繪界面中有更新的部分view,這樣就大大提升界面繪制的速度踩麦。
顯示系統(tǒng)
圖形繪制好了后枚赡,需要送到LCD顯示屏上氓癌,我們才能看到谓谦。繪制界面時(shí),我們只關(guān)心單個(gè)界面贪婉,顯示的時(shí)候反粥,可能就有多個(gè)界面了。做過(guò)Android應(yīng)該開(kāi)發(fā)的都知道疲迂,我們需要繼承一個(gè)Activity才顿,用Activity呈現(xiàn)我們的界面。Activity的生命周期管理尤蒿,也就伴隨了窗口的管理郑气。這中間就涉及了兩個(gè)Android中兩個(gè)主要的服務(wù),AMS(ActivityManagerService)和WMS(WindowManagerService)腰池。View尾组,AMS,WMS可以說(shuō)是整個(gè)上層顯示系統(tǒng)的三駕馬車示弓。
在Android中讳侨,一個(gè)窗口用一個(gè)Surface描述。多個(gè)窗口(窗口不一定都是Activity)奏属,需要同時(shí)顯示跨跨,我們就需要將多個(gè)窗口進(jìn)行合并。這就需要顯示系統(tǒng)中重量級(jí)的服務(wù)SurfaceFlinger囱皿,Surfaceflinger控制窗口的合成勇婴,將多個(gè)窗口合并成一個(gè),再送到LCD嘱腥。
Surfaceflinger是Native的服務(wù)咆耿,Surfaceflinger中怎么去描述一個(gè)窗口呢?Surfaceflinger采用圖層的概念爹橱,即Layer萨螺。SurfaceFlinger合成窄做,就是基于Display HAL的實(shí)現(xiàn),將多個(gè)Layer合并慰技。Display HAL椭盏,各個(gè)廠商的實(shí)現(xiàn)就千差萬(wàn)別了。
Buffer管理
前面討論了怎么繪制吻商,怎么顯示掏颊。但是,繪制艾帐,繪在什么地方乌叶,拿什么去顯示。答案只能是內(nèi)存Buffer柒爸。Android的系統(tǒng)中准浴,采用GraphicBuffer對(duì)buffer進(jìn)行封裝,而buffer采用ion實(shí)現(xiàn)捎稚,能在進(jìn)程間共享乐横。
Surface屬性應(yīng)用進(jìn)程,Layer屬于SurfaceFlinger進(jìn)程今野。如果只用一個(gè)Buffer葡公,那么兩個(gè)進(jìn)程都有可能同時(shí)在用Buffer,這就可能會(huì)造成我們看到的屏幕顯示不對(duì)条霜,存在撕裂催什。另外,只用一個(gè)Buffer宰睡,效率也不高啊蒲凶,繪制本來(lái)就是GPU在繪制,顯示這邊是CPU或者是其他的硬件模塊夹厌,一個(gè)工作豹爹,另外一個(gè)不工作,且不浪費(fèi)矛纹。所以Android采用Buffer隊(duì)列的方式臂聋,即BufferQueue。繪制的是一個(gè)Buffer或南,顯示的是一個(gè)buffer孩等,各自處理完后,交換一下Buffer采够。這樣效率就高很多了肄方。這中間再采用一個(gè)生產(chǎn)者-消費(fèi)者模型,Buffer是載體蹬癌,Surface應(yīng)用這邊是Producer权她,SurfaceFlinger這邊是是Consumer虹茶。這樣就更好理解了。
顯示系統(tǒng)的架構(gòu)
有了前面的描述隅要,是不是對(duì)Android的圖形顯示系統(tǒng)有了大概的認(rèn)識(shí)了蝴罪?沒(méi)有關(guān)系,我們直接來(lái)看架構(gòu)圖步清。架構(gòu)圖來(lái)自Androd的官網(wǎng)要门, https://source.android.com/devices/graphics/ ,
大家可以對(duì)照?qǐng)D再回味一下,前面的描述廓啊。有些地方欢搜,這個(gè)圖并不能很好的體現(xiàn),不過(guò)沒(méi)有關(guān)系谴轮,接下來(lái)我們會(huì)詳細(xì)的介紹各個(gè)模塊和流程炒瘟。
換一種方式來(lái)描述Android的顯示系統(tǒng),架構(gòu)圖如下:
再和前面Android的圖進(jìn)行對(duì)照书聚,是不是更清楚一些了唧领。
這個(gè)圖里藻雌,前面的描述里有點(diǎn)沒(méi)有說(shuō)到雌续,SurfaceFlinger到OpenGLES,大家是不是覺(jué)得有點(diǎn)奇怪胯杭。其實(shí)是這樣的驯杜,SurfaceFlinger合成,有兩種方式做个,Client和Device鸽心。Client就是Client合成完Layer后再將合成后的數(shù)據(jù)給到HWComposer,HWComposer此時(shí)做的工作很少居暖,直接給到Display顽频。Device則是將未合成的Layer,給到硬件合成的設(shè)備太闺,合成完后再給到Display糯景。
可能大家還是很迷茫,沒(méi)有關(guān)系~省骂,我們接下來(lái)將參照Android的源碼蟀淮,逐一為大家講解。
從應(yīng)用的角度理解Android
做Android開(kāi)發(fā)钞澳,我們都講了太多的架構(gòu)怠惶,也聽(tīng)了太多的架構(gòu)。不知道大家有沒(méi)有從應(yīng)用的角度去看過(guò)Android的系統(tǒng)轧粟?我們先來(lái)看Android的整體系統(tǒng)架構(gòu)策治。
Android基于Linux內(nèi)核脓魏,我們是不是可以將上層Android理解為L(zhǎng)inux內(nèi)核的一個(gè)應(yīng)用。這個(gè)應(yīng)用非常龐大通惫,集集了電話轧拄,BT,WiFi讽膏,音視頻播放檩电,Camera等功能。
基于Linux內(nèi)核的系統(tǒng)非常的多府树,比如常用的俐末,Debian系列的Ubuntu,Debian奄侠;Redhat系統(tǒng)的RedHat卓箫,F(xiàn)edora等。你可以理解Android自成一個(gè)系列垄潮。所以烹卒,我們也可以基于Linux內(nèi)核去開(kāi)發(fā)自己的系統(tǒng)。
回到Android弯洗,Android在Linux中加了很多驅(qū)動(dòng)旅急,再采用硬件抽象的方式,向上提供接口牡整,這就是我們所說(shuō)的HAL層藐吮。所以我們要增加一個(gè)模塊,需要增加Linux驅(qū)動(dòng)逃贝,然后實(shí)現(xiàn)HAL谣辞,以供上層使用。當(dāng)然沐扳,我們也可以基于Android的HAL去開(kāi)發(fā)上層的系統(tǒng)泥从,又可以將基于HAL的系統(tǒng)看成一個(gè)應(yīng)用。據(jù)了解沪摄,F(xiàn)irefoxOS躯嫉,360OS,YunOS等卓起,基本都是基于Android的HAL的方式去開(kāi)發(fā)的(Oops~如有褻瀆和敬,神靈保佑...)。
基于HAL的Android Framework戏阅,分為Native Framework和JavaFramework昼弟。HAL層是C++寫的,按里說(shuō)奕筐,Native的 Framework應(yīng)該就夠了舱痘,什么還要去實(shí)現(xiàn)Java的Framework呢变骡?Android的應(yīng)用大多數(shù)都是用Java開(kāi)發(fā),中間還有一個(gè)Java虛擬機(jī)芭逝,和JNI塌碌。
其實(shí),這是有歷史原因的⊙ⅲ現(xiàn)在Android已經(jīng)形成了一個(gè)很大的生態(tài)鏈台妆,但是想想當(dāng)初,Android系統(tǒng)剛才發(fā)布胖翰,得有開(kāi)發(fā)者呀接剩,沒(méi)有開(kāi)發(fā)者的支持,如何能形成生態(tài)鏈萨咳。所以懊缺,Android就采用了這種Java開(kāi)發(fā)方式,大大籠絡(luò)了Java開(kāi)發(fā)人員培他。
再回到我們的顯示子系統(tǒng)鹃两,Surfaceflinger基于HAL HWComposer,管理和控制著整個(gè)Android的顯示舀凛。而上層俊扳,則是WMS,AMS腾降,View等系統(tǒng)服務(wù)管理和控制著整個(gè)Android的顯示拣度。
回到上一章給出的Display架構(gòu)圖碎绎,我們是不是可以直接基于Native的Framework進(jìn)行應(yīng)用的開(kāi)發(fā)呢螃壤,答案是肯定的。Android也為此提供了NDK筋帖,以便于Android Native應(yīng)用的開(kāi)發(fā)奸晴。
下面,讓我們從一個(gè)Native應(yīng)用開(kāi)始日麸,揭開(kāi)Android顯示系統(tǒng)的面紗~