當(dāng)前位置:首頁 > 公眾號精選 > Linux閱碼場
[導(dǎo)讀]圖形系統(tǒng)是計(jì)算機(jī)中最重要的子系統(tǒng)之一。我們平時(shí)使用的電腦、手機(jī)都是圖形界面的。對于普通人來說,沒有圖形界面的計(jì)算機(jī)幾乎是沒法用的,今天我們就來講一講圖形系統(tǒng)背后的原理。

作者簡介:

程磊,某手機(jī)大廠系統(tǒng)開發(fā)工程師,閱碼場榮譽(yù)總編輯,最大的愛好是鉆研Linux內(nèi)核基本原理。


目錄:

一、圖形系統(tǒng)簡介

1.1 圖形系統(tǒng)的誕生

1.2 圖形系統(tǒng)的總體結(jié)構(gòu)

1.3 圖形系統(tǒng)的各層職能

二、安卓圖形系統(tǒng)

2.1 框架概覽

2.2 渲染系統(tǒng)概覽

2.3 窗口系統(tǒng)概覽

2.4 顯示系統(tǒng)概覽

三、生產(chǎn)者消費(fèi)者模型

3.1 概覽

3.2 BufferQueue

3.3 顯存分配與同步

3.4 生產(chǎn)消費(fèi)流程

四、總結(jié)回顧



一、圖形系統(tǒng)簡介


圖形系統(tǒng)是計(jì)算機(jī)中最重要的子系統(tǒng)之一。我們平時(shí)使用的電腦、手機(jī)都是圖形界面的。對于普通人來說,沒有圖形界面的計(jì)算機(jī)幾乎是沒法用的,今天我們就來講一講圖形系統(tǒng)背后的原理。

1.1 圖形系統(tǒng)的誕生

早期的計(jì)算機(jī)是沒有圖形界面的,都是命令行界面。大家坐在終端前面輸入命令、執(zhí)行命令、等待命令完成,如此循環(huán)往復(fù)。這樣的計(jì)算機(jī)比較適合科研人員、理工男使用,但是想要普及到千家萬戶是不可能的。后來施樂公司帕克研究中心(Xerox Palo Alto Research Center,Xerox PARC)率先研究出了圖形界面的計(jì)算機(jī),提出了WIMP的概念。WIMP就是Window(窗口)、Icon(圖標(biāo))、Menu(菜單)、Pointer(指針/鼠標(biāo))。我們現(xiàn)在的計(jì)算機(jī)仍然是WIMP模式的。可惜施樂公司并沒有把圖形界面的計(jì)算機(jī)做起來,而是被喬布斯和比爾蓋茨發(fā)揚(yáng)光大了。喬布斯去參觀帕克研究中心的時(shí)候,被他們所展示的圖形界面驚呆了,回去之后立馬在自己公司做起了圖形界面的操作系統(tǒng)。比爾蓋茨發(fā)現(xiàn)蘋果的圖形界面確實(shí)不錯(cuò),也開始自己做圖形界面,于是便有了Windows系統(tǒng)。后來蘋果和微軟因?yàn)閳D形界面的問題還打起了官司。

1.2 圖形系統(tǒng)的總體結(jié)構(gòu)


圖形模式與命令行模式相比,編程模式和軟件結(jié)構(gòu)都發(fā)生了很大的變化。在命令行模式的時(shí)候,程序員只需要考慮程序本身的流程,然后通過標(biāo)準(zhǔn)輸入輸出和終端打交道就可以了。但是到了圖形模式的時(shí)候,一切都變了。程序員首先要考慮是如何繪制程序的界面,然后再通過消息循環(huán)對程序的點(diǎn)擊等各種事件進(jìn)行處理。不僅程序員編程的模式變了,操作系統(tǒng)實(shí)現(xiàn)的方式也發(fā)生了很大的變化。命令行模式下,操作系統(tǒng)只需要提供一個(gè)shell,shell不斷地讀取命令、執(zhí)行命令就可以了。但是在圖形模式下,操作系統(tǒng)首先要提供一個(gè)桌面,作為用戶使用電腦的起點(diǎn),還要提供文件管理器,方便用戶查看管理文件。對程序員來說,操作系統(tǒng)還要提供圖形編程接口,提供渲染庫,還要負(fù)責(zé)對所有的窗口進(jìn)行合成和顯示。于是在操作系統(tǒng)里面便誕生了一個(gè)重要又龐大的子系統(tǒng),圖形系統(tǒng)。根據(jù)前面幾句的描述,我們先來看一下圖形系統(tǒng)的簡單結(jié)構(gòu)。

