What is off-screen rendering?
In my previous blog I had a detailed explanation of how images are displayed on the screen, rightportal, here is a brief review:There are three main steps:
- The CPU calculates what needs to be displayed and passes it to the GPU over the data bus
- The GPU takes the data and renders it and stores it in the frame cache
- Then the video controller will follow
VSync
The signal reads the frame buffer line by line and passes through possible digital-to-analog conversion to the display.
Screen rendering can be done in two ways:
-
On-screen Rendering: Current Screen Rendering, which refers to the Rendering operations performed by the GPU in the Screen buffer currently used for display. The current screen rendering displays data directly from the frame cache and displays it directly.
-
Off-screen Rendering refers to when the GPU creates a new buffer (off-screen cache) outside the current Screen buffer to render. After all data is rendered in the off-screen render area, it is submitted to the frame cache and then displayed.
-
In addition, if all off-screen rendering is called off-screen rendering, there is a special kind of off-screen rendering:
CPU rendering: If we overwrite the drawRect method and draw using any Core Graphics technology, CPU rendering is involved. The whole rendering process is completed synchronously by CPU in App, and the rendered bitmap is finally handed over to GPU for display.
CoreGraphic is usually thread-safe, so it can be drawn asynchronously and then put back into the main thread when displayed. A simple asynchronous drawing process looks like this:
-(void)display { dispatch_async(backgroundQueue, ^{ CGContextRef ctx = CGBitmapContextCreate(...) ; // draw in context... CGImageRef img = CGBitmapContextCreateImage(ctx); CFRelease(ctx); dispatch_async(mainQueue, ^{ layer.contents = img; }); }); }Copy the code
Second, the cause of off-screen rendering trigger
- # # # 1. Use
mask
thelayer
(layer.mask
);
When mask is used, the contents of mask and layer are drawn separately and put into the off-screen cache area, and then mixed into the frame cache area, and then displayed.
- ###2. Need to be trimmed
layer
(layer.masksToBounds / view.clipsToBounds)
(Use with rounded cornerslayer.masksToBounds / view.clipsToBounds
) :
The following figure forCALayer
Structure diagram of
If you just use layer.cornerradius:
layer.cornerRadius = 4;
Copy the code
Only backguroundColor and border rounded, not content rounded, unless layer.masksToBounds or view.clipsToBounds are set:
Layer. masksToBounds = YES; layer.masksToBounds = YES; view.clipsToBounds = YES;Copy the code
This is when an off-screen render is triggered, so it’s not necessarily multiple levels that trigger an off-screen render.
- ###3. Set group transparency to
YES
, and the transparency is not 1layer(layer.allowsGroupOpacity/ layer.opacity)
(note group transparency); - ###4
layer (layer.shadow)
; - ###5. Rasterized
layer (layer.shouldRasterize)
:
ShouldRasterize: shouldRasterize: shouldRasterize
When the value of this property is
YES
, the layer is rendered as a bitmap in its local coordinate space and then composited to the destination with any other content.
When this property is enabled, the layer is rendered as a bitmap and stored until all the content to be displayed has been rendered and mixed before it can be displayed on the screen. Where do you put the layer bitmap and other rendered content? Can only be placed in the off-screen cache, so rasterization also triggers off-screen rendering.
ShouldRasterize is recommended as follows:
-
If layer cannot be reused, there is no need to turn on rasterization;
-
If layer is not static, it needs to be modified frequently, such as in animation. In this case, turning on rasterization actually affects efficiency. For example, we often deal with the TableViewCell in our schedule, because the Redrawing of TableViewCell is very frequent (because of Cell reuse), if the content of the Cell changes constantly, the Cell needs to be redrawn constantly, if the Cell. Layer can be rasterized at this time. It will cause a lot of off-screen rendering and reduce the graphics performance.
-
Off-screen rendering cache content is time-limited. If cached content is not used within 100ms, it will be discarded and cannot be reused.
-
Off-screen rendering has limited cache space and will fail beyond 2.5 times the screen pixel size and cannot be reused.
-
###6. Layer (UILabel, CATextLayer, Core Text, etc.) with Text drawn
Why use off-screen rendering?
The frame cache only holds the display content temporarily, and when it is displayed on the screen, it is discarded. But when using rounded, shadows, mask, the layer properties of mixture was designated as before not pre synthesis is not directly drawn in the screen, that is unable to render a complete display directly, so we need to build a new screen rendering, use an off-screen buffer to save content in batches, wait for after completion of all of the content rendering again to the frame buffer, For display. Off-screen rendering does not mean software rendering, but it does mean that layers must be rendered in an off-screen context (whether CPU or GPU) before they can be displayed. Off-screen rendering is expensive compared to the current screen rendering, mainly in two ways:
- Create a new buffer: To render off-screen, first create a new buffer.
- Context switch: The whole process of off-screen rendering requires multiple context changes: first, from the current Screen (on-screen) to off-screen (off-screen); After the off-screen rendering is complete, the rendering results of the off-screen buffer are displayed on the screen. It is necessary to switch the context from off-screen to the current screen. Context switching is costly.
Remember to like it if you think it’s good! I heard that the people who read the praise will meet the test, meet the prize will be in. ღ(´ · ᴗ · ‘)