關於layer.cornerRadius的離屏渲染問題

案例解讀

在咱們平常開發過程當中 ,常常使用layer.cornerRadius的方式來設置圓角。那到底會不會帶來離屏渲染呢 。今天咱們來研究一下。 下面是幾個不一樣形式的layer.cornerRadius圓角案例緩存

//1.按鈕存在背景圖片
    UIButton *btn1 = [UIButton buttonWithType:UIButtonTypeCustom];
    btn1.frame = CGRectMake(100, 30, 100, 100);
    btn1.layer.cornerRadius = 50;
    [self.view addSubview:btn1];
    btn1.backgroundColor = [UIColor blueColor];
    [btn1 setImage:[UIImage imageNamed:@"btn.png"] forState:UIControlStateNormal];
    btn1.clipsToBounds = YES;
    
    //2.按鈕不存在背景圖片
    UIButton *btn2 = [UIButton buttonWithType:UIButtonTypeCustom];
    btn2.frame = CGRectMake(100, 180, 100, 100);
    btn2.layer.cornerRadius = 50;
    btn2.backgroundColor = [UIColor blueColor];
    [self.view addSubview:btn2];
    btn2.clipsToBounds = YES;
    
    //3.UIImageView 設置了圖片+背景色;
    UIImageView *img1 = [[UIImageView alloc]init];
    img1.frame = CGRectMake(100, 320, 100, 100);
    img1.backgroundColor = [UIColor blueColor];
    [self.view addSubview:img1];
    img1.layer.cornerRadius = 50;
    img1.layer.masksToBounds = YES;
    img1.image = [UIImage imageNamed:@"btn.png"];
    
    //4.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;
    img2.image = [UIImage imageNamed:@"btn.png"];
複製代碼

運行的效果如圖所示bash

首先開啓模擬器的離屏渲染檢測app

結果顯示 性能

由上圖能夠看出,並非使用了 layer.cornerRadius就必定會產生離屏渲染。 其產生的緣由有以下幾個 :

  • 當圖片大小比UIImageView的大小要大,而且clipsToBounds設置的屬性爲true,這時候,會產生 圖片的裁剪。就會產生離屏渲染。
  • 有背景顏色和背景圖片一塊兒渲染。我的理解爲,有背景顏色 和和背景圖片 都包含 ,會產生不一樣的層次。於是會產生離屏渲染。

離屏渲染原理 app 爲了提升渲染效率 ,開闢了 offscreen BufferFrameBuffer 兩個緩衝區,目的是爲了以空間換取時間。提早進行渲染(offscreenBuffer)能夠提升複用目的 還有在特殊效果時 ,屏幕須要使用額外的offscreen Buffer 來保存中間狀態,不得不使用離屏渲染,如圓角、陰影。 , 可是離屏渲染渲染也會帶來性能問題--容易掉幀. 離屏渲染產生的緣由主要有兩方面:優化

1.在VSync(垂直脈衝)信號做用下,視頻控制器每隔16.67ms就會去幀緩衝區(當前屏幕緩衝區)讀取渲染後的數據;可是有些效果被認爲不能直接呈現於屏幕前,而須要在別的地方作額外的處理,進行預合成。ui

好比圖層屬性的混合體再沒有預合成以前不能直接在屏幕中繪製,因此就須要屏幕外渲染。屏幕外渲染並不意味着軟件繪製,可是它意味着圖層必須在被顯示以前必須在一個屏幕外上下文中被渲染(不論CPU仍是GPU)。spa

2.有些視圖渲染後的紋理須要被屢次複用,但屏幕內的渲染緩衝區是實時更新的,因此須要經過開闢屏幕外的渲染緩衝區,將視圖的內容渲染成紋理並緩存,而後再須要的時候在調入屏幕緩衝區,能夠避免屢次渲染的開銷。code

典型的例子就是光柵化。光柵化就是經過把視圖的內容渲染成紋理並緩存,等到下次調用的時候直接去緩存的取出紋理,可是更新內容時候,會啓用離屏渲染,因此更新的代價比較大,只能用於靜態內容;並且若是光柵化的元素100ms沒有被使用,也將被移除,故而不經常使用元素的光柵化並不會優化顯示。orm

注意:光柵化的元素,總大小限制爲2.5倍的屏幕。cdn

相關文章
相關標籤/搜索