Surface flinger (01) display system framework of Android GUI system

Keywords: Android less

Link to the general outline of this series of articles: surface flinger series of articles of Android GUI system

Summary & description of key points in this chapter:

The mind map of this chapter is as above. It mainly describes the basis of the display system, understands the relationship between FrameBuffer and Android, gives the overall framework of SurfaceFlinger and a core demo test program. The next chapter will focus on the demo.

1 frameBuffer and Android

When our program wants to display content on the screen, our mechanism is to write content directly to FrameBuffer (hereinafter referred to as FB). Next, let's talk about the strategy of Android practical FB:

If there is only one FB, there is no problem when the app write speed is greater than the LCD display speed; when the app write speed is less than or equal to the LCD display speed, it will jam and flash. In order to solve this problem, more than two FB are generally used. Take two FBS for example, APP writes FB0, LCD renders FB1 at this time, LCD renders FB0 at the end of FB0 writing, APP writes FB1 at this time, and then circulates continuously.

For Android system, there are many apps. If these apps write content to FB at the same time, the displayed content will be disordered. Therefore, a big housekeeper is needed to manage it. This big housekeeper is surface flinger.

2. Sketch description of the overall framework of surfaceflinger (because it is a sketch, mainly for the convenience of learning and understanding, it is not perfect)

SF can do the following things:

  1. Provide buffer to app: apply memory to Ashman through the granlloc module to get the file handle fd, pass the fd to the corresponding app through the binder mechanism, and then the app performs mmap operation to get the corresponding buffer.
  2. Synthesize the buffer (interface data) sent from the app: according to the layer (i.e. Z value, determined by WindowManagerService) of each interface, pass these sorted overall buffers to hardwarecomposer (hereinafter referred to as HWC).
  3. When HWC cannot process (no HWC hardware, more than HWC layers) buffer, use the graphics library GL to process.
  4. Either SF or APP can directly call EGL layer interface to realize rendering function.

3 simplest Surface test procedure

In order to better understand the surface flinger display process, we first use the simplest example to perceive the minimum display system. At the same time, the following chapters will analyze the internal mechanism of SF. The program code is as follows:

#include <cutils/memory.h>
#include <utils/Log.h>
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>
#include <android/native_window.h>

using namespace android;

int main(int argc, char** argv)
{
    // Start the binder and its thread pool
    sp<ProcessState> proc(ProcessState::self());
    ProcessState::self()->startThreadPool();

    // Creating a client for surfacelinker
    sp<SurfaceComposerClient> client = new SurfaceComposerClient();
    
    //Get surface
    sp<SurfaceControl> surfaceControl = client->createSurface(String8("resize"),
            160, 240, PIXEL_FORMAT_RGB_565, 0);
    sp<Surface> surface = surfaceControl->getSurface();

    //Set the layer. The higher the layer value is, the higher the display layer is
    SurfaceComposerClient::openGlobalTransaction();
    surfaceControl->setLayer(100000);
    SurfaceComposerClient::closeGlobalTransaction();

    //Get buffer - > lock buffer - > write buffer - > unlock and submit buffer
    ANativeWindow_Buffer outBuffer;
    surface->lock(&outBuffer, NULL);
    ssize_t bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);
    android_memset16((uint16_t*)outBuffer.bits, 0xF800, bpr*outBuffer.height);
    surface->unlockAndPost();
    sleep(3);

    //Ditto
    surface->lock(&outBuffer, NULL);
    android_memset16((uint16_t*)outBuffer.bits, 0x07E0, bpr*outBuffer.height);
    surface->unlockAndPost();
    sleep(3);
    
    IPCThreadState::self()->joinThreadPool();
    
    return 0;
}

The corresponding Android.mk file is as follows:

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_SRC_FILES:= \
	SurfaceTest.cpp

LOCAL_SHARED_LIBRARIES := \
	libcutils \
	libutils \
    libui \
    libgui \
    libbinder

LOCAL_MODULE:= SurfaceTest

LOCAL_MODULE_TAGS := tests

include $(BUILD_EXECUTABLE)

The display effect of the program is as follows (that is, a color block is displayed on the interface):

The whole process is summarized as follows:

Get surfaceflinger - > get surface - > set layer - > get buffer - > lock buffer - > write buffer - > unlock and submit buffer

224 original articles published, 30 praised, 20000 visitors+
Private letter follow

Posted by ChaosXero on Fri, 13 Mar 2020 22:22:55 -0700