iOS 離屏渲染 1. 什麼是離屏渲染? 2. 離屏渲染檢測方法 3. 什麼情況下會觸發離屏渲染? 4. 離屏渲染存在的問題

1. 什麼是離屏渲染?

iOS 中對於圖層的繪製遵循“畫家算法”,對於疊加了多個 layer 的圖形,會先繪製最底層的 layer,最後繪製頂部的 layer,底層的 layer 會被上層的覆蓋。

一般情況下,圖層被渲染完成後,會放入幀緩衝區,並依次顯示在屏幕上。但對於某些特殊的圖片數據,無法通過疊加圖層的方法來達到預期效果。而當某些圖片數據較複雜,無法一次性完成渲染時,會將每一步渲染的結果放入離屏緩衝區,最後組合渲染成所需要的效果,這就是離屏渲染。

2. 離屏渲染檢測方法

勾選 Simulater -> Debug -> Color Off-screen Rendered,應用中產生離屏渲染的 view 會有淺黃色背景。


3. 什麼情況下會觸發離屏渲染?

3.1 圖片 + 背景色 + 圓角

按照“畫家算法”,背景色和圖片會依次渲染併疊加顯示。但由於設置了圓角,且此時前兩個圖層已經顯示在了屏幕上,不能對邊角進行裁剪處理,無法達到圓角效果。此時,需要在各個圖層顯示在屏幕前,暫存於各個臨時開闢的空間(離屏緩衝區),待所有圖層渲染完成後,再一起進行圓角裁剪處理,最後顯示在屏幕上。

// 離屏渲染示例代碼:
UIImageView *imageView1 = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
imageView1.image = [UIImage imageNamed:@"avatar"];
imageView1.backgroundColor = [UIColor blueColor];
imageView1.layer.cornerRadius = CGRectGetWidth(imageView1.bounds) / 2.0f;
imageView1.layer.masksToBounds = YES; // 或 imageView1.clipsToBounds = YES;
[self.view addSubview:imageView1];

3.2 開啓了 shouldRasterize

關於 shouldRasterize,蘋果官方文檔解釋如下:

When the value of this property is true, the layer is rendered as a bitmap in its local coordinate space and then composited to the destination with any other content.

即爲 true 時,設置了該屬性的 layer 會被渲染成位圖。一般情況下,如果某個view 視圖層級較爲複雜,且需要不斷複用或產生動畫效果,可以將其 layer 的該屬性設置爲 true 以避免頻繁重複渲染,提升性能。

3.3 mask(遮罩)

- (void)viewDidLoad {
    [super viewDidLoad];
    // mask
    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 100)];
    view.backgroundColor = [UIColor redColor];
    view.center = self.view.center;
    [self.view addSubview:view];
    
    CALayer *maskLayer = [CALayer layer];
    maskLayer.frame = view.bounds;
    UIImage *maskImage = [UIImage imageNamed:@"2020"];
    maskLayer.contents = (__bridge id)maskImage.CGImage;
    view.layer.mask = maskLayer;
}

3.4 其它

設置高斯模糊、陰影、組透明度等。

4. 離屏渲染存在的問題

4.1 需要開闢額外的存儲空間(最大不能超過),容易產生性能問題;
4.2 渲染時間增加,容易導致掉幀;
4.3 離屏緩衝區空間最大不能超過屏幕像素大小的 2.5 倍,且渲染完後 100ms 內沒有被使用時會被丟棄,無法複用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章