在多數(shù)博客中提到的runloop 在即將休眠前的屏幕繪制
和接收到VSync 信號(hào)后的屏幕繪制
,它們之間是什么關(guān)系呢?
這個(gè)問題困擾了我很長時(shí)間农尖,現(xiàn)在做一個(gè)簡單總結(jié)。
runloop 在即將休眠前的屏幕繪制:如果 CoreAnimation 有未提交內(nèi)容入宦,則提交到 GPU 中去工作蛙埂。也就是說,runloop 與屏幕繪制之間沒有直接的關(guān)系驰弄,只是從 CPU 提交到 GPU麻汰。
接收到 VSync 信號(hào)后的屏幕繪制:VSync 信號(hào)由硬件時(shí)鐘生成,每秒鐘發(fā)出 60 次戚篙。當(dāng) runloop 進(jìn)入到 mach_msg_trap(睡眠)的狀態(tài)時(shí)五鲫,可以通過 mach_port 接收傳過來的時(shí)鐘信號(hào)通知(source1 事件),被喚醒岔擂。如果 CoreAnimation 有未提交內(nèi)容位喂,則執(zhí)行提交操作、如果有 CADisplayLink 等用戶自定義回調(diào)乱灵,則觸發(fā)回調(diào)塑崖。
FPS中的刷新屏幕:當(dāng)兩次 Vsync 信號(hào)到達(dá)之間,如果幀緩沖區(qū)中的數(shù)據(jù)發(fā)生了改變痛倚,就會(huì)刷新這一幀弃舒。卡頓是由于 CPU 和 GPU 的過載導(dǎo)致幀緩沖區(qū)的數(shù)據(jù)沒有刷新状原。
關(guān)于YY大神提到的
App 的 Runloop 在啟動(dòng)后會(huì)注冊(cè)對(duì)應(yīng)的 CFRunLoopSource 通過 mach_port 接收傳過來的時(shí)鐘信號(hào)通知聋呢,隨后 Source 的回調(diào)會(huì)驅(qū)動(dòng)整個(gè) App 的動(dòng)畫與顯示。
我不能贊同颠区。因?yàn)槲以?demo 中測試發(fā)現(xiàn)削锰,當(dāng)屏幕靜止不動(dòng)時(shí),runloop 處于一個(gè)每一分鐘喚醒一次的狀態(tài)毕莱,并沒有被 Vsync 信號(hào)喚醒器贩。只有當(dāng)在 runloop 中加入了 CADisplayLink 之后,才會(huì)在一秒鐘被喚醒 60 次朋截,CADisplayLink 應(yīng)該是 source1 的 mach_msg 觸發(fā)(補(bǔ)充 source1: 當(dāng) 硬件事件發(fā)生的時(shí)候蛹稍,mach_port 轉(zhuǎn)發(fā)給App進(jìn)程,source1 接收后觸發(fā) source0 再觸發(fā)到 UIApplication 的事件隊(duì)列中的)部服。