Guide language: in the process of testing fluency, it is necessary to contact with FPS, Jank and other indicators, but in order to deepen understanding, today to simply pick a pick android rendering principle; PerfDog uses Jank as an indicator to represent the game’s fluency. Details can be found in APP& Should the game pay attention to Jank?

I. CPU and GPU structure

Most mobile devices now have cpus (central processing units) and Gpus (graphics processing units), and some now have an NPU for smart computing. Take a quick look at their structure;

The green ones are computing units (ALUs), the orange-red ones are storage units, and the orange-yellow ones are control units. The CPU needs to be very versatile to deal with different data types, and at the same time to carry out complex mathematical and logical operations, so the internal structure of the CPU is extremely complex. CPU is the Cache occupies a lot of space, there are many complicated control logic and the optimization of circuit, actually only a small part of CPU computing power, in the early days, CPU besides doing logic calculation, is also responsible for memory management, graphical display and operation in the actual operation performance will be discounted, but also unable to display complex graphics, Completely inadequate to meet the requirements of today’s 3D games; So the GPU came into being. On the other hand, GPU is faced with large-scale data with highly unified type and no mutual dependence and pure computing environment that does not need to be interrupted, so the structure is quite different. GPU adopts a large number of computing units and long pipeline, but only has very simple control logic and eliminates Cache. GPU converts and drives the display information required by the computer system, provides row scanning signals to the display, controls the correct display of the display, and is mainly responsible for the work of graphics display.

Ii.Android system drawing mechanism

Now Android terminal usually in a typical display system, the CPU first issued the image drawing instruction to let THE GPU to draw a style, but the CPU can not directly communicate with the GPU, but also to comply with the corresponding rules, and now we do everything to go through the same process, can not be chaotic; So the CPU sends some instructions to OpenGL ES to draw a style. OpenGL ES is a set of apis through which drivers can be operated to enable the GPU to perform various operations. The GPU receives these commands, starts rasterization, and displays the styles on the screen;

Now let’s add the application to the display flow

In the Android application layer, LayoutInflater maps the layout XML file into an object and loads it into memory. This UI object contains information such as size, location, and so on. Then THE CPU takes out the UI object from the memory, and processes it into a multidimensional vector graph after operation, and then gives it to the GPU to raster it into a bitmap and display it on the screen. A brief introduction to vector and bitmaps A vector map is described by a function that describes how the graph generates a bitmap: described by a matrix of pixels

The Android system redraws the Activity every 16ms, so the application must complete all logical operations of the screen refresh within 16ms to achieve 60 frames per second (60FPS). However, this parameter is determined by the phone’s hardware. Most phones now have a screen refresh rate of 60 Hertz (a measure of the number of periodically varying repetitions per second). Exceeding 16ms will result in what is known as frame loss (1000ms/60=16.66ms).

Three. One frame image complete rendering process

The Android application window contains many View elements, which are organized in a tree structure to form the so-called View tree structure. Before drawing the UI of an Android application window, determine the size and position of its child View elements within the parent element. The process of determining the size and position of each child View element in the parent View element is also called the measurement process and layout process. The UI rendering process of Android application Windows can be divided into Measure, Layout and Draw stages (initiated by the performTraversals() method of ViewRootImpl)

Measure – Recursively (depth-first) determine the size (height, width) of all views layout – recursively (depth-first) determine the position of all views Draw – Draw all views of the application window on the canvas

After many draws, all views to be displayed in this frame have been drawn. Note that drawing the view hierarchy is done in the graphics buffer; The graphics buffer is then handed over to the SurfaceFlinger service

SurfaceFlinger Service Overview:

The SurfaceFlinger service, like other System services, is started and run in the System process of the Android System. It is mainly responsible for unified management of the Frame Buffer (Frame Buffer, SurfaceFlinger automatically creates two threads during the startup of the SurfaceFlinger service: one thread is used to monitor console events and the other thread is used to render the UI of the system. In order for an Android application to draw its UI on the frame buffer of the system, it needs to pass the UI data to the SurfaceFlinger service and inform itself of the specific UI data (such as the area to draw the UI, location, etc.). Android applications and SurfaceFlinger services run in different processes and communicate with each other through Binder mechanisms, which can be roughly divided into three steps: 1. The first step is to create a connection to the SurfaceFlinger service, 2 through which to create a Surface, 3. Request SurfaceFlinger service to render the Surface (each window of the Android application corresponds to a Canvas, which can also be understood as a window of the Android application). We cannot optimize this part in the APP layer, which is what ROOM does.

In simple terms, when the Android application layer draws the View hierarchy in the graphics buffer, the application layer communicates with SurfaceFlinger via Binder mechanism and delivers the graphics buffer to the SurfaceFlinger service using an anonymous shared memory. Anonymous shared memory is abstracted into a more upper-tier data structure, SharedClient, with up to 31 SharedBufferStacks in each SharedClient. Each SharedBufferStack corresponds to a Surface which is a window.

The frame cache has an address, which is in memory. The display controller automatically takes data from the frame buffer and displays it by constantly writing data to the frame buffer. All graphics share the same frame cache in memory.

4. The mechanism of VSync

In order to reduce the lag, Android 4.1(JB) has started to introduce VSync (vertical synchronization) mechanism, which simply means that CPU/GPU will receive VSync signal, Android system sends VSync signal every 16ms, Triggering a rendering of the UI (i.e. showing a frame every 16ms) requires two tasks in 16ms: converting the UI object into a series of polygons and textures (rasterization) and the CPU passing processing data to the GPU. However, even the introduction of Vsync is not perfect. If the CPU and GPU render a frame for more than 16ms for some reason, Vsync will make the hardware display wait until the GPU finishes rasterization, which directly causes the frame to stay 16ms longer or even longer. Give the user a pause.