L上下文
mEGLContext = mRenderEngine->getEGLContext();
LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
"couldn't create EGLContext");
// make the GLContext current so that we can create textures when creating
// Layers (which may happens before we render something)即显示设备
getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
mEventControlThread = new EventControlThread(this);
mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);//创建EventControl // initialize our drawing state
mDrawingState = mCurrentState;
// set initial conditions (e.g. unblank default device)即初始化显示装备
initializeDisplays();
mRenderEngine->primeCache();
// start boot animation即启动开机动画
startBootAnim();
ALOGV("Done initializing");
}
(4)Android系统中有一个ServiceManager,专门用来管理所有的服务,而SurfaceFlinger不是由ServiceManager启动的,因此需要向ServiceManager注册SurfaceFlinger,同时还注册了GpuService。(在main函数里面注册)
(5)执行SF的run方法,SurfaceFlinger::run,进入消息循环,SurfaceFlinger启动成功,开始工作。代码如下:
void SurfaceFlinger::run() {
do {
waitForEvent();
} while (true);
}
(分析参考博客https://blog.csdn.net/u012439416/article/details/79733178)
waitForEvent方法如下:
mEventQueue.waitMessage();
MessageQueue的waitMessage方法也是一个do – while循环,里面逻辑如下:
>阻塞消息:
IPCThreadState::self()->flushCommands();
int32_t ret = mLooper->pollOnce(-1);
flushCommands方法主要是对binder驱动进行交互, 清理binder
pollOnce是消息机制,主要调用了epoll_wait函数,会阻塞,阻塞完了会分发消息队列中的消息。这里的消息只有自己在Handler中发的消息,还有在setEventThread中自己添加的消息。
>处理不同消息
2.2、工作流程
在执行SF的run方法时,SurfaceFlinger::run,进入MessageQueue.cpp中的waitForEvent方法:
当Surface绘制完成后会发出一个Invalidate的消息给Surfaceflinger的等待线程,当waitForEvent接收到消息后就会交给onMessageReceivered去处理,处理过程中会依次调用handleMessageTransaction、handleMessageInvalidate、handleMessageRefresh接口。
(1)调用handleMessageTransaction时,会调用:
> 有事务处理请求时,调用handleTransaction进行处理(getTransactionFlags)
> 调用handleTransactionLocked
> commitTransactionao提交事务
该函数主要处理之前对屏幕和应用程序窗口的改动。窗口状态的改变只能在一个Transaction中进行。因为窗口状态的改变可能造成本窗口和其他窗口的可见区域变化,所以就必须重新来计算窗口的可见区域。在这个处理子过程中Android会根据标志位来对所有layer进行遍历,一旦发现哪个窗口的状态发生了变化就设置标志位以在将来重新计算这个窗口的可见区域。
(2)调用handleMessageInvalidate时,会调用handlePageFlip
> handlePageFlip绘制(Layer从FrontBuffer中取得新数据,并生成一张OpenGL中的纹理。现在Layer准备好了数据,下一步开始进行绘制)
该函数主要调用handlePageFlip()函数,该函数主要是从各Layer对应的BufferQueue中拿图形缓冲区数据,并根据内容更新脏区域。
(3)handleMessageRefresh——进行合并和渲染输出:
(4)合并渲染完成后,该线程继续等待下一个invalidate消息。
4、总结(处理流程、交互模块)
4.1、处理流程
首先SF的启动过程:> 启动进程脚本.rc
> main_sf.cpp的main()函数
>> 启动线程池,设置线程最大数量
>> 实例化(创建对象)SF.cpp
>>> SF:SF构造函数,初始化一些成员变量
>>> (强指针<p>)SF::onFirstRef执行到MessageQueue.cpp,执行init()创建Handler、Looper
>> 设置进程优先级
>> 执行sf.init()初始化方法
>>> 初始化 graphics H/W ...,
>>> 创建对象显示设备HWComposer.cpp
>>> 创建event线程
>>> 初始化显示设备
>> 注册ServiceManager、GPUService
>> 运行SF.run()方法 (详细处理合成图像)
SF的工作流程分析(实现图像混合):
> 在run方法中waitForEvent等待事件(MessagQueu.cpp),收到重绘消息后,将退出等待,交给onMessageReceivered去处理
> ha