可以看到圖形系統(tǒng)的總體結(jié)構(gòu)還挺簡單的,GUI進(jìn)程需要窗口系統(tǒng)來創(chuàng)建和管理窗口,需要渲染系統(tǒng)來幫忙繪制界面,最后讓顯示系統(tǒng)把畫面顯示到顯示器上。

1.3 圖形系統(tǒng)的各層職能


知道了圖形系統(tǒng)的總體結(jié)構(gòu),我們再來詳細(xì)描述一下各層的職能。


窗口系統(tǒng)一般以進(jìn)程的方式運(yùn)行在用戶空間,我們把它的進(jìn)程叫做DisplayServer。窗口系統(tǒng)有兩個(gè)職責(zé):一是窗口管理器,負(fù)責(zé)窗口的創(chuàng)建、縮放、銷毀等工作;二是合成管理器,負(fù)責(zé)把各個(gè)GUI進(jìn)程繪制完成之后的窗口合成為一個(gè)位圖,然后送到顯示系統(tǒng)去顯示。


渲染系統(tǒng)是以so庫的形式存在,被加載到每個(gè)GUI進(jìn)程的內(nèi)存空間中。渲染系統(tǒng)負(fù)責(zé)執(zhí)行GUI進(jìn)程的繪制命令,在窗口的顯示Buffer上生成相應(yīng)的位圖。渲染分為2D渲染和3D渲染,2D渲染一般用CPU來執(zhí)行,3D渲染一般用GPU來執(zhí)行。但是現(xiàn)在經(jīng)常也將2D渲染用GPU來做。不過很多普通程序并不是直接使用渲染庫的,而是使用的控件庫,因?yàn)橹苯邮褂娩秩編焯闊┝恕1热缥覀円嬕粋€(gè)按鈕,用渲染庫API來畫的話是非常麻煩的,但是使用控件庫API的話,我們只需要指定位置、大小、樣式等屬性就可以輕松畫一個(gè)按鈕。


顯示系統(tǒng)是以驅(qū)動(dòng)的形式存在于內(nèi)核中,驅(qū)動(dòng)是屏幕控制器的驅(qū)動(dòng)或者DPU的驅(qū)動(dòng)。顯示系統(tǒng)的作用就是把所有窗口形成的一個(gè)位圖在顯示器上顯示。早期的顯示驅(qū)動(dòng)模型是FBDEV,它針對的是屏幕控制器,屏幕控制器沒有運(yùn)算能力,只能接收窗口系統(tǒng)已經(jīng)合成好的位圖來顯示。此時(shí)窗口系統(tǒng)的合成管理器會(huì)使用渲染系統(tǒng)來合成各個(gè)窗口的位圖,合成也可以看出是一種特殊的渲染。后來屏幕控制器逐漸發(fā)展成了DPU,具有了運(yùn)算能力,能進(jìn)行合成操作。此時(shí)也誕生了新的顯示驅(qū)動(dòng)模型DRM,DRM允許窗口系統(tǒng)不進(jìn)行合成操作,而是把各個(gè)窗口的顯存都發(fā)給自己,通過DPU進(jìn)行合成操作,然后再送到顯示器顯示。



二、安卓圖形系統(tǒng)


Android是目前最流行的移動(dòng)操作系統(tǒng)之一,我們今天就來具體分析一下Android的圖形系統(tǒng)。

2.1 框架概覽


在講Android之前,我們先來看一下Linux發(fā)行版的圖形系統(tǒng)。由于Android的內(nèi)核也是Linux,所以它們的顯示系統(tǒng)是一樣的。Linux的渲染系統(tǒng)用的是OpenGL,以及最新的Vulkan,控件庫用的是GTK(GNOME)或者Qt(KDE)。Linux的窗口系統(tǒng)歷史悠久且復(fù)雜,可以追述到UNIX時(shí)代。這里我們就不展開說了,我們直接說現(xiàn)狀。在Linux上,窗口系統(tǒng)的協(xié)議和實(shí)現(xiàn)是明確分開的,Linux長期使用的窗口協(xié)議叫做X Window,實(shí)現(xiàn)是X.org。不過由于X Window太過古老,很多設(shè)計(jì)都不符合現(xiàn)狀的情況,還有沉重的歷史包袱。因此有人設(shè)計(jì)了新的窗口的協(xié)議Wayland,Wayland最流行的實(shí)現(xiàn)叫做Weston?,F(xiàn)在大部分Linux發(fā)行版已經(jīng)開始轉(zhuǎn)向Wayland/Weston了。


