android graphic(3)—surfaceflinger的启动流程
来源:互联网 发布:win7网络加速器 编辑:程序博客网 时间:2024/05/16 11:22
- 如何启动
- 执行流程
- new SurfaceFlinger
- init函数
- run函数
- 给SF发消息
- SF处理消息
这篇文章只分析SF消息驱动流程的建立,不涉及具体的功能实现,关于SF和HWC如何交互后续分析,基于android 4.4,以下将surfaceflinger简称为SF。
如何启动
android 4.4中SF在init.rc中启动,如下所示:
service surfaceflinger /system/bin/surfaceflinger class main user system group graphics drmrpc onrestart restart zygote
可以看出,SF是/system/bin/下的一个应用程序,在makefile中搜索LOCAL_MODULE:= surfaceflinger
即可找到具体的makefile和代码,
#首先是个SF的动态库LOCAL_MODULE:= libsurfaceflingerinclude $(BUILD_SHARED_LIBRARY)# 其次是surfaceflinger,LOCAL_SRC_FILES:= \ main_surfaceflinger.cpp LOCAL_SHARED_LIBRARIES := \ libsurfaceflinger \ libcutils \ liblog \ libbinder \ libutilsLOCAL_MODULE:= surfaceflingerinclude $(BUILD_EXECUTABLE)
从上面makefile就能看出来,首先有个动态库libsurfaceflinger.so,然后SF只是对库的一个“封装调用”,多了一个main_surfaceflinger.cpp
,里面仅有个main函数,下面展开。
执行流程
只关注SF流程,不关注binder线程等。
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();#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(); // publish surface flinger sp<IServiceManager> sm(defaultServiceManager()); sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false); // run in this thread // ③ flinger->run(); return 0;}
main函数主要的内容包含三方面,逐步分析。
new SurfaceFlinger
首先,new了一个SF,并使用sp指针,所以我们需要关注SF类中是否实现了onFirstRef()函数。
sp<SurfaceFlinger> flinger = new SurfaceFlinger();
构造函数中初始化一些值,
SurfaceFlinger::SurfaceFlinger() : BnSurfaceComposer(), 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), mDebugFps(0), mDebugDisableTransformHint(0), mDebugInSwapBuffers(0), mLastSwapBufferTime(0), mDebugInTransaction(0), mLastTransactionTime(0), mBootFinished(false), mPrimaryHWVsyncEnabled(false), mHWVsyncAvailable(false), mDaltonize(false){//一些调试的变量等}
SF确实实现了onFirstRef()函数,
//mutable MessageQueue mEventQueue;void SurfaceFlinger::onFirstRef(){ mEventQueue.init(this);}
调用MessageQueue的init,在MessageQueue中建了一个Looper和Handler,注意不是java中的,native实现的。 到后面就可以看到SF的核心就是接收消息,处理消息。
void MessageQueue::init(const sp<SurfaceFlinger>& flinger){ mFlinger = flinger; mLooper = new Looper(true); mHandler = new Handler(*this);}
init函数
init中主要创建了OpenGL ES环境,对显示器的初始化等。
void SurfaceFlinger::init() { ALOGI( "SurfaceFlinger's main thread ready to run. " "Initializing graphics H/W..."); 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)); // 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); } if (err != NO_ERROR) { // still didn't work, probably because we're on the emulator... // try a simplified query ALOGW("no suitable EGLConfig found, trying a simpler query"); err = selectEGLConfig(mEGLDisplay, mHwc->getVisualID(), 0, &mEGLConfig); } if (err != NO_ERROR) { // this EGL is too lame for android LOG_ALWAYS_FATAL("no suitable EGLConfig found, giving up"); } // 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); ALOGI("EGL informations:"); ALOGI("vendor : %s", eglQueryString(mEGLDisplay, EGL_VENDOR)); ALOGI("version : %s", eglQueryString(mEGLDisplay, EGL_VERSION)); ALOGI("extensions: %s", eglQueryString(mEGLDisplay, EGL_EXTENSIONS)); ALOGI("Client API: %s", eglQueryString(mEGLDisplay, EGL_CLIENT_APIS)?:"Not Supported"); ALOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, mEGLConfig); // 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, false); 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();}
最后部分启动了开机动画程序bootanim,肯定是SF启动起来后才能去执行绘画相关的进程。
void SurfaceFlinger::startBootAnim() { // start boot animation property_set("service.bootanim.exit", "0"); property_set("ctl.start", "bootanim");}
run函数
run函数非常简单,但却是SF的核心,是个while循环,循环处理消息等。
void SurfaceFlinger::run() { do { waitForEvent(); } while (true);}
void SurfaceFlinger::waitForEvent() { mEventQueue.waitMessage();}
可以看到,接收处理消息的关键在mLooper->pollOnce(-1);
,
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);}
给SF发消息
首先关注如何给SF发送消息,以Client创建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; } //handler是执行消息动作的地方, 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); //调用SF的postMessageSync发送同步消息 mFlinger->postMessageSync(msg); return static_cast<MessageCreateLayer*>( msg.get() )->getResult();}
类MessageBase就是封装了类似于一个Handler,里面有个Barrier,我们能够猜到,这个Barrier 肯定是用来进行同步发送消息的,利用Barrier 去等待”wait”。
class MessageBase : public MessageHandler{public: MessageBase(); // return true if message has a handler virtual bool handler() = 0; // waits for the handler to be processed void wait() const { barrier.wait(); }protected: virtual ~MessageBase();private: virtual void handleMessage(const Message& message); mutable Barrier barrier;};
MessageBase的handleMessage函数,可以看到MessageBase的handler()函数是真正消息处理的地方,执行完成后,调用barrier.open();
,打开barrier,这样调用barrier.wait()
的地方就能退出了。
void MessageBase::handleMessage(const Message&) { this->handler(); barrier.open();};
接着分析mFlinger->postMessageSync(msg);
,这是给SF发同步消息的入口,当然也可以发异步消息,实现是类似的,
status_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg, nsecs_t reltime, uint32_t flags) { //向mEventQueue,即MessageQueue中发送消息 status_t res = mEventQueue.postMessage(msg, reltime); //这里等着,同步就在同步函数中等着 if (res == NO_ERROR) { msg->wait(); } return res; }
可以看到在同步发送消息中,barrier在postMessageSync函数中一直等着呢(wait),等待SF调用handleMessage()函数去将barrier这个栅栏打开(open)。
SF处理消息
上面提到,处理消息的关键就在mLooper->pollOnce(-1);
函数中,而pollOnce又会调用pollInner,只摘取了处理消息的一段,
int Looper::pollInner(int timeoutMillis) { // Invoke pending message callbacks. mNextMessageUptime = LLONG_MAX; while (mMessageEnvelopes.size() != 0) { 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();#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS ALOGD("%p ~ pollOnce - sending message: handler=%p, what=%d", this, handler.get(), message.what);#endif //处理消息啊 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; } }}
从上面代码可以看到,发给SF的消息被封装在MessageEnvelope结构中,SF一直在mMessageEnvelopes队列中从头部取出消息,然后执行,即handler->handleMessage(message);
,
void MessageBase::handleMessage(const Message&) { this->handler(); //打开栅栏 barrier.open();};
调用handleMessage执行handler(),所以SF创建Surface的核心代码就是SF的createLayer函数,
result = flinger->createLayer(name, client, w, h, format, flags, handle, gbp);
执行完成后,打开barrier。
- android graphic(3)—surfaceflinger的启动流程
- android graphic(3)—surfaceflinger的启动流程
- android graphic(4)—surfaceflinger和Vsync
- android graphic(6)—surfaceflinger和MessageQueue
- android graphic(4)—surfaceflinger和Vsync
- android graphic(6)—surfaceflinger和MessageQueue
- Android Graphic SurfaceFlinger 疑难解答
- Android Graphic SurfaceFlinger分析
- Android 4.4 Graphic系统详解(1) SurfaceFlinger的启动过程
- Android 4.4 Graphic系统详解(1) SurfaceFlinger的启动过程
- Android 4.4 Graphic系统详解(1) SurfaceFlinger的启动过程
- Android 4.4 Graphic系统详解(1) SurfaceFlinger的启动过程
- Android 4.4 Graphic系统详解(1) SurfaceFlinger的启动过程
- UNDERSTANDING ANDROID GRAPHIC- SURFACEFLINGER (IV)
- android graphic(5)—surfaceflinger和Vsync (简化)
- android graphic(5)—surfaceflinger和Vsync (简化)
- Android 4.2 JellyBean Graphic Component -- SurfaceFlinger 1
- Android 4.2 JellyBean Graphic Component -- SurfaceFlinger 2
- Android中使用Gson解析JSON数据
- 第四章:Mac OS X内核故事之从PowerPC到Intel:
- qt 通过样式表修改背景
- SQLite3
- 第五章:Mac OS X内核故事之从32位到64位
- android graphic(3)—surfaceflinger的启动流程
- ratio_to_report 分析函数求占比
- 这行代码你敢试试吗
- Eclipse安装Freemarker Editor插件
- 16.php代理模式
- 为程序申请管理员权限
- linux下安装memcached服务
- 设置iframe的高度自适应,无滚动条
- mcbsp