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 main函数

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 大体流程:

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(&producer, &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(&mPrimaryDispSync,
                vsyncPhaseOffsetNs, true, "app");
        mEventThread = new EventThread(vsyncSrc);
        sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
                sfVsyncPhaseOffsetNs, true, "sf");
        mSFEventThread = new EventThread(sfVsyncSrc);
        mEventQueue.setEventThread(mSFEventThread);
    } else {
        //创建DispSyncSource对象
        sp<VSyncSource> 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<SurfaceFlinger>& 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 ; i<NUM_BUILTIN_DISPLAYS ; i++) {
        mAllocatedDisplayIDs.markBit(i);
    }

    if (mHwc) {
        if (mHwc->registerProcs) {
            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)​​​​​​​

  • 11
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: SurfaceFlinger是Android系统中的一个重要组件,负责管理和显示所有的图形界面。它的显示流程如下: 1. 应用程序创建一个Surface对象,将图形数据发送给SurfaceFlinger。 2. SurfaceFlinger将图形数据存储在一个称为SurfaceTexture的缓冲区中。 3. SurfaceFlinger使用OpenGL ES对图形数据进行处理和渲染。 4. SurfaceFlinger将渲染后的图像发送到显示器。 5. 如果有多个应用程序同时发送图形数据,SurfaceFlinger会根据优先级和Z轴深度对它们进行排序和合成。 6. 最终,SurfaceFlinger将所有图形数据合成为一个图像,并将其显示在屏幕上。 总之,SurfaceFlinger是Android系统中的一个非常重要的组件,它负责管理和显示所有的图形界面,保证了Android系统的流畅性和稳定性。 ### 回答2: SurfaceFlinger是Android的图形渲染引擎,负责掌控所有图形对象的显示。下面是SurfaceFlinger的显示流程。 1. 确定显示设备:SurfaceFlinger首先要确定使用哪个硬件设备来显示图像。 2. 提取图形对象:SurfaceFlinger会提取界面中包含的所有图形对象,这些对象可以是应用程序创建的窗口,也可以是系统悬浮窗、状态栏、壁纸等。 3. 图形对象组装:SurfaceFlinger会将所有被提取的图形对象组装成层(layer),按照层级关系维护图形对象的顺序。 4. 图形对象合成:SurfaceFlinger会使用OpenGL ES对所有层进行合成,生成一张完整的帧缓存。 5. 帧缓存提交:SurfaceFlinger将生成的帧缓存提交给硬件设备进行显示。 整个显示过程中,SurfaceFlinger还负责处理窗口跨越的动画效果,以及处理图形对象的动态增加或删除等情况。 需要注意的是,在上述流程中,层级关系对于图形对象的显示非常重要。较上层的对象会覆盖掉较下层的对象,这个特性在界面中用于实现窗口的遮挡和浮动效果。而不同的层级可以有不同的属性,例如透明度等,这些属性也会影响它们在合成帧缓存时的表现。此外,每个图形对象在SurfaceFlinger内部都会有一个对应的Surface对象,Surface对象内部保存了该图形对象的像素数据,SurfaceFlinger会使用这些数据进行图形对象的合成和显示。 ### 回答3: SurfaceFlinger是Android操作系统用于显示图形的一个重要组件,它负责管理系统中所有显示的界面,包括应用程序UI、系统UI、动画效果及其它与显示相关的任务。下面我们简单介绍一下SurfaceFlinger的工作流程SurfaceFlinger在系统启动时便会启动,它通过系统调用EGL创建一个屏幕缓冲区(framebuffer),这个缓冲区是硬件加速的显存空间,它用于显示内容。应用程序或系统UI产生的每一个图形子集必须是基于帧缓冲区中的Surface对象,这些Surface对象可以是不同应用或UI组件的输出。这些输出通常是在本地内存中被创建或花费大量的CPU时间计算,但是它们最终都会被发送到SurfaceFlinger进行显示处理。 在处理单个图形子集之前,SurfaceFlinger使用双缓冲技术来管理整个帧缓冲区的更新。当一帧完全渲染后,SurfaceFlinger直接交换当前帧缓冲区与另一个缓冲区的指针,实现页面刷新的无缝过渡。这种技术可以避免一些出现残影和撕裂的问题。 处理一个图形子集通常分为三个阶段:更新、合并和显示。在更新阶段,渲染线程会对传入的图形数据进行处理,并将其写入屏幕缓冲区的一个Surface中。在合并阶段,SurfaceFlinger会将所有正在显示的Surface的像素数据合并到屏幕缓冲区的输出Surface中,并应用混合和过滤效果。最后,在显示阶段,渲染引擎会将输出Surface中的像素数据转发到帧缓冲区中,然后输出到屏幕上显示给用户。 除了处理图形子集外,SurfaceFlinger还负责处理用户输入,并将其传递给正在显示的应用程序或UI组件。用户输入通常包括触摸事件、按键事件、语音输入和手写输入等。 总之,SurfaceFlinger是Android系统中一个重要且复杂的组件,担负着管理和协调所有显示图像的任务,对于保证用户体验和操作流畅度起到了至关重要的作用。每个应用程序与SurfaceFlinger交互时,必须要遵循先进先出的原则,并且应用程序中应该尽可能地减少对SurfaceFlinger的请求,以保证更高的流畅度和性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

魏铁锤爱摸鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值