什么是離屏渲染?
離屏渲染(offscreen-rendering)顧名思義為屏幕外的渲染,即渲染的結(jié)果不會(huì)直接呈現(xiàn)到當(dāng)前屏幕上音比,而是等待合適的時(shí)機(jī)才會(huì)被顯示。
正常情況下氢惋,在當(dāng)前屏幕顯示的內(nèi)容洞翩,由 GPU 渲染完成后放到當(dāng)前屏幕的幀緩存區(qū)稽犁,不需要額外的渲染空間。
假如 GPU 因?yàn)槊媾R一些限制菱农,無(wú)法把渲染結(jié)果直接寫(xiě)入frame buffer缭付,而是先暫存在另外的內(nèi)存區(qū)域,之后再寫(xiě)入frame buffer循未,那么這個(gè)過(guò)程被稱之為離屏渲染陷猫。
離屏渲染的過(guò)程
通常的渲染流程是這樣的
在正常情況下,經(jīng)過(guò)CPU的計(jì)算以及GPU的渲染之后的妖,不停地將內(nèi)容渲染完成放入Frame Buffer
中幀緩存區(qū)绣檬,隨后視頻控制器會(huì)讀取幀緩存區(qū)的數(shù)據(jù),經(jīng)過(guò)數(shù)模轉(zhuǎn)換嫂粟,再逐行顯示到屏幕上
出現(xiàn)離屏渲染的渲染流程:
與普通情況下 GPU 直接將渲染好的內(nèi)容放入Frame Buffer
中不同娇未,在某些特殊情況下,需要先額外創(chuàng)建離屏渲染緩沖區(qū) offscreen Buffer
星虹,將提前渲染好的內(nèi)容放入其中零抬,等到合適的時(shí)機(jī)再將 offscreen Buffer 中的內(nèi)容進(jìn)一步疊加、渲染宽涌,最后將結(jié)果切換到 Frame Buffer 中平夜。
離屏渲染的利弊
優(yōu)勢(shì)
- 特殊的渲染效果:使用額外的離屏緩沖區(qū)(offscreen butter)保存中間狀態(tài),最后疊加卸亮、處理后繪制在屏幕上忽妒,這樣就不得不使用離屏渲染
- 效率優(yōu)勢(shì):需要多次使用的效果,提前渲染存入離屏緩沖區(qū)兼贸,然后復(fù)用來(lái)提高效率段直。
劣勢(shì)
- 內(nèi)存開(kāi)支:開(kāi)辟離屏緩沖區(qū)(大小不超過(guò)2.5倍屏幕像素大小)
- 時(shí)間和性能開(kāi)支:從離屏緩沖區(qū)拷貝數(shù)據(jù)到幀緩沖區(qū)溶诞,上下文切換耗性能鸯檬,容易出現(xiàn)掉幀的情況
常見(jiàn)的觸發(fā)離屏渲染的情況
- 使用了 mask 的 layer (layer.mask)
- 需要進(jìn)行裁剪的 layer (layer.masksToBounds /view.clipsToBounds)
- 設(shè)置了組透明度為 YES,并且透明度不為 1 的layer (layer.allowsGroupOpacity/ layer.opacity)
- 添加了投影的 layer (layer.shadow*)
- 采用了光柵化的 layer (layer.shouldRasterize)
不過(guò)使用光柵化的時(shí)候需要注意以下幾點(diǎn):
- 如果layer不能被復(fù)用螺垢,則不必打開(kāi)光柵化
- 如果layer不是靜態(tài)的京闰,需要被頻繁修改,如處于動(dòng)畫(huà)中甩苛,那開(kāi)啟離屏渲染反而會(huì)影響效率
- 離屏渲染緩存內(nèi)容有時(shí)間限制蹂楣,緩存內(nèi)容100ms內(nèi)沒(méi)有被使用,那么它就會(huì)丟棄讯蒲,無(wú)法進(jìn)行復(fù)用了
- 離屏渲染緩存空間有限痊土,不能超過(guò)2.5倍屏幕像素大小
- 繪制了文字的 layer (UILabel, CATextLayer, Core Text 等)