天天看點

拍立淘---試妝魔鏡 OpenGL ES 2.0 架構及性能優化

拍立淘---試妝魔鏡 OpenGL ES 2.0 架構及性能優化
拍立淘---試妝魔鏡 OpenGL ES 2.0 架構及性能優化
拍立淘---試妝魔鏡 OpenGL ES 2.0 架構及性能優化

單線程模型,優先級過低:從camera擷取到cmsamplebufferref yuv圖像幀,拷貝像素資料到記憶體(多了一次拷貝記憶體的開銷)進行美妝渲染以及一些其他的檢測計算,導緻的render線程性能消耗過多,cpu負載過重,使用率在78%左右,直接導緻了fps過低,在5s機型上實測在 20 fps 以下,非常的卡頓。

opengl渲染通過ui主線程runloop回調:opengl 渲染在drawrect中實作,通過setneedsdisplay回調重新整理,會有主線程被占用導緻的螢幕卡頓的問題。

渲染全鍊路設計為單層framebuffer結構,所有渲染過程及opengl函數調用都在一個vc函數中,導緻過多的渲染參數控制(每增加一個功能,就需要增加一個參數控制),并且與底層渲染子產品存在較高的耦合度,導緻此函數實作越來越臃腫複雜。

framebuffer等一些資源的重複建立所帶來的性能開銷,以及多執行個體下的美妝子產品重複的初始化導緻出現多份拷貝,記憶體使用率不高,開銷過大。

更好的支援rgb32和yuv420像素格式轉換以及camera 分辨率切換。

更加友善靈活地控制整個渲染全鍊路以及每個可插拔式渲染節點,滿足角點閃星或者美妝渲染層的即時生效和幀同步。

更好的性能及更高的fps,一些角點檢測,光線檢測可異步計算減少更新同步頻率, 保證camera fps的流暢性,一些像素格式轉換,算法可移植到gpu(shader program),角點閃星效果從core animation移植opengl gldrawarrays,動效改為shader實作, 都極大地減少了cpu負載,合理的平衡cpu和gpu負載均衡,提升了螢幕重新整理性能和fps。

支援更加靈活的capture取圖方式,opengl支援擷取每層渲染紋理的截圖,支援更多功能需求,例如對比美妝前後效果,去除角點閃星渲染等功能。

拍立淘---試妝魔鏡 OpenGL ES 2.0 架構及性能優化

整個過程中的所有鍊路節點都繼承至glnode基類,通過shader,提供對每幀紋理緩存(openglframebuffer)的渲染能力,通過addtarget添加子節點集合,最終形成單連結清單渲染全鍊路。

渲染全鍊路以input節點類為輸入源起點,可以是一張圖檔,一段視訊,或者是持續性的camera視訊輸入,過程中可選擇性加入角點檢測,人臉偵測,美妝渲染,坐标變換濾鏡等渲染節點,最後将最終渲染的一幀或多幀圖像紋理緩存輸出到output節點(glview或caeagllayer)。

拍立淘---試妝魔鏡 OpenGL ES 2.0 架構及性能優化

input 線程主要提供每幀圖像源資料,它的每幀圖像處理性能直接決定螢幕顯示的fps,是以它設定為高優先級,一些比較耗時的cpu操作都采用異步線程去計算完成,如角點計算,光線強度計算,截屏等功能。

render 線程主要負責opengl es 2.0 的全鍊路渲染,主線程中一些設定更改節點參數,添加移除部分鍊路節點,更改渲染全路徑等ui操作都需要異步切換到此render線程執行,為了確定内部資料線程安全。

detector 線程主要負責異步計算圖像的角點資訊和光線強度,通過邊緣弱化(中心門檻值越低,邊緣門檻值越高),壓縮像素點采樣(減少計算的像素點)進而提升性能,減少此線程對整體性能的影響,計算得到的結果資料通知render線程同步更新opengl資料緩存,在接下來的渲染中,讀取最新的結果資料進行顯示。

通過對紋理的像素格式,大小,屬性作為hash key辨別,建立全局共享紋理(framebuffer)緩存隊列,同時使用記憶體引用計數機制管理每一個紋理緩存,監聽記憶體警告,當記憶體緊張時,釋放所有緩存紋理,同時每個渲染節點都讀取和使用緩存紋理進行每層紋理的更新與向下傳遞,減少了建立和銷毀紋理的性能消耗。

耗時的像素轉換(yuv420轉換rgb32)計算通過調用gpu shader執行計算:

角點閃星動效通過調用gpu shader執行渲染:

用gpu shader 替換執行cpu計算代碼,大大減少了cpu的運算負載,提升了實時渲染性能和fps。

試妝魔鏡子產品算法模型執行異步初始化,成功後修改節點鍊路,添加試妝魔鏡節點至opengl渲染全鍊路,當重複進入存在多個渲染全鍊路應用場景時,後續不需要再次初始化算法模型,可以直接使用已初始化的共享試妝魔鏡執行個體執行渲染操作。

camera輸出的圖像像素分辨率過高,直接進行計算消耗太多的性能,實際螢幕顯示的尺寸也小于原有圖像的比例,是以需要對原始圖像進行壓縮采樣,減少像素計算的時間複雜度,同時為了更好的調控性能,争對不同的機器硬體設定不同的門檻值和延遲時間間隔,控制角點顯示的個數和協調不同裝置的計算能力,當檢測擷取每幀圖像的時間間隔內插補點達到門檻值時,再檢查detector計算任務隊列是否已經處理完畢,添加此幀圖像進入計算隊列讓異步線程執行具體計算邏輯,最終将計算結果同步更新至渲染線程opengl資料緩存進行顯示。

iphone 5s機型下實測:cpu 使用率穩定在50%左右, fps穩定在35幀,gpu使用率為8%,整個頁面進入新增記憶體在15m左右,卡頓現象已經徹底消失。

類似webgl,将opengl渲染動态化,通過js的語言動态特性解析執行opengl全鍊路渲染,開發opengl native容器,以native的性能動态執行一些js腳本ar動效。

将此架構移植到android,底層opengl層采用統一c語言實作,通過适配層提供統一接口和适配平台差異性。

繼續閱讀