離屏渲染定義
離屏渲染的流程如圖:

GPU把渲染好的的內(nèi)容存放到離屏渲染緩沖區(qū)中,在離屏渲染緩沖區(qū)(OffscreenBuffer)中進(jìn)一步做一些處理后,再提交到幀緩沖區(qū)(FrameBuffer)中。
離屏渲染的效率問(wèn)題( 對(duì)性能有什么影響?)
從上面的流程來(lái)看,離屏渲染時(shí)由于 App 需要提前對(duì)部分內(nèi)容進(jìn)行額外的渲染并保存到 Offscreen Buffer,以及需要在必要時(shí)刻對(duì) Offscreen Buffer 和 Framebuffer 進(jìn)行內(nèi)容切換,所以會(huì)需要更長(zhǎng)的處理時(shí)間。
并且 Offscreen Buffer 本身就需要額外的空間,大量的離屏渲染可能早能內(nèi)存的過(guò)大壓力。與此同時(shí),Offscreen Buffer 的總大小也有限,不能超過(guò)屏幕總像素的 2.5 倍。
使用離屏渲染的原因
情況一:
一般都是系統(tǒng)去觸發(fā),例如對(duì)layer層相關(guān)處理:包括圓角、陰影、mask等等。iOS系統(tǒng)扁平化后出現(xiàn)的高斯模糊也是利用離屏渲染方式。
情況二:
是一種主動(dòng)行為,是為了提高復(fù)用的效率。通常是設(shè)置layer的shouldRasterize屬性來(lái)實(shí)現(xiàn)。
shouldRasterize官方文檔

開(kāi)啟后,會(huì)將layer作為位圖保存下來(lái),下次直接與其他內(nèi)容進(jìn)行混合。這個(gè)保存的位置就是OffscreenBuffer中。這樣下次需要再次渲染的時(shí)候,就可以直接拿來(lái)使用了。
shouldRasterize使用建議:
- layer不復(fù)用,沒(méi)必要使用shouldRasterize
- layer不是靜態(tài)的,也就是說(shuō)要頻繁的進(jìn)行修改,沒(méi)必要使用shouldRasterize
- 時(shí)間方面:離屏渲染緩存有100ms時(shí)間限制,超過(guò)該時(shí)間的內(nèi)容會(huì)被丟棄,進(jìn)而不能達(dá)到復(fù)用的目的
- 空間方面:離屏渲染空間是屏幕像素的2.5倍,如果超過(guò)也無(wú)法復(fù)用。
常見(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)
- 繪制了文字的 layer (UILabel, CATextLayer, Core Text 等)