1、什么是離屏渲染?
1)On-Screen Rendering
意為當(dāng)前屏幕渲染,指的是 GPU 的渲染操作是在當(dāng)前用于顯示的屏幕緩沖區(qū)中進(jìn)行。
2)Off-Screen Rendering
意為離屏渲染,指的是 GPU 在當(dāng)前屏幕緩沖區(qū)以外新開辟一個(gè)緩沖區(qū)進(jìn)行渲染操作。
2、離屏渲染觸發(fā)的時(shí)機(jī)
當(dāng)圖層屬性的混合體被指定為在未預(yù)合成之前不能直接在屏幕中繪制時(shí),屏幕外渲染就被喚起了。屏幕外渲染并不意味著軟件繪制,但是它意味著圖層必須在被顯示之前在一個(gè)屏幕外上下文中被渲染(不論 CPU 還是 GPU)。
離屏渲染可以被 Core Animation 自動(dòng)觸發(fā),或者被應(yīng)用程序強(qiáng)制觸發(fā)。屏幕外的渲染會(huì)合并/渲染圖層樹的一部分到一個(gè)新的緩沖區(qū),然后該緩沖區(qū)被渲染到屏幕上。
這里提到的 offscreen rendering 主要講的是通過(guò) GPU 執(zhí)行的 offscreen,事實(shí)上還有的 offscreen rendering 是通過(guò) CPU 來(lái)執(zhí)行的。
如果我們重寫了 drawRect 方法,并且使用任何 Core Graphics 的技術(shù)進(jìn)行了繪制操作,就涉及到了 CPU 渲染。整個(gè)渲染過(guò)程由 CPU 在 App 內(nèi)同步地完成,渲染得到的 bitmap 最后再交由 GPU 用于顯示。其它類似 cornerRadios, masks, shadows 等觸發(fā)的 offscreen 是基于 GPU 的。
PS:CoreGraphic 通常是線程安全的,所以可以進(jìn)行異步繪制,顯示的時(shí)候再放回主線程。
2.1 觸發(fā)離屏渲染的方式
1、圓角(當(dāng)和maskToBounds一起使用時(shí))
2、圖層蒙版
3、陰影
4、光柵化:設(shè)置 shouldRasterize = YES 便會(huì)觸發(fā)光柵化
光柵化的概念:
將圖轉(zhuǎn)化為一個(gè)個(gè)柵格組成的圖像,即從矢量的點(diǎn)線面的描述,變成像素的描述。
光柵化是一種特殊的離屏渲染,它的主要工作量集中在?CPU?上,而不是前文介紹的那種 GPU 單獨(dú)開辟緩存進(jìn)行圖形生成計(jì)算,并且 CPU 光柵化完成后會(huì)將該 bitmap 緩存于本地,以便重復(fù)利用,它在形式上也是一種離屏渲染,但不屬于 OpenGL 名字中特指的那種 GPU 新開 buffer 生成圖形的過(guò)程。?
光柵化注意兩點(diǎn):
1、不要過(guò)度使用,系統(tǒng)限制了緩存的大小為 2.5X Screen Size.
如果過(guò)度使用,超出緩存之后,同樣會(huì)造成大量的 offscreen 渲染。
2、被光柵化的圖片如果超過(guò)?100ms?沒(méi)有被使用,則會(huì)被移除
因此我們應(yīng)該只對(duì)連續(xù)不斷使用的圖片進(jìn)行緩存。對(duì)于不常使用的圖片緩存是沒(méi)有意義,且耗費(fèi)資源的。
注:對(duì)于那些需要?jiǎng)赢嫸乙谄聊煌怃秩镜膱D層來(lái)說(shuō),你可以用 CAShapeLayer,contentsCenter 或者shadowPath 來(lái)獲得同樣的表現(xiàn)而且較少地影響到性能。
3、為什么要盡量避免離屏渲染?
一般導(dǎo)致圖形性能的問(wèn)題大部分都出在了 offscreen rendering, 因此如果我們發(fā)現(xiàn)列表滾動(dòng)不流暢,動(dòng)畫卡頓等問(wèn)題,就可以想想和找出我們哪部分代碼導(dǎo)致了大量的 offscreen 渲染。
離屏渲染主要在兩個(gè)地方開銷較大:
1、創(chuàng)建新緩沖區(qū)
要想進(jìn)行離屏渲染,首先要?jiǎng)?chuàng)建一個(gè)新的緩沖區(qū)。
2、上下文切換
離屏渲染的整個(gè)過(guò)程,需要多次切換上下文環(huán)境:先是從當(dāng)前屏幕(On-Screen)切換到離屏(Off-Screen);等到離屏渲染結(jié)束以后,將離屏緩沖區(qū)的渲染結(jié)果顯示到屏幕上,又需要將上下文環(huán)境從離屏切換到當(dāng)前屏幕。而上下文環(huán)境的切換是要付出很大代價(jià)的。
4、硬件加速
硬件加速是指用到了 GPU 的 API,以下這些情況不會(huì)用到硬件加速
1)使用 CGContexts 繪制的圖形
2)所有在 drawRect 中完成的圖形繪制。
3)shouldRasterize 屬性為 YES 的 CALayer(在 CPU 渲染)。
4)用到了 mask 或 drop shadow 的 CALayer。
5)Text (包括UILabels, CATextLayers, Core Text, 等等)
參考文檔:iOS圖形原理與離屏渲染