了解了Linux發(fā)行版的圖形體系,我們再來看一下Android的圖形體系。

Android的圖形系統(tǒng)并沒有明確的協(xié)議,實(shí)現(xiàn)既協(xié)議。這是因?yàn)長inux系統(tǒng)是標(biāo)準(zhǔn)的開源系統(tǒng),很多事情都喜歡先定個(gè)協(xié)議,然后誰都可以實(shí)現(xiàn)這個(gè)協(xié)議。而Android雖然也開源,但是它是由谷歌直接實(shí)現(xiàn)的,其它廠商拿來用,所以沒有必要定個(gè)協(xié)議。Android的圖形系統(tǒng)在具體細(xì)節(jié)上和Linux的圖形系統(tǒng)差別還是很大的,這是因?yàn)長inux圖形系統(tǒng)面向的是桌面系統(tǒng),Android圖形系統(tǒng)面向的是移動(dòng)系統(tǒng),兩者的使用環(huán)境不同,開發(fā)環(huán)境不同,導(dǎo)致了具體的實(shí)現(xiàn)細(xì)節(jié)也不相同。其中一個(gè)最大的不同就是Android圖形系統(tǒng)中沒有典型的窗口概念。在其它窗口系統(tǒng)中,一般都會(huì)有個(gè)CreateWindow的接口用來創(chuàng)建一個(gè)窗口,返回值是窗口句柄,然后我們就可以用這個(gè)窗口句柄來做其它事了。但是在Android中,不是這樣的邏輯,窗口的概念被隱藏并分散在具體的實(shí)現(xiàn)中去了,程序員面對的是Activity和View、ViewGroup。下面幾個(gè)小節(jié)會(huì)對Android圖形系統(tǒng)的各個(gè)部分進(jìn)行介紹。

2.2 渲染系統(tǒng)概覽


Android中一開始用的是OpenGL ES進(jìn)行3D渲染,用skia進(jìn)行2D 軟件渲染。后來為了優(yōu)化2D渲染,開發(fā)了hwui進(jìn)行硬件渲染,hwui是對OpenGL ES的封裝。再后來變成了hwui調(diào)用skia,skia對OpenGL ES進(jìn)行了封裝來進(jìn)行硬件渲染,當(dāng)然skia也保留了軟件渲染部分。下面我們看一下圖。

OpenGL ES system warpper是系統(tǒng)提供的標(biāo)準(zhǔn)接口庫,它的so位置是固定的,方便程序加載,其接口是標(biāo)準(zhǔn)規(guī)定的接口,方便程序使用。不過它本身沒有任何實(shí)現(xiàn)邏輯,所有的實(shí)現(xiàn)邏輯都在GPU廠商提供的不開源的庫里面。

普通APK并不會(huì)直接使用這些渲染庫,而是使用的系統(tǒng)提供的控件庫。Android提供的控件大部分都在package android.view 和android.widget中。

2.3 窗口系統(tǒng)概覽


窗口系統(tǒng)有兩個(gè)職責(zé),窗口管理器和合成管理器。在Android中這兩者并不在一起,窗口管理器是在system_server進(jìn)程中實(shí)現(xiàn),名字叫做WindowManagerService(WMS),是用Java語言實(shí)現(xiàn)的,因?yàn)閟ystem_server就是Java進(jìn)程。Android為什么要把WindowManagerService放在system_server中實(shí)現(xiàn)呢?這是system_server中有ActivityManagerService(AMS),兩者的關(guān)系比較密切,放在一起比較合適。合成管理器是在一個(gè)獨(dú)立進(jìn)程中實(shí)現(xiàn)的,叫做SurfaceFlinger。最開始的時(shí)候SurfaceFlinger是直接進(jìn)行合成的,后來由于硬件合成的興起,SurfaceFlinger不再直接進(jìn)行合成操作了,而是把合成操作轉(zhuǎn)發(fā)給底層。WindowManagerService和SurfaceFlinger之間使用Binder進(jìn)程間通信來交互。下面我們來看一下圖:

