1. 程式人生 > >離屏渲染(圖層性能 15.2)

離屏渲染(圖層性能 15.2)

end 指定 性能 希望 idl 一個 aps 性能問題 main

離屏渲染

當圖層屬性的混合體被指定為在未預合成之前不能直接在屏幕中繪制時,屏幕外渲染就被喚起了。屏幕外渲染並不意味著軟件繪制,但是它意味著圖層必須在被顯示之前在一個屏幕外上下文中被渲染(不論CPU還是GPU)。圖層的以下屬性將會觸發屏幕外繪制:

  • 圓角(當和maskToBounds一起使用時)
  • 圖層蒙板
  • 陰影

屏幕外渲染和我們啟用光柵化時相似,除了它並沒有像光柵化圖層那麽消耗大,子圖層並沒有被影響到,而且結果也沒有被緩存,所以不會有長期的內存占用。但是,如果太多圖層在屏幕外渲染依然會影響到性能。

有時候我們可以把那些需要屏幕外繪制的圖層開啟光柵化以作為一個優化方式,前提是這些圖層並不會被頻繁地重繪。

對於那些需要動畫而且要在屏幕外渲染的圖層來說,你可以用CAShapeLayercontentsCenter或者shadowPath來獲得同樣的表現而且較少地影響到性能。

CAShapeLayer

cornerRadiusmaskToBounds獨立作用的時候都不會有太大的性能問題,但是當他倆結合在一起,就觸發了屏幕外渲染。有時候你想顯示圓角並沿著圖層裁切子圖層的時候,你可能會發現你並不需要沿著圓角裁切,這個情況下用CAShapeLayer就可以避免這個問題了。

你想要的只是圓角且沿著矩形邊界裁切,同時還不希望引起性能問題。其實你可以用現成的UIBezierPath的構造器+bezierPathWithRoundedRect:cornerRadius:

(見清單15.1).這樣做並不會比直接用cornerRadius更快,但是它避免了性能問題。

清單15.1 用CAShapeLayer畫一個圓角矩形

技術分享
 1 #import "ViewController.h"
 2 #import 
 3 
 4 @interface ViewController ()
 5 
 6 @property (nonatomic, weak) IBOutlet UIView *layerView;
 7 
 8 @end
 9 
10 @implementation ViewController
11 
12 - (void)viewDidLoad
13 {
14
[super viewDidLoad]; 15 16 //create shape layer 17 CAShapeLayer *blueLayer = [CAShapeLayer layer]; 18 blueLayer.frame = CGRectMake(50, 50, 100, 100); 19 blueLayer.fillColor = [UIColor blueColor].CGColor; 20 blueLayer.path = [UIBezierPath bezierPathWithRoundedRect: 21 CGRectMake(0, 0, 100, 100) cornerRadius:20].CGPath; 22 ? 23 //add it to our view 24 [self.layerView.layer addSublayer:blueLayer]; 25 } 26 @end
View Code

可伸縮圖片

另一個創建圓角矩形的方法就是用一個圓形內容圖片並結合第二章『寄宿圖』提到的contensCenter屬性去創建一個可伸縮圖片(見清單15.2).理論上來說,這個應該比用CAShapeLayer要快,因為一個可拉伸圖片只需要18個三角形(一個圖片是由一個3*3網格渲染而成),然而,許多都需要渲染成一個順滑的曲線。在實際應用上,二者並沒有太大的區別。

清單15.2 用可伸縮圖片繪制圓角矩形

技術分享
 1 @implementation ViewController
 2 
 3 - (void)viewDidLoad
 4 {
 5     [super viewDidLoad];
 6 
 7     //create layer
 8     CALayer *blueLayer = [CALayer layer];
 9     blueLayer.frame = CGRectMake(50, 50, 100, 100);
10     blueLayer.contentsCenter = CGRectMake(0.5, 0.5, 0.0, 0.0);
11     blueLayer.contentsScale = [UIScreen mainScreen].scale;
12     blueLayer.contents = (__bridge id)[UIImage imageNamed:@"Circle.png"].CGImage;
13     //add it to our view
14     [self.layerView.layer addSublayer:blueLayer];
15 }
16 @end
View Code

使用可伸縮圖片的優勢在於它可以繪制成任意邊框效果而不需要額外的性能消耗。舉個例子,可伸縮圖片甚至還可以顯示出矩形陰影的效果。

shadowPath

在第2章我們有提到shadowPath屬性。如果圖層是一個簡單幾何圖形如矩形或者圓角矩形(假設不包含任何透明部分或者子圖層),創建出一個對應形狀的陰影路徑就比較容易,而且Core Animation繪制這個陰影也相當簡單,避免了屏幕外的圖層部分的預排版需求。這對性能來說很有幫助。

如果你的圖層是一個更復雜的圖形,生成正確的陰影路徑可能就比較難了,這樣子的話你可以考慮用繪圖軟件預先生成一個陰影背景圖。

離屏渲染(圖層性能 15.2)