- 方法一: 隨著zygote啟動(Default)
啟動的流程是 main@SystemServer.java ->system_init@com_android_server_SystemServer.cpp
->system_init@system_init.cpp
在system_init的function裡寫著
property_get("system_init.startsurfaceflinger", propBuf, "1"); if (strcmp(propBuf, "1") == 0) { // Start the SurfaceFlinger SurfaceFlinger::instantiate(); } ... ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool();
因此,假設系統中不存在"system_init.startsensorservice"就會執行SurfaceFlinger::instantiate();定義 在BinderService.h 最終執行
sm->addService(String16(SERVICE::getServiceName()), new SERVICE());
將surfaceflinger加入系統的service.
我們可以在例如init.rc裡面直接去啟動surfaceflinger,程式碼位置是main_surfaceflinger.cpp 程式碼的內容是
sm->addService(String16(SERVICE::getServiceName()), new SERVICE());
將surfaceflinger加入系統的service.
- 方法二:直接執行surfaceflinger
我們可以在例如init.rc裡面直接去啟動surfaceflinger,程式碼位置是main_surfaceflinger.cpp 程式碼的內容是
int main(int argc, char** argv) { SurfaceFlinger::publishAndJoinThreadPool(); return 0; }SurfaceFlinger定義在SurfaceFlinger.h,而他是繼承BinderService 定義在BinderService.h 因此,我們可以在 BinderService.h看到 publishAndJoinThreadPool()的實做
spproc(ProcessState::self()); sp sm(defaultServiceManager()); sm->addService(String16(SERVICE::getServiceName()), new SERVICE()); ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool();
兩種方法都是利用
sm->addService(String16(SERVICE::getServiceName()), new SERVICE());將surfaceflinger加入service並利用
ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool();進入surfaceflinger裡的
SurfaceFlinger::readyToRun()定義在Thread::_threadLoop@Threads.cpp
... self->mStatus = self->readyToRun(); ...readyToRun()會做幾件事:
- 建立GraphicPlane
GraphicPlane& plane(graphicPlane(dpy)); DisplayHardware* const hw = new DisplayHardware(this, dpy); plane.setDisplayHardware(hw);
- 如果是framebuffer的話,會呼叫fb_device_open()@framebuffer.cpp 在裡面要注意的是他透過mapFrameBuffer()->mapFrameBufferLocked()嘗試開啟
- 初始化EGL
- 取得Display資訊
char const * const device_template[] = { "/dev/graphics/fb%u", "/dev/fb%u", 0 };與kernel做溝通. 如果是graphic的話就要看平台實做了。
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); eglInitialize(display, NULL, NULL); eglGetConfigs(display, NULL, 0, &numConfigs); err = selectConfigForPixelFormat(display, attribs, format, &config);
surface = eglCreateWindowSurface(display, config, mNativeWindow.get(), NULL); if (mFlags & PARTIAL_UPDATES) { // if we have partial updates, we definitely don't need to // preserve the backbuffer, which may be costly. eglSurfaceAttrib(display, surface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED); }
if (property_get("qemu.sf.lcd_density", property, NULL) <= 0) { if (property_get("ro.sf.lcd_density", property, NULL) <= 0) { LOGW("ro.sf.lcd_density not defined, using 160 dpi by default."); strcpy(property, "160"); } } else { /* for the emulator case, reset the dpi values too */ mDpiX = mDpiY = atoi(property); } mDensity = atoi(property) * (1.0f/160.0f);
context = eglCreateContext(display, config, NULL, contextAttributes);context存放著當前的 顏色,texture 等等的資訊
eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
mHwc = new HWComposer(mFlinger); if (mHwc->initCheck() == NO_ERROR) { mHwc->setFrameBuffer(mDisplay, mSurface); }
property_set("ctl.start", "bootanim");在readyToRun()跑完之後,就會進入SurfaceFlinger::threadLoop()在下一篇會討論