做一樣的模板網(wǎng)站會(huì)被告侵權(quán)嗎品牌營銷策劃公司哪家好
Android GPU渲染屏幕繪制顯示基礎(chǔ)概念(1)
?
Android中的圖像生產(chǎn)者OpenGL,Skia,Vulkan將繪制的數(shù)據(jù)存放在圖像緩沖區(qū)中,Android中的圖像消費(fèi)SurfaceFlinger從圖像緩沖區(qū)將數(shù)據(jù)取出,進(jìn)行加工及合成。
SurfaceFlinger是Android最重要的圖像消費(fèi)者,Activity繪制的界面,都會(huì)傳遞到SurfaceFlinger,SurfaceFlinger的作用是接收?qǐng)D像緩沖區(qū)數(shù)據(jù),然后交給HWComposer或者OpenGL做合成。
SurfaceFlinger是如何接收?qǐng)D像緩沖區(qū)的數(shù)據(jù)呢?先了解Layer(層)概念,一個(gè)Layer包含一個(gè)Surface,一個(gè)Surface對(duì)應(yīng)一塊圖形緩沖區(qū),而一個(gè)界面是由多個(gè)Surface組成的,所以它們會(huì)一一對(duì)應(yīng)到SurfaceFlinger的Layer中。SurfaceFlinger通過讀取Layer的緩沖數(shù)據(jù),就相當(dāng)于讀取界面上Surface的圖像數(shù)據(jù)。
圖像數(shù)據(jù)→CPU→顯卡驅(qū)動(dòng)→顯卡(GPU)→顯存(幀緩沖)→顯示器
App繪制及SF的合成分別由對(duì)應(yīng)的軟件VSYNC驅(qū)動(dòng):VSYNC-app驅(qū)動(dòng)App繪制;VSYNC-sf驅(qū)動(dòng)SF進(jìn)行合成。
VSYNC-app與VSYNC-sf按需發(fā)射,如果App要更新界面,它申請(qǐng)VSYNC-app,如果沒有App申請(qǐng)VSYNC-app,那么VSYNC-app不發(fā)射。同樣,當(dāng)App更新界面,它會(huì)把對(duì)應(yīng)的Graphic Buffer放到Buffer Queue中。Buffer Queue通知SF進(jìn)行合成,此時(shí)SF申請(qǐng)VSYNC-sf。如果SF不申請(qǐng)VSYNC-sf,VSYNC-sf將不再發(fā)射。如果App持續(xù)不斷的更新,它就得不斷申請(qǐng)VSYNC-app;而對(duì)SF來說,只要有合成任務(wù),它就得再去申請(qǐng)VSYNC-sf。Choreographer 可以接收系統(tǒng)的 VSYNC 信號(hào),統(tǒng)一管理應(yīng)用的輸入、動(dòng)畫和繪制等任務(wù)的執(zhí)行時(shí)機(jī)。
VSYNC-app與VSYNC-sf相互獨(dú)立。VSYNC-app觸發(fā)App繪制,Vsync-sf觸發(fā)SF合成。App繪制與SF合成都會(huì)加大CPU負(fù)載,為避免繪制與合成造成性能問題,VSYNC-app可與VSYNC-sf稍微錯(cuò)開。
- Vsync offset機(jī)制: Vsync-app、Vsync-sf并不是同時(shí)通知的,Vsync-sf相對(duì)晚些,但對(duì)于App來說,可認(rèn)為大約同時(shí)發(fā)生。
硬件VSYNC同步信號(hào)發(fā)送周期是固定的,既然都相互獨(dú)立在自己進(jìn)程里等待VSync信號(hào)到來,然后各司其職做自己的工作,那通過更改偏移量的方式把“APP進(jìn)程”和“sf進(jìn)程”接收到VSync信號(hào)的時(shí)間錯(cuò)開就可以實(shí)現(xiàn):在一個(gè)硬件VSync信號(hào)周期內(nèi)完成“渲染”和“合成”兩件事,具體方案如下:
VSyncPhaseOffsetNs = 0,硬件VSync發(fā)生后,直接轉(zhuǎn)發(fā)給app進(jìn)程,讓它開始繪制;
sfVSyncPhaseOffsetNs ≥1,硬件VSync發(fā)生后,延遲幾毫秒再轉(zhuǎn)發(fā)給sf進(jìn)程,因?yàn)閍pp已經(jīng)渲染完成,sf合成剛剛渲染的圖層;
好了,在一個(gè)硬件VSync周期(如熟知的16ms)內(nèi)“渲染”和“合成”的工作都已經(jīng)完成了,并且由于GPU性能過于快速,距離下次硬件VSync信號(hào)發(fā)送甚至還有14ms...等下一次硬件VSync信號(hào)到來時(shí),顯示框架完成,畫面切換,和之前的方案比,同樣是60HZ的屏幕,用戶從按下按鈕到看到畫面更新,只需要等待1個(gè)VSync信號(hào)周期,也就是約16ms。
SF合成的是App的上一幀,而App當(dāng)前正在繪制的那一幀,要等到下一個(gè)VSYNC-sf來臨再進(jìn)行合成。Choreographer用于實(shí)現(xiàn)CPU/GPU的繪制是在VSYNC到來時(shí)開始。
GPU(Graphics Processin Unit,圖形處理器),是一種專門用于圖像運(yùn)算的處理器,在計(jì)算機(jī)系統(tǒng)中通常被稱為 "顯卡"的核心部件就是 GPU。
?
UI 組件在繪制到屏幕之前,都需要經(jīng)過 Rasterization(柵格化)操作,而柵格化又是一個(gè)非常耗時(shí)的操作。Rasterization 柵格化是繪制那些 Button、Shape、Path、String、Bitmap 等顯示組件最基礎(chǔ)的操作。柵格化將這些 UI 組件拆分到顯示器的不同像素上進(jìn)行顯示。這是一個(gè)非常耗時(shí)的操作,GPU 的引入就是為了加快柵格化。
Android APP而言,GPU硬件加速繪制可以分為:
第一階段:APP在UI線程構(gòu)建渲染的命令及數(shù)據(jù).
第二階段:CPU將數(shù)據(jù)上傳(共享或者拷貝)給GPU,PC一般有顯存,但ARM嵌入式設(shè)備內(nèi)存一般是GPU-CPU共享內(nèi)存.
第三階段:通知GPU渲染,CPU一般不會(huì)阻塞等待GPU渲染結(jié)束,效率低,CPU通知結(jié)束后就返回繼續(xù)執(zhí)行其他任務(wù),Fence輔助GPU CPU同步.
第四階段:swapBuffers,通知SurfaceFlinger圖層合成.
第五階段:SurfaceFlinger合成圖層,如果之前提交的GPU渲染任務(wù)沒結(jié)束,則等待GPU渲染完成,再合成(Fence機(jī)制),合成依然是依賴GPU,不過這作為下一個(gè)任務(wù).
第一階段主要是CPU工作,這個(gè)階段前期運(yùn)行在UI線程,后期部分運(yùn)行在RenderThread(渲染線程),第二個(gè)階段主要運(yùn)行在渲染線程,CPU將數(shù)據(jù)同步(共享)給GPU,之后,GPU進(jìn)行渲染,CPU一般不會(huì)阻塞等待GPU渲染完畢,而是通知結(jié)束后就返回。CPU返回后,會(huì)直接將GraphicBuffer提交給SurfaceFlinger,告訴SurfaceFlinger進(jìn)行合成,但是這個(gè)時(shí)候GPU可能并未完成之前的圖像渲染,這時(shí)候就牽扯到一個(gè)同步,Android中,用的是Fence機(jī)制,SurfaceFlinger合成前會(huì)查詢Fence,如果GPU渲染沒有結(jié)束,則等待GPU渲染結(jié)束,GPU結(jié)束后,會(huì)通知SurfaceFlinger進(jìn)行合成,SF合成后,提交顯示,最終完成圖像的渲染顯示。
GraphicBuffer是整個(gè)圖形系統(tǒng)的核心,渲染操作都將在此對(duì)象上進(jìn)行,包括同步給GPU和HWC,每當(dāng)應(yīng)用有顯示需求時(shí),應(yīng)用會(huì)向系統(tǒng)申請(qǐng)一塊GraphicBuffer內(nèi)存,這塊內(nèi)存將會(huì)共享給GPU用于渲染工作,接著會(huì)同步給HWC用于合成和顯示,可以把每一個(gè)GraphicBuffer對(duì)象看做是一個(gè)個(gè)渲染完成的圖層。
在Android里,GraphicBuffer的同步主要借助Fence同步機(jī)制,最大特點(diǎn)是能處理GPU、CPU、HWC的同步。GPU處理一般是異步的,CPU命令并不是即刻被GPU執(zhí)行的,而是被緩存在緩沖區(qū)中,而CPU可能不知道執(zhí)行時(shí)機(jī),除非CPU阻塞等待,但毫無疑問會(huì)使CPU、GPU并行處理效率降低,至少,渲染線程是被阻塞,所以,CPU提交命令后就返回,不等待GPU處理。SurfaceFlinger圖形合成,SurfaceFlinger需要知道什么時(shí)候GraphicBuffer被GPU處理填充完畢,這個(gè)時(shí)候就是Fence機(jī)制發(fā)揮作用的地方。
一個(gè)GraphicBuffer對(duì)象的生命周期:
渲染階段:應(yīng)用有繪圖需求了,系統(tǒng)分配一塊內(nèi)存給應(yīng)用,應(yīng)用調(diào)用GPU執(zhí)行繪圖,此時(shí)使用者是GPU。
合成階段:GPU渲染完成后將圖層傳遞給sf進(jìn)程,sf進(jìn)程決定由誰來合成,hwc或者GPU,如果使用GPU合成,那么此時(shí)GraphicBuffer的使用者依舊是GPU,如果使用hwc合成,那么此時(shí)GraphicBuffer的使用者是hwc。
顯示階段:所有的GraphicBuffer在此階段使用者都是hwc,因?yàn)閔wc控制著顯示芯片。
從生命周期可以看出GraphicBuffer對(duì)象在流轉(zhuǎn)的過程中,會(huì)被GPU、CPU、DPU三個(gè)不同的硬件訪問。如果同一塊內(nèi)存能夠被多個(gè)硬件設(shè)備訪問,就需要一個(gè)同步機(jī)制,Android圖形系統(tǒng)中,Fence機(jī)制就是用來不同模塊訪問時(shí)的數(shù)據(jù)安全,Fence的邏輯實(shí)現(xiàn)可參考Java的synchronized互斥鎖,可把Fence理解為一把硬件的互斥鎖,每個(gè)需要訪問GraphicBuffer的角色,在使用前都要檢查這把鎖是否unlock了才能進(jìn)行操作,否則就要等待(waitForever)。
BufferQueue
它是一個(gè)封裝了GraphicBuffer的隊(duì)列,BufferQueue對(duì)外提供了GraphicBuffer對(duì)象出列/入列的接口。BufferQueue生產(chǎn)者/消費(fèi)者模式,大多數(shù)情況,APP作為GraphicBuffer的生產(chǎn)者,sf進(jìn)程作為GraphicBuffer的消費(fèi)者,共同操作一個(gè)buffer隊(duì)列。
生產(chǎn)者:APP進(jìn)程
1、producer->dequeueBuffer()
? 從隊(duì)列取出一個(gè)狀態(tài)為“FREE”的buffer,此時(shí)該buffer狀態(tài)變化為:FREE->DEQUEUED
2、producer->queueBuffer()
? 將渲染完成的buffer入列,此時(shí)該buffer狀態(tài)變化為:DEQUEUED->QUEUED
消費(fèi)者:sf進(jìn)程
1、consumer->acquireBuffer()
? 從隊(duì)列中取出一個(gè)狀態(tài)為“QUEUED”的渲染完的buffer準(zhǔn)備去合成送顯,此時(shí)該buffer的狀態(tài)變化為:QUEUED->ACQUIRED
2、consumer->releaseBuffer()
? buffer內(nèi)容已經(jīng)顯示過了,可以重新入列給APP使用了,此時(shí)該buffer的狀態(tài)變化為:ACQUIRED->FREE
每個(gè)Buffer的一生,就是在不斷地循環(huán)FREE->DEQUEUED->QUEUED->ACQUIRED->FREE這個(gè)過程,這中間有任何一個(gè)環(huán)節(jié)出現(xiàn)延遲,反應(yīng)到屏幕上就是應(yīng)用出現(xiàn)了卡頓。
無論App使用哪種API進(jìn)行圖形開發(fā)繪制,在繪制流程結(jié)束后,APP作為圖層的生產(chǎn)者總是會(huì)調(diào)用BufferQueue的queueBuffer()方法將GraphicBuffer入列,一旦有新的圖層加入隊(duì)列,就意味著作為圖層消費(fèi)者的SF進(jìn)程可以開始工作了。
當(dāng)APP端的Surface發(fā)生變化以后,Layer的onFrameAvailable()方法會(huì)被調(diào)用,經(jīng)過層層轉(zhuǎn)發(fā),最終由MessageQueue#requestNextVSync()執(zhí)行VSync信號(hào)的請(qǐng)求。
APP進(jìn)程中的每一個(gè)Surface對(duì)象,對(duì)應(yīng)SF進(jìn)程當(dāng)中的一個(gè)Layer對(duì)象,它倆共享一個(gè)BufferQueue,
Surface作為圖層的生產(chǎn)者,封裝了出列入列的操作,
Layer作為圖層的消費(fèi)者,封裝了獲取渲染圖層和釋放圖層的操作。
?
一個(gè)APP完整的顯示流程大致分為三個(gè)階段
app-請(qǐng)求
APP頁面元素一旦發(fā)生變化,調(diào)用invalidate()/requestLayout()方法請(qǐng)求下一次VSync信號(hào),此時(shí)sf什么都不做。
app-VSync & sf-請(qǐng)求
app-VSync信號(hào)到來后,APP進(jìn)程執(zhí)行繪圖三部曲,繪圖流程結(jié)束后,sf收到onFrameAvailable(),sf進(jìn)程請(qǐng)求VSync。
sf-VSync
sf-VSync信號(hào)到來,sf進(jìn)程執(zhí)行合成,接著將結(jié)果提交給hwc,等待下次硬件VSync信號(hào)發(fā)生,切換Framebuffer展示給用戶。
?
?
?
?
Android性能:Double Buffer雙緩沖/Triple Buffer三緩沖丟幀Jank與無丟幀No Jank-CSDN博客文章瀏覽閱讀850次,點(diǎn)贊6次,收藏13次。Android ADB調(diào)試真機(jī)設(shè)備Android ADB(Andorid Debug Bridge),是Android開發(fā)中有用的測試和調(diào)試工具。使用Android ADB調(diào)試設(shè)備,直接在Windows的dos命令窗口輸入命名adb即可,如圖:為什么執(zhí)行adb命令后是這樣?_android 抓trace。三Buffer輪轉(zhuǎn)情況下,基本不會(huì)有這種情況的發(fā)生,渲染線程一般在 dequeueBuffer 時(shí),都可以順利拿到可用的 Buffer (如果 dequeueBuffer 本身耗時(shí)那就也會(huì)拉長時(shí)間)。https://blog.csdn.net/zhangphil/article/details/138213964
?