What is off-screen rendering
Off-screen Rendering refers to off-screen Rendering, when the GPU creates a new buffer in addition to the current Screen buffer to render
Why do I need to render off-screen
Because rendering a view to the screen in the frame buffer is discarded. So when we have multiple sets of views that need to be combined and then processed uniformly. You need to create an additional off-screen buffer in the screen buffer to record these views. Then unified processing. Finally rendering display
How do I create an off-screen render
Let’s first analyze the off-screen rendering of rounded corners:
To recap, when we add a cornerRadius to a view. Which views are rounded?Copy the code
Apple’s official answer:
Setting the radius to a value greater than 0.0 causes the layer to begin drawing rounded corners on its background.by Default, the corner radius does not apply to the image in the layer’s contents property; it applies only to the background color and border of the layer. However, setting the masksToBounds property to YES causes the content to be clipped to the rounded corners.The default value of This property is 0.0.
That is, the background view and the border view, does not containcontents
View. So when we just setcornerRadius
Is not setmasksToBounds
For YES. The view still does not have rounded corners visually
Then we rounded corners in the following four cases: A. Set pictures in the button view. And set the cornerRadius and cropped masksToBounds. B. Button view does not set images. Set the cornerRadius and cropped masksToBounds. C. The image view does not set the background color. Set the cornerRadius and cropped masksToBounds. D. Image view sets the background color. Set the cornerRadius and cropped masksToBounds. Produces an off-screen rendering
The relevant codes are as follows:
UIButton * btn1 = [UIButton buttonWithType:(UIButtonTypeCustom)]; btn1.frame = CGRectMake(100, 30, 100, 100); [btn1 setImage:[UIImage imageNamed:@"WX20201127-92813"] forState:UIControlStateNormal]; [self.view addSubview:btn1]; btn1.layer.cornerRadius = 50; btn1.layer.masksToBounds = YES; UIButton * btn2 = [UIButton buttonWithType:(UIButtonTypeCustom)]; btn2.frame = CGRectMake(100, 150, 100, 100); btn2.backgroundColor = UIColor.grayColor; [self.view addSubview:btn2]; btn2.layer.cornerRadius = 50; btn2.layer.masksToBounds = YES; // For images. Setting the background color and image creates an off-screen rendering. UIImageView * img1 = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@" wx20201127-92813 "]]; img1.frame = CGRectMake(100, 270, 100, 100); img1.backgroundColor = UIColor.blueColor; img1.layer.cornerRadius = 50; img1.layer.masksToBounds = YES; [self.view addSubview:img1]; UIImageView * img2 = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"WX20201127-92813"]]; img2.frame = CGRectMake(100, 390, 100, 100); img2.layer.cornerRadius = 50; img2.layer.masksToBounds = YES; [self.view addSubview:img2];Copy the code
The effect is as follows:
So when does an off-screen rendering happen? The superficial conclusions we draw are:
2. Image view rounded after adding background color and imageCopy the code
Next, we will improve img2: Adding no background color to tempView will not produce an off-screen rendering. Adding a background color to the tempView will still result in an off-screen rendering
UIImageView * img3 = [[UIImageView alloc]init];
img3.frame = CGRectMake(100, 510, 100, 100);
img3.layer.cornerRadius = 50;
img3.layer.masksToBounds = YES;
[self.view addSubview:img3];
UIView *tempView = [[UIView alloc]init];
tempView.backgroundColor = UIColor.redColor;
tempView.frame = img3.bounds;
[img3 addSubview:tempView];
Copy the code
From this we can know: when we need to combine multiple layers, we need to use the off-screen rendering technology. After rendering multiple layers, place them in the frame buffer. Display to the screen
The thing to notice is that this is the combination. Not superposition.Copy the code
So what are some of the views that we normally use that are combinations. And need to do an off-screen rendering?
2. Mask mask 3. Raster 4. Set transparency for combined view 5. Gradient 7. Draw text 8. System ground glass effectCopy the code
How to avoid off-screen rendering?
1. Off-screen rendering for rounded corners. We can adopt four solutions: a. Cover it with a hollow view with rounded corners B. Use the rounded corner method in YYImage C. Use CALayer with UIBezierPath
UIGraphicsBeginImageContextWithOptions(size, false, scale) UIBezierPath.init(roundedRect: imgRect, cornerRadius: self.layer.cornerRadius).addClip() self.image? .draw(in: imgRect) self.image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext()Copy the code
2. If the view cannot be reused. It is not static. It is not recommended to enable rasterization when frequent modifications are required. Because this will turn on the off-screen rendering and affect efficiency 3. Use transparency as little as possible or not 4. Draw asynchronously. Reduce layers
Off-screen rendering cache content has a time limit. Cache content 100ms of content if not in use. Then it will be discarded. 2. Cache space for off-screen rendering is limited. More than 2.5 screen pixels. It’s not going to work. It’s not going to be reusable