離屏渲染的定義
GPU由于多個(gè)圖層無(wú)法一次性渲染完成嘴脾,而需要保留其中間狀態(tài)尘执,中間狀態(tài)存放的位置即:offscreen Buffer。而后對(duì)offscreen Buffer中內(nèi)容進(jìn)行整體渲染完成后寫(xiě)入Frame Buffer的整個(gè)流程稱為離屏渲染闸英。如下圖:
離屏渲染xcode檢測(cè)的效果圖
xcode檢測(cè)渲染情況設(shè)置如下:
離屏渲染原理
1虑灰、普通渲染流程
subLayer1繪制:subLayer1渲染完成——>寫(xiě)入FrameBuffer——>Display——>subLayer1從FrameBuffer中清空
subLayer2繪制:subLayer2渲染完成——>寫(xiě)入FrameBuffer——>Display——>subLayer2從FrameBuffer中清空
subLayer3繪制:subLayer3渲染完成——>寫(xiě)入FrameBuffer——>Display——>subLayer3從FrameBuffer中清空
相對(duì)來(lái)說(shuō):subLayer1、subLayer2、subLayer3之間是相互獨(dú)立的
2蛮粮、離屏渲染流程(進(jìn)行圓角操作)
如上圖益缎,進(jìn)行圓角裁剪,每個(gè)圖層都需裁剪一次然想,顯然三個(gè)圖層無(wú)法一次渲染完成莺奔,需offscreenBuffer存放其中間狀態(tài)
subLayer1繪制:從offscreenBuffer中獲取subLayer1進(jìn)行圓角裁剪,渲染完成——>寫(xiě)入FrameBuffer——>Display——>subLayer1從FrameBuffer中清空
subLayer2繪制:從offscreenBuffer中獲取subLayer1進(jìn)行圓角裁剪变泄,渲染完成——>寫(xiě)入FrameBuffer——>Display——>subLayer2從FrameBuffer中清空
subLayer3繪制:從offscreenBuffer中獲取subLayer1進(jìn)行圓角裁剪令哟,渲染完成——>寫(xiě)入FrameBuffer——>Display——>subLayer3從FrameBuffer中清空
以上流程中subLayer1、subLayer2妨蛹、subLayer3之間相對(duì)獨(dú)立屏富,但圖層間若有相互關(guān)聯(lián)時(shí),需額外的處理蛙卤,如:圖層疊加狠半,會(huì)有額外計(jì)算和渲染。
常見(jiàn)離屏渲染場(chǎng)景總結(jié)
1颤难、cornerRadius+clipsToBounds(裁剪+圓角)
2神年、shadow(陰影)
3、group opacity(組透明度)
4行嗤、mask(遮蓋)
5已日、UIBlurEffect(毛玻璃)
對(duì)離屏渲染效率的小改進(jìn)(shouldRasterize光柵化)
離屏渲染開(kāi)銷(xiāo)很大,會(huì)影響性能栅屏。為盡量降低離屏渲染帶來(lái)的影響捂敌,可對(duì)其優(yōu)化。如:對(duì)第一幀已經(jīng)裁出了圓角既琴,則將其結(jié)果緩存下來(lái)占婉,下一幀渲染復(fù)用該緩存效果,避免重新裁剪一次甫恩。
CALayer為提供了:shouldRasterize逆济。一旦被設(shè)置為true,Render Server就會(huì)強(qiáng)制把layer的渲染結(jié)果(包括其子layer磺箕,以及圓角奖慌、陰影、group opacity等等)保存在一塊內(nèi)存中松靡,則下一幀可以復(fù)用简僧,而不會(huì)再次觸發(fā)離屏渲染。
注意點(diǎn):
1雕欺、shouldRasterize至少會(huì)觸發(fā)一次離屏渲染岛马。如果你的layer本來(lái)并不復(fù)雜棉姐,也沒(méi)有圓角陰影等等,打開(kāi)這個(gè)開(kāi)關(guān)反而會(huì)增加一次不必要的離屏渲染
2啦逆、離屏渲染緩存有空間上限伞矩,最多不超過(guò)屏幕總像素的2.5倍大小
3、一旦緩存超過(guò)100ms沒(méi)有被使用夏志,會(huì)自動(dòng)被丟棄
4乃坤、layer的內(nèi)容(包括子layer)必須是靜態(tài)的,因?yàn)橐坏┌l(fā)生變化(如resize沟蔑,動(dòng)畫(huà))湿诊,之前辛苦處理得到的緩存就失效了。如果這件事頻繁發(fā)生瘦材,我們就又回到了“每一幀都需要離屏渲染”的情景厅须,而這正是開(kāi)發(fā)者需要極力避免的。針對(duì)這種情況宇色,Xcode提供了“Color Hits Green and Misses Red”的選項(xiàng)九杂,幫助我們查看緩存的使用是否符合預(yù)期
彩蛋:除了解決多次離屏渲染的開(kāi)銷(xiāo),shouldRasterize可應(yīng)用于另一個(gè)場(chǎng)景:如果layer的子結(jié)構(gòu)非常復(fù)雜宣蠕,渲染一次所需時(shí)間較長(zhǎng)例隆,同樣可以打開(kāi)這個(gè)開(kāi)關(guān),把layer繪制到一塊緩存抢蚀,然后在接下來(lái)復(fù)用這個(gè)結(jié)果镀层,這樣就不需要每次都重新繪制整個(gè)layer樹(shù)
思考
CPU渲染緩解GPU壓力?