当前位置:   article > 正文

Android 7.1 GUI系统-vsync信号的产生和接收(五)_hwcomposer源码分析

hwcomposer源码分析

Vsync信号的产生。

以下代码基于高通msm8909芯片,android7.1的源码。

Vsync信号的产生有两种来源,一种是硬件,也就是显示模块产生;一中是软件模拟,因为目前基本都是硬件产生的,所以软件模拟的代码就没有分析的必要了。

接下来分析由硬件产生的vsync是怎么传到surfaceflinger的。

这个硬件源就是HWComposer,它一方面管理这composerhal模块,composer模块是厂商定制UI合成的接口,我们通常不会直接操作HWComposer模块,而是通过surfaceflinger使用它;另一方面就是产生vsync信号。

简单介绍下HWComposer,有很多名字类似的文件,

frameworks/native/services/surfaceflinger/displayhardware/目录下的HWComposer.hHWComposer.cpp这两个文件可以认为是硬件的抽象层,具体的硬件是指:hwcomposer#defineHWC_HARDWARE_MODULE_ID"hwcomposer"),HWComposer.cpp文件是android提供的标准的api,具体到硬件平台可能会稍微有点区别,比如msm8909android7.1的代码根据宏定义:TARGET_USES_HWC2,实际加载的文件是HWComposer_hwc1.cpp,相应的surfaceflinger对应的文件是SurfaceFlinger_hwc1.cpp


Hardware/libhardware/include/hardware/Hwcomposer.h;

hardware/libhardware/modules/hwcomposer/Hwcomposer.cpp这两个文件是hwchal模块。

相应的lib库是libhwcomposer.msm8909,库的实现代码在hardware/qcom/display/libhwcompser目录下,主要文件有hwc.cpphwc_vsync.cpphwc_uevents.cpphwc_utils.cpp等。

下面先看下hwcomposer这个模块的加载,这个模块是由surfaceflinger来加载的:

SurfaceFlinger_hwc1.cpp,如下代码中,只列出与hwcomposer,与vsync有关的代码。

  1. HWComposer* mHwc;
  2. void SurfaceFlinger::init() {
  3. //首先是启动EventThread线程, sfVsyncPhaseOffsetNs, vsyncPhaseOffsetNs这两个值都是1000000,在这两个值不等的情况下,会启动两个EventThread,一个是为surfaceflinger服务,一个是为有刷新UI需求的应用程序服务。这里走的是else。
  4. if (vsyncPhaseOffsetNs != sfVsyncPhaseOffsetNs) {
  5. }else{
  6. sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
  7. vsyncPhaseOffsetNs, true, "sf-app");
  8. mEventThread = new EventThread(vsyncSrc, *this);
  9. mEventQueue.setEventThread(mEventThread);
  10. }
  11. //初始化一个HWComposer对象。其中的参数一个是surfaceflinger自身,另一个其实也是surfaceflinger自身,只是其类型转成了HWComposer::EventHandler,可见surfaceflinger一定继承自HWComposer::EventHandler,并实现了其中接口onVSyncReceived等。
  12. mHwc = DisplayUtils::getInstance()->getHWCInstance(this,
  13. *static_cast<HWComposer::EventHandler *>(this));
  14. }

  1. DisplayUtils.cpp
  2. HWComposer* DisplayUtils::getHWCInstance(const sp<SurfaceFlinger>& flinger,
  3. HWComposer::EventHandler& handler) @DisplayUtils.cpp{
  4. //直接new了一个 HWComposer实例,转到其构造函数。
  5. return new HWComposer(flinger,handler);
  6. }

  1. HWComposer_hwc1.cpp
  2. HWComposer::HWComposer(const sp<SurfaceFlinger>& flinger,EventHandler& handler)
  3. : mFlinger(flinger),mEventHandler(handler)...{
  4. //首先加载FB的hal模块,对应设备用framebuffer_device_t* mFbDev表示;,然后加载Hwc模块,对应的设备用struct hwc_composer_device_1* mHwc表示。
  5. int fberr = loadFbHalModule();
  6. loadHwcModule();
  7. //这里注册硬件回调事件,这个事件就是vsync信号,先分析传入的参数 mCBContext->procs。
  8. if (mHwc) {
  9. if (mHwc->registerProcs) {
  10. //设置回调事件对应的方法实现,
  11. mCBContext->procs.invalidate = &hook_invalidate;
  12. mCBContext->procs.vsync = &hook_vsync;
  13. //注册硬件回调事件。
  14. mHwc->registerProcs(mHwc, &mCBContext->procs);
  15. }
  16. }
  17. }

