SurfaceFlinger及Android應用RenderThread角度觀察Jank丟幀卡頓
CPU、GPU、Display 三個部分:CPU 負責計算幀數據,把計算好的數據交給 GPU,GPU 會對圖形數據進行渲染,渲染好后放到 buffer (圖像緩沖區)存起來,然后 Display (屏幕或顯示器)把 Buffer呈現到屏幕。
Google 在 Android 4.1 系統中對 Android Display 系統進行了重構,引入了 Project Butter(黃油計劃):在系統收到 Vsync 信號后,上層 CPU 和 GPU 馬上進行下一幀畫面數據的處理,完成后及時將數據寫入到 Buffer 中,Google 稱之為 Drawing with Vsync。
在ViewRootImpl中完成對界面的measure、layout和draw等繪制流程后,用戶依然還是看不到內容,因為Android系統的顯示流程除了UI 線程的繪制外,還需要經過RenderThread線程的渲染處理,渲染完成后,還需要通過Binder調用“上幀”交給surfaceflinger進程進行合成后才能最終顯示到屏幕上。
Android應用渲染流程中,應用扮演的是生產者角色,SurfaceFlinger扮演的是消費者,工作的流程如下:
應用在開始繪制渲染之前,需要通過調用dequeueBuffer從SurfaceFlinger管理的BufferQueue 申請一處于free狀態的可用Buffer,如果此時沒有可用Buffer則阻塞等待;
應用拿到可用的Buffer后,使用GPU繪制渲染,渲染完成后再通過Binder調用queueBuffer將數據返回給應用進程對應的BufferQueue,如果是 GPU 渲染的話,這里還有個 GPU處理的過程,所以這個 Buffer 不會馬上可用,需要等 GPU 渲染完成的Fence信號,并申請sf的Vsync-sf喚醒消費者SurfaceFlinger進行消費;
SurfaceFlinger 收到 Vsync-sf 信號之后,開始準備合成,使用 acquireBuffer獲取應用對應的 BufferQueue 中的 Buffer 并進行合成操作;
合成結束后,SurfaceFlinger 調用 releaseBuffer將 Buffer 置為可用的free狀態,返回到應用對應的 BufferQueue中。
從 SurfaceFlinger 角度來說,在 App 連續的動畫或者手指滑動列表時(關鍵是連續),如果有一個 Vsync 到來時候 ,App 沒有可以用來合成的 Buffer,那么這個 Vsync 周期 SurfaceFlinger 就不會走合成邏輯(或者是去合成其他的 Layer),那么這一幀就會顯示 App 的上一幀的畫面,這里發生了卡頓;
從App的角度來看,如果渲染線程在一個 Vsync 周期內沒有 queueBuffer 到 SurfaceFlinger 中 App 對應的 BufferQueue 中,那么我們認為這里發生了卡頓。
如果線程Running時長過長導致運行變慢,最終出現上幀超時而掉幀,就需要結合具體tag信息查看到底在執行什么邏輯,然后結合自身的代碼實現看是否可以優化。或者看看當前JIT線程任務是否繁忙,判斷是否是因為應用沒有被及時編譯成機器碼而導致運行時長過長。
出于功耗節能的原因,VSYNC-sf與VSYNC-app并不一定會固定不停觸發。如果app或sf并沒有刷新畫面的需求,那么觸發信號進行繪制和合成是不必要的(功耗)。觸發VSYNC-sf和VSYNC-app的兩個EventThread會在requestNextVsync調用后才會將下一個VSYNC-sf或VSYNC-app發出。因此,當(各自EventThread)requestNextVsync沒有調用時,VSYNC-app和VSYNC-sf也就出現異常。BufferQueueLayer::onFrameAvailable會在應用提交后調用,該方法通過調用SF的signalLayerUpdate觸發產生下一個VSYNC-sf。
Android trace presentFence屏幕顯示的幀-CSDN博客文章瀏覽閱讀807次,點贊20次,收藏21次。在Android系統中,presentFence是屏幕顯示幀的關鍵信號,當幀成功顯示時,presentFence會發出信號。FrameMissed、GpuFrameMissed和HwcFrameMissed表示上一次合成的結果,SurfaceFlinger在每次被Vsync-sf喚醒時會檢查上一次合成的presentFence是否已發出信號,若未發出則認為是幀丟失。BufferTx在queueBuffer后增加,在SurfaceFlinger合成時減少,其內有可用Buffer時,SurfaceFlingerhttps://blog.csdn.net/zhangphil/article/details/148099387