一奇钞、圖片撕裂
如圖,很多人在游戲中應(yīng)該都見過這種情況漂坏,在某個界面景埃,出現(xiàn)上下兩部分?jǐn)鄬拥那闆r,這個就是圖片撕裂顶别。
1谷徙、出現(xiàn)原因
出現(xiàn)圖片撕裂的主要原因就是,視頻控制器的顯示速度比不上GPU的處理圖形的速度驯绎。
在GPU拿到位圖數(shù)據(jù)之后完慧,會通過GPU進(jìn)行圖形處理,并顯示到屏幕上剩失,過程為 GPU渲染->存入幀緩存區(qū)-> 視頻控制器 -> 讀取幀緩存區(qū)信息 -> 數(shù)模轉(zhuǎn)化(數(shù)字信號處->模擬型號) -> 逐行顯示到屏幕上屈尼。
因此,當(dāng)?shù)谝粠膱D像正在逐行顯示且并未完全顯示完成的時候拴孤,GPU拿到了新的數(shù)據(jù)脾歧,且存入了幀緩存區(qū),而后視頻控制器讀取的幀緩存區(qū)的位圖信息演熟,是新的一幀的位圖信息鞭执,這個時候,就會出現(xiàn)圖片斷層芒粹,即圖片撕裂兄纺。
2、解決辦法
在iOS中引入了垂直信號vSync+雙緩存區(qū)doubleBuffering的方式來解決圖片撕裂化漆。
2.1 垂直信號vSync
幀緩存區(qū)加鎖估脆,在上一幀緩存區(qū)位圖數(shù)據(jù)完全顯示之前,GPU即使拿到了新一幀的數(shù)據(jù)获三,也不存入幀緩存區(qū)旁蔼,直到上一幀顯示完全。
2.2 雙緩存區(qū)doubleBuffering
GPU會開辟A和B兩個緩存區(qū)疙教。
基本流程就是棺聊,當(dāng)A 幀緩存區(qū)拿到一幀數(shù)據(jù),就會給A 幀緩存區(qū)加上鎖贞谓,此時限佩,如果GPU拿到新一幀的數(shù)據(jù),則會存入B幀緩存區(qū)裸弦,不會存入A幀緩存區(qū)祟同,直到A幀緩存區(qū)的數(shù)據(jù)逐行掃描完成之后,A 幀緩存區(qū)才會解鎖理疙。
二晕城、掉幀
通過垂直信號vSync + 雙緩存區(qū)doubleBuffering能夠較好的解決圖片撕裂的問題,但是同時窖贤,卻引入了另外一個問題砖顷,那就是掉幀。
1赃梧、形成原因
掉幀的本質(zhì)其實是顯示了同一幀的數(shù)據(jù)滤蝠,在iOS中,每一幀的處理時間是1/60 ≈ 16.67ms授嘀。在vSync信號到來之后物咳,CPU會開始做各種計算、解碼等工作蹄皱,并將結(jié)果交給GPU览闰,由GPU做各種變換、合成巷折、渲染等工作焕济,而后GPU會把結(jié)果交給幀緩存區(qū),在下一次vSync到來的時候盔几,逐行顯示到屏幕上晴弃。而掉幀的主要原因是 ,當(dāng)下一次vSync到來的時候逊拍,在二級緩存的情況之下上鞠,CPU/GPU并沒有成功的把數(shù)據(jù)提交給幀緩存區(qū),而此時芯丧,屏幕只能渲染舊的幀芍阎,因此形成了掉幀。
2缨恒、解決辦法谴咸?轮听??
事實上岭佳,掉幀的問題不能夠完全解決血巍,只能盡可能的減少。
為了盡可能減少掉幀問題珊随,從而引入了三級緩存述寡。本質(zhì)就是再增加一個離屏緩存區(qū)。
基本流程是叶洞,在顯示A緩存區(qū)數(shù)據(jù)的時候鲫凶,同時B和C緩存區(qū)會渲染下兩幀的數(shù)據(jù),周而復(fù)始的衩辟,CPU/GPU會不停的循環(huán)處理螟炫、渲染下兩幀的數(shù)據(jù),從而緩解掉幀的問題艺晴。
綜上總結(jié)一下屏幕卡頓原因
1不恭、CPU/GPU 渲染流?線耗時過?導(dǎo)致掉幀
- 垂直同步Vsync + 雙緩存區(qū) DoubleBuffering 以掉幀為代價解決了圖片撕裂;
- 三緩存區(qū): 合理使?CPU/GPU的空閑時間财饥, 以減少掉幀次數(shù)换吧。