離屏渲染

什么是離屏渲染贩挣?

離屏渲染(Off-Screen Rendering)顧名思義,指的是GPU在當(dāng)前屏幕緩沖區(qū)以外新開辟一個(gè)緩沖區(qū)進(jìn)行渲染操作没酣。如果要在顯示屏上顯示內(nèi)容王财,我們至少需要一塊與屏幕像素?cái)?shù)據(jù)量一樣大的frame buffer,作為像素?cái)?shù)據(jù)存儲(chǔ)區(qū)域裕便,而這也是GPU存儲(chǔ)渲染結(jié)果的地方绒净。如果有時(shí)因?yàn)槊媾R一些限制,無(wú)法把渲染結(jié)果直接寫入frame buffer偿衰,而是先暫存在另外的內(nèi)存區(qū)域疯溺,之后再寫入frame buffer论颅,那么這個(gè)過程被稱之為離屏渲染哎垦。

渲染結(jié)果是先經(jīng)過離屏buffer,再到frame buffer囱嫩。

常見觸發(fā)離屏渲染?

測(cè)試環(huán)境(Xcode12.5.1漏设、iPhone 12墨闲、iOS 14.5)

設(shè)置cornerRadius并不一定就會(huì)觸發(fā)離屏渲染。

UIImageView為例:

cornerRadius+clipsToBounds或者layer.masksToBounds = YES也不會(huì)觸發(fā)離屏渲染郑口。即使設(shè)置了圖片也不會(huì)觸發(fā)離屏渲染鸳碧。iOS9 之后蘋果做了優(yōu)化,但是當(dāng)imageView添加子視圖,并且子視圖有超出父視圖的部分犬性,設(shè)置clipsToBounds或者layer.masksToBounds為YES瞻离,此時(shí)超出的部分會(huì)觸發(fā)離屏渲染

cornerRadius+clipsToBounds或者layer.masksToBounds+backgroundColor。則會(huì)觸發(fā)離屏渲染乒裆。所以我們?cè)O(shè)置imgView為圓角的時(shí)候套利,盡量不要設(shè)置背景顏色,其他視圖同理例如UIView鹤耍,UILabel,UIButton肉迫。

cornerRadius+clipsToBounds或者layer.masksToBounds +borderColor + borderWidth 會(huì)觸發(fā)離屏渲染,當(dāng)borderWidth為0時(shí)也不會(huì)觸發(fā)離屏渲染稿黄。

根據(jù)油畫算法喊衫,GPU沒辦法一步到位既設(shè)置圓角又設(shè)置背景顏色、或者邊框杆怕,所以會(huì)觸發(fā)離屏渲染族购。

光柵會(huì)觸發(fā)離屏渲染:

shouldRasterize = YES;會(huì)觸發(fā)離屏渲染陵珍。

開啟光柵化會(huì)將圖層渲染為一個(gè)屏幕之外的位圖寝杖,然后將這個(gè)位圖緩存起來。如果圖層比較復(fù)雜撑教,這樣做會(huì)比重繪所有幀劃算朝墩。但是光柵化原始圖像需要時(shí)間,會(huì)消耗額外的內(nèi)存伟姐。

如果使用合理收苏,光柵化可以提供很大的性能優(yōu)勢(shì),但是對(duì)于內(nèi)容不斷變化的圖層來說愤兵,就沒必要緩存鹿霸,因此為了避免額外內(nèi)存消耗,不要使用光柵秆乳。

如何檢測(cè)光柵化是否正確使用:(使用真機(jī)調(diào)試)

Xcode->Debug->View Debugging -> Rendering -> color Hits Green and Misses Red.當(dāng)開啟光柵懦鼠,渲染的結(jié)果會(huì)被緩存钻哩,如果圖層為綠色,就表示有渲染緩存可用肛冶;若為紅色街氢,則無(wú),緩存會(huì)被重新創(chuàng)建睦袖,可能引起性能問題珊肃。?

陰影不一定觸發(fā)離屏渲染:

設(shè)置陰影會(huì)觸發(fā)離屏渲染,因?yàn)殛幱疤幱趌ayer下面馅笙,根據(jù)油畫算法伦乔,陰影會(huì)優(yōu)先渲染,但是此時(shí)陰影的本體(layer與其子layer)還沒有組合在一起董习,因此GPU會(huì)開啟新的內(nèi)存烈和,將本體 畫好,再根據(jù)渲染結(jié)果的形狀皿淋,添加陰影到frame buffer,最后將內(nèi)容畫上去招刹。如果預(yù)先告訴Core Animation陰影的形狀,那么陰影可以獨(dú)立渲染出來不依賴本體沥匈。

所以單純?cè)O(shè)置陰影會(huì)觸發(fā)離屏渲染蔗喂,但是設(shè)置了shaowPath將不會(huì)觸發(fā)。

遮罩mask會(huì)觸發(fā)離屏渲染:

mask也是layer類型,但是是覆蓋在layer和其所有子layer組合之上高帖,根據(jù)渲染原理缰儿,屏幕上的每一個(gè)像素點(diǎn)都是當(dāng)前像素點(diǎn)上多個(gè)layer通過GPU混合顏色計(jì)算出來,因此多加一個(gè)mask會(huì)增加GPU計(jì)算難度散址,導(dǎo)致無(wú)法一次性渲染緩存到frame buffer里面乖阵,因此會(huì)觸發(fā)離屏渲染。

抗鋸齒會(huì)觸發(fā)離屏渲染:

當(dāng)view縮放或者旋轉(zhuǎn)會(huì)造成邊框出現(xiàn)鋸齒预麸,在出現(xiàn)鋸齒是時(shí)瞪浸,打開allowsEdgeAntialiasing = YES時(shí),會(huì)將邊框磨平吏祸,而鋸齒的計(jì)算也會(huì)觸發(fā)離屏渲染对蒲。

