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

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

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