1. 什么是圖像撕裂
圖像撕裂是我們所觀看到的一張圖片發(fā)生上下錯位拾枣,出現(xiàn)了明顯的斷層沃疮,如下圖:
GPU進行渲染到顯示的過程大致是一下這幾步:
GPU進?渲染->幀緩存區(qū)? ->視頻控制器->讀取幀緩存區(qū)信息(位圖) -> 數(shù)模轉(zhuǎn)化(數(shù)字信號處->模 擬型號) ->(逐?掃描)顯示,
當?shù)谝粠瑘D像掃描到某個位置時梅肤,GPU拿到新的數(shù)據(jù)并存到幀緩沖區(qū)司蔬,這個時候視頻控制器從幀緩沖區(qū)掃描的是新拿到的一幀的圖像,最后就形成了在我們?nèi)庋劭吹降臄鄬蝇F(xiàn)象姨蝴,即我們看到的一張圖片其本質(zhì)是兩張圖片組合而來(舊圖片和新圖片)俊啼,究其原因就是視頻控制器顯示速度大于了GPU處理圖形的速度。
2. 如何解決撕裂
雙緩沖區(qū)
雙緩沖區(qū)是在幀緩存區(qū)中開辟兩個緩沖區(qū)左医,一個緩沖區(qū)通過視頻控制器進行當前幀數(shù)據(jù)的讀取顯示授帕,另一個緩沖區(qū)進行接收下一幀GPU渲染的圖像。兩個緩沖區(qū)都執(zhí)行結(jié)束浮梢,然后再交換緩沖區(qū)跛十。
這里解釋一下什么是垂直同步Vsync
電子槍從上到下逐行掃描,掃描完成后顯示器就呈現(xiàn)一幀畫面秕硝。然后電子槍回到初始位置進行下一次掃描芥映。為了同步顯示器的顯示過程和系統(tǒng)的視頻控制器,顯示器會用硬件時鐘產(chǎn)生一系列的定時信號远豺。當電子槍換行進行掃描時奈偏,顯示器會發(fā)出一個水平同步信號(horizonal synchronization),簡稱 HSync躯护;而當一幀畫面繪制完成后惊来,電子槍回復到原位,準備畫下一幀前榛做,顯示器會發(fā)出一個垂直同步信號(vertical synchronization)唁盏,簡稱 VSync内狸。顯示器通常以固定頻率進行刷新检眯,這個刷新率就是 VSync 信號產(chǎn)生的頻率。雖然現(xiàn)在的顯示器基本都是液晶顯示屏了昆淡,但其原理基本一致锰瘸。
為了解決撕裂,APPLE引入了: 垂直同步Vsync + 雙緩存區(qū) DoubleBuffering
(1)垂直同步Vsync:幀緩存區(qū)加鎖 防?出現(xiàn)撕裂情況 昂灵。
(2)雙緩存區(qū) DoubleBuffering :就是GPU開辟AB兩個幀緩沖區(qū)避凝,顯示到屏幕上的叫屏幕緩沖區(qū)舞萄,未顯示到屏幕上的叫離屏緩沖區(qū),圖片渲染的時候管削,在離屏緩沖區(qū)渲染倒脓,渲染完成后,兩個緩沖區(qū)交換含思。這樣渲染完成的圖片就可以顯示出一張完整的圖片了崎弃。從而去解決撕裂問題。
執(zhí)行流程就是當A幀緩沖區(qū)拿到第一幀數(shù)據(jù)含潘,給A緩沖區(qū)加上一把鎖饲做,屏幕控制器從A拿到數(shù)據(jù)并逐行掃描完成,A幀緩沖區(qū)解鎖遏弱,并且屏幕控制器指向B幀緩沖區(qū)盆均,B幀緩沖區(qū)加鎖并逐行掃描顯示,在屏幕控制器掃描B幀緩沖區(qū)的時候漱逸,A幀緩沖區(qū)拿到GPU傳過來的新一幀數(shù)據(jù)泪姨,以此類推,解決撕裂問題饰抒。
3. 掉幀
當采用垂直同步Vsync + 雙緩存區(qū) DoubleBuffering時又會產(chǎn)生一個新的問題驴娃,出現(xiàn)了一個新的問題--->掉幀
特別說明:掉幀不是因為丟失了一幀的數(shù)據(jù)就叫掉幀!
掉幀指的是重復渲染同?幀數(shù)據(jù)循集,可以理解為我們所說的屏幕卡頓了唇敞。
撕裂和掉幀的取舍?
如果一旦屏幕產(chǎn)生撕裂咒彤,用戶可能會覺得是手機本身的問題疆柔。
掉幀,則只是會使用戶感覺手機產(chǎn)生了卡頓镶柱,何況掉幀的概率也比較小旷档,并不是時時出現(xiàn)卡頓,所以相比于撕裂歇拆,掉幀相對而言是更可取的鞋屈。
以60fps舉例,每幀畫面的處理時間大概在16.7ms(1s/60 ≈16.7ms)故觅,當超過這個時間就會出現(xiàn)掉幀厂庇,如上圖:當接收接收Vsync ,由于cpu/gpu還沒處理完圖?數(shù)據(jù)(大于了16.7ms) -> 拿不到FrameBuffer ->這個時候屏幕控制器只能顯示同一幀的數(shù)據(jù),即: 掉幀(重復渲染同?幀數(shù)據(jù))输吏。
為了減少掉幀(注意不是解決权旷,掉幀問題只能盡量的減少,而不是解決贯溅,三級緩沖區(qū)也有可能出現(xiàn)掉幀)拄氯,引入三緩存區(qū)躲查,三緩沖區(qū)是為了充分利用CPU/GPU的空余時間,開辟ABC三個幀緩沖區(qū)译柏,A顯示到屏幕上, B也渲染好镣煮,C再從GPU拿取渲染數(shù)據(jù),當屏幕緩沖區(qū)和幀緩沖區(qū)都弄好了鄙麦,然后視頻控制器再指向幀緩沖區(qū)的另外一個怎静,再顯示,這樣交替黔衡,達到減少掉幀的情況蚓聘,這樣做就比二級緩沖區(qū)多了一個確認的操作。
總結(jié):屏幕卡頓原因:
CPU/GPU 渲染流?線耗時過?->掉幀
垂直同步Vsync + 雙緩存區(qū) DoubleBuffering 以掉幀作為代價->解決屏幕撕裂
三緩存區(qū): 合理充分使?CPU/GPU 減少掉幀次數(shù);