Hwc模块的加载、准备的过程:


  1. HWComposer_hwc1.cpp
  2. void HWComposer::loadHwcModule(){
  3. hw_module_t const* module;
  4. //这里会加载相应的lib库, hw_get_module这个方法是上层使用者加载HAL库的通用入口,传入硬件模块的ID,在系统指定的目录加载正确的HAL库,以出参的形式的得到打开的硬件模块 module。
  5. if (hw_get_module(HWC_HARDWARE_MODULE_ID, &module) != 0) {
  6. return;
  7. }
  8. //调用硬件模块的open方法,打开指定的硬件设备,
  9. int err = hwc_open_1(module, &mHwc);
  10. }

hardware/libhardware/include/hardware/hardware.h

//每一个硬件模块都会定义的一个数据结构,


  1. typedef struct hw_module_t {
  2. //每一个HAL库都会提供的一个方法methods,
  3. struct hw_module_methods_t* methods;
  4. }hw_module_t;

  1. typedef struct hw_module_methods_t {
  2. //这个 methods的数据结构中只有一个函数指针变量open,用来打开指定的硬件设备。
  3. int (*open)(const struct hw_module_t* module, const char* id,
  4. struct hw_device_t** device);
  5. } hw_module_methods_t;

针对HWComposer模块,其相应的open函数是hwc_device_open

hwc.cpp

  1. static struct hw_module_methods_t hwc_module_methods = {
  2. .open = hwc_device_open
  3. };

//在打开这个hwc设备时,给很多函数指针赋了值,我们只关注dev->device.registerProcs = hwc_registerProcs;


  1. static int hwc_device_open(const struct hw_module_t* module, const char* name,
  2. struct hw_device_t** device)
  3. {
  4. int status = -EINVAL;
  5. if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
  6. struct hwc_context_t *dev;
  7. dev = (hwc_context_t*)malloc(sizeof(*dev));
  8. if(dev == NULL)
  9. return status;
  10. memset(dev, 0, sizeof(*dev));
  11. //Initialize hwc context
  12. initContext(dev);
  13. //Setup HWC methods
  14. dev->device.common.tag = HARDWARE_DEVICE_TAG;
  15. dev->device.common.version = HWC_DEVICE_API_VERSION_1_5;
  16. dev->device.common.module = const_cast<hw_module_t*>(module);
  17. dev->device.common.close = hwc_device_close;
  18. dev->device.prepare = hwc_prepare;
  19. dev->device.set = hwc_set;
  20. dev->device.eventControl = hwc_eventControl;
  21. dev->device.setPowerMode = hwc_setPowerMode;
  22. dev->device.query = hwc_query;
  23. dev->device.registerProcs = hwc_registerProcs;
  24. dev->device.dump = hwc_dump;
  25. dev->device.getDisplayConfigs = hwc_getDisplayConfigs;
  26. dev->device.getDisplayAttributes = hwc_getDisplayAttributes;
  27. dev->device.getActiveConfig = hwc_getActiveConfig;
  28. dev->device.setActiveConfig = hwc_setActiveConfig;
  29. *device = &dev->device.common;
  30. status = 0;
  31. }
  32. return status;
  33. }

然后分析注册硬件的回调的参数,这个参数mCBContext->procs会接收到hwc模块发出的vsync信号。

mCBContext的类型是cb_context*,定义如下:


  1. HWComposer_hwc1.cpp
  2. struct HWComposer::cb_context {
  3. //callbacks由继承自 hwc_procs_t,接着看下 hwc_procs_t的定义。
  4. struct callbacks : public hwc_procs_t {
  5. void (*zero[4])(void);
  6. };
  7. callbacks procs;
  8. HWComposer* hwc;
  9. };

