翻出了4年前實(shí)習(xí)期間手繪梳理的Android圖形框架根竿,其實(shí)有些細(xì)節(jié)都記不清了。 所以這里再文字梳理一邊,加深理解也作為一個(gè)積淀革骨,接下來(lái)希望能梳理清楚Android系統(tǒng)如何進(jìn)行HDR上屏的至朗。
先籠統(tǒng)來(lái)說(shuō)屉符,我們知道,我們將某個(gè)圖像在Androids設(shè)備上顯示涉及下述環(huán)節(jié):
1. 我們將要顯示的數(shù)據(jù)交付給Android系統(tǒng)(Canvas锹引、OpenGLES矗钟、Vulkan),
2. Android系統(tǒng)將要顯示的內(nèi)容處理成相應(yīng)的buffer(GUI+芯片)嫌变,
3. 顯示硬件根據(jù)buffer數(shù)據(jù)使顯示屏每個(gè)像素發(fā)出對(duì)應(yīng)的光(LCD吨艇、OLED屏幕設(shè)備)。
GUI架構(gòu)處理的就是上述的第二步腾啥。
———— ———— ———————————————————————————
推薦相關(guān)文章:
從Android的基本View組件解釋view hierarchy如何與Android GUI協(xié)作:
https://www.zhihu.com/question/25811504
GUI最重要成員Surface东涡、SurfaceFlinger介紹:
Android 卷I-Surface系統(tǒng),從Android的基本View組件解釋view hierarchy如何與Android GUI協(xié)作:
https://wiki.jikexueyuan.com/project/deep-android-v1/surface.html
SurfaceFlinger 圖形系統(tǒng):
https://blog.csdn.net/freekiteyu/article/details/79483406
SurfaceFlinger 用于應(yīng)用程序的典型繪圖流程:
https://blog.csdn.net/xuesen_lin/article/details/8954840
SurfaceFlinger如何OpenGLES聯(lián)動(dòng)起來(lái):
https://blog.csdn.net/xuesen_lin/article/details/8954553
承載圖像信息的Buffer的介紹:
羅神的Android幀緩沖區(qū)(Frame Buffer)硬件抽象層(HAL)模塊Gralloc的實(shí)現(xiàn)原理分析: https://blog.csdn.net/Luoshengyang/article/details/7747932
———— ———— ———————————————————————————
從手繪紙最上面開(kāi)始說(shuō)吧倘待,Android 框架提供了各種用于 2D 和 3D 圖形渲染的 API软啼,可與制造商的圖形驅(qū)動(dòng)程序?qū)崿F(xiàn)代碼交互,
應(yīng)用開(kāi)發(fā)者可通過(guò)三種方式將圖像繪制到屏幕上:使用畫(huà)布延柠、OpenGL ES 或 Vulkan祸挪。2D指的沒(méi)有開(kāi)啟硬件加速的Canvas,但是針對(duì)Android 4.0以上的系統(tǒng)贞间,默認(rèn)開(kāi)啟了硬件加速贿条,所以我們基本上可以理解圖像繪制目前市面上Android手機(jī)都會(huì)用到GPU處理。
不過(guò)不管是2D還是3D增热、Canvas還是gles或是Vulkan整以,我們都會(huì)把繪制數(shù)據(jù)畫(huà)到Surface上去。注意這里Surface不等于我們常說(shuō)SurfaceView峻仇。最直接理解公黑,Surface就是作為SurfaceFlinger的代理,SurfaceFlinger作為系統(tǒng)服務(wù)摄咆,是系統(tǒng)資源凡蚜,供各個(gè)App使用,每個(gè)App要去用這個(gè)資源就需要代理交接吭从,而這個(gè)代理對(duì)接什么呢朝蜘?window,窗口涩金。
Window擁有一個(gè)Surface谱醇,在Surface里繪制Window里的內(nèi)容暇仲。一個(gè)application通過(guò)ViewRoot向Windows Manager Service申請(qǐng)創(chuàng)建窗口,WMS也是系統(tǒng)服務(wù)負(fù)責(zé)分配窗口資源副渴,Windows Manager為每一個(gè)窗口創(chuàng)建Surface來(lái)讓application在上面繪制各種物體奈附。我們看到android機(jī)上各種圖案都是通過(guò)一個(gè)個(gè)win來(lái)組織的,win有很多種 比如systemWindow煮剧,status bar(電量斥滤、wifi、信號(hào)那塊)轿秧、navigation bar(home頁(yè)中跌,前進(jìn)咨堤,后退)菇篡、還有我們開(kāi)發(fā)者最熟悉的Activity對(duì)應(yīng)的win,application window一喘。各種window驱还,z軸疊加,如果布局不好會(huì)擋住凸克,這也是為什么各種劉海屏幕议蟆、曲面屏幕,手機(jī)廠商都有一定的適配工作萎战。
Activity內(nèi)的各種子view布局就靈活很多咐容,最終布局也會(huì)由ViewRoot來(lái)管理,管理的結(jié)構(gòu)是一個(gè)叫View Hierarchy(視窗繼承關(guān)系)根據(jù)這個(gè)關(guān)系蚂维,View Root把Activity里的各種子View 布局好規(guī)劃好映射到 Surface里的buffer里去戳粒,這樣子,當(dāng)我們一個(gè)View內(nèi)容發(fā)生改變的時(shí)候虫啥,我們不用整個(gè)surface里面的buffer更新蔚约,只用更新部分區(qū)域,這個(gè)過(guò)程就是下圖中的invalidate和draw涂籽。
說(shuō)到這里苹祟,可以引出 SurfaceView,它獨(dú)立于Activity评雌,有自己的線程(當(dāng)然 生命周期還是需要依附于Activity)树枫,有自己獨(dú)立的window,我們知道window是z軸排列的景东,所以一般SurfaceView是與Activity是存在“覆蓋”關(guān)系的团赏,在有的比較低性能的手機(jī)上我們切換應(yīng)用的時(shí)候,可以看到activity與surfaceview是分開(kāi)的耐薯,activity的一般會(huì)布局上“挖個(gè)透明區(qū)域”留給SurfaceView顯示舔清。由于SurfaceView的獨(dú)立線程特性丝里,使得它很適合用來(lái)做一些相對(duì)耗時(shí)可能會(huì)block的事情,比如視頻媒體相關(guān)的体谒。
同時(shí)媒體展示還有一個(gè)常用的控件杯聚,叫做TextureView,參考到Google Android Developer:https://developer.android.com/reference/android/view/TextureView抒痒,這個(gè)控件通過(guò)SurfaceTexture可以使用GPU資源幌绍,這點(diǎn)跟SurfaceView一樣,但是它沒(méi)有自己獨(dú)立的window故响,它跟其他控件一樣從屬于ViewRoot傀广,對(duì)應(yīng)的是整個(gè)Activity的window,在View Hierarchy結(jié)構(gòu)中彩届,也是為什么這個(gè)控件可以輕易的“ moved, transformed, animated, etc.”伪冰。還有一個(gè)東西叫GLSurfaceView,這個(gè)是封裝好了的SurfaceView樟蠕,也能夠配置HDR色域贮聂,而且吧這個(gè)控件游戲常用到,也就是說(shuō)寨辩,HDR技術(shù)也可以落地到游戲上去吓懈。
一個(gè)有獨(dú)立的window,一個(gè)從屬于ViewRoot的window靡狞,所以SurfaceView為什么transform往往需要開(kāi)發(fā)者自行開(kāi)發(fā)耻警,但是ViewRoot早已預(yù)設(shè)了控件transform的能力,SurfaceTexture沿用就好甸怕。
到這里簡(jiǎn)單描述一下我理解得的 常見(jiàn)的activity甘穿、surfaceview如何“承上”(承載App里各種view)了,接下來(lái)就是比較難的Android GUI的內(nèi)容了蕾各,我把它概括為啟下扒磁?把我們期待App的中各個(gè)區(qū)塊的內(nèi)容填充告訴到Android 系統(tǒng)服務(wù)。
啟下的起點(diǎn)就從surface開(kāi)始吧式曲,
上面我們提到了 surface妨托,surface在我看來(lái)是兩個(gè)東西組成,一個(gè)是buffer queue吝羞,實(shí)現(xiàn)一套生產(chǎn)者消費(fèi)者模式兰伤;一個(gè)是緩存,buffer queue傳送的東西钧排,存儲(chǔ)著我們“承上”來(lái)的繪制或者素材數(shù)據(jù)敦腔,比如我粗暴地理解成bitmap。
消費(fèi)者生產(chǎn)者模式恨溜,我們的應(yīng)用符衔、系統(tǒng)應(yīng)用找前、各種窗口生產(chǎn)出要上屏的內(nèi)容,這些內(nèi)容以surface的形式判族,交由給SurfaceFlinger進(jìn)行整合生產(chǎn)出整塊屏幕顯示內(nèi)容給Display HAL層去上屏躺盛;怎么交由呢?surface中還有一個(gè)可以跟SurfaceFlinger系統(tǒng)服務(wù)打交道的代理形帮,我們應(yīng)用的surface當(dāng)然在我們應(yīng)用進(jìn)程槽惫,要跟 SurfaceFlinger 打交道需要跨進(jìn)程,所以不是即時(shí)的辩撑,我們常常說(shuō)屏幕的刷新幀率多少界斜,比如120hz屏幕,其實(shí)也對(duì)應(yīng)著SurfaceFlinger需要每秒鐘整合多少次屏幕內(nèi)容合冀,或者我們可以理解成每1/120s各薇,SurfaceFlinger就把這段時(shí)間,各個(gè)進(jìn)程送來(lái)的上屏內(nèi)容收集水慨,然后一層一層的摞起來(lái)得糜,整合成一個(gè)整個(gè)屏幕的畫(huà)面數(shù)據(jù)敬扛;SurfaceFlinger與Display HAL之間也有一個(gè) buffer queue晰洒, 一個(gè)存放當(dāng)前上屏數(shù)據(jù),一個(gè)存放著下一個(gè)上屏數(shù)據(jù)啥箭,120hz屏幕每1/120s交替一次谍珊。
以上就是根據(jù)我的理解大致的描述發(fā)生在Android系統(tǒng)服務(wù)中上屏過(guò)程,如若有什么地方說(shuō)的錯(cuò)誤的急侥,望指正砌滞;
那么HDR這個(gè)能力是怎么在Android的上屏過(guò)程中實(shí)現(xiàn)的呢?我通過(guò)上網(wǎng)查閱資料以及分析Dump下來(lái)的SurfaceFlinger的信息坏怪,大致腦補(bǔ)出了一個(gè)workflow贝润,僅供參考:
首先,我們知道铝宵,對(duì)于上屏內(nèi)容處理打掘,SurfaceFlinger處理的單元是Layer,確實(shí)每一Layer都有字段標(biāo)識(shí)它是不是HDR以及HDR mode鹏秋。
所以對(duì)于第三方開(kāi)發(fā)尊蚁,我們需要做的就是把HDR信息配置到window上去,這個(gè)信息最終會(huì)配置到對(duì)應(yīng)的Layer上侣夷。Google Android Developer有介紹一些方法横朋。https://developer.android.com/training/wide-color-gamut
然后我們知道SurfaceFlinger每次要處理很多Layer,一般UI layer的數(shù)據(jù)是8bit sRGB百拓,而如果有一個(gè)layer是 10bit HDR RGB琴锭。與此同時(shí)平時(shí)廠商介紹手機(jī)的時(shí)候晰甚,色域的介紹基本上都是覆蓋P3 or DCI-P3色域百分之多少,其實(shí)也就是說(shuō)决帖,即使layer是 10bit HDR压汪,其實(shí)就目前的手機(jī)屏幕支持的色域能力而言,我們手機(jī)也展示不了真實(shí)的BT 2020的色域下的表現(xiàn)古瓤,是轉(zhuǎn)到了P3色域下的表現(xiàn)止剖。所以在這個(gè)屏幕的廣色域模式下,任何顏色最終都是映射到P3色域上落君。
SDR的layer經(jīng)過(guò)一次 Color Gamut轉(zhuǎn)化穿香,將BT709的顏色映射到P3的色域下;而HDR的layer除了需要經(jīng)歷Color Gamut轉(zhuǎn)化绎速,將BT2020的顏色映射到P3的色域下之外還需要color-transfer的轉(zhuǎn)換皮获,比如說(shuō)PQ模式,由于屏幕硬件設(shè)備的Gamma值是固定的纹冤,假定是值a洒宝,芯片可以通過(guò)對(duì)PQ模式下Layer的RGB值乘上一個(gè)系數(shù),Color-Transfer(PQ)/ a , 最終也實(shí)現(xiàn)了對(duì)應(yīng)的Color-Transfer的作用萌京,當(dāng)然可能因?yàn)槭謾C(jī)屏幕遠(yuǎn)達(dá)不到HDR標(biāo)準(zhǔn)值的亮度值要求雁歌,Color-Transfer(PQ)值可能被優(yōu)化過(guò),相較之下 iOS的HDR能力反而做的好得多。
接下來(lái)談下HDR跟屏幕之間的關(guān)系知残。
目前常常各大廠商PR稿在介紹屏幕能力的時(shí)候會(huì)著重強(qiáng)調(diào)自己的屏幕是OLED屏幕靠瞎。其實(shí)OLED屏幕之前,主流的手機(jī)的屏幕是LCD屏幕求妹。OLED屏幕雖然有很多被人吐槽的點(diǎn)乏盐,比如說(shuō)燒屏、低頻PWM調(diào)光晃眼睛制恍,但是它的發(fā)光特性卻非常適合HDR功能父能。OLED屏幕是屏幕整齊排布的是自行發(fā)光體,而LCD屏幕是屏幕排布的只是濾鏡元件净神,亮度通過(guò)背光實(shí)現(xiàn)何吝,有點(diǎn)像是皮影戲,后面打著大燈控制亮度强挫,前面帶有顏色的濾鏡片控制顏色岔霸,這種背光的模式導(dǎo)致即使屏幕要顯示帶有黑色的畫(huà)面,但是黑色區(qū)域也不是真正的無(wú)光俯渤,只是相對(duì)的黑呆细,但是OLED屏幕就可以控制黑色區(qū)域完全不發(fā)光就可以實(shí)現(xiàn)“極致的黑”,所以當(dāng)分母為0,亮度比就可以非常非常大絮爷,所以O(shè)LED屏幕的亮度比遠(yuǎn)大于LCD屏幕趴酣。而我們知道,HDR技術(shù)的目的是讓明暗細(xì)節(jié)都能在同一幀畫(huà)面中體現(xiàn)出來(lái)坑夯,OLED的屏幕的特性就與HDR目的非常契合岖寞,所以移動(dòng)端的HDR技術(shù)常常和OLED屏幕聯(lián)系起來(lái)。
絮絮叨叨先說(shuō)到這里了柜蜈。