1.1.3 SurfaceFlinger初始化&工作流程

1. SurfaceFlinger程序入口

/frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp

int main(int, char**) {     signal(SIGPIPE, SIG_IGN);       hardware::configureRpcThreadpool(1 /* maxThreads */,             false /* callerWillJoin */);       startGraphicsAllocatorService();       // When SF is launched in its own process, limit the number of     // binder threads to 4.     ProcessState::self()->setThreadPoolMaxThreadCount(4);       // Set uclamp.min setting on all threads, maybe an overkill but we want     // to cover important threads like RenderEngine.     if (SurfaceFlinger::setSchedAttr(true) != NO_ERROR) {         ALOGW("Couldn't set uclamp.min: %s\n", strerror(errno));     }       // The binder threadpool we start will inherit sched policy and priority     // of (this) creating thread. We want the binder thread pool to have     // SCHED_FIFO policy and priority 1 (lowest RT priority)     // Once the pool is created we reset this thread's priority back to     // original.     int newPriority = 0;     int origPolicy = sched_getscheduler(0);     struct sched_param origSchedParam;       int errorInPriorityModification = sched_getparam(0, &origSchedParam);     if (errorInPriorityModification == 0) {         int policy = SCHED_FIFO;         newPriority = sched_get_priority_min(policy);           struct sched_param param;         param.sched_priority = newPriority;           errorInPriorityModification = sched_setscheduler(0, policy, &param);     }       // start the thread pool     sp<ProcessState> ps(ProcessState::self());     ps->startThreadPool();       // Reset current thread's policy and priority     if (errorInPriorityModification == 0) {         errorInPriorityModification = sched_setscheduler(0, origPolicy, &origSchedParam);     } else {         ALOGE("Failed to set SurfaceFlinger binder threadpool priority to SCHED_FIFO");     }       // instantiate surfaceflinger     sp<SurfaceFlinger> flinger = surfaceflinger::createSurfaceFlinger();       // Set the minimum policy of surfaceflinger node to be SCHED_FIFO.     // So any thread with policy/priority lower than {SCHED_FIFO, 1}, will run     // at least with SCHED_FIFO policy and priority 1.     if (errorInPriorityModification == 0) {         flinger->setMinSchedulerPolicy(SCHED_FIFO, newPriority);     }       setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);       set_sched_policy(0, SP_FOREGROUND);       // Put most SurfaceFlinger threads in the system-background cpuset     // Keeps us from unnecessarily using big cores     // Do this after the binder thread pool init     if (cpusets_enabled()) set_cpuset_policy(0, SP_SYSTEM);       // initialize before clients can connect     flinger->init();       // publish surface flinger     sp<IServiceManager> sm(defaultServiceManager());     sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false,                    IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);       startDisplayService(); // dependency on SF getting registered above       if (SurfaceFlinger::setSchedFifo(true) != NO_ERROR) {         ALOGW("Couldn't set to SCHED_FIFO: %s", strerror(errno));     }       // run surface flinger in this thread     flinger->run();/ Use StartPropertySetThread instead. }     void SurfaceFlinger::onFirstRef() {     // std::unique_ptr<MessageQueue> mEventQueue;     mEventQueue->init(this); }   void MessageQueue::init(const sp<SurfaceFlinger>& flinger) {     mFlinger = flinger;     mLooper = new Looper(true);     mHandler = new Handler(*this); }

main方法是surfaceflinger的入口。该方法中关注到sp<SurfaceFlinger> flinger = surfaceflinger::createSurfaceFlinger()。这里创建了surfaceFlinger,实际上这里的sp隐含了一个方法调用——onFirstRef()。这个方法有点特殊,在代码层面看不到调用关系。实际上它是当强指针(sp-strong point)第一次被引用时,会被调用。继续可以看到在onFirstRef中执行了mEventQueue的init方法。继续看这个init方法,实际上创建了Looer和handler两个成员。这连个成员的作用是循环接受和发送消息,处理消息的作用。

注意到flinger→init()方法。该方法中调用mCompositionEngine->setRenderEngine(renderengine::RenderEngine::create初始化了renderEngine。renderEngine是用来做软件合成的。

// Use StartPropertySetThread instead. void SurfaceFlinger::init() { ALOGI( "SurfaceFlinger's main thread ready to run. " "Initializing graphics H/W..."); Mutex::Autolock _l(mStateLock);       // Get a RenderEngine for the given display / config (can't fail) // TODO(b/77156734): We need to stop casting and use HAL types when possible. // Sending maxFrameBufferAcquiredBuffers as the cache size is tightly tuned to single-display. mCompositionEngine->setRenderEngine(renderengine::RenderEngine::create( renderengine::RenderEngineCreationArgs::Builder() .setPixelFormat(static_cast<int32_t>(defaultCompositionPixelFormat)) .setImageCacheSize(maxFrameBufferAcquiredBuffers) .setUseColorManagerment(useColorManagement) .setEnableProtectedContext(enable_protected_contents(false)) .setPrecacheToneMapperShaderOnly(false) .setSupportsBackgroundBlur(mSupportsBlur) .setContextPriority( useContextPriority ? renderengine::RenderEngine::ContextPriority::REALTIME : renderengine::RenderEngine::ContextPriority::MEDIUM) .build()));

最后调用flinger->run()方法,进入消息等待中。