hwc_procs_t的定义在hwcomposer.h中,


  1. hwcomposer.h
  2. typedef struct hwc_procs {
  3. //invalidate会触发屏幕刷新,在invalidate被调用不久会调用prepare和set,但是不保证调用了invalidate屏幕就一定会刷新,比如之前屏幕已经刷新过了,就不会在刷新。
  4. void (*invalidate)(const struct hwc_procs* procs);
  5. //vsync是分析这部分代码的目的,在收到一个vsync事件,并且HWC_EVENT_VSYNC是enabled的,这个vsync方法会被hwcomposer hal模块调用,其中的参数disp标示这个vsync事件是属于那个显示设备。
  6. void (*vsync)(const struct hwc_procs* procs, int disp, int64_t timestamp);
  7. //在一个显示设备连接或断开时会调用hotplug,主显示设备一直都是连接的,这个方法不会被调用,主要是针对可热插拔的设备。
  8. void (*hotplug)(const struct hwc_procs* procs, int disp, int connected);
  9. } hwc_procs_t;

分析完了HWComposer这边的参数,接着看下mHwc->registerProcs的实现,

hwc.cpp

//设置注册到HWC的回调函数。

  1. static void hwc_registerProcs(struct hwc_composer_device_1* dev,
  2. hwc_procs_t const* procs)
  3. {
  4. hwc_context_t* ctx = (hwc_context_t*)(dev);
  5. if(!ctx) {
  6. ALOGE("%s: Invalid context", __FUNCTION__);
  7. return;
  8. }
  9. //vsync将通过proc会调到HWComposer的vsync函数。
  10. ctx->proc = procs;
  11. //当有回调函数注册时,会启动uevent,vsync两个线程。uevent线程跟屏幕invalidate有关。
  12. init_uevent_thread(ctx);
  13. init_vsync_thread(ctx);
  14. }

//主要关注vsync线程的开启。


hwc_vsync.cpp

//创建一个线程,然后执行其vsync_loop方法。

  1. void init_vsync_thread(hwc_context_t* ctx){
  2. int ret;
  3. pthread_t vsync_thread;
  4. ret = pthread_create(&vsync_thread, NULL, vsync_loop, (void*) ctx);
  5. }

  1. static void *vsync_loop(void *param){
  2. //物理显示设备的个数。
  3. int num_displays = HWC_NUM_DISPLAY_TYPES – 1;
  4. //如果系统属性指定使用模拟vsync,把ctx->vstate.fakevsync = true;
  5. if(property_get("debug.hwc.fakevsync", property, NULL) > 0) {
  6. ctx->vstate.fakevsync = true;
  7. }
  8. //非模拟vsync的情况,当有多个显示设备时,对每个显示设备都要执行回调,发出通知。
  9. if (LIKELY(!ctx->vstate.fakevsync)) {
  10. do {
  11. for (int dpy = HWC_DISPLAY_PRIMARY; dpy < num_displays; dpy++) {
  12. event_list[ev].callback(ctx, dpy, vdata);
  13. }
  14. }while(true)
  15. }else{
  16. //使用模拟vsync的情况,通常是明确通过属性设置了或在开机时vsync时间戳节点还没打开,这时候会使用模拟vsync,模拟vsync指发给主显示设备。
  17. do {
  18. usleep(16666);
  19. uint64_t timestamp = systemTime();
  20. //这个回调就是执行的HWComposer的vsync方法。
  21. ctx->proc->vsync(ctx->proc, HWC_DISPLAY_PRIMARY, timestamp);
  22. }while(true)
  23. }
  24. }

HWComposer_hwc1.cpp

HWComposer这边vsync的接收函数是:hook_vsync,前面贴出的HWComposer的构造函数的代码中:mCBContext->procs.vsync= &hook_vsync; hook_vsync又调用了HWComposervsync方法。


  1. void HWComposer::vsync(int disp, int64_t timestamp) {
  2. //HWComposer直接通过mEventHandler把vsync信号传到surfaceflinger。
  3. mEventHandler.onVSyncReceived(disp, timestamp);
  4. }

//接着看surfaceflinger是如何处理vsync信号的。surfaceflinger中事件管理员是mEventQueue

