Android4.4 Surfaceflinger Frame-Render a surface (ii)

Source: Internet
Author: User

Surfaceflinger since startup, there are mainly three types of threads involved:

1.binder thread, responsible for monitoring binder device completion and client handover

2. The Console event monitoring thread, which is responsible for monitoring the sleep/wake State switching events of the hardware frame buffer.

3.UI rendering thread, responsible for rendering the UI.

A UI rendering thread

UI render line accesses tile is dormant when the binder thread detects that a message from another process sends a request to render the UI that wakes up the UI render thread. On the other hand, once the console event monitoring thread of the Surfaceflinger service discovers that the hardware frame buffer is about to go to sleep or wake, it sends a message to the message queue of the UI render thread of the Surfaceflinger service. So that the UI rendering thread of the Surfaceflinger service can perform operations that freeze or unfreeze the display. (from Lao Luo's Android tour) I'm going to start with the client's request to render the UI and begin to look at the entire process of rendering the UI.

The UI rendering thread runs the process:

Here is the surfaceflinger of the various agents responsible for things: The bpsurfacecomposer described above is SF on the client's binder agent, Bnsurfacecomposer is the local object responsible and bpxxx interaction, They are primarily responsible for the entire process of client requests and monitoring of binder devices. The real transaction between client and server is given to Bpsurfacecomposerclient and Bnsurfacecomposerclient, who are responsible for notifying the management of a UI rendering and other important processes. Then I will start from bpsurfacecomposerclient agent, remember where this bpsurfacecomposerclient was born? Before the client requests to connect to the server:

void Surfacecomposerclient::onfirstref () {    sp<isurfacecomposer> sm (Composerservice::getcomposerservice ( ));    if (SM! = 0) {        sp<isurfacecomposerclient> conn = Sm->createconnection ();        IF (conn! = 0) {            mclient = conn;            Mstatus = No_error;}}    }

One of the

sentences mclient = conn, which saves the returned surfacecomposerclient, and because Mclient is a strong pointer, resulting in the end is actually mclient is the object of the Bpsurfacecomposerclient class, specific reasons before the study of the SF startup process is described in detail. After the connection, a Bpsurfacecomposerclient object is obtained so that the next rendering can be done after the connection is made. Let's look at the Bpsurfacecomposerclient class again:

Class Bpsurfacecomposerclient:public Bpinterface<isurfacecomposerclient>{public:bpsurfacecomposerclient ( Const sp<ibinder>& Impl): bpinterface<isurfacecomposerclient> (impl) {} virtual status_t cre Atesurface (const string8& name, uint32_t W, uint32_t H, pixelformat format, uint32_t flags, SP&L        t;ibinder>* handle, sp<igraphicbufferproducer>* GBP) {Parcel data, reply;        Data.writeinterfacetoken (Isurfacecomposerclient::getinterfacedescriptor ());        DATA.WRITESTRING8 (name);        Data.writeint32 (w);        Data.writeint32 (h);        Data.writeint32 (format);        Data.writeint32 (flags);        Remote ()->transact (create_surface, data, &reply);        *handle = Reply.readstrongbinder ();        *GBP = interface_cast<igraphicbufferproducer> (Reply.readstrongbinder ());    return Reply.readint32 ();  } Virtual status_t destroysurface (const sp<ibinder>& handle) {      Parcel data, reply;        Data.writeinterfacetoken (Isurfacecomposerclient::getinterfacedescriptor ());        Data.writestrongbinder (handle);        Remote ()->transact (destroy_surface, data, &reply);    return Reply.readint32 (); }};


He has two member functions, namely Createsurface and Destroysurface, which correspond to creating and destroying a surface. The core statements of the two core functions are in remote ()->transact (create_surface, data, &reply);

The Transact function, which was previously described as the only way to deal with binder equipment. Do not do too much in-depth, here means simply send a message create_surface to the server, and a surface of information packaged into data sent in the past.

Server side will be wired to monitor binder device, once received the message naturally called corresponding function. Here is bnsurfacecomposerclient responsible, but this side with the previous bnsurfacecomposer a bit different, bnsurfacecomposerclient derived a client class to take charge of this matter, Let's look at this class:

Class Client:public Bnsurfacecomposerclient{public:client (const sp<surfaceflinger>& Flinger);    ~client ();    status_t Initcheck () const; protected by Surfaceflinger::mstatelock void Attachlayer (const sp<ibinder>& handle, const sp<layer>& Amp    Layer);    void Detachlayer (const layer* Layer);    Sp<layer> getlayeruser (const sp<ibinder>& handle) Const;private://Isurfacecomposerclient interface  Virtual status_t createsurface (const string8& name, uint32_t W, uint32_t h,pixelformat format,    uint32_t flags, sp<ibinder>* handle, sp<igraphicbufferproducer>* GBP);    Virtual status_t destroysurface (const sp<ibinder>& handle);    Virtual status_t ontransact (uint32_t code, const parcel& data, parcel* reply, uint32_t flags);    Constant sp<surfaceflinger> Mflinger; protected by MLock defaultkeyedvector< Wp<ibinder> wp<layer> > Mlayers; Thread-safe mutable Mutex MLock;};

In fact, the core member function is two createsurface and ontransact. First look at Ontransact, after all, he is responsible for receiving messages.

status_t client::ontransact (    uint32_t Code, const parcel& data, parcel* reply, uint32_t flags) {    //these must be checked     ipcthreadstate* IPC = Ipcthreadstate::self ();     const int PID = Ipc->getcallingpid ();     const int UID = IPC->GETCALLINGUID ();     const int self_pid = Getpid ();     if (cc_unlikely (pid! = self_pid && uid! = aid_graphics && uid! = 0)) {         //we ' re called from a Differen T process, do the real check         if (! Permissioncache::checkcallingpermission (Saccesssurfaceflinger))         {             aloge ("Permission denial:"                     " Can ' t openglobaltransaction pid=%d, uid=%d ", PID, UID);             return permission_denied;         }     }     Return Bnsurfacecomposerclient::ontransact (Code, data, reply, flags);}


Here the previous statement in order to determine whether to get into the use of SF permission, see his return bnsurfacecomposerclient::ontransact (code, data, reply, flags); Called directly another ontransact and then looked at the ontransact in the Bnsurfacecomposerclient class.

status_t bnsurfacecomposerclient::ontransact (uint32_t code, const parcel& data, parcel* reply, uint32_t flags) {            Switch (code) {case Create_surface: {check_interface (isurfacecomposerclient, data, reply);            String8 name = Data.readstring8 ();            uint32_t w = data.readint32 ();            uint32_t h = data.readint32 ();            PixelFormat format = Data.readint32 ();            uint32_t flags = Data.readint32 ();            Sp<ibinder> handle;            Sp<igraphicbufferproducer> GBP;            status_t result = Createsurface (name, W, h, Format, flags, &handle, &AMP;GBP);            Reply->writestrongbinder (handle);            Reply->writestrongbinder (Gbp->asbinder ());            Reply->writeint32 (result);        return no_error;        } break;            Case Destroy_surface: {check_interface (isurfacecomposerclient, data, reply); Reply->writeint32 (destroysurface (DATA.readstrongbinder ()));        return no_error;        } break;    Default:return bbinder::ontransact (Code, data, reply, flags); }}


This is the core of the process, remember that the message is Create_surface, so the first branch here, first parse the packet to get some data such as SURFACE name, length, width, and format. Then it was created by Createsurface, but there is a problem here where the createsurface does not indicate which class it belongs to, and finds that it is not traceable to trace the definition, which reminds me of the function that called his subclass client. We go back to the previous createsurface in the client class;

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 B     E called from the GL thread so that it can * has 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 ();}


This function is really a watershed in the SF field, where the function defines a Messagecreatelayer class, and I understand that this class encapsulates a surface into a message that contains all the information about surface. sp<messagebase> msg = new Messagecreatelayer (Mflinger.get (), name, this, W, h, format, flags, handle, GBP); Defines a message encapsulation Surface,mflinger->postmessagesync (msg); This sends an asynchronous signal to SF, which wakes up the core processing portion of the UI rendering thread in the SF hibernation state.

Let's look at this function:

status_t Surfaceflinger::p ostmessagesync (const sp<messagebase>& MSG,        nsecs_t reltime, uint32_t flags) {    status_t res = meventqueue.postmessage (msg, reltime);    if (res = = No_error) {        msg->wait ();    }    return res;}


Call PostMessage ()

status_t MessageQueue::p ostmessage (        const sp<messagebase>& MessageHandler, nsecs_t reltime) {    Const Message Dummymessage;    if (Reltime > 0) {        mlooper->sendmessagedelayed (reltime, MessageHandler, dummymessage);    } else {        Mlooper->sendmessage (MessageHandler, dummymessage);    }    return no_error;}


This way, either sendmessagedelayed or SendMessage will trigger the thread to wake the main thread (render UI). So I'll use a graph to introduce the next main thread:

The picture is rough, but that's the way it goes, when the main thread receives the message, it executes the handlemessage. Here you can refer to the previous money several SF process series articles to see how the next is rendered.




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.