Render機(jī)制概述
要分析AP的graphics performance榜轿,需要了解OGL ES API的模型,觀察其行為進(jìn)行推測(cè)碴里。
下面是這個(gè)機(jī)制的3個(gè)有用的部分:
- CPU-GPU rendering pipeline
- Tile-based rendering
- Shader core architecture
Synchronous API, Asynchronous Execution
很重要的基礎(chǔ)是何乎,了解AP調(diào)用的OGLES API需要執(zhí)行的render操作较屿。AP執(zhí)行一系列func calls最爬,以設(shè)置下一個(gè)draw task所需的state凫岖,然后調(diào)用glDrawxxx來(lái)觸發(fā)一次真正的draw operation. 由于API是synchronous同步的,就會(huì)感覺(jué)后續(xù)的render操作都是立即發(fā)生的返咱,其實(shí)不是這樣钥庇,這是driver造成的錯(cuò)覺(jué)。
與draw calls類(lèi)型咖摹,第二個(gè)錯(cuò)覺(jué)來(lái)自driver的end-of-frame buffer flip评姨。
我們知道用eglSwapBuffer來(lái)swap front and back-buffer,這也是driver造成的同步假象萤晴,實(shí)際硬件的buffer swap都在很長(zhǎng)時(shí)間以后發(fā)生吐句。
Pipelining
這么做是為了performance。
如果我們強(qiáng)制把render做同步店读,就可能發(fā)生:
- GPU idle嗦枢,但CPU忙于為下一個(gè)draw創(chuàng)建state
- CPU idle,但GPU在渲染
這不利于performance两入,所有的idle都不該有净宵。
為了去除idle,GLES driver維護(hù)了synchronous rendering的假象裹纳,實(shí)際底層render和frame swaps 是異步的(asynchronously under the hood)择葡。通過(guò)async可以建立一個(gè)小backlog of work,允許創(chuàng)建一個(gè)pipeline:GPU處理一個(gè)pipeline尾的older workloads剃氧,而CPU向另一個(gè) push new work敏储。這樣就可以時(shí)pipeline一直是full的,GPU總有工作可以做朋鞍,以提高performance已添。
Mali GPU pipeline的units根據(jù)per rendertarget basis來(lái)schedule,render target可能是window surface或者是off-screen render buffer滥酥。一個(gè)render target被處理為兩個(gè)步驟:
- GPU處理所有render target的draw calls的vertex shading更舞,
- 處理整個(gè)render target的fragment shading
可以看到,CPU處理比較快坎吻,Geometry就是頂點(diǎn)著色階段缆蝉,F(xiàn)ragment就是Pixel著色,時(shí)間最長(zhǎng)瘦真。
Pipeline Throttling
圖中可以看到刊头,fragment work是3個(gè)操作里面最慢的,它愈發(fā)落后于CPU處理和geometry stages诸尽。
這種延遲是用戶受不了的原杂,不該因fragment stage而使backlog of work過(guò)大。所以需要機(jī)制周期性的降低CPU thread的速度您机,當(dāng)pipeline full時(shí)不再enqueue穿肄,
這種throttling mechanism節(jié)流機(jī)制一般由host windowing system處理年局,而不是graphic driver。
比如被碗,adnroid上某宪,在指定buffer的orientation前,我們不能做任何draw操作锐朴,因?yàn)閡ser可能會(huì)rotate device,change frame size兴喂。Surfaceflinger, Android的window surface manager,就會(huì)控制pipeline depeth: 在排隊(duì)等待render的queue如果超過(guò)了N個(gè)buffer焚志,就不再給AP的graphics stack返回buffer.
只要達(dá)到N衣迷,CPU就會(huì)idle,阻塞在EGL或者OGLES API func酱酬,直到display consume pending buffer壶谒,釋放一個(gè)新buffer去做render。
這種機(jī)制下膳沽,如果graphics stack跑的比顯示的刷新率塊汗菜,就也會(huì)劍指pipeline buffering。
這個(gè)圖里挑社,vsync limited陨界,等待vertical blank signal,他用來(lái)告訴display controller何時(shí)switch to next front-buffer痛阻。如果GPU處理frame比display顯示的速度快菌瘪,那SF就會(huì)積攢大量早已render好的buffer,等待顯示阱当。
如圖俏扩,vsync limited,這時(shí)CPU和GPU會(huì)周期性的idel弊添。
然后DVFS(dynamic voltage and frequency scaling)就會(huì)試圖降低工作頻率從而降低電壓和功耗录淡。