它是MessageQueue类型的对象,所以vsync信号肯定是要送到mEventQueue中的,是怎么送过去的呢?这个过程比想的稍微复杂了点。

  1. SurfaceFlinger_hwc1.cpp
  2. void SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) {
  3. bool needsHwVsync = false;
  4. { // Scope for the lock
  5. Mutex::Autolock _l(mHWVsyncLock);
  6. if (type == 0 && mPrimaryHWVsyncEnabled) {
  7. needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp);
  8. }
  9. }
  10. if (needsHwVsync) {
  11. enableHardwareVsync();
  12. } else {
  13. disableHardwareVsync(false);
  14. }
  15. }

为了说清楚vsync的接收过程,还要看几个相关的类,从surfaceflinger的初始化开始。

  1. void SurfaceFlinger::init() {
  2. sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
  3. vsyncPhaseOffsetNs, true, "sf-app");
  4. mEventThread = new EventThread(vsyncSrc, *this);
  5. mEventQueue.setEventThread(mEventThread);
  6. mHwc = DisplayUtils::getInstance()->getHWCInstance(this,
  7. *static_cast<HWComposer::EventHandler *>(this));
  8. mEventControlThread = new EventControlThread(this);
  9. mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
  10. }

在这个初始化函数中,HWComposer前面已经分析过,接着简单介绍下几个类的主要功能。

1),mPrimaryDispSync实例的类型是DispSync,这个DispSync的主要作用是模拟软件的vsync源,在收到硬件模块hwc传来的vsync后,可能会disable掉硬件vsync源,不在执行回调HWComposer这边vsync的接收函数是:hook_vsync,控制硬件vsync源开、关的就是EventControlThread.cpp

DispSync在每次接收到硬件的vsync时,都会判断要不要继续使用硬件的vsync,这个判断的其中一个方法是addResyncSample,这个方法也是onVSyncReceived(SurfaceFlinger_hwc1.cpp中的vsync接收函数)中执行判断的依据。还有一个方法是addPresentFence,这个方法在surfaceflinger处理显示合成的后期会调用,判断是否要使用硬件hwcvsync


DispSyncswvsync信号,传给注册的监听者,是在线程的threadLoop循环中实现的。


  1. virtual bool threadLoop() {
  2. nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
  3. while (true) {
  4. //计算下一次的vsync时间,如果这个时间还没到,就wait一段时间差,
  5. targetTime = computeNextEventTimeLocked(now);
  6. if (now < targetTime) {
  7. err = mCond.waitRelative(mMutex, targetTime - now);
  8. }
  9. //获取都有那些监听,然后调用其回调onDispSyncEvent。
  10. callbackInvocations = gatherCallbackInvocationsLocked(now);
  11. fireCallbackInvocations(callbackInvocations);
  12. }
  13. }

2),接着EventControlThread怎样控制硬件vsync的开关。


  1. bool EventControlThread::threadLoop() {
  2. // mVsyncEnabled这个值在初始化 EventControlThread时赋值为false,
  3. bool vsyncEnabled = mVsyncEnabled;
  4. //这里会去调用HWComposer的实现。
  5. mFlinger->eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC,
  6. mVsyncEnabled);
  7. //在线程启动后,这个while循环会进入wait,直到调用它的setVsyncEnabled的方法把这个唤醒。初始化时mVsyncEnabled是false,那就是说线程刚启动时是把vsync关闭的,是后面初始化显示设备时通过 setVsyncEnabled打开了。
  8. while (true) {
  9. status_t err = mCond.wait(mMutex);
  10. if (err != NO_ERROR) {
  11. ALOGE("error waiting for new events: %s (%d)",
  12. strerror(-err), err);
  13. return false;
  14. }
  15. //唤醒后,判断要不要重新设置vsync的开、关。
  16. if (vsyncEnabled != mVsyncEnabled) {
  17. mFlinger->eventControl(HWC_DISPLAY_PRIMARY,
  18. SurfaceFlinger::EVENT_VSYNC, mVsyncEnabled);
  19. vsyncEnabled = mVsyncEnabled;
  20. }
  21. }
  22. //这里返回值是false,就是说这个线程的threadloop不会在被系统调用,换句话它他是一个单次循环,只是通过内部的while实现循环执行。
  23. return false;
  24. }