谷歌推出了叫做HWC(硬件合成器)的模塊,用來處理硬件合成。剛開始的時(shí)候HWC只是個(gè)so庫,運(yùn)行在SurfaceFlinger進(jìn)程中,后來HWC獨(dú)立成單獨(dú)的進(jìn)程了。在HWC中有很多廠商提供的不開源和半開源的庫。

這個(gè)圖里面沒有畫和APK之間的交互。窗口系統(tǒng)和APK之間的交互有兩部分,一是程序在創(chuàng)建Activity的時(shí)候會(huì)和WMS交互來創(chuàng)建窗口。Android里面沒有典型的窗口概念,可以把PhoneWindow、DecorView、ViewRootImpl、Surface糅合在一起當(dāng)做窗口的概念。還有一部分沒有畫,是APK的渲染與SurfaceFlinger合成之間的生產(chǎn)者消費(fèi)者關(guān)系,這個(gè)邏輯在下一章里講。

想要深入地學(xué)習(xí)AMS,推薦閱讀老羅的Android之旅中的WMS篇:https://blog.csdn.net/Luoshengyang/article/details/8462738

,以及袁輝輝寫的WMS分析:http://gityuan.com/2017/01/08/windowmanger/



2.4 顯示系統(tǒng)概覽

顯示系統(tǒng)直接和屏幕相關(guān),屬于內(nèi)核里的驅(qū)動(dòng)。內(nèi)核一般對任一類型的硬件都會(huì)有個(gè)驅(qū)動(dòng)模型,所有的硬件廠商都在這個(gè)硬件模型上開發(fā)驅(qū)動(dòng)。最早對顯示器抽象出來的驅(qū)動(dòng)模型加做FBDEV,后來隨著硬件和軟件的發(fā)展,又誕生了新的驅(qū)動(dòng)模型DRM?,F(xiàn)在大部分系統(tǒng)都轉(zhuǎn)向DRM了,所有我們這里講一下DRM。先畫個(gè)圖看一下:
這個(gè)結(jié)構(gòu)其實(shí)也是很多驅(qū)動(dòng)的結(jié)構(gòu)。內(nèi)核定義并實(shí)現(xiàn)了DRM Core,硬件廠商按照DRM Core的要求擴(kuò)展結(jié)構(gòu)體,實(shí)現(xiàn)函數(shù)指針,然后調(diào)用注冊函數(shù)注冊自己。在用戶空間使用的硬件會(huì)創(chuàng)建一個(gè)設(shè)備文件,用戶空間可以open設(shè)備文件,用ioctl來調(diào)用各種命令,ioctl的命令是Core定義好的,具體的驅(qū)動(dòng)要去實(shí)現(xiàn)這些命令。用戶空間直接使用ioctl命令還是比較麻煩的,所以還會(huì)有一個(gè)libdrm庫,用來封裝各種ioctl命令,轉(zhuǎn)化為函數(shù)接口,這樣進(jìn)程使用就比較方便了。


三、生產(chǎn)者消費(fèi)者模型


在講渲染與合成之前,我們先來講一講它們之間的關(guān)系以及它們交互的流程。

3.1 概覽


渲染與合成是生產(chǎn)者消費(fèi)者關(guān)系,那么它們之間是怎么交互的呢?Android實(shí)現(xiàn)了一個(gè)生產(chǎn)者消費(fèi)者模型BufferQueue,生成者與消費(fèi)者通過BufferQueue來交互。BufferQueue管理的是GraphicBuffer,生產(chǎn)者渲染的內(nèi)容要放到GraphicBuffer上,消費(fèi)者合成內(nèi)容的來源來自GraphicBuffer。GraphicBuffer通過谷歌定義的Hidl接口Gralloc來分配內(nèi)存,Gralloc又通過ION分配內(nèi)存。ION是建立在DMA-BUF的基礎(chǔ)之上的跨空間跨設(shè)備的內(nèi)存分配方法。為了加快生成消費(fèi)的流程,BufferQueue可以采取異步的模式,異步的時(shí)候就需要進(jìn)行步調(diào)同步了,為此采取的辦法是Fence。Fence是一種跨空間跨設(shè)備的同步機(jī)制??缈臻g的意思是指進(jìn)程與進(jìn)程之間、內(nèi)核與用戶空間之間,跨設(shè)備指的是兩個(gè)設(shè)備的驅(qū)動(dòng)之間或者驅(qū)動(dòng)與進(jìn)程之間。下面我們畫個(gè)圖看一下它們的總體關(guān)系。

