目录
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方法。
贴一张网上的图:
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;
}
总结流程:
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);
}
}
此部分后续查找资料分析
创建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之后,将其放入到MQ中,通过调用**MessageQuene.setEventThread方法**实现。其内部调用eventThread的createEventConnection建立连接,在通过createEventConnection的返回值获取BitTube对象,获取BitTube的fd利用Looper的addFd来监听数据,一旦数据到来则调用MedssageQuene的cb_eventReceiver方法代表事件接受者处理。
当Vsync信号来临时再看此处监听的逻辑处理
#### MessageQueue::setEventThread
原文链接:SurfaceFlinger浅析之初始化流程(下) - 掘金 (juejin.cn)