接着看EventControlThread线程被唤醒的条件:


  1. void EventControlThread::setVsyncEnabled(bool enabled) {
  2. Mutex::Autolock lock(mMutex);
  3. mVsyncEnabled = enabled;
  4. mCond.signal();
  5. }

只要有人调用setVsyncEnabled,通过mCond.signal();都会唤醒这个线程。第一次启动时谁会调用这个方法打开硬件的vsync呢?


大致列出调用逻辑以下方法都在SurfaceFlinger_hwc1.cpp中。

  1. void SurfaceFlinger::init() {
  2. //显示相关的初始化,这个调用在EventControlThread线程运行起来之后。
  3. initializeDisplays();
  4. }

通过异步消息,调用了onInitializeDisplays();


  1. void SurfaceFlinger::initializeDisplays() {
  2. class MessageScreenInitialized : public MessageBase {
  3. virtual bool handler() {
  4. flinger->onInitializeDisplays();
  5. }
  6. };
  7. sp<MessageBase> msg = new MessageScreenInitialized(this);
  8. postMessageAsync(msg);
  9. }

  1. void SurfaceFlinger::onInitializeDisplays() {
  2. //这个方法在每次点亮屏幕时都会被调用,针对主显示屏来说,应该是每次点两屏,都会重新打开硬件模块hwc的vsync。
  3. setPowerModeInternal(getDisplayDevice(d.token), HWC_POWER_MODE_NORMAL);
  4. }

既然点亮屏时会enable硬件hwcvsync,息屏时也会disable硬件hwcvsync

  1. void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& hw,
  2. int mode) {
  3. mEventThread->onScreenAcquired();
  4. resyncToHardwareVsync(true);
  5. }

  1. void SurfaceFlinger::resyncToHardwareVsync(bool makeAvailable) {
  2. //这里调用了EventControlThread中的 setVsyncEnabled,参数true,会enable硬件的vsync。同时注意这里的变量 mPrimaryHWVsyncEnabled = true,这个变量是 SurfaceFlinger::onVSyncReceived的中一个判断条件,在收到硬件hwc的vsync回调时,判断要不要disable硬件vsync。
  3. mEventControlThread->setVsyncEnabled(true);
  4. mPrimaryHWVsyncEnabled = true;
  5. }

最后看看mFlinger->eventControl()是如何控制vsync的。

  1. void SurfaceFlinger::eventControl(int disp, int event, int enabled) {
  2. ATRACE_CALL();
  3. //直接调用了HWComposer_hwc1.cpp中的实现。
  4. getHwComposer().eventControl(disp, event, enabled);
  5. }

  1. void HWComposer::eventControl(int disp, int event, int enabled) @HWComposer_hwc1.cpp{
  2. err = mHwc->eventControl(mHwc, disp, event, enabled);
  3. //根据enabled,让HWComposer::VSyncThread::VSyncThread线程wait或者唤醒。
  4. mVSyncThread->setEnabled(enabled);
  5. }

mHwc->eventControl()最终的实现在hwc_vsync.cpp,通过IO命令控制硬件vsync

  1. int hwc_vsync_control(hwc_context_t* ctx, int dpy, int enable)@hwc_vsync.cpp{
  2. ioctl(ctx->dpyAttr[dpy].fd, MSMFB_OVERLAY_VSYNC_CTRL, &enable);
  3. }

3),DispSyncSource,这个类是SurfaceFlinger_hwc1.cpp的内部类,他的构造函数中持有DispSync的引用,即mDispSync,这个类的主要功能是通过mDispSync添加、删除对vsyncDispSync中的)的监听,并接收vsync(来自DispSync)回调。

这个函数虽然也叫vsyncenabled,实际只是向DispSync添加、删除对vsync的监听。


  1. virtual void setVSyncEnabled(bool enable) @SurfaceFlinger_hwc1.cpp$DispSyncSource{
  2. if (enable) {
  3. status_t err = mDispSync->addEventListener(mName, mPhaseOffset,
  4. static_cast<DispSync::Callback*>(this));
  5. }else{
  6. status_t err = mDispSync→removeEventListener(
  7. static_cast<DispSync::Callback*>(this));
  8. }
  9. }

DispSync注册的监听vsync的回调类型是DispSync::CallbackDispSyncSource继承了这个类,并实现了其中的方法onDispSyncEvent

DispSync会把软件vsync信号通过注册的监听,回调其onDispSyncEvent函数。

  1. virtual void onDispSyncEvent(nsecs_t when) @SurfaceFlinger_hwc1.cpp$DispSyncSource{
  2. sp<VSyncSource::Callback> callback;
  3. callback = mCallback;
  4. callback->onVSyncEvent(when);
  5. }

这里出现了VSyncSource::Callback的回调,vsync信号会传到VSyncSource::Callback类中的onVSyncEvent函数。

这个VSyncSource::Callback的实现具体是什么?

surfaceflinger的初始化(init()函数)中,有这么一句代码:


mEventThread = new EventThread(vsyncSrc, *this);

其中参数vsyncSrc就是DispSyncSource,所以接着看EventThread线程的实现。这个线程在他第一次被引用时,由其强指针的特性执行其onFirstRef方法,让这个线程运行起来,第一次被引用的地方就是紧接着实例化其对象的代码:

mEventQueue.setEventThread(mSFEventThread);

这里让surfaceflinger的消息管理员mEventQueueMessageQueue)跟EventThread线程绑定,现在越来越接近目标了,还记得分析这段的目的是想弄明白vsync信号是怎么传到surfaceflingermEventQueue的。

  1. bool EventThread::threadLoop() @EventThread.cpp{
  2. signalConnections = waitForEvent(&event);
  3. }

waitForEvent会调用下面的enableVSyncLocked函数,然后通过DispSyncSourcesetCallback函数,设置一个类型是VSyncSource::Callback的回调,这个回调的实现端就是EventThread自身。


  1. void EventThread::enableVSyncLocked() @EventThread.cpp{
  2. mVSyncSource->setCallback(static_cast<VSyncSource::Callback*>(this));
  3. }

所以前面DispSync会先把vsync信号通过回调传到DispSyncSourceonDispSyncEvent,最后在传到EventThreadonVSyncEvent函数。



4),EventThread是如何处理vsync信号的。

  1. void EventThread::onVSyncEvent(nsecs_t timestamp) @EventThread.cpp{
  2. Mutex::Autolock _l(mLock);
  3. mVSyncEvent[0].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
  4. mVSyncEvent[0].header.id = 0;
  5. mVSyncEvent[0].header.timestamp = timestamp;
  6. mVSyncEvent[0].vsync.count++;
  7. mCondition.broadcast();
  8. }

上面的函数做了两件事情,一是填充了DisplayEventReceiver::Event类型的事件对象mVSyncEvent,主要包括事件的类型DisplayEventReceiver::DISPLAY_EVENT_VSYNC,还有事件戳timestamp。另外一个事情是mCondition.broadcast(),唤醒等待的EventThread线程。

EventThread线程什么情况下wait的呢?一种情况是没有对vsync感兴趣的客户端,另一种情况是正在等待vsync信号的产生,还有一种情况是当前屏幕是off,不需要vsync,这是会进入一个16ms的超时等待。

唤醒之后,线程继续循环。

  1. bool EventThread::threadLoop() @EventThread.cpp{
  2. DisplayEventReceiver::Event event;
  3. Vector< sp<EventThread::Connection> > signalConnections;
  4. //线程就是在waitForEvent中进入等待的。
  5. signalConnections = waitForEvent(&event);
  6. //开始分发vsync给所有的监听者,eventthread处理的事件不是只有vsync,还有DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG;
  7. const size_t count = signalConnections.size();
  8. for (size_t i=0 ; i<count ; i++) {
  9. const sp<Connection>& conn(signalConnections[i]);
  10. status_t err = conn->postEvent(event);
  11. }
  12. //返回值true,系统会再次调用这个线程的threadloop,从而形成一个循环。
  13. return true;
  14. }

waitForEvent除了会让线程进入wait,还有一个作用是找出等待事件的connections,也即是对vsync感兴趣的监听者,找出来后保存在signalConnections中。所有对vsync感兴趣的监听者都会被保存在mDisplayEventConnections中。

通常有两类监听者,


一类是surfaceflinger,它负责UI数据的合成,肯定要受vsync信号的触发。负责vsync接收的是surfaceflinger的事件管理员MessageQueue,相应的实例对象是mEventQueue,前面提到当实例化EventThread对象后,mEventQueue就跟EventThread执行了绑定,具体代码:


  1. void MessageQueue::setEventThread(const sp<EventThread>& eventThread)
  2. {
  3. mEventThread = eventThread;
  4. mEvents = eventThread->createEventConnection();
  5. mEventTube = mEvents->getDataChannel();
  6. mLooper->addFd(mEventTube->getFd(), 0, Looper::EVENT_INPUT,
  7. MessageQueue::cb_eventReceiver, this);
  8. }

首先通过eventThread的接口createEventConnection创建了一个Connection,赋值给mEvents,并且当这个Connection实例被引用时,会执行其onFirstRef方法,将这个Connection注册到EventThread中,把这个connection保存到EventThread中的变量mDisplayEventConnections中。


  1. void EventThread::Connection::onFirstRef() {
  2. mEventThread->registerDisplayEventConnection(this);
  3. }

mEvents的类型是sp<IDisplayEventConnection>,也即是Connection的客户端,对应的服务端的实现是EventThread的内部类Connection,这个可以从它的继承关系看出:

class Connection : public BnDisplayEventConnection {}

Connection继承了BnDisplayEventConnection

然后,通过mEvents获取一个mEventTube,这个BitTube的实质是socketpair,它有一个发送端,一个接收端。

最后通过mEventTube->getFd()获取了socketpair的接收端,并且给这个接收设置了回调MessageQueue::cb_eventReceiver,通过Looper接口addFd把他们加入到Looper中的监视请求列表mRequests,我们知道主线程循环从消息队列中取消息时,会调用LooperpollOnce,然后是pollInner,在这个pollInner中,只要有事件需要处理,就会执行其callback函数,在这个场景中,就会执行MessageQueue::cb_eventReceiver

弄清楚了事件的接收端,那事件的发送端在哪里呢?负责发送的服务端就是EventThread,具体实现就是下面的postEvent


  1. bool EventThread::threadLoop() {
  2. status_t err = conn->postEvent(event);
  3. }

//mChannel就是前面说的BitTube,会通过其mSendFdevent数据写入。

  1. status_t EventThread::Connection::postEvent(
  2. const DisplayEventReceiver::Event& event) {
  3. ssize_t size = DisplayEventReceiver::sendEvents(mChannel, &event, 1);
  4. return size < 0 ? status_t(size) : status_t(NO_ERROR);
  5. }

第二类对vsync感兴趣的监听者是应用程序,不在详细分析,只把它创建connection的过程列一下。

每一个有窗口的应用进程,都会有一个渲染线程RenderThread

  1. frameworks/base/libs/hwui/renderthread/
  2. bool RenderThread::threadLoop() @RenderThread.cpp{
  3. initThreadLocals();
  4. }

  1. void RenderThread::initThreadLocals() {
  2. initializeDisplayEventReceiver();
  3. }

//接收vsync的回调RenderThread::displayEventReceiverCallback,


  1. void RenderThread::initializeDisplayEventReceiver() {
  2. mDisplayEventReceiver = new DisplayEventReceiver();
  3. mLooper->addFd(mDisplayEventReceiver->getFd(), 0,
  4. Looper::EVENT_INPUT, RenderThread::displayEventReceiverCallback, this);
  5. }

//先获取surfaceflinger的句柄

ISurfaceComposer

  1. DisplayEventReceiver::DisplayEventReceiver() {
  2. sp<ISurfaceComposer> sf(ComposerService::getComposerService());
  3. if (sf != NULL) {
  4. mEventConnection = sf->createDisplayEventConnection();
  5. if (mEventConnection != NULL) {
  6. mDataChannel = mEventConnection->getDataChannel();
  7. }
  8. }
  9. }

//调用eventthread中接口createEventConnection

  1. sp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
  2. return mEventThread->createEventConnection();
  3. }

  1. sp<EventThread::Connection> EventThread::createEventConnection() const {
  2. return new Connection(const_cast<EventThread*>(this));
  3. }




声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/504092
推荐阅读
相关标签
  

闽ICP备14008679号