?????????????

3.2 BufferQueue


BufferQueue是Android中對渲染與合成這一對生產(chǎn)消費(fèi)關(guān)系模型的實(shí)現(xiàn)。我們先來看BufferQueue的使用方法。


void BfferQueue::createBufferQueue(sp* outProducer, sp* outConsumer) { spcore(new BufferQueueCore()); spproducer(new BufferQueueProducer(core)); spconsumer(new BufferQueueConsumer(core)); *outProducer = producer; *outConsumer = consumer;}

可以看到創(chuàng)建一個(gè)BufferQueue就是創(chuàng)建一個(gè)BufferQueueCore,然后以這個(gè)core為參數(shù)分別創(chuàng)建生產(chǎn)者基礎(chǔ)接口和消費(fèi)者基礎(chǔ)接口。一般情況下都是在消費(fèi)者進(jìn)程中創(chuàng)建的BufferQueue,然后把生產(chǎn)者接口用Binder跨進(jìn)程傳遞給生產(chǎn)者進(jìn)程。當(dāng)然也可以反過來,也可以兩者都跨進(jìn)程,也可以兩者都不跨進(jìn)程。之所以大部分情況下選擇在消費(fèi)者進(jìn)程中創(chuàng)建BufferQueue,是為了想讓消費(fèi)者準(zhǔn)備好,然后生產(chǎn)者一生成就可以立馬得到消費(fèi)了。

一般情況下我們并不會(huì)直接使用原始的生產(chǎn)者或者消費(fèi)者接口,而是會(huì)對它們進(jìn)行層層封裝,封裝之后的接口就比較方便使用了。下面我們看一下它的封裝邏輯圖。
這個(gè)圖畫的是APK與SurfaceFlinger對BufferQueue的使用情況??梢钥吹綄υ忌a(chǎn)者接口的封裝一般都是Surface,但是我們也會(huì)經(jīng)常在代碼中看到SurfaceControl,這是怎么回事呢?這是為了完成控制權(quán)與繪制權(quán)的分離。APK啟動(dòng)的時(shí)候會(huì)去請求WMS創(chuàng)建窗口也就是Surface,WMS再去請求SurfaceFlinger創(chuàng)建BufferQueue,并獲得其原始生產(chǎn)者接口。WMS自身把原始生產(chǎn)者封裝為SurfaceControl,以便對Surface進(jìn)行控制。然后又把原始生產(chǎn)者封裝為Surface傳遞給APK,這樣APK就只有繪制權(quán)了。APK如果想設(shè)置Surface的屬性,還得請求WMS的幫忙。下面畫個(gè)圖看一下:
下面我們再看一下BufferQueue的內(nèi)部管理邏輯。BufferQueue管理的是GraphicBuffer,但又不是直接管理的GraphicBuffer,而是定義了BufferSlot結(jié)構(gòu)體。BufferSlot包含對GraphicBuffer的智能指針應(yīng)用和對Fence的智能指針引用,以及BufferState。BufferQueueCore包含一個(gè)BufferSlot的數(shù)組,有64個(gè)元素,由于BufferSlot內(nèi)部都是智能指針引用,所以它一開始都是空的,只有用到了才會(huì)分配。BufferQueue在管理BufferSlot的時(shí)候并不會(huì)直接去操作它們,而是會(huì)管理它們的下標(biāo)。下面我們畫個(gè)圖看一下。
BufferQueue用4個(gè)整數(shù)容器來管理BufferSlot,BufferSlot的下標(biāo)放在不同的容器中有不同的含義。首先是BufferQueue硬編碼定義的64是all slots,當(dāng)創(chuàng)建BufferQueue之后我們可以使用接口函數(shù)來設(shè)置我們要用多少個(gè)Buffer,不用的下標(biāo)就會(huì)被放置在容器mUnusedSlots中,使用的下標(biāo)就會(huì)被放置在容器mFreeSlots中。然后當(dāng)我們使用某個(gè)Buffer的時(shí)候,無論是生產(chǎn)者使用還是消費(fèi)者使用,都會(huì)把它的下標(biāo)放入容器mActiveBuffers中去。當(dāng)消費(fèi)者使用完一個(gè)Buffer的時(shí)候又會(huì)把它放入容器mFreeBuffers中去。mFreeBuffers和mFreeSlots的區(qū)別是前者的BufferSlot已經(jīng)關(guān)聯(lián)上GraphicBuffer了,而后者僅僅是一個(gè)空的slot。Buffer的狀態(tài)變遷我們在3.4節(jié)中講。

