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

129 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第5天,点击查看活动详情

初始化非虚拟显示屏

(创建显示设备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

\