假設(shè)一個(gè)開(kāi)發(fā)需求,需要你把頭像圖片設(shè)置成圓形,可能你會(huì)毫不猶豫的在鍵盤(pán)上啪啪啪的敲出下面的代碼:
self.iconView.layer.cornerRadius = self.iconView.height;
self.iconView.layer.masksToBounds = YES;
告訴你很不幸的是,此時(shí)你已經(jīng)觸發(fā)了離屏渲染
GPU屏幕渲染的方式有兩種
-
<a name="fenced-code-block"> On-Screen Rendering(當(dāng)前屏幕的渲染)</a>
GPU的渲染操作是在當(dāng)前用于顯示的屏幕緩沖區(qū)進(jìn)行。
-
<a name="fenced-code-block"> Off-Screen Rendering(離屏渲染)</a>
當(dāng)使用到圓角,陰影,遮罩的時(shí)候,圖層屬性的混合體被指定為在沒(méi)有預(yù)合成之前不能直接在屏幕中繪制,GPU在當(dāng)前的屏幕緩沖區(qū)之外開(kāi)辟一個(gè)緩沖區(qū),渲染到紋理,最后將結(jié)果渲染到
幀緩沖區(qū)。這會(huì)導(dǎo)致在兩個(gè)緩沖區(qū)之間進(jìn)行切換,由于離屏渲染在每一幀都會(huì)發(fā)生,所以在滾動(dòng)界面的時(shí)候,如果有大量的離屏渲染就會(huì)嚴(yán)重影響幀率。
不要小看這個(gè)上下文的切換,它對(duì)性能的影響是挺大的,所有的內(nèi)存訪問(wèn)都是比較慢的,CPU/GPU可以很輕松的完成每秒以?xún)|為單位的運(yùn)算,但是內(nèi)存只能以百萬(wàn)為單位。
還有一種比較特殊的渲染,就是CPU渲染,如果我們重寫(xiě)了drawRect方法,并且使用任何的Core Graphics的技術(shù)進(jìn)行繪制,就涉及到了CPU渲染,整個(gè)渲染過(guò)程同步完成,渲染結(jié)束得到的bitmap給GPU用來(lái)顯示。注意的是,Core Graphics通常是線程安全的,可以異步繪制,然后放到主線程進(jìn)行顯示
在蘋(píng)果公開(kāi)的資料中提到,涉及到離屏渲染的操作有:mask, shadow, cornerRadius
Instrument中的Core Animation工具有一個(gè)Color Offscreen-Rendered Yellow的選項(xiàng),它會(huì)將已經(jīng)被渲染到屏幕外緩沖區(qū)的區(qū)域標(biāo)記為黃色