3.3 顯存分配與同步


當(dāng)我們第一次使用BufferSlot的時(shí)候就會(huì)去分配GraphicBuffer,那么GraphicBuffer又是怎么樣分配內(nèi)存的呢?GraphicBuffer會(huì)通過谷歌定義的Gralloc接口來分配內(nèi)存。Gralloc接口又是通過兩個(gè)Hidl接口IAllocator和IMapper來實(shí)現(xiàn)的。下面我們畫圖來看一下。

可以看到最終分配內(nèi)存的方法是ION。ION是一種跨空間跨設(shè)備的內(nèi)存分配方法,ION是基于DMA-BUF的,我們先來說一下DMA-BUF。

DMA-BUF是一種跨空間跨設(shè)備的內(nèi)存共享機(jī)制,它僅僅是一個(gè)框架,并不能分配內(nèi)存。DMA-BUF既不是DMA也不是BUF,而是Sharing。DMA-BUF定義了兩個(gè)角色:Exporter(導(dǎo)出者),負(fù)責(zé)分配內(nèi)存,一個(gè)體系中只能存在一個(gè)導(dǎo)入者;Importer(導(dǎo)入者),也叫User,負(fù)責(zé)使用內(nèi)存,可以有N個(gè),一般有兩個(gè),一個(gè)寫,既生產(chǎn)者,一個(gè)讀,既消費(fèi)者。下面我們畫圖來看一下:
明白了DMA-BUF,我們再來看一下ION。ION是建立在DMA-BUF的基礎(chǔ)之上的,ION能夠在進(jìn)程之間、進(jìn)程和內(nèi)核之間、設(shè)備之間共享內(nèi)存都?xì)w功于DMA-BUF。ION自身有許多heap,不同的heap用來分配不同類型的內(nèi)存,ION默認(rèn)使用system heap。內(nèi)核里的代碼可以直接使用ION的接口,為了讓用戶空間也能使用ION,ION創(chuàng)建了一個(gè)設(shè)備文件/dev/ion。用戶空間可以用各種ioctl命令來使用ION,顯然這不太方便,于是產(chǎn)生了libion來幫助大家方便地使用ION??偨Y(jié)一下,如下圖所示:
GraphicBuffer的內(nèi)存分配完成之后,就可以用來渲染和合成了。但是我們現(xiàn)在只能進(jìn)行同步操作,而GPU的渲染是異步,為了能提高性能,我們需要一種異步使用下的等待通知機(jī)制。為此內(nèi)核中實(shí)現(xiàn)了Fence,它主要是給DMA-BUF用的,所以它也是一種跨空間跨設(shè)備的機(jī)制。因此,F(xiàn)ence是一種跨設(shè)備跨空間的wait/notify機(jī)制,它和Java中的wait/notify、C++中條件變量的wait/signal的語義是一樣的,不同的是,Java、C++中的機(jī)制只能在進(jìn)程內(nèi)使用。Fence還有一個(gè)很大的特點(diǎn)就是它的notify信號不會(huì)丟失,這是因?yàn)镕ence是一次性的,用完就扔,每次使用都需要重新申請一個(gè),不能復(fù)用,因此Fence都是有編號的。Fence不僅有編號,還有context,不同的場景都可以創(chuàng)建context。同一個(gè)context下的fence編號是有可比較性的,編號小的時(shí)間在前。不同context下的fence編號不具有可比較性。下面我們畫圖來看一下。

3.4 生產(chǎn)消費(fèi)流程


