SurfaceFlinger (3) of android Gui system and androidgui System

Source: Internet
Author: User

SurfaceFlinger (3) of android Gui system and androidgui System
7. SurfaceFlinger

SurfaceFlinger has been mentioned in the previous section and is involved in many cases.

SurfaceFlinger is the core of GUI refreshing UI, so any improvements to SurfaceFlinger will have a major impact on the android UI system.

SurfaceFlinger consists of four parts:

1) butter program --- project butter

2) Startup Process

3) SurfaceFlinger & BufferQueue relationship

4) Vsync Signal Processing

7.1 butter Program

Is to give the android system, a layer of "butter" on the figure ". Let's see how andorid coated SurfaceFlinger with butter.

The butter consists of two parts: Vsync & Triple buffer.

Triple buffer:

The Double buffer technology mentioned above also mentions that when FrameBufferNativeWindow applies for buffer, it can be 2 or 3.

This 3 is the Triple Buffer technology to be discussed soon.

We will first look at the dual-buffer technology.

Previously, dual buffering is to put a buffer on bitmap. After all the elements are ready, the bitmap is flushed to the screen.

This will solve the problem of choppy.

Assume that the screen refresh frequency is 66Hz and the CPU frequency is 100Hz.

I have already talked about the double buffer technology. Here is a simple introduction.

In the preceding assumptions, the UI refresh is 0.015 s, while the buffer preparation is 0.01 s.

A Frame Buffer represents an image.

0.01 s:

At this time, the buffer has data ready, and the display only displays 2/3 of the image.

0.015 s

The display displays the first frame of the image, while the buffer has filled the second frame with 1/3

0.02 s

Buffer has prepared the second frame, and the display has a problem. 1/3 of the content belongs to the second frame and 2/3 of the content belongs to the first frame.

This is why android introduces dual-buffer technology.

What if the buffer preparation time is slower than the screen refresh image speed?

Each refresh of the display screen is a scan of the display screen, but there is an interval (physical device, there must be this interval ).

The typical screen refresh frequency of a PC display is 60Hz. This is because 60 frames are refreshed every second. From the perspective of the human, the screen will feel smooth.

Therefore, the interval is 1/60 seconds, that is, 16 ms. If the preparation time is less than 16 ms, we can achieve "seamless connection ". The screen is very flow.

This gap is called VBI. This time is the best time for the swap buffer. Vsync is also the focus of SurfaceFlinger.

If the image preparation time is <= 16 ms. OK, the image is smooth, but we cannot guarantee that the device performance is very good. Therefore, it is possible that the image preparation time exceeds 16 ms.


Let's take a look at this figure. Data A is in the buffer at the beginning. At this time, it can be directly displayed on the screen. After 16 ms, data B is not ready yet, and the screen can only show. In this way, the exchange of opportunities in turn is wasted. To the next swap, B is displayed on the screen. This is a waste of time. Wait for the next time A, 16 ms, still not ready, continue to waste. Therefore, dual-buffer technology is also a waste. Is there A way to circumvent it, such as the time between B & A, if I add A buffer, C. After B is ready, although C is not good, B can be displayed on the screen. After the next 16ms arrives, C is ready, this can greatly reduce the waste of CPU time. That is, the idea of changing space for time. Therefore, multiple buffers are used to determine the number of buffers based on the actual memory of the system. 7.2 start SurfaceFlinger

SurfaceFlinger, as we have mentioned earlier, is actually a service.

void SurfaceFlinger::onFirstRef(){    mEventQueue.init(this);}

Initialize the event queue.

void MessageQueue::init(const sp<SurfaceFlinger>& flinger){    mFlinger = flinger;    mLooper = new Looper(true);    mHandler = new Handler(*this);}

Logoff & Handler created

But when will this loose get up?

void MessageQueue::waitMessage() {    do {        IPCThreadState::self()->flushCommands();        int32_t ret = mLooper->pollOnce(-1);        switch (ret) {            case Looper::POLL_WAKE:            case Looper::POLL_CALLBACK:                continue;            case Looper::POLL_ERROR:                ALOGE("Looper::POLL_ERROR");            case Looper::POLL_TIMEOUT:                // timeout (should not happen)                continue;            default:                // should not happen                ALOGE("Looper::pollOnce() returned unknown status %d", ret);                continue;        }    } while (true);}

We can see that the logoff function will be called eventually. We can see that lo_:: POLL_TIMEOUT: android has nothing to do, even though they should not happen.

In fact, handler took a lap and found that he finally returned to surfaceflinger for processing:

void SurfaceFlinger::onMessageReceived(int32_t what) {    ATRACE_CALL();    switch (what) {        case MessageQueue::TRANSACTION: {            handleMessageTransaction();            break;        }        case MessageQueue::INVALIDATE: {            bool refreshNeeded = handleMessageTransaction();            refreshNeeded |= handleMessageInvalidate();            refreshNeeded |= mRepaintEverything;            if (refreshNeeded) {                // Signal a refresh if a transaction modified the window state,                // a new buffer was latched, or if HWC has requested a full                // repaint                signalRefresh();            }            break;        }        case MessageQueue::REFRESH: {            handleMessageRefresh();            break;        }    }}
7.3 client

Any App with a UI interface has a client in surfaceflinger.

Therefore, an app corresponds to the client (ISurfaceComposerClient) in a surfaceflinger ).

 

Next we will analyze the two important functions of surfaceflinger:

sp<ISurfaceComposerClient> SurfaceFlinger::createConnection(){    sp<ISurfaceComposerClient> bclient;    sp<Client> client(new Client(this));    status_t err = client->initCheck();    if (err == NO_ERROR) {        bclient = client;    }    return bclient;}

Returns ISurfaceComposerClient, which is the bind object of the client.

In fact, the above marked with a red sentence, the necessary validity check, now the Code:

status_t Client::initCheck() const {    return NO_ERROR;}

With clinet, let's take a look at the appearance of the surface.

status_t Client::createSurface(        const String8& name,        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,        sp<IBinder>* handle,        sp<IGraphicBufferProducer>* gbp){    /*     * createSurface must be called from the GL thread so that it can     * have access to the GL context.     */    class MessageCreateLayer : public MessageBase {        SurfaceFlinger* flinger;        Client* client;        sp<IBinder>* handle;        sp<IGraphicBufferProducer>* gbp;        status_t result;        const String8& name;        uint32_t w, h;        PixelFormat format;        uint32_t flags;    public:        MessageCreateLayer(SurfaceFlinger* flinger,                const String8& name, Client* client,                uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,                sp<IBinder>* handle,                sp<IGraphicBufferProducer>* gbp)            : flinger(flinger), client(client),              handle(handle), gbp(gbp),              name(name), w(w), h(h), format(format), flags(flags) {        }        status_t getResult() const { return result; }        virtual bool handler() {            result = flinger->createLayer(name, client, w, h, format, flags,                    handle, gbp);            return true;        }    };    sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(),            name, this, w, h, format, flags, handle, gbp);    mFlinger->postMessageSync(msg);    return static_cast<MessageCreateLayer*>( msg.get() )->getResult();}

There are actually two sentences:

PostMessageSync does not directly create the surface at the beginning and then put it in the surfaceflinger queue. This will not interrupt the current operation.

Then start the createlayer method. This method has been analyzed before.

 

 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.