Android4.4——SurfaceFlinger启动
http://blog.csdn.net/yaowei514473839/article/details/39560055
SurfaceFlinger是一项系统底层的服务,是负责UI方面的渲染的,与应用Application实时交互,实时刷新Surface,是与用户最直接打交道的一项服务。
下面我们将分析SurfaceFlinger服务的启动过程。
在system/core/rootdir/init.rc文件中,有这么段代码:
- ……
- service servicemanager /system/bin/servicemanager
- class core
- user system
- group system
- critical
- onrestart restart healthd
- onrestart restart zygote
- onrestart restart media
- onrestart restart surfaceflinger
- onrestart restart drm
- ……
- service surfaceflinger /system/bin/surfaceflinger
- class main
- user system
- group graphics drmrpc
- onrestart restart zygote
- ……
好,下面来开始跟踪一下其中最终要的surfaceflinger服务的main函数。
Step 1、main()
在Android 4.4中,SurfaceFlinger的启动由frameworks/native/services/surfaceflinger/Main_surfaceflinger.cpp
中的main函数启动。
- int main(int argc, char** argv) {
- // When SF is launched in its own process, limit the number of
- // binder threads to 4.
- ProcessState::self()->setThreadPoolMaxThreadCount(4);
- // start the thread pool
- sp<ProcessState> ps(ProcessState::self());
- ps->startThreadPool();
- // instantiate surfaceflinger
- sp<SurfaceFlinger> flinger = new SurfaceFlinger(); //创建一个SurfaceFlinger对象
- #if defined(HAVE_PTHREADS)
- setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);
- #endif
- set_sched_policy(0, SP_FOREGROUND);
- // initialize before clients can connect
- flinger->init(); //初始化SurfaceFlinger
- // publish surface flinger
- sp<IServiceManager> sm(defaultServiceManager());
- sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);//将SrufaceFlinger加入服务
- // run in this thread
- flinger->run();//运行SurfaceFlinger服务
- return 0;
- }
这里创建了SurfaceFlinger对象,随后初始化该对象,并且以该对象作为参数,将SurfaceFlinger服务加入ServiceManager中。
接下来,来分步解析。
Step 2、new SurfaceFlinger()
该代码在frameworks/native/services/surfaceflinger.cpp中。
- SurfaceFlinger::SurfaceFlinger()
- : BnSurfaceComposer(),//创建SurfaceComposer本地对象
- mTransactionFlags(0),
- mTransactionPending(false),
- mAnimTransactionPending(false),
- mLayersRemoved(false),
- mRepaintEverything(0),
- mRenderEngine(NULL),
- mBootTime(systemTime()),
- mVisibleRegionsDirty(false),
- mHwWorkListDirty(false),
- mAnimCompositionPending(false),
- mDebugRegion(0),
- mDebugDDMS(0),
- mDebugDisableHWC(0),
- mDebugDisableTransformHint(0),
- mDebugInSwapBuffers(0),
- mLastSwapBufferTime(0),
- mDebugInTransaction(0),
- mLastTransactionTime(0),
- mBootFinished(false),
- mGpuTileRenderEnable(false),
- mPrimaryHWVsyncEnabled(false),
- mHWVsyncAvailable(false),
- mDaltonize(false)
- {
- ALOGI("SurfaceFlinger is starting");
- // debugging stuff...
- char value[PROPERTY_VALUE_MAX];
- property_get("ro.bq.gpu_to_cpu_unsupported", value, "0");
- mGpuToCpuSupported = !atoi(value);
- property_get("debug.sf.showupdates", value, "0");
- mDebugRegion = atoi(value);
- property_get("debug.sf.ddms", value, "0");
- mDebugDDMS = atoi(value);
- if (mDebugDDMS) {
- if (!startDdmConnection()) {
- // start failed, and DDMS debugging not enabled
- mDebugDDMS = 0;
- }
- }
- }
Step 2、SurfaceFlinger::OnFirstRef()
由于flinger为sp<SurfaceFlinger>强指针类型,当第一次被一个强指针引用时,就会执行SurfaceFlinger::OnFirstRef()函数。
- void SurfaceFlinger::onFirstRef()
- {
- mEventQueue.init(this);
- }
这里,mEventQueue是一个MessageQueue对象,是一个消息队列。定义的地方在SurfaceFlinger.h文件中。
- mutable MessageQueue mEventQueue;
将SurfaceFlinger对象作为参数传入ini函数中,对MessageQueue初始化。将surfaceFlinger对象本神赋值给MessageQueue.mFlinger,也对MessageQueue中mHandler和mLooper进行赋值。
Step 3、MessageQueue::init
代码位于frameworks/native/services/surfaceflinger/MessageQueue.cpp中。
- void MessageQueue::init(const sp<SurfaceFlinger>& flinger)
- {
- mFlinger = flinger; <pre name="code" class="java"> //创建主线程1
- mLooper = new Looper(true);
- mHandler = new Handler(*this);
- }
将之前传入的SurfaceFlinger对象赋给MessageQueue的成员变量mFlinger,并且创建了消息队列的循环体Looper和事件处理器Handler。关于Looper和Handler,可以参考:http://www.cnblogs.com/codingmyworld/archive/2011/09/14/2174255.html这个博客,里面讲的很是详细。
MessageQueue::init函数创建了下图中的主线程1,Looper配合着Message、Handle、Thread、MessageQueue完成了太多的事情,在这里简单说就是它搞了一个睡眠等待事件,然后等着被唤醒。结合到SF中就是说,这里开了一个线程等待surface的刷新,而做出相关的操作。至于是怎么唤醒的可以参考这个连接的博文http://blog.csdn.net/broadview2006/article/details/8552148。
Step 4、SurfaceFlinger::init()
在前面几步后,完成了SurfaceFlinger对象的创建过程后,需要对SurfaceFlinger对象进行初始化。
本部分的代码位于frameworks/native/services/wurfaceflinger.cpp中。
- void SurfaceFlinger::init() {
- status_t err;
- Mutex::Autolock _l(mStateLock);
- // initialize EGL for the default display
- mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- eglInitialize(mEGLDisplay, NULL, NULL);
- // Initialize the H/W composer object. There may or may not be an
- // actual hardware composer underneath.
- mHwc = new HWComposer(this,
- *static_cast<HWComposer::EventHandler *>(this)); //创建HWComposer对象,通过HWComposer对象可以产生VSync同步信号。
- // First try to get an ES2 config
- err = selectEGLConfig(mEGLDisplay, mHwc->getVisualID(), EGL_OPENGL_ES2_BIT,
- &mEGLConfig);
- if (err != NO_ERROR) {
- // If ES2 fails, try ES1
- err = selectEGLConfig(mEGLDisplay, mHwc->getVisualID(),
- EGL_OPENGL_ES_BIT, &mEGLConfig);
- }
- // print some debugging info
- EGLint r,g,b,a;
- eglGetConfigAttrib(mEGLDisplay, mEGLConfig, EGL_RED_SIZE, &r);
- eglGetConfigAttrib(mEGLDisplay, mEGLConfig, EGL_GREEN_SIZE, &g);
- eglGetConfigAttrib(mEGLDisplay, mEGLConfig, EGL_BLUE_SIZE, &b);
- eglGetConfigAttrib(mEGLDisplay, mEGLConfig, EGL_ALPHA_SIZE, &a);
- // get a RenderEngine for the given display / config (can't fail)
- mRenderEngine = RenderEngine::create(mEGLDisplay, mEGLConfig);
- // retrieve the EGL context that was selected/created
- mEGLContext = mRenderEngine->getEGLContext();
- // figure out which format we got
- eglGetConfigAttrib(mEGLDisplay, mEGLConfig,
- EGL_NATIVE_VISUAL_ID, &mEGLNativeVisualId);
- LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
- "couldn't create EGLContext");
- // initialize our non-virtual displays
- for (size_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
- DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);
- // set-up the displays that are already connected
- if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) {
- // All non-virtual displays are currently considered secure.
- bool isSecure = true;
- createBuiltinDisplayLocked(type);
- wp<IBinder> token = mBuiltinDisplays[i];
- sp<BufferQueue> bq = new BufferQueue(new GraphicBufferAlloc());
- sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i, bq);
- sp<DisplayDevice> hw = new DisplayDevice(this,
- type, allocateHwcDisplayId(type), isSecure, token,
- fbs, bq,
- mEGLConfig);
- if (i > DisplayDevice::DISPLAY_PRIMARY) {
- // FIXME: currently we don't get blank/unblank requests
- // for displays other than the main display, so we always
- // assume a connected display is unblanked.
- ALOGD("marking display %d as acquired/unblanked", i);
- hw->acquireScreen();
- }
- mDisplays.add(token, hw);
- }
- }
- // make the GLContext current so that we can create textures when creating Layers
- // (which may happens before we render something)
- getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
- // start the EventThread
- sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
- vsyncPhaseOffsetNs, true);
- mEventThread = new EventThread(vsyncSrc);
- sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
- sfVsyncPhaseOffsetNs, true);
- mSFEventThread = new EventThread(sfVsyncSrc);
- mEventQueue.setEventThread(mSFEventThread);
- mEventControlThread = new EventControlThread(this);
- mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
- // set a fake vsync period if there is no HWComposer
- if (mHwc->initCheck() != NO_ERROR) {
- mPrimaryDispSync.setPeriod(16666667);
- }
- // initialize our drawing state
- mDrawingState = mCurrentState;
- // set initial conditions (e.g. unblank default device)
- initializeDisplays();
- // start boot animation
- startBootAnim();
- }
- // start the EventThread
- sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
- vsyncPhaseOffsetNs, true);
- mEventThread = new EventThread(vsyncSrc);
- sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
- sfVsyncPhaseOffsetNs, true);
- mSFEventThread = new EventThread(sfVsyncSrc);
- mEventQueue.setEventThread(mSFEventThread);
- mEventControlThread = new EventControlThread(this);
- mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
这里分两个线路来说:
1、EventThread继承自Thread线程类,Thread的基类中有RefBase,如下:
- class VSyncSource : public virtual RefBase {
- public:
- class Callback: public virtual RefBase {
- public:
- virtual ~Callback() {}
- virtual void onVSyncEvent(nsecs_t when) = 0;
- };
- virtual ~VSyncSource() {}
- virtual void setVSyncEnabled(bool enable) = 0;
- virtual void setCallback(const sp<Callback>& callback) = 0;
- };
- class EventThread : public Thread, private VSyncSource::Callback {
- class Connection : public BnDisplayEventConnection {
- public:
- Connection(const sp<EventThread>& eventThread);
- status_t postEvent(const DisplayEventReceiver::Event& event);
- // count >= 1 : continuous event. count is the vsync rate
- // count == 0 : one-shot event that has not fired
- // count ==-1 : one-shot event that fired this round / disabled
- int32_t count;
- private:
- virtual ~Connection();
- virtual void onFirstRef();
- virtual sp<BitTube> getDataChannel() const;
- virtual void setVsyncRate(uint32_t count);
- virtual void requestNextVsync(); // asynchronous
- sp<EventThread> const mEventThread;
- sp<BitTube> const mChannel;
- };
- …
- };
- void EventThread::onFirstRef() {
- run("EventThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
- }
- bool EventThread::threadLoop() {
- DisplayEventReceiver::Event event;
- Vector< sp<EventThread::Connection> > signalConnections;
- signalConnections = waitForEvent(&event);//等待Vsync事件
- // dispatch events to listeners...
- const size_t count = signalConnections.size();
- for (size_t i=0 ; i<count ; i++) {
- const sp<Connection>& conn(signalConnections[i]);
- // now see if we still need to report this event
- status_t err = conn->postEvent(event);//事件信息写入BitTuBe,也就是已建立连接的套接字队的一个套接字中,注册的接收端通过另一个套接字接收数据
- if (err == -EAGAIN || err == -EWOULDBLOCK) {
- // The destination doesn't accept events anymore, it's probably
- // full. For now, we just drop the events on the floor.
- // FIXME: Note that some events cannot be dropped and would have
- // to be re-sent later.
- // Right-now we don't have the ability to do this.
- ALOGW("EventThread: dropping event (%08x) for connection %p",
- event.header.type, conn.get());
- } else if (err < 0) {
- // handle any other error on the pipe as fatal. the only
- // reasonable thing to do is to clean-up this connection.
- // The most common error we'll get here is -EPIPE.
- removeDisplayEventConnection(signalConnections[i]);
- }
- }
- return true;
- }
如果收到一个Vsync事件,就会执行到conn->postEvent(event),该函数作用请看上面的注释。至此,EventThread线程发送了一个套接字信息。下面继续讲讲上面提到的注册的接收端。
2、到底谁来接收套接字?
在之前SurfaceFlinger::init函数中有这样一句代码:
- mEventQueue.setEventThread(mSFEventThread);
setEventThread函数的具体实现如下。
- void MessageQueue::setEventThread(const sp<EventThread>& eventThread)
- {
- mEventThread = eventThread;
- mEvents = eventThread->createEventConnection();//创建一个到EventThread的连接
- mEventTube = mEvents->getDataChannel();//得到发送Vsync事件通知的BitTuBe
- mLooper->addFd(mEventTube->getFd(), 0, ALOOPER_EVENT_INPUT,
- MessageQueue::cb_eventReceiver, this);
- }
- int MessageQueue::cb_eventReceiver(int fd, int events, void* data) {
- MessageQueue* queue = reinterpret_cast<MessageQueue *>(data);
- return queue->eventReceiver(fd, events);//返回事件接收者
- }
- int MessageQueue::eventReceiver(int fd, int events) {
- ssize_t n;
- DisplayEventReceiver::Event buffer[8];
- while ((n = DisplayEventReceiver::getEvents(mEventTube, buffer, 8)) > 0) {
- for (int i=0 ; i<n ; i++) {
- if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
- #if INVALIDATE_ON_VSYNC
- mHandler->dispatchInvalidate();
- #else
- mHandler->dispatchRefresh();
- #endif
- break;
- }
- }
- }
- return 1;
- }
dispatchInvalidate请看看这篇博客:http://blog.csdn.net/w401229755/article/details/38224481的后半段。这里只看dispatchRefresh函数。
- void MessageQueue::Handler::dispatchRefresh() {
- if ((android_atomic_or(eventMaskRefresh, &mEventMask) & eventMaskRefresh) == 0) {
- mQueue.mLooper->sendMessage(this, Message(MessageQueue::REFRESH));
- }
- }
Step 5、SurfaceFlinger::run()
在创建初始化SurfaceFlinger对象后,随后调用SurfaceFlinger的成员函数run()运行SurfaceFlinger服务。
本代码位于frameworks/native/services/surfaceflinger.cpp中。
- void SurfaceFlinger::run() {
- do {
- waitForEvent();
- } while (true);
- }
这里创建了下图中的线程2。
由于SurfaceFlinger服务需要时刻运行,实时绘制,所以不能理解使用do...while循环无限调用SurfaceFlinger成员函数waitForEvent。
Step 6 、SurfaceFlinger::waitForEvent()
本代码位于frameworks/native/services/surfaceflinger.cpp中。
- void SurfaceFlinger::waitForEvent() {
- mEventQueue.waitMessage();
- }
Step 7、MessageQueue::waitMessage()
本代码位于frameworks/native/services/MessageQueue.cpp中。
- void MessageQueue::waitMessage() {
- do {
- IPCThreadState::self()->flushCommands();
- int32_t ret = mLooper->pollOnce(-1);
- switch (ret) {
- case ALOOPER_POLL_WAKE:
- case ALOOPER_POLL_CALLBACK:
- continue;
- case ALOOPER_POLL_ERROR:
- ALOGE("ALOOPER_POLL_ERROR");
- case ALOOPER_POLL_TIMEOUT:
- // timeout (should not happen)
- continue;
- default:
- // should not happen
- ALOGE("Looper::pollOnce() returned unknown status %d", ret);
- continue;
- }
- } while (true);
- }
Step 8、Looper::pollOnce()
mLooper->pollOnce函数的代码位于frameworks/base/libs/utils/Looper.cpp中。
- int Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) {
- int result = 0;
- for (;;) {
- while (mResponseIndex < mResponses.size()) {
- const Response& response = mResponses.itemAt(mResponseIndex++);
- int ident = response.request.ident;
- if (ident >= 0) {
- int fd = response.request.fd;
- int events = response.events;
- void* data = response.request.data;
- if (outFd != NULL) *outFd = fd;
- if (outEvents != NULL) *outEvents = events;
- if (outData != NULL) *outData = data;
- return ident;
- }
- }
- if (result != 0) {
- if (outFd != NULL) *outFd = 0;
- if (outEvents != NULL) *outEvents = 0;
- if (outData != NULL) *outData = NULL;
- return result;
- }
- result = pollInner(timeoutMillis);
- }
- }
Step 9、Looper::pollInner
- int Looper::pollInner(int timeoutMillis) {
- // Adjust the timeout based on when the next message is due.
- if (timeoutMillis != 0 && mNextMessageUptime != LLONG_MAX) {
- nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
- int messageTimeoutMillis = toMillisecondTimeoutDelay(now, mNextMessageUptime);
- if (messageTimeoutMillis >= 0
- && (timeoutMillis < 0 || messageTimeoutMillis < timeoutMillis)) {
- timeoutMillis = messageTimeoutMillis;
- }
- }
- // Poll.
- int result = ALOOPER_POLL_WAKE;
- mResponses.clear();
- mResponseIndex = 0;
- // We are about to idle.
- mIdling = true;
- struct epoll_event eventItems[EPOLL_MAX_EVENTS];
- int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis);
- // No longer idling.
- mIdling = false;
- // Acquire lock.
- mLock.lock();
- // Check for poll error.
- if (eventCount < 0) {
- if (errno == EINTR) {
- goto Done;
- }
- result = ALOOPER_POLL_ERROR;
- goto Done;
- }
- // Check for poll timeout.
- if (eventCount == 0) {
- result = ALOOPER_POLL_TIMEOUT;
- goto Done;
- }
- // Handle all events.
- for (int i = 0; i < eventCount; i++) {
- int fd = eventItems[i].data.fd;
- uint32_t epollEvents = eventItems[i].events;
- if (fd == mWakeReadPipeFd) {
- if (epollEvents & EPOLLIN) {
- awoken();
- } else {
- ALOGW("Ignoring unexpected epoll events 0x%x on wake read pipe.", epollEvents);
- }
- } else {
- ssize_t requestIndex = mRequests.indexOfKey(fd);
- if (requestIndex >= 0) {
- int events = 0;
- if (epollEvents & EPOLLIN) events |= ALOOPER_EVENT_INPUT;
- if (epollEvents & EPOLLOUT) events |= ALOOPER_EVENT_OUTPUT;
- if (epollEvents & EPOLLERR) events |= ALOOPER_EVENT_ERROR;
- if (epollEvents & EPOLLHUP) events |= ALOOPER_EVENT_HANGUP;
- pushResponse(events, mRequests.valueAt(requestIndex));
- } else {
- ALOGW("Ignoring unexpected epoll events 0x%x on fd %d that is "
- "no longer registered.", epollEvents, fd);
- }
- }
- }
- Done: ;
- // Invoke pending message callbacks.
- mNextMessageUptime = LLONG_MAX;
- <strong>while (mMessageEnvelopes.size() != 0)</strong> {
- nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
- const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(0);
- if (messageEnvelope.uptime <= now) {
- // Remove the envelope from the list.
- // We keep a strong reference to the handler until the call to handleMessage
- // finishes. Then we drop it so that the handler can be deleted *before*
- // we reacquire our lock.
- { // obtain handler
- sp<MessageHandler> handler = messageEnvelope.handler;
- Message message = messageEnvelope.message;
- mMessageEnvelopes.removeAt(0);
- mSendingMessage = true;
- mLock.unlock();
- handler->handleMessage(message);
- } // release handler
- mLock.lock();
- mSendingMessage = false;
- result = ALOOPER_POLL_CALLBACK;
- } else {
- // The last message left at the head of the queue determines the next wakeup time.
- mNextMessageUptime = messageEnvelope.uptime;
- break;
- }
- }
- // Release lock.
- mLock.unlock();
- // Invoke all response callbacks.
- for (size_t i = 0; i < mResponses.size(); i++) {
- Response& response = mResponses.editItemAt(i);
- if (response.request.ident == ALOOPER_POLL_CALLBACK) {
- int fd = response.request.fd;
- int events = response.events;
- void* data = response.request.data;
- int callbackResult = response.request.callback->handleEvent(fd, events, data);
- if (callbackResult == 0) {
- removeFd(fd);
- }
- // Clear the callback reference in the response structure promptly because we
- // will not clear the response vector itself until the next poll.
- response.request.callback.clear();
- result = ALOOPER_POLL_CALLBACK;
- }
- }
- return result;
- }
pollOnce与pollInner的关系,请看看这篇博客:http://blog.csdn.net/broadview2006/article/details/8541727。
在Looper::pollInner函数中内部调用MessageQueue::mHandler处理消息?????
PS:(下面一段摘自大侠林学森的博客文章——Android显示系统之SurfaceFlinger(一))
这样子就构建了一个简洁而又完整的循环消息处理框架,SurfaceFlinger就是基于这个框架完成来自系统中各个程序的显示请求的。大家可能会有疑问,mHandler是由MessageQueue直接通过new Handler()生成的,这样的话如何能处理特定的SurfaceFlinger消息请求呢?个人感觉有这个困惑是由于Handler类取名不当引起的。实际上此Handler并非我们经常看到的那个Handler,这里的Handler是MessageQueue中自定义的一个事件处理器,也就是说它是专门为SurfaceFlinger设计的。
Step 10、MessageQueue::Handler::handleMessage()
代码位于frameworks/native/services/surfaceflinger/MessageQueue.cpp中。
- void MessageQueue::Handler::handleMessage(const Message& message) {
- switch (message.what) {
- case INVALIDATE:
- android_atomic_and(~eventMaskInvalidate, &mEventMask);
- mQueue.mFlinger->onMessageReceived(message.what);
- break;
- case REFRESH:
- android_atomic_and(~eventMaskRefresh, &mEventMask);
- mQueue.mFlinger->onMessageReceived(message.what);
- break;
- case TRANSACTION:
- android_atomic_and(~eventMaskTransaction, &mEventMask);
- mQueue.mFlinger->onMessageReceived(message.what);
- break;
- }
- }
附上一张网上大牛画的一张有关SurfaceFlinger的图,逻辑很清晰。