preface
Many Android developers often ask me, what do I need to learn to be a good Android engineer? Their descriptions vary somewhat, but in general, we all need to learn a set of skills to be a good Android engineer.
In my opinion, such confusion is normal. Android is a large and dynamic ecosystem, and it can take weeks to get to know and learn about its tools and concepts, but many of them are not very important or very useful in the end. So, in this article, I’m going to share some of the key skills I’ve used in Android development that I hope will help you focus your mind on what’s important.
So today, I’m going to present the Android Knowledge Map, which I hope you’ll enjoy, based on my own experience and what I’ve seen and heard.
Two, display the basic knowledge of the system
In a typical Display system, there are generally three parts: CPU, GPU and Display. CPU is responsible for calculating frame data and handing the calculated data to GPU, which will render the graphics data and store it in buffer(image buffer) after rendering. Then the Display (screen or Display) is responsible for rendering the data in the buffer onto the screen. The diagram below:
2.1 Basic Concepts
-
Screen refresh Frequency The number of screen refreshes in a second (how many frames of images are displayed in a second), in Hz (Hertz), such as the common 60 Hz. The refresh rate depends on the hardware’s fixed parameters (which do not change).
-
Instead of showing an image on the screen all at once, a progressive scan displays pixels of the entire screen in sequence from left to right and top to bottom, though the process is too fast for the human eye to notice the change. Taking a screen with a refresh rate of 60 Hz as an example, this process is 1000/60 ≈ 16ms.
-
Frame Rate refers to the number of frames drawn by a GPU in one second (unit: FPS). In the movie industry, for example, 24 frames is enough to make the picture run very smoothly. Android, on the other hand, has a more fluid 60 FPS, meaning the GPU can draw up to 60 frames per second. The frame rate changes dynamically. For example, when the picture is still, there is no drawing operation on GPU, and the screen refreshes the data in buffer, that is, the last frame data operated by GPU.
-
Tearing data across a screen has come from two different frames and will cause a tearing sensation, as shown in the image below
2.2 double cache
2.2.1 Causes of picture tearing
The screen refresh frequency is fixed, for example, every 16.6ms to display a frame from the buffer. Ideally, the frame rate and refresh frequency are consistent, that is, every frame drawn, the monitor displays a frame. However, CPU/GPU writing data is uncontrollable, so some data in the buffer will be rewritten before it is displayed at all, that is, the data in the buffer may come from different frames. When the screen is refreshed, it does not know the state of the buffer, so the frame captured from the buffer is not a complete frame. That is, the picture is torn.
To put it simply, during the Display process, the data in the buffer is modified by CPU/GPU, causing the picture to tear.
2.2.2 double cache
So how do you fix the tear? The answer is to use dual caching.
Since the same buffer is used to draw the image and read the screen, it is possible to read an incomplete frame when the screen is refreshed.
Dual cache, so that draw and display have their own buffer: The GPU always writes a completed Frame of image data to the Back Buffer, whereas the display uses the Frame Buffer. The Frame Buffer does not change when the screen refreshes, and they swap when the Back Buffer is ready. The diagram below:
2.2.3 VSync
The question arises again: when should two buffers be swapped?
If the Back buffer is intended to run after a frame has been completed, it will cause problems if the screen has not fully displayed the previous frame. It seems that you can only do this after the screen has processed a frame of data.
When a screen is scanned, the device needs to go back to the first row to enter the next cycle, with a time gap called the VerticalBlanking Interval(VBI). So, this point in time is the perfect time for us to swap buffers. Because the screen is not tearing, we have avoided a Screen tearing situation during the swap.
VSync, short for Vertical synchronization, uses the VerticalSync Pulse that emerged during the VBI era to ensure that dual buffers are exchanged at the optimal point in time. In addition, the swap refers to the respective memory address, which can be considered instantaneous.
So The concept of V-Sync wasn’t invented by Google. It was invented in the early days of the PC.
3. Android screen refresh mechanism
3.1 Problems before Android4.1
In Android, before Android4.1, the screen refresh also follows the dual-cache +VSync mechanism described above. The diagram below:
Take a look at what will happen in chronological order:
- Display displays the data of frame 0. At this time, CPU and GPU render the picture of frame 1 and finish it before Display displays the next frame
- Because rendering is timely, after Display is finished on frame 0, after VSync 1, the cache is swapped and then frame 1 is displayed normally
- Frame 2 is then processed, not until the second VSync is about to arrive.
- When the second VSync comes, frame 1 is still displayed because frame 2 is not ready and the cache is not swapped. This situation, named “Jank” by the Android development team, occurs when frames are lost.
- When frame 2 data is ready, it will not be displayed immediately, but will wait for the next VSync to cache swap.
So basically, the screen is showing frame 1 one more time for no reason.
The reason is that the CPU/GPU calculation for frame 2 was not completed before the VSync signal arrived.
As we know, the exchange of double cache is carried out when Vsyn arrives. After the exchange, the screen will take the new data in the Frame buffer, and the Back buffer at this time can be used by GPU to prepare the next Frame data. If the CPU/GPU starts running when Vsyn arrives, there is a full 16.6ms, which should basically avoid Jank (unless CPU/GPU calculations go beyond 16.6ms). So how do you make CPU/GPU calculations happen when Vsyn comes?
3.2 drawing with VSync
In order to optimize Display performance, Google has reconfigured the Android Display system in Android 4.1 to implement Project Butter: The system will immediately start rendering the next frame after receiving the VSync Pulse. As soon as the VSync notification is received (triggered every 16ms), the CPU and GPU immediately start calculating and writing data to buffer. The diagram below:
The CPU/GPU synchronizes data processing according to VSYNC signal, allowing the CPU/GPU to have a complete 16ms time to process data, reducing jank.
In summary, VSync synchronization allows the CPU/GPU to take full advantage of 16.6ms time, reducing jank.
Again, what if the interface is complex and the CPU/GPU processing time is longer than 16.6ms? The diagram below:
- In the second period, the GPU was still processing B frame, so the cache could not be exchanged, resulting in the repeated display of A frame.
- After B completes, it has to wait for the next signal because it lacks the VSync pulse signal. So in the process, a lot of time is wasted.
- When the next VSync occurs, the CPU/GPU immediately performs the operation (frame A), and the cache is swapped, and the corresponding display corresponds to B. It seems normal at this point. Just because of the execution time is still more than 16 ms, lead to the next should perform the buffer exchange was delayed, so repeated again, then there are more and more “Jank”.
Why can’t the CPU handle the drawing work in the second 16ms?
The reason is that there are only two buffers. The Back buffer is being used by THE GPU to process the data of Frame B, and the content of the Frame buffer is used for Display Display. In this way, both buffers are occupied, and the CPU cannot prepare the data of the next Frame. Then, if another buffer is provided, the CPU, GPU, and display device can all use their own buffer without affecting each other.
3.3 three cache
Three-buffer is to add a Graphic Buffer on the basis of double Buffer mechanism, so as to maximize the use of idle time, the disadvantage of using more than one Graphic Buffer occupied memory.
-
The first Jank was unavoidable. However, in the second 16ms period, CPU/GPU used the third Buffer to complete the calculation of C frame. Although A frame would still be displayed once more, the subsequent display would be relatively smooth, effectively avoiding the further aggravation of Jank.
-
Note that in paragraph 3, the calculation of frame A is complete, but it is not shown until the fourth vsync comes, or if it is double-buffered, it is shown at the third VYNSC.
Triple buffering makes good use of the time spent waiting for vYSNC, reducing jank but bringing latency. So, is more Buffer better? This is negative. Two buffers are normal, but three are enough after Jank appears.
That’s how the Android screen refresh works.
The last
Those who want to learn more about the interview can ** click here to get the Interview Documentation for free ** In addition, I also share some free quality resources, including: Android learning PDF+ architecture video + source notes, advanced architecture technology advanced brain map, Android development interview topic information, advanced architecture information this several pieces of content. Share with you, very suitable for the recent interview and want to continue to advance in the technical path of friends. Come and get the learning materials