SurfaceFlinger浅析之初始化流程(上)

2022-10-09 12:34:48 浏览数 (2)

theme: fancy

大致流程: ISurfaceComposer 用于定义访问SurfaceFlinger的Binder IPC接口(应用的DisplayEventReceiver通过该接口向SurfaceFlinger发送创建事件连接的请求也就是createEventConnection),接着SF会创建Connection对象,再通过Connection对象获取BitTube对象(本质是Socket),Looper监听BitTube的fd,接受到事件后回调MQ的eventReceiver方法。

贴一张网上的图:

SurfaceFlinger main函数

代码语言:javascript复制
int main(int, char**) {
    ProcessState::self()->setThreadPoolMaxThreadCount(4);
    
    sp<ProcessState> ps(ProcessState::self());
    ps->startThreadPool();
    //实例化surfaceflinger
    sp<SurfaceFlinger> flinger =  new SurfaceFlinger();
    
    setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);
    set_sched_policy(0, SP_FOREGROUND);
    
    //初始化(调用init函数)
    flinger->init();
    
    //将SurfaceFliger添加到到Service Manager中
    sp<IServiceManager> sm(defaultServiceManager());
    sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);
    
    //调用run方法
    flinger->run();
    
    return 0;
}

总结流程

  • 实例化surfaceflinger
  • 初始化(调用init函数)
  • 将SurfaceFliger添加到到Service Manager中
  • 调用SurfaceFliger的run方法

SurfaceFlinger的init 大体流程:

代码语言:javascript复制
void SurfaceFlinger::init() {
    Mutex::Autolock _l(mStateLock);

    //初始化EGL,作为默认的显示
    mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    eglInitialize(mEGLDisplay, NULL, NULL);

    // 初始化硬件HWcomposer对象
    mHwc = new HWComposer(this, *static_cast<HWComposer::EventHandler *>(this));

    //获取RenderEngine引擎
    mRenderEngine = RenderEngine::create(mEGLDisplay, mHwc->getVisualID());

    //检索创建的EGL上下文
    mEGLContext = mRenderEngine->getEGLContext();

    //初始化非虚拟显示屏
    for (size_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i  ) {
        DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);
        //建立已连接的显示设备
        if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) {
            bool isSecure = true;
            createBuiltinDisplayLocked(type);
            wp<IBinder> token = mBuiltinDisplays[i];

            sp<IGraphicBufferProducer> producer;
            sp<IGraphicBufferConsumer> consumer;
            //创建BufferQueue的生产者和消费者
            BufferQueue::createBufferQueue(&amp;producer, &amp;consumer,
                    new GraphicBufferAlloc());

            sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i, consumer);
            int32_t hwcId = allocateHwcDisplayId(type);
            //创建显示设备
            sp<DisplayDevice> hw = new DisplayDevice(this,
                    type, hwcId, mHwc->getFormat(hwcId), isSecure, token,
                    fbs, producer,
                    mRenderEngine->getEGLConfig());
            if (i > DisplayDevice::DISPLAY_PRIMARY) {
                hw->setPowerMode(HWC_POWER_MODE_NORMAL);
            }
            mDisplays.add(token, hw);
        }
    }

    getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);

    //当应用和sf的vsync偏移量一致时,则只创建一个EventThread线程
    if (vsyncPhaseOffsetNs != sfVsyncPhaseOffsetNs) {
        sp<VSyncSource> vsyncSrc = new DispSyncSource(&amp;mPrimaryDispSync,
                vsyncPhaseOffsetNs, true, "app");
        mEventThread = new EventThread(vsyncSrc);
        sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&amp;mPrimaryDispSync,
                sfVsyncPhaseOffsetNs, true, "sf");
        mSFEventThread = new EventThread(sfVsyncSrc);
        mEventQueue.setEventThread(mSFEventThread);
    } else {
        //创建DispSyncSource对象
        sp<VSyncSource> vsyncSrc = new DispSyncSource(&amp;mPrimaryDispSync,
                vsyncPhaseOffsetNs, true, "sf-app");
        //创建线程EventThread
        mEventThread = new EventThread(vsyncSrc);
        //将创建的EventThread 保存至MQ中
        mEventQueue.setEventThread(mEventThread);
    }

    //创建EventControlThread线程并运行
    mEventControlThread = new EventControlThread(this);
    mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);

    //当不存在HWComposer时,则设置软件vsync模拟
    if (mHwc->initCheck() != NO_ERROR) {
        mPrimaryDispSync.setPeriod(16666667);
    }
}

初始化EGL检索EFL上下文

此部分后续查找资料分析

创建HWComposer

创建HWComposer模块(硬件显示设备 用于注册Vsync信号 由驱动发射)的初始化: HWComposer模块会判断硬件是否支持vsync即能否打开composer设备;当不支持时会创建一个线程来定时模拟Vsync信号来临(VsyncThread)

HWComposer内部 加载HAL层的HWComposer模块

HWComposer构造函数接受SurfaceFlinger参数,内部加载frameBuffer的HAL层模块和加载HWComposer模块,加载HWCompser模块成功后会进行注册Vsync的回调函数【后续硬件底层Vsync信号上来时也是该模块接收到】

代码部分:
代码语言:javascript复制
HWComposer::HWComposer(
        const sp<SurfaceFlinger>&amp; flinger,
        EventHandler&amp; handler)
    : mFlinger(flinger),
      mFbDev(0), mHwc(0), mNumDisplays(1),
      mCBContext(new cb_context),
      mEventHandler(handler),
      mDebugForceFakeVSync(false)
{
    ...
    bool needVSyncThread = true;
    int fberr = loadFbHalModule(); //加载framebuffer的HAL层模块
    loadHwcModule(); //加载HWComposer模块

    //标记已分配的display ID
    for (size_t i=0 ; i<NUM_BUILTIN_DISPLAYS ; i  ) {
        mAllocatedDisplayIDs.markBit(i);
    }

    if (mHwc) {
        if (mHwc->registerProcs) {
            mCBContext->hwc = this;
            mCBContext->procs.invalidate = &amp;hook_invalidate;
            //VSYNC信号的回调方法
            mCBContext->procs.vsync = &amp;hook_vsync;
            if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1))
                mCBContext->procs.hotplug = &amp;hook_hotplug;
            else
                mCBContext->procs.hotplug = NULL;
            memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero));
            //注册回调函数
            mHwc->registerProcs(mHwc, &amp;mCBContext->procs);
        }

        //进入此处,说明已成功打开硬件composer设备,则不再需要vsync线程
        needVSyncThread = false;
        eventControl(HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0);
        ...
    }
    ...

    if (needVSyncThread) {
        //不支持硬件的VSYNC,则会创建线程来模拟定时VSYNC信号
        mVSyncThread = new VSyncThread(*this);
    }
}

0 人点赞