Surfaceflinger has its own message queue MessageQueue, which is used to handle display-related messages, such as VSync messages.
Related documents:
- Frameworks/native/services/surfaceflinger/messagequeue.h
- Frameworks/native/services/surfaceflinger/messagequeue.cpp
The classes MessageQueue and handler are defined in the MessageQueue.h file with the following code:
Class MessageQueue {//Class Handler definition is also here class Handler:public MessageHandler {enum {Eventmaski Nvalidate = 0x1, Eventmaskrefresh = 0x2, eventmasktransaction = 0x4}; messagequeue& Mqueue; int32_t Meventmask; Public:handler (messagequeue& queue): Mqueue (Queue), Meventmask (0) {} virtual void Handlemessage (const message& message); void Dispatchrefresh (); void Dispatchinvalidate (); void Dispatchtransaction (); }; Friend class Handler; Sp<surfaceflinger> Mflinger; Sp<looper> Mlooper; Sp<eventthread> Meventthread; Sp<idisplayeventconnection> mevents; Sp<bittube> Meventtube; Sp
- Mlooper thread loop body, mainly used for fetching messages
- Mhander Message Processing class
- Meventthread, mevents, meventtube mainly related to the distribution of VSYNC messages
The Surfaceflinger class has a member variable of type MessageQueue, which is defined as follows:
// these are thread safe mutable MessageQueue mEventQueue;
- A meventqueue is constructed when the Surfaceflinger is constructed.
void SurfaceFlinger::onFirstRef(){ mEventQueue.init(this);}
- Call the init function of MessageQueue to initialize
void MessageQueue::init(const sp<SurfaceFlinger>& flinger){ mFlinger = flinger; mLooper = new Looper(true); mHandler = new Handler(*this); }
- Initialize Mflinger, Mlooper, mhandler three member variables
void SurfaceFlinger::init() { ...... mSFEventThread = new EventThread(sfVsyncSrc); mEventQueue.setEventThread(mSFEventThread); ...... }
- Call MessageQueue's Seteventthread function in Surfaceflinger's init function
void MessageQueue::setEventThread(const sp<EventThread>& eventThread){ mEventThread = eventThread; mEvents = eventThread->createEventConnection(); mEventTube = mEvents->getDataChannel(); mLooper->addFd(mEventTube->getFd(), 0, Looper::EVENT_INPUT, MessageQueue::cb_eventReceiver, this);}
- Set Meventthread, Mevents, Meventtube, and add file handles to Mlooper
The message is monitored primarily in the surfaceflinger run function.
void SurfaceFlinger::run() { do { waitForEvent(); } while (true);}
- The dead loop has been listening to messages
- Call Waitforevent to wait for a message event
void SurfaceFlinger::waitForEvent() { mEventQueue.waitMessage();}
- Call MessageQueue's WaitMessage wait message
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);}
- WaitMessage listens to messages primarily by calling Mlooper's Pollonce method
Android Surfaceflinger Service (iv)-----messaging mechanism MessageQueue