明白了前面的知識之后,我們就要來看一看生產(chǎn)消費(fèi)的具體流程了。我們先來看一下BufferSlot的狀態(tài)變遷,BufferSlot的狀態(tài)變化是和生產(chǎn)消費(fèi)的流程相關(guān)的。我們先看圖再來解說。


一個(gè)BufferSlot最初是處于Free狀態(tài)的,當(dāng)生產(chǎn)者準(zhǔn)備生產(chǎn)的時(shí)候,會(huì)先dequeueBuffer,此時(shí)就會(huì)得到BufferSlot,BufferSlot的狀態(tài)也會(huì)變?yōu)镈equeued。得到的BufferSlot如果之前是空的slot,就會(huì)去分配內(nèi)存,流程在上一節(jié)中說過了,如果是已經(jīng)分配內(nèi)存的slot則直接使用。然后生產(chǎn)者開始生產(chǎn),把生產(chǎn)的內(nèi)存都放到GraphicBuffer中去。當(dāng)生產(chǎn)完成時(shí)就會(huì)調(diào)用queueBuffer,以告訴消費(fèi)者我生產(chǎn)完了,你可以開始消費(fèi)了。queueBuffer之后,BufferSlot的狀態(tài)就由Dequeue轉(zhuǎn)變?yōu)镼ueued。此時(shí)的GraphicBuffer會(huì)被封裝為一個(gè)BufferItem結(jié)構(gòu)體,放入mQueue隊(duì)列中。消費(fèi)者得到消息后就要準(zhǔn)備消費(fèi)了。消費(fèi)者先acquireBuffer,從mQueue隊(duì)列中獲取一個(gè)BufferItem,其對應(yīng)的BufferSlot的狀態(tài)就轉(zhuǎn)化為Acquired了。然后消費(fèi)者就可以開始消費(fèi)了,當(dāng)消費(fèi)完成的時(shí)候,會(huì)調(diào)用releaseBuffer表明自己消費(fèi)完成,把BufferSlot還給BufferQueue,此時(shí)BufferSlot的狀態(tài)就回歸Free了。

明白了BufferSlot的狀態(tài)變化以及生成消費(fèi)的基本流程之后,我們再來看一下,在VSync下,在有Fence的情況下,生成消費(fèi)的流程。我們先看圖:
首先渲染和合成是兩個(gè)獨(dú)立的線程,兩者是同時(shí)進(jìn)行的,雙方都是在收到VSync信號時(shí)開始執(zhí)行的。其次渲染和合成都分別有一個(gè)額外的線程來進(jìn)行異步渲染與合成,不會(huì)阻塞主流線程。主流線程沒有阻塞操作,不會(huì)卡住,兩個(gè)異步線程都在等Fence信號,有可能會(huì)卡住。當(dāng)某個(gè)異步線程一直卡住的時(shí)候,比如說合成線程卡住了,會(huì)導(dǎo)致渲染線程一直在wait Fence信號也會(huì)卡住,但是主線程還能繼續(xù)運(yùn)行。


四、總結(jié)回顧


通過本文我們對Android的圖形系統(tǒng)有了基本的了解,對圖形渲染與合成這一對生產(chǎn)者消費(fèi)者模型也有了大概的認(rèn)知。下面讓我們看圖再來回顧一下:

圖形系統(tǒng)由渲染系統(tǒng)、窗口系統(tǒng)、顯示系統(tǒng)三部分組成,渲染系統(tǒng)負(fù)責(zé)幫助GUI進(jìn)程實(shí)現(xiàn)界面的繪制,窗口系統(tǒng)負(fù)責(zé)為GUI進(jìn)程分配窗口、管理窗口并對所有的Surface進(jìn)行合成,顯示系統(tǒng)負(fù)責(zé)把合成的畫面送到顯示器里去顯示?,F(xiàn)在硬件合成比較流行,窗口系統(tǒng)都是把圖形合成的任務(wù)交給顯示系統(tǒng)通過硬件來完成。

參考文獻(xiàn):

https://blog.csdn.net/hexiaolong2009/category_9281458.html
https://blog.csdn.net/hexiaolong2009/category_9705063.html
https://blog.csdn.net/hexiaolong2009/category_10331964.html

http://www.wowotech.net/sort/graphic_subsystem


如需進(jìn)程磊老師群溝通

請?zhí)砑有●R微信:Linuxer2022



本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運(yùn)營商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡稱"軟通動(dòng)力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