SurfaceFlinger浅析之初始化流程

目录

SurfaceFlinger main函数

SurfaceFlinger的init 大体流程:

初始化EGL检索EFL上下文

创建HWComposer

代码部分:

初始化非虚拟显示屏

代码部分:

EventThread::waitForEvent


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

贴一张网上的图:

SurfaceFlinger浅析之初始化流程_第1张图片

SurfaceFlinger main函数

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

总结流程

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

SurfaceFlinger的init 大体流程:

void SurfaceFlinger::init() {
    Mutex::Autolock _l(mStateLock);

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

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

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

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

    //初始化非虚拟显示屏
    for (size_t i=0 ; iisConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) {
            bool isSecure = true;
            createBuiltinDisplayLocked(type);
            wp token = mBuiltinDisplays[i];

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

            sp fbs = new FramebufferSurface(*mHwc, i, consumer);
            int32_t hwcId = allocateHwcDisplayId(type);
            //创建显示设备
            sp 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 vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
                vsyncPhaseOffsetNs, true, "app");
        mEventThread = new EventThread(vsyncSrc);
        sp sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
                sfVsyncPhaseOffsetNs, true, "sf");
        mSFEventThread = new EventThread(sfVsyncSrc);
        mEventQueue.setEventThread(mSFEventThread);
    } else {
        //创建DispSyncSource对象
        sp vsyncSrc = new DispSyncSource(&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信号上来时也是该模块接收到】

代码部分:
HWComposer::HWComposer(
        const sp& flinger,
        EventHandler& 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 ; iregisterProcs) {
            mCBContext->hwc = this;
            mCBContext->procs.invalidate = &hook_invalidate;
            //VSYNC信号的回调方法
            mCBContext->procs.vsync = &hook_vsync;
            if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1))
                mCBContext->procs.hotplug = &hook_hotplug;
            else
                mCBContext->procs.hotplug = NULL;
            memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero));
            //注册回调函数
            mHwc->registerProcs(mHwc, &mCBContext->procs);
        }

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

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

初始化非虚拟显示屏

(创建显示设备DisplayDevice及GraphicBufferQuene的生产者和消费者) 启动app和sf两个EventThread线程(应用和sf的vsync的偏移量不一样时)

主要工作:建立连接设备显示设备

必备条件解释: 显示设备需要消费GPU放入缓冲区的数据用于显示,所以需要创建1缓冲区及显示设备,缓冲区又分为生产者和消费者,因此创建显示设备前需要创建好FraphicBufferQuene的 生产者和消费者。

显示设备分为三类:主设备,扩展设备,虚拟设备,前两个是内置的显示设备,因此只创建两个显示设备即可。除此之外创建显示设备时还会创建FrameBufferSurface, 因此到现在为止创建了两个显示设备还有两个FrameBufferSurface及两个生产者(IGraphicBufferProducer)和消费者(IGraphicBufferConsumer)的GraphicBufferQuene

代码部分:

## 创建EventThread并保存到MQ中

**流程处理:**

创建DispSyncSource,利用DispSyncSource创建EventThread,再将创建的EventThread添加到MessageQuene中(mEventQuene.setEventhread)

\


提醒:

如果Vsync没有偏移,则只初始化一个DisplayVsyncSource(名字叫app-sf)和一个EventThread;否则初始化两个EventThread两个DisplayEventSource(名字分别是一个app用于处理,一个Sf用于合成)。

EventThread构造器需要DisplayVsyncSource参数,且内部会有一个集合用于存放其内部类Connection(singalConnections属性,代表需要接受Vsync连接的Connection连接)

EventThread的onFirstRef会调用其run方法,会进入到**EventThread的threadloop方法**中: 在这个方法中通过调用**waitForEvent**(等待事件)方法,参数为DisplayEventReceiver参数(客户端用于接受Vsync信号的类 , **EventThread中默认就有一个**)

#### EventThread::threadLoop

通过查找正在等待事件的连接集合数量(mDisplayEventConnection的长度)来确定singalConnections的长度,如果没有需要接受Vsync信号的Connection则condition.await阻塞休眠 当有需要接受事件的Connection时,遍历singalConnections集合分发给所有的Connection

收到Vsync信号时会唤醒这个Condition,之后遍历singalConnections调用其元素Conneciton的postEvent方法

EventThread::waitForEvent

当创建完EventThread之后,将其放入到MQ中,通过调用**MessageQuene.setEventThread方法**实现。其内部调用eventThread的createEventConnection建立连接,在通过createEventConnection的返回值获取BitTube对象,获取BitTube的fd利用Looper的addFd来监听数据,一旦数据到来则调用MedssageQuene的cb_eventReceiver方法代表事件接受者处理。

当Vsync信号来临时再看此处监听的逻辑处理

#### MessageQueue::setEventThread

原文链接:SurfaceFlinger浅析之初始化流程(下) - 掘金 (juejin.cn)​​​​​​​

你可能感兴趣的:(java,数据库,开发语言)