APP -> FrameBuffer -> Display緩存
APP -> offscreenBuffer -> FrameBuffer -> Displayapp
mask layer 渲染完畢,不能單獨當即顯示,要等待 contents layer 渲染完畢進行混合,等待過程當中,先存在 離屏渲染緩衝區。
等待內容都渲染完畢,傳遞到 幀緩衝區,等待顯示。優化
app 進行額外的渲染和合並 -> offscreenBuffer 組合 -> FrameBuffer -> Display動畫
離屏渲染空間限制:屏幕的 2.5 倍ui
一、獲取圖像 -> Render Content
二、縮放處理 -> Capture Content
三、水平毛玻璃 -> Horizontal Blur Content
四、垂直毛玻璃 -> Vertical Blur Content
五、合成 -> Compositing Content
六、輸出到 FrameBufferspa
因爲兩個 幀緩衝區 空間有限,因此不能存在 幀緩衝區。
處理過程當中的 content 存儲在 offscreenBuffer。code
開啓光柵化,layer 渲染爲位圖後, 會保存在緩衝區,能夠複用在其餘內容。orm
不建議開啓的場景:cdn
layer 渲染的時候分爲三層 blog
文檔顯示:
layer.cornerRadius 只會設置 backgroundColor 和 border 的圓角。不會設置 contents 的圓角。
除非同時設置了 layer.masksToBounds 爲 YES(對應 view.clipsToBounds)。
簡單理解:
layer.cornerRadius 會修改 backgroundColor 和 border 兩個圖層。
layer.masksToBounds 會讓上述切圓角擴張到修改 contents 圖層,子視圖的圖層也在這裏。 此時,繪製完 backgroundColor 層後,須要暫存到 offscreenBuffer,等待 contents 層渲染完畢,再進行 裁剪操做,而後輸出到 FrameBuffer。這就是就是離屏渲染。
UIButton *btn1 = [UIButton buttonWithType:UIButtonTypeCustom];
btn1.frame = CGRectMake(100, 30, 100, 100);
btn1.layer.cornerRadius = 50;
[self.view addSubview:btn1];
btn1.clipsToBounds = YES;
[btn1 setImage:[UIImage imageNamed:@"btn.png"] forState:UIControlStateNormal];
複製代碼
解析
設置 image 後,觸發離屏渲染。
若是不設置 image, contents = nil,系統進行了優化, 不用切圓角,所以直接對 backgroundColor 層操做後,輸出到 FrameBuffer 便可。
// UIImageView 設置了切圓角,設置了背景色,設置了圖片
UIImageView *img1 = [[UIImageView alloc]init];
img1.frame = CGRectMake(100, 320, 100, 100);
[self.view addSubview:img1];
img1.layer.cornerRadius = 50;
img1.layer.masksToBounds = YES;
img1.backgroundColor = [UIColor blueColor];
img1.image = [UIImage imageNamed:@"btn.png"];
複製代碼
解析
若是不設置 backgroundColor,不會觸發離屏渲染。
由於 backgroundColor 圖層爲空,不要渲染,所以,只須要對 contents 層操做後,輸出到 FrameBuffer 便可。
// UIImageView 設置了切圓角,沒有設置背景色,可是加了一個子視圖
UIImageView *img2 = [[UIImageView alloc]init];
img2.frame = CGRectMake(100, 480, 100, 100);
[self.view addSubview:img2];
img2.layer.cornerRadius = 50;
img2.layer.masksToBounds = YES;
UIView *subView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];
subView.backgroundColor = [UIColor redColor];
[img2 addSubview:subView];
複製代碼
解析
案例二中,若是沒有背景色,img2.layer.contents 直接是位圖,能夠直接裁剪,輸出到 FrameBuffer。
可是案例三中,img2.layer.contents 實際上是子視圖的渲染出來的位圖,若是要給 contents 加圓角,則必須等待子視圖渲染完成,存到 offscreenBuffer,而後再對緩衝區中的渲染結果進行裁剪,所以產生了離屏渲染。
案例二中,UIImageView 不設置背景色,只設置 image,就不會觸發背景色。
那爲何在案例一中,UIButton 只是設置了 image,沒有設置背景色,卻觸發了離屏渲染呢?
實際上是由於 UIButton 設置 image 的時候,是把 image 添加到了 UIButton 的一個 UIImageView 子視圖上,就變成了案例三的這種狀況,會觸發離屏渲染。
離屏渲染本質:要等待對多個非空圖層的渲染結果進行操做,過程當中的圖層須要儲存起來,這個存儲位置就是 offscreenBuffer(離屏渲染緩衝區),整個過程就叫作離屏渲染。
// UIImageView 設置了切圓角,不設置背景色
imageView.backgroundColor = [UIColor clearColor];
imageView.layer.cornerRadius = 50;
imageView.layer.masksToBounds = YES;
複製代碼
UI 切圖帶圓角
使用 貝塞爾曲線,裁剪 UIImage,繪製一個帶圓角的 UIImage。
增長一個帶圓角,中間鏤空的切圖,蓋在須要圓角的視圖上面。