不透明可能觸發(fā)離屏渲染:

當(dāng)視圖沒有子視圖時(shí),設(shè)置alpha<1,不會(huì)觸發(fā)離屏渲染,當(dāng)有子視圖時(shí)贡翘,因?yàn)镚PU渲染時(shí)蹈矮,除了要渲染子視圖,還需要渲染父視圖的內(nèi)容鸣驱,沒有辦法一步到位泛鸟,所以會(huì)觸發(fā)。

怎么查看項(xiàng)目中是否觸發(fā)離屏渲染踊东?

打來模擬器->Debug->Color Off-screen Rendered

如果所屬區(qū)域被標(biāo)記為黃色就代表觸發(fā)了離屏渲染

離屏渲染的影響北滥?

GPU的操作是高度流水線化的刚操。本來所有計(jì)算工作都在有條不紊地正在向frame buffer輸出,此時(shí)突然收到指令再芋,需要輸出到另一塊內(nèi)存菊霜,那么流水線中正在進(jìn)行的一切都不得不被丟棄,切換到只能服務(wù)于我們當(dāng)前的“切圓角”操作祝闻。等到完成以后再次清空占卧,再回到向frame buffer輸出的正常流程。

在tableView或者collectionView中联喘,滾動(dòng)的每一幀變化都會(huì)觸發(fā)每個(gè)cell的重新繪制,因此一旦存在離屏渲染辙纬,上面提到的上下文切換就會(huì)每秒發(fā)生60次豁遭,并且很可能每一幀有幾十張的圖片要求這么做,對(duì)于GPU的性能沖擊可想而知(GPU非常擅長(zhǎng)大規(guī)模并行計(jì)算贺拣,但是我想頻繁的上下文切換顯然不在其設(shè)計(jì)考量之中)

離屏渲染消耗性能的原因蓖谢?

1、需要?jiǎng)?chuàng)建新的緩沖區(qū)

2譬涡、離屏渲染的整個(gè)過程闪幽,需要多次切換上下文環(huán)境,先是從當(dāng)前屏幕(On-Screen)切換到離屏(Off-Screen)涡匀;等到離屏渲染結(jié)束以后盯腌,將離屏緩沖區(qū)的渲染結(jié)果顯示到屏幕上,又需要將上下文環(huán)境從離屏切換到當(dāng)前屏幕

如何優(yōu)化離屏渲染陨瘩?

1腕够、使用cornerRadius設(shè)置了圓角,能不設(shè)置背景顏色或者borderWidth盡量避免設(shè)置

2舌劳、如果不能避免帚湘,能夠使用圓角圖片的盡量使用圓角圖片,不能避免的可以創(chuàng)建弧形layer蓋住對(duì)應(yīng)角甚淡,視覺上制造圓角效果大诸。

3、設(shè)置陰影贯卦,使用shadowPath來規(guī)避離屏渲染

4资柔、特殊復(fù)雜并且復(fù)用度高的View,使用layer mask并打開shouldRasterize來對(duì)渲染結(jié)果進(jìn)行緩存

參考:?

https://zhuanlan.zhihu.com/p/72653360?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末脸侥,一起剝皮案震驚了整個(gè)濱河市建邓,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌睁枕,老刑警劉巖官边,帶你破解...
    沈念sama閱讀 212,884評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件沸手,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡注簿,警方通過查閱死者的電腦和手機(jī)契吉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來诡渴,“玉大人捐晶,你說我怎么就攤上這事⊥纾” “怎么了惑灵?”我有些...
    開封第一講書人閱讀 158,369評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)眼耀。 經(jīng)常有香客問我英支,道長(zhǎng),這世上最難降的妖魔是什么哮伟? 我笑而不...
    開封第一講書人閱讀 56,799評(píng)論 1 285
  • 正文 為了忘掉前任干花,我火速辦了婚禮,結(jié)果婚禮上楞黄,老公的妹妹穿的比我還像新娘池凄。我一直安慰自己,他們只是感情好鬼廓,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,910評(píng)論 6 386
  • 文/花漫 我一把揭開白布肿仑。 她就那樣靜靜地躺著,像睡著了一般桑阶。 火紅的嫁衣襯著肌膚如雪柏副。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,096評(píng)論 1 291
  • 那天蚣录,我揣著相機(jī)與錄音割择,去河邊找鬼。 笑死萎河,一個(gè)胖子當(dāng)著我的面吹牛荔泳,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播虐杯,決...
    沈念sama閱讀 39,159評(píng)論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼玛歌,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了擎椰?” 一聲冷哼從身側(cè)響起支子,我...
    開封第一講書人閱讀 37,917評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎达舒,沒想到半個(gè)月后值朋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體叹侄,經(jīng)...
    沈念sama閱讀 44,360評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,673評(píng)論 2 327
  • 正文 我和宋清朗相戀三年昨登,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了趾代。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,814評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡丰辣,死狀恐怖撒强,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情笙什,我是刑警寧澤飘哨,帶...
    沈念sama閱讀 34,509評(píng)論 4 334
  • 正文 年R本政府宣布,位于F島的核電站得湘,受9級(jí)特大地震影響杖玲,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜淘正,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,156評(píng)論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望臼闻。 院中可真熱鬧鸿吆,春花似錦、人聲如沸述呐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)乓搬。三九已至思犁,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間进肯,已是汗流浹背激蹲。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評(píng)論 1 267
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留江掩,地道東北人学辱。 一個(gè)月前我還...
    沈念sama閱讀 46,641評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像环形,于是被迫代替她去往敵國(guó)和親策泣。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,728評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容