一、概述
SurfaceFlinger作为负责绘制应用UI的核心,Android平台所创建的Window都是由surface所支持,所有可见的surface渲染到显示设备都是通过SurfaceFlinger来完成的。
SurfaceFlinger进程是由init进程创建,运行在独立的SurfaceFlinger进程。Android应用进程必须和SurfaceFlinger进程交互,才能完成应用UI绘制到frameBuffer(帧缓冲区),这里是通过IPC的方式进行通信的。
SurfaceComposerClient对象是一个比较重要的类,WMS通过该类中的mClient、mParent和SurfaceFlinger进行交互。
1 | sp<ISurfaceComposerClient> mClient; |
每一个应用在SurfaceFlinger中都有一个client与之相对应,当应用执行onResume方法时流程如下:
1.WMS会请求SurfaceFlinger来绘制Surface;
2.SurfaceFlinger创建Layer;
3.一个生产者的Binder对象通过WMS传递给应用,因此应用可以直接向SurfaceFlinger发送帧消息。
二、启动过程
SurfaceFlinger启动是通过surfaceflinger.rc启动
[->native/services/surfaceflinger/surfaceflinger.rc]
1 | service surfaceflinger /system/bin/surfaceflinger |
SurfaceFlinger属于核心类,当SurfaceFlinger重启时会触发zygote重启,SurfaceFlinger服务启动是在其main函数中
2.1 main
[->native/services/surfaceflinger/main_surfaceflinger.cpp]
1 | int main(int, char**) { |
主要的工作如下:
1.启动图形处理服务
2.开启线程池,最大binder线程池数的个数为4
3.设置surfacefinger进程为高优先级以及后台调度策略
4.创建SurfaceFlinger,并初始化
5.注册SurfaceFlinger服务和GpuService
6.开启显示服务,最后执行surfacefinger的run方法
2.2 创建SurfaceFlinger
1 | SurfaceFlinger* DisplayUtils::getSFInstance() { |
[->G:/AOSP/native/services/surfaceflinger/SurfaceFlinger.cpp]
1 | SurfaceFlinger::SurfaceFlinger(SurfaceFlinger::SkipInitializationTag) |
SurfaceFlinger继承于BnSurfaceComposer,flinger的数据类型为sp强指针类型,当首次被强指针引用时会执行onFirstRef方法。
2.2.1 onFirstRef
[->G:/AOSP/native/services/surfaceflinger/SurfaceFlinger.cpp]
1 | void SurfaceFlinger::onFirstRef() |
2.2.2 MQ.init
[->G:/AOSP/native/services/surfaceflinger/MessageQueue.cpp]
1 | void MessageQueue::init(const sp<SurfaceFlinger>& flinger) { |
handler是MessageQueue的内部类,native层的handler机制和java层的一样
2.3 SF.init
[->native/services/surfaceflinger/SurfaceFlinger.cpp]
1 | // Do not call property_set on main thread which will be blocked by init |
2.3.1 创建HWComposer
[->native/services/surfaceflinger/DisplayHardware/HWComposer.cpp]
1 | HWComposer::HWComposer(std::unique_ptr<android::Hwc2::Composer> composer) |
2.3.2 processDisplayHotplugEventsLocked
1 | void SurfaceFlinger::processDisplayHotplugEventsLocked() { |
这里遍历连接的显示设备,这里的显示设置主要分成3类:主设备,拓展设备,虚拟设备,具体的处理操作在processDisplayChangesLocked函数中,见2.4.3节
1 | enum DisplayType { |
2.3.3 processDisplayChangesLocked
1 | void SurfaceFlinger::processDisplayChangesLocked() { |
2.3.4 initializeDisplays
[->native/services/surfaceflinger/SurfaceFlinger.cpp]
1 | void SurfaceFlinger::initializeDisplays() { |
这里通过handler发送消息,进行显示设备的初始化操作。
2.4 EventThread线程
[->native/services/surfaceflinger/EventThread.cpp]
1 | EventThread::EventThread(VSyncSource* src, ResyncWithRateLimitCallback resyncWithRateLimitCallback, |
EventThread继承于VSyncSource::Callback
2.4.1 onFirstRef
1 | void EventThread::Connection::onFirstRef() { |
注册显示设备事件
2.4.2 threadMain
1 | void EventThread::threadMain() NO_THREAD_SAFETY_ANALYSIS { |
2.4.3 waitForEventLocked
1 | // This will return when (1) a vsync event has been received, and (2) there was |
EventThread线程进入mCondition的wait方法,等待唤醒
2.5 setEventThread
[->native/services/surfaceflinger/MessageQueue.cpp]
1 | void MessageQueue::setEventThread(android::EventThread* eventThread) { |
这里主要是监听EventTube(类型为BitTube),当有数据来的时候,调用cb_eventReceiver方法
2.6 SF.run
[->native/services/surfaceflinger/SurfaceFlinger.cpp]
1 | void SurfaceFlinger::run() { |
这里是一个while循环,一直在等待消息,如果有消息就进行处理。
三、Vsync信号
前面2.4.1创建HWComposer过程中,会注册一些回调方法。
3.1 registerCallback
1 | //创建HWComposer |
当硬件产生Vsync信号时,则会回调onVsyncReceived方法,SurfaceFlinger继承ComposerCallback。
1 | class ComposerCallback { |
3.2 onVsyncReceived
1 | void SurfaceFlinger::onVsyncReceived(int32_t sequenceId, |
3.3 addResyncSample
[->native/services/surfaceflinger/DispSync.cpp]
1 | bool DispSync::addResyncSample(nsecs_t timestamp) { |
3.3.1 DispSync初始化
1 | void DispSync::init(bool hasSyncFramework, int64_t dispSyncPresentTimeOffset) { |
3.3.2 DispSyncThread.run
1 | virtual bool threadLoop() { |
3.4 DS.updateModelLocked
1 | void DispSync::updateModelLocked() { |
3.5 DST.updateModel
[->native/services/surfaceflinger/DispSync.cpp]
1 | void updateModel(nsecs_t period, nsecs_t phase, nsecs_t referenceTime) { |
后面进入到DispSyncThread线程,线程里面具体的执行方法在3.3.2中有详细介绍,这里主要看下 fireCallbackInvocations方法。
1 | void fireCallbackInvocations(const Vector<CallbackInvocation>& callbacks) { |
在SurfaceFlinger里面有调用init方法,其中创建了DispSyncSource对象,这里是调用了DispSyncSource的onDispSyncEvent方法。
3.6 DSS.onDispSyncEvent
[->native/services/surfaceflinger/SurfaceFlinger.cpp::DispSyncSource]
1 | virtual void onDispSyncEvent(nsecs_t when) { |
3.7 onVSyncEvent
1 | void EventThread::onVSyncEvent(nsecs_t timestamp) { |
mCondition.notify_all能够唤醒处理waitForEventLocked的EventThread(2.4.2),并执行postEvent
3.8 ET.postEvent
1 | status_t EventThread::Connection::postEvent(const DisplayEventReceiver::Event& event) { |
3.9 DER.sendEvents
[->native\libs\gui\DisplayEventReceiver.cpp]
1 | ssize_t DisplayEventReceiver::sendEvents(gui::BitTube* dataChannel, |
在2.5节中有监听BitTube,此处调用sendObjects,当收到数据时,则调用回调方法。
3.9.1 MQ.cb_eventReceiver
1 | int MessageQueue::cb_eventReceiver(int fd, int events, void* data) { |
3.9.2 MQ.eventReceiver
1 | int MessageQueue::eventReceiver(int /*fd*/, int /*events*/) { |
3.10 MQ.dispatchInvalidate
1 | void MessageQueue::Handler::dispatchInvalidate() { |
3.11 MQ.handleMessage
1 | void MessageQueue::Handler::handleMessage(const Message& message) { |
3.12 SF.onMessageReceived
1 | void SurfaceFlinger::onMessageReceived(int32_t what) { |
四、图像输出
上面经过Vsync信号后,经过层层调用到onMessageReceived方法,如果屏幕刷新,则会调用到handleMessageRefresh方法流程,具体如下:
4.1 SF.handleMessageRefresh
1 | void SurfaceFlinger::handleMessageRefresh() { |
4.2 SF.preComposition
1 | void SurfaceFlinger::preComposition(nsecs_t refreshStartTime) |
4.3 SF.rebuildLayerStacks
1 | void SurfaceFlinger::rebuildLayerStacks() { |
4.4 SF.setUpHWComposer
1 | void SurfaceFlinger::setUpHWComposer() { |
4.5 SF.doComposition
1 | void SurfaceFlinger::doComposition() { |
4.5.1 doDisplayComposition
1 | void SurfaceFlinger::doDisplayComposition( |
4.5.2 doComposeSurfaces
1 | bool SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& displayDevice) |
4.5.3 postFramebuffer
1 | void SurfaceFlinger::postFramebuffer() |
4.6 SF.postComposition
1 | void SurfaceFlinger::postComposition(nsecs_t refreshStartTime) |
五、总结
本文主要介绍了SurfaceFlinger和绘制相关的流程,首先介绍了SurfcaeFlinger的启动过程,后面分析Vsync信号如何进行通知屏幕的绘制,最后分析了屏幕的绘制图像输出流程。
这三个过程主要的线程如下:
- 主线程“/system/bin/surfaceflinger”: 主线程
- 线程“EventThread”:EventThread
- 线程“EventControl”: EventControlThread
- 线程“DispSync”:DispSyncThread
SurfcaeFlinger的启动过程
1.启动图形处理服务
2.开启线程池,最大binder线程池数的个数为4
3.设置SurfaceFlinger进程为高优先级以及后台调度策略
4.创建SurfaceFlinger,并初始化,启动app和sf的两个EventThread线程
5.注册SurfaceFlinger服务和GpuService
6.启动显示服务,最后执行surfacefinger的run方法
Vsync信号处理
1.如果要接收Vsync信号,则必须先注册,当Vsync信号来时会调用onVsyncReceived方法
2.通过调用DispSyncThread.updateModel中的mCond.signal() 来唤醒DispSyncThread线程;
3.执行EventThread::onVSyncEvent()方法中调用 mCondition.notify_all() 唤醒EventThread线程;
4.在DisplayEventReceiver.sendEvents调用BitTube::sendObjects,当收到数据时会执行MQ.cb_eventReceiver,然后通过handler消息机制进入到SurfaceFlinger主线程,调用SF.onMessageReceived方法
图形输出
1.根据上次绘制的图层是否有更新,来判断是否执行invalidate过程
2.重新每个显示屏所有可见点Layer列表
3.更新HWComposer图层
4.合成所有Layer的图像
5.回调每个Layer的onPostComposition