赞
踩
Vsync信号的产生。
以下代码基于高通msm8909芯片,android7.1的源码。
Vsync信号的产生有两种来源,一种是硬件,也就是显示模块产生;一中是软件模拟,因为目前基本都是硬件产生的,所以软件模拟的代码就没有分析的必要了。
接下来分析由硬件产生的vsync是怎么传到surfaceflinger的。
这个硬件源就是HWComposer,它一方面管理这composer的hal模块,composer模块是厂商定制UI合成的接口,我们通常不会直接操作HWComposer模块,而是通过surfaceflinger使用它;另一方面就是产生vsync信号。
简单介绍下HWComposer,有很多名字类似的文件,
frameworks/native/services/surfaceflinger/displayhardware/目录下的HWComposer.h,HWComposer.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这两个文件是hwc的hal模块。
相应的lib库是libhwcomposer.msm8909,库的实现代码在hardware/qcom/display/libhwcompser目录下,主要文件有hwc.cpp,hwc_vsync.cpp,hwc_uevents.cpp,hwc_utils.cpp等。
下面先看下hwcomposer这个模块的加载,这个模块是由surfaceflinger来加载的:
SurfaceFlinger_hwc1.cpp,如下代码中,只列出与hwcomposer,与vsync有关的代码。
- HWComposer* mHwc;
- void SurfaceFlinger::init() {
- //首先是启动EventThread线程, sfVsyncPhaseOffsetNs, vsyncPhaseOffsetNs这两个值都是1000000,在这两个值不等的情况下,会启动两个EventThread,一个是为surfaceflinger服务,一个是为有刷新UI需求的应用程序服务。这里走的是else。
- if (vsyncPhaseOffsetNs != sfVsyncPhaseOffsetNs) {
- }else{
- sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
- vsyncPhaseOffsetNs, true, "sf-app");
- mEventThread = new EventThread(vsyncSrc, *this);
- mEventQueue.setEventThread(mEventThread);
- }
- //初始化一个HWComposer对象。其中的参数一个是surfaceflinger自身,另一个其实也是surfaceflinger自身,只是其类型转成了HWComposer::EventHandler,可见surfaceflinger一定继承自HWComposer::EventHandler,并实现了其中接口onVSyncReceived等。
- mHwc = DisplayUtils::getInstance()->getHWCInstance(this,
- *static_cast<HWComposer::EventHandler *>(this));
- }
- DisplayUtils.cpp
- HWComposer* DisplayUtils::getHWCInstance(const sp<SurfaceFlinger>& flinger,
- HWComposer::EventHandler& handler) @DisplayUtils.cpp{
- //直接new了一个 HWComposer实例,转到其构造函数。
- return new HWComposer(flinger,handler);
- }
- HWComposer_hwc1.cpp
- HWComposer::HWComposer(const sp<SurfaceFlinger>& flinger,EventHandler& handler)
- : mFlinger(flinger),mEventHandler(handler)...{
- //首先加载FB的hal模块,对应设备用framebuffer_device_t* mFbDev表示;,然后加载Hwc模块,对应的设备用struct hwc_composer_device_1* mHwc表示。
- int fberr = loadFbHalModule();
- loadHwcModule();
- //这里注册硬件回调事件,这个事件就是vsync信号,先分析传入的参数 mCBContext->procs。
- if (mHwc) {
- if (mHwc->registerProcs) {
- //设置回调事件对应的方法实现,
- mCBContext->procs.invalidate = &hook_invalidate;
- mCBContext->procs.vsync = &hook_vsync;
- //注册硬件回调事件。
- mHwc->registerProcs(mHwc, &mCBContext->procs);
- }
- }
- }
Hwc模块的加载、准备的过程:
- HWComposer_hwc1.cpp
- void HWComposer::loadHwcModule(){
- hw_module_t const* module;
- //这里会加载相应的lib库, hw_get_module这个方法是上层使用者加载HAL库的通用入口,传入硬件模块的ID,在系统指定的目录加载正确的HAL库,以出参的形式的得到打开的硬件模块 module。
- if (hw_get_module(HWC_HARDWARE_MODULE_ID, &module) != 0) {
- return;
- }
- //调用硬件模块的open方法,打开指定的硬件设备,
- int err = hwc_open_1(module, &mHwc);
- }
hardware/libhardware/include/hardware/hardware.h
//每一个硬件模块都会定义的一个数据结构,
- typedef struct hw_module_t {
- //每一个HAL库都会提供的一个方法methods,
- struct hw_module_methods_t* methods;
- }hw_module_t;
- typedef struct hw_module_methods_t {
- //这个 methods的数据结构中只有一个函数指针变量open,用来打开指定的硬件设备。
- int (*open)(const struct hw_module_t* module, const char* id,
- struct hw_device_t** device);
- } hw_module_methods_t;
针对HWComposer模块,其相应的open函数是hwc_device_open:
hwc.cpp
- static struct hw_module_methods_t hwc_module_methods = {
- .open = hwc_device_open
- };
//在打开这个hwc设备时,给很多函数指针赋了值,我们只关注dev->device.registerProcs = hwc_registerProcs;。
- static int hwc_device_open(const struct hw_module_t* module, const char* name,
- struct hw_device_t** device)
- {
- int status = -EINVAL;
-
- if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
- struct hwc_context_t *dev;
- dev = (hwc_context_t*)malloc(sizeof(*dev));
- if(dev == NULL)
- return status;
- memset(dev, 0, sizeof(*dev));
-
- //Initialize hwc context
- initContext(dev);
-
- //Setup HWC methods
- dev->device.common.tag = HARDWARE_DEVICE_TAG;
- dev->device.common.version = HWC_DEVICE_API_VERSION_1_5;
- dev->device.common.module = const_cast<hw_module_t*>(module);
- dev->device.common.close = hwc_device_close;
- dev->device.prepare = hwc_prepare;
- dev->device.set = hwc_set;
- dev->device.eventControl = hwc_eventControl;
- dev->device.setPowerMode = hwc_setPowerMode;
- dev->device.query = hwc_query;
- dev->device.registerProcs = hwc_registerProcs;
- dev->device.dump = hwc_dump;
- dev->device.getDisplayConfigs = hwc_getDisplayConfigs;
- dev->device.getDisplayAttributes = hwc_getDisplayAttributes;
- dev->device.getActiveConfig = hwc_getActiveConfig;
- dev->device.setActiveConfig = hwc_setActiveConfig;
- *device = &dev->device.common;
- status = 0;
- }
- return status;
- }
然后分析注册硬件的回调的参数,这个参数mCBContext->procs会接收到hwc模块发出的vsync信号。
mCBContext的类型是cb_context*,定义如下:
- HWComposer_hwc1.cpp
- struct HWComposer::cb_context {
- //callbacks由继承自 hwc_procs_t,接着看下 hwc_procs_t的定义。
- struct callbacks : public hwc_procs_t {
- void (*zero[4])(void);
- };
- callbacks procs;
- HWComposer* hwc;
- };
hwc_procs_t的定义在hwcomposer.h中,
- hwcomposer.h
- typedef struct hwc_procs {
- //invalidate会触发屏幕刷新,在invalidate被调用不久会调用prepare和set,但是不保证调用了invalidate屏幕就一定会刷新,比如之前屏幕已经刷新过了,就不会在刷新。
- void (*invalidate)(const struct hwc_procs* procs);
- //vsync是分析这部分代码的目的,在收到一个vsync事件,并且HWC_EVENT_VSYNC是enabled的,这个vsync方法会被hwcomposer hal模块调用,其中的参数disp标示这个vsync事件是属于那个显示设备。
- void (*vsync)(const struct hwc_procs* procs, int disp, int64_t timestamp);
- //在一个显示设备连接或断开时会调用hotplug,主显示设备一直都是连接的,这个方法不会被调用,主要是针对可热插拔的设备。
- void (*hotplug)(const struct hwc_procs* procs, int disp, int connected);
- } hwc_procs_t;
分析完了HWComposer这边的参数,接着看下mHwc->registerProcs的实现,
hwc.cpp
//设置注册到HWC的回调函数。
- static void hwc_registerProcs(struct hwc_composer_device_1* dev,
- hwc_procs_t const* procs)
- {
- hwc_context_t* ctx = (hwc_context_t*)(dev);
- if(!ctx) {
- ALOGE("%s: Invalid context", __FUNCTION__);
- return;
- }
- //vsync将通过proc会调到HWComposer的vsync函数。
- ctx->proc = procs;
-
- //当有回调函数注册时,会启动uevent,vsync两个线程。uevent线程跟屏幕invalidate有关。
- init_uevent_thread(ctx);
- init_vsync_thread(ctx);
- }
//主要关注vsync线程的开启。
hwc_vsync.cpp
//创建一个线程,然后执行其vsync_loop方法。
- void init_vsync_thread(hwc_context_t* ctx){
- int ret;
- pthread_t vsync_thread;
- ret = pthread_create(&vsync_thread, NULL, vsync_loop, (void*) ctx);
- }
- static void *vsync_loop(void *param){
- //物理显示设备的个数。
- int num_displays = HWC_NUM_DISPLAY_TYPES – 1;
- //如果系统属性指定使用模拟vsync,把ctx->vstate.fakevsync = true;
- if(property_get("debug.hwc.fakevsync", property, NULL) > 0) {
- ctx->vstate.fakevsync = true;
- }
- //非模拟vsync的情况,当有多个显示设备时,对每个显示设备都要执行回调,发出通知。
- if (LIKELY(!ctx->vstate.fakevsync)) {
- do {
- for (int dpy = HWC_DISPLAY_PRIMARY; dpy < num_displays; dpy++) {
- event_list[ev].callback(ctx, dpy, vdata);
- }
- }while(true)
- }else{
- //使用模拟vsync的情况,通常是明确通过属性设置了或在开机时vsync时间戳节点还没打开,这时候会使用模拟vsync,模拟vsync指发给主显示设备。
- do {
- usleep(16666);
- uint64_t timestamp = systemTime();
- //这个回调就是执行的HWComposer的vsync方法。
- ctx->proc->vsync(ctx->proc, HWC_DISPLAY_PRIMARY, timestamp);
- }while(true)
- }
- }
HWComposer_hwc1.cpp
HWComposer这边vsync的接收函数是:hook_vsync,前面贴出的HWComposer的构造函数的代码中:mCBContext->procs.vsync= &hook_vsync; hook_vsync又调用了HWComposer的vsync方法。
- void HWComposer::vsync(int disp, int64_t timestamp) {
- //HWComposer直接通过mEventHandler把vsync信号传到surfaceflinger。
- mEventHandler.onVSyncReceived(disp, timestamp);
- }
//接着看surfaceflinger是如何处理vsync信号的。surfaceflinger中事件管理员是mEventQueue,
它是MessageQueue类型的对象,所以vsync信号肯定是要送到mEventQueue中的,是怎么送过去的呢?这个过程比想的稍微复杂了点。
- SurfaceFlinger_hwc1.cpp
- void SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) {
- bool needsHwVsync = false;
-
- { // Scope for the lock
- Mutex::Autolock _l(mHWVsyncLock);
- if (type == 0 && mPrimaryHWVsyncEnabled) {
- needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp);
- }
- }
-
- if (needsHwVsync) {
- enableHardwareVsync();
- } else {
- disableHardwareVsync(false);
- }
- }
为了说清楚vsync的接收过程,还要看几个相关的类,从surfaceflinger的初始化开始。
- void SurfaceFlinger::init() {
- sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
- vsyncPhaseOffsetNs, true, "sf-app");
- mEventThread = new EventThread(vsyncSrc, *this);
- mEventQueue.setEventThread(mEventThread);
- mHwc = DisplayUtils::getInstance()->getHWCInstance(this,
- *static_cast<HWComposer::EventHandler *>(this));
- mEventControlThread = new EventControlThread(this);
- mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
- }
在这个初始化函数中,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处理显示合成的后期会调用,判断是否要使用硬件hwc的vsync。
DispSync把sw的vsync信号,传给注册的监听者,是在线程的threadLoop循环中实现的。
- virtual bool threadLoop() {
- nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
- while (true) {
- //计算下一次的vsync时间,如果这个时间还没到,就wait一段时间差,
- targetTime = computeNextEventTimeLocked(now);
- if (now < targetTime) {
- err = mCond.waitRelative(mMutex, targetTime - now);
- }
- //获取都有那些监听,然后调用其回调onDispSyncEvent。
- callbackInvocations = gatherCallbackInvocationsLocked(now);
- fireCallbackInvocations(callbackInvocations);
- }
- }
2),接着EventControlThread怎样控制硬件vsync的开关。
- bool EventControlThread::threadLoop() {
- // mVsyncEnabled这个值在初始化 EventControlThread时赋值为false,
- bool vsyncEnabled = mVsyncEnabled;
- //这里会去调用HWComposer的实现。
- mFlinger->eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC,
- mVsyncEnabled);
- //在线程启动后,这个while循环会进入wait,直到调用它的setVsyncEnabled的方法把这个唤醒。初始化时mVsyncEnabled是false,那就是说线程刚启动时是把vsync关闭的,是后面初始化显示设备时通过 setVsyncEnabled打开了。
- while (true) {
- status_t err = mCond.wait(mMutex);
- if (err != NO_ERROR) {
- ALOGE("error waiting for new events: %s (%d)",
- strerror(-err), err);
- return false;
- }
- //唤醒后,判断要不要重新设置vsync的开、关。
- if (vsyncEnabled != mVsyncEnabled) {
- mFlinger->eventControl(HWC_DISPLAY_PRIMARY,
- SurfaceFlinger::EVENT_VSYNC, mVsyncEnabled);
- vsyncEnabled = mVsyncEnabled;
- }
- }
- //这里返回值是false,就是说这个线程的threadloop不会在被系统调用,换句话它他是一个单次循环,只是通过内部的while实现循环执行。
- return false;
- }
接着看EventControlThread线程被唤醒的条件:
- void EventControlThread::setVsyncEnabled(bool enabled) {
- Mutex::Autolock lock(mMutex);
- mVsyncEnabled = enabled;
- mCond.signal();
- }
只要有人调用setVsyncEnabled,通过mCond.signal();都会唤醒这个线程。第一次启动时谁会调用这个方法打开硬件的vsync呢?
大致列出调用逻辑以下方法都在SurfaceFlinger_hwc1.cpp中。
- void SurfaceFlinger::init() {
- //显示相关的初始化,这个调用在EventControlThread线程运行起来之后。
- initializeDisplays();
- }
通过异步消息,调用了onInitializeDisplays();
- void SurfaceFlinger::initializeDisplays() {
- class MessageScreenInitialized : public MessageBase {
- virtual bool handler() {
- flinger->onInitializeDisplays();
- }
- };
- sp<MessageBase> msg = new MessageScreenInitialized(this);
- postMessageAsync(msg);
- }
- void SurfaceFlinger::onInitializeDisplays() {
- //这个方法在每次点亮屏幕时都会被调用,针对主显示屏来说,应该是每次点两屏,都会重新打开硬件模块hwc的vsync。
- setPowerModeInternal(getDisplayDevice(d.token), HWC_POWER_MODE_NORMAL);
- }
既然点亮屏时会enable硬件hwc的vsync,息屏时也会disable硬件hwc的vsync。
- void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& hw,
- int mode) {
- mEventThread->onScreenAcquired();
- resyncToHardwareVsync(true);
- }
- void SurfaceFlinger::resyncToHardwareVsync(bool makeAvailable) {
- //这里调用了EventControlThread中的 setVsyncEnabled,参数true,会enable硬件的vsync。同时注意这里的变量 mPrimaryHWVsyncEnabled = true,这个变量是 SurfaceFlinger::onVSyncReceived的中一个判断条件,在收到硬件hwc的vsync回调时,判断要不要disable硬件vsync。
- mEventControlThread->setVsyncEnabled(true);
- mPrimaryHWVsyncEnabled = true;
- }
最后看看mFlinger->eventControl()是如何控制vsync的。
- void SurfaceFlinger::eventControl(int disp, int event, int enabled) {
- ATRACE_CALL();
- //直接调用了HWComposer_hwc1.cpp中的实现。
- getHwComposer().eventControl(disp, event, enabled);
- }
- void HWComposer::eventControl(int disp, int event, int enabled) @HWComposer_hwc1.cpp{
- err = mHwc->eventControl(mHwc, disp, event, enabled);
- //根据enabled,让HWComposer::VSyncThread::VSyncThread线程wait或者唤醒。
- mVSyncThread->setEnabled(enabled);
- }
mHwc->eventControl()最终的实现在hwc_vsync.cpp,通过IO命令控制硬件vsync。
- int hwc_vsync_control(hwc_context_t* ctx, int dpy, int enable)@hwc_vsync.cpp{
- ioctl(ctx->dpyAttr[dpy].fd, MSMFB_OVERLAY_VSYNC_CTRL, &enable);
- }
3),DispSyncSource,这个类是SurfaceFlinger_hwc1.cpp的内部类,他的构造函数中持有DispSync的引用,即mDispSync,这个类的主要功能是通过mDispSync添加、删除对vsync(DispSync中的)的监听,并接收vsync(来自DispSync)回调。
这个函数虽然也叫vsyncenabled,实际只是向DispSync添加、删除对vsync的监听。
- virtual void setVSyncEnabled(bool enable) @SurfaceFlinger_hwc1.cpp$DispSyncSource{
- if (enable) {
- status_t err = mDispSync->addEventListener(mName, mPhaseOffset,
- static_cast<DispSync::Callback*>(this));
- }else{
- status_t err = mDispSync→removeEventListener(
- static_cast<DispSync::Callback*>(this));
- }
- }
向DispSync注册的监听vsync的回调类型是DispSync::Callback,DispSyncSource继承了这个类,并实现了其中的方法onDispSyncEvent。
DispSync会把软件vsync信号通过注册的监听,回调其onDispSyncEvent函数。
- virtual void onDispSyncEvent(nsecs_t when) @SurfaceFlinger_hwc1.cpp$DispSyncSource{
- sp<VSyncSource::Callback> callback;
- callback = mCallback;
- callback->onVSyncEvent(when);
- }
这里出现了VSyncSource::Callback的回调,vsync信号会传到VSyncSource::Callback类中的onVSyncEvent函数。
这个VSyncSource::Callback的实现具体是什么?
在surfaceflinger的初始化(init()函数)中,有这么一句代码:
mEventThread = new EventThread(vsyncSrc, *this);
其中参数vsyncSrc就是DispSyncSource,所以接着看EventThread线程的实现。这个线程在他第一次被引用时,由其强指针的特性执行其onFirstRef方法,让这个线程运行起来,第一次被引用的地方就是紧接着实例化其对象的代码:
mEventQueue.setEventThread(mSFEventThread);
这里让surfaceflinger的消息管理员mEventQueue(MessageQueue)跟EventThread线程绑定,现在越来越接近目标了,还记得分析这段的目的是想弄明白vsync信号是怎么传到surfaceflinger的mEventQueue的。
- bool EventThread::threadLoop() @EventThread.cpp{
- signalConnections = waitForEvent(&event);
- }
waitForEvent会调用下面的enableVSyncLocked函数,然后通过DispSyncSource的setCallback函数,设置一个类型是VSyncSource::Callback的回调,这个回调的实现端就是EventThread自身。
- void EventThread::enableVSyncLocked() @EventThread.cpp{
- mVSyncSource->setCallback(static_cast<VSyncSource::Callback*>(this));
- }
所以前面DispSync会先把vsync信号通过回调传到DispSyncSource的onDispSyncEvent,最后在传到EventThread的onVSyncEvent函数。
4),EventThread是如何处理vsync信号的。
- void EventThread::onVSyncEvent(nsecs_t timestamp) @EventThread.cpp{
- Mutex::Autolock _l(mLock);
- mVSyncEvent[0].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
- mVSyncEvent[0].header.id = 0;
- mVSyncEvent[0].header.timestamp = timestamp;
- mVSyncEvent[0].vsync.count++;
- mCondition.broadcast();
- }
上面的函数做了两件事情,一是填充了DisplayEventReceiver::Event类型的事件对象mVSyncEvent,主要包括事件的类型DisplayEventReceiver::DISPLAY_EVENT_VSYNC,还有事件戳timestamp。另外一个事情是mCondition.broadcast(),唤醒等待的EventThread线程。
EventThread线程什么情况下wait的呢?一种情况是没有对vsync感兴趣的客户端,另一种情况是正在等待vsync信号的产生,还有一种情况是当前屏幕是off,不需要vsync,这是会进入一个16ms的超时等待。
唤醒之后,线程继续循环。
- bool EventThread::threadLoop() @EventThread.cpp{
- DisplayEventReceiver::Event event;
- Vector< sp<EventThread::Connection> > signalConnections;
- //线程就是在waitForEvent中进入等待的。
- signalConnections = waitForEvent(&event);
- //开始分发vsync给所有的监听者,eventthread处理的事件不是只有vsync,还有DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG;
- const size_t count = signalConnections.size();
- for (size_t i=0 ; i<count ; i++) {
- const sp<Connection>& conn(signalConnections[i]);
- status_t err = conn->postEvent(event);
- }
- //返回值true,系统会再次调用这个线程的threadloop,从而形成一个循环。
- return true;
- }
waitForEvent除了会让线程进入wait,还有一个作用是找出等待事件的connections,也即是对vsync感兴趣的监听者,找出来后保存在signalConnections中。所有对vsync感兴趣的监听者都会被保存在mDisplayEventConnections中。
通常有两类监听者,
一类是surfaceflinger,它负责UI数据的合成,肯定要受vsync信号的触发。负责vsync接收的是surfaceflinger的事件管理员MessageQueue,相应的实例对象是mEventQueue,前面提到当实例化EventThread对象后,mEventQueue就跟EventThread执行了绑定,具体代码:
- void MessageQueue::setEventThread(const sp<EventThread>& eventThread)
- {
- mEventThread = eventThread;
- mEvents = eventThread->createEventConnection();
- mEventTube = mEvents->getDataChannel();
- mLooper->addFd(mEventTube->getFd(), 0, Looper::EVENT_INPUT,
- MessageQueue::cb_eventReceiver, this);
- }
首先通过eventThread的接口createEventConnection创建了一个Connection,赋值给mEvents,并且当这个Connection实例被引用时,会执行其onFirstRef方法,将这个Connection注册到EventThread中,把这个connection保存到EventThread中的变量mDisplayEventConnections中。
- void EventThread::Connection::onFirstRef() {
- mEventThread->registerDisplayEventConnection(this);
- }
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,我们知道主线程循环从消息队列中取消息时,会调用Looper的pollOnce,然后是pollInner,在这个pollInner中,只要有事件需要处理,就会执行其callback函数,在这个场景中,就会执行MessageQueue::cb_eventReceiver。
弄清楚了事件的接收端,那事件的发送端在哪里呢?负责发送的服务端就是EventThread,具体实现就是下面的postEvent:
- bool EventThread::threadLoop() {
- status_t err = conn->postEvent(event);
- }
//mChannel就是前面说的BitTube,会通过其mSendFd把event数据写入。
- status_t EventThread::Connection::postEvent(
- const DisplayEventReceiver::Event& event) {
- ssize_t size = DisplayEventReceiver::sendEvents(mChannel, &event, 1);
- return size < 0 ? status_t(size) : status_t(NO_ERROR);
- }
第二类对vsync感兴趣的监听者是应用程序,不在详细分析,只把它创建connection的过程列一下。
每一个有窗口的应用进程,都会有一个渲染线程RenderThread,
- frameworks/base/libs/hwui/renderthread/
- bool RenderThread::threadLoop() @RenderThread.cpp{
- initThreadLocals();
- }
- void RenderThread::initThreadLocals() {
- initializeDisplayEventReceiver();
- }
//接收vsync的回调RenderThread::displayEventReceiverCallback,
- void RenderThread::initializeDisplayEventReceiver() {
- mDisplayEventReceiver = new DisplayEventReceiver();
- mLooper->addFd(mDisplayEventReceiver->getFd(), 0,
- Looper::EVENT_INPUT, RenderThread::displayEventReceiverCallback, this);
- }
//先获取surfaceflinger的句柄
ISurfaceComposer。
- DisplayEventReceiver::DisplayEventReceiver() {
- sp<ISurfaceComposer> sf(ComposerService::getComposerService());
- if (sf != NULL) {
- mEventConnection = sf->createDisplayEventConnection();
- if (mEventConnection != NULL) {
- mDataChannel = mEventConnection->getDataChannel();
- }
- }
- }
//调用eventthread中接口createEventConnection。
- sp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
- return mEventThread->createEventConnection();
- }
- sp<EventThread::Connection> EventThread::createEventConnection() const {
- return new Connection(const_cast<EventThread